Annotation of hatari/src/debug/debugdsp.c, revision 1.1.1.8

1.1       root        1: /*
                      2:   Hatari - debugdsp.c
                      3: 
1.1.1.5   root        4:   This file is distributed under the GNU General Public License, version 2
                      5:   or at your option any later version. Read the file gpl.txt for details.
1.1       root        6: 
                      7:   debugdsp.c - function needed for the DSP debugging tasks like memory
                      8:   and register dumps.
                      9: */
                     10: const char DebugDsp_fileid[] = "Hatari debugdsp.c : " __DATE__ " " __TIME__;
                     11: 
                     12: #include <stdio.h>
1.1.1.6   root       13: #include <ctype.h>
1.1       root       14: 
                     15: #include "config.h"
                     16: 
                     17: #include "main.h"
                     18: #include "breakcond.h"
                     19: #include "configuration.h"
                     20: #include "debugui.h"
                     21: #include "debug_priv.h"
                     22: #include "debugdsp.h"
                     23: #include "dsp.h"
                     24: #include "evaluate.h"
1.1.1.3   root       25: #include "history.h"
1.1.1.4   root       26: #include "log.h"
1.1       root       27: #include "memorySnapShot.h"
1.1.1.2   root       28: #include "profile.h"
1.1       root       29: #include "str.h"
                     30: #include "symbols.h"
                     31: 
                     32: static Uint16 dsp_disasm_addr;    /* DSP disasm address */
                     33: static Uint16 dsp_memdump_addr;   /* DSP memdump address */
                     34: static char dsp_mem_space = 'P';  /* X, Y, P */
                     35: 
1.1.1.2   root       36: static bool bDspProfiling;        /* Whether profiling is enabled */
1.1       root       37: static int nDspActiveCBs = 0;     /* Amount of active conditional breakpoints */
                     38: static int nDspSteps = 0;         /* Amount of steps for DSP single-stepping */
                     39: 
                     40: 
                     41: /**
                     42:  * Readline match callback to list register names usable within debugger.
                     43:  * STATE = 0 -> different text from previous one.
                     44:  * Return next match or NULL if no matches.
                     45:  */
                     46: static char *DebugDsp_MatchRegister(const char *text, int state)
                     47: {
1.1.1.6   root       48:        static const char* regs[] = {
1.1       root       49:                "a0", "a1", "a2", "b0", "b1", "b2", "la", "lc",
                     50:                "m0", "m1", "m2", "m3", "m4", "m5", "m6", "m7",
                     51:                "n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7",
                     52:                "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
                     53:                "omr", "pc", "sp", "sr", "ssh", "ssl",
                     54:                "x0", "x1", "y0", "y1",
                     55:        };
1.1.1.8 ! root       56:        return DebugUI_MatchHelper(regs, ARRAY_SIZE(regs), text, state);
1.1       root       57: }
                     58: 
                     59: /**
                     60:  * Command: Dump or set a DSP register
                     61:  */
                     62: int DebugDsp_Register(int nArgc, char *psArgs[])
                     63: {
                     64:        char *assign;
                     65:        Uint32 value;
                     66:        char *arg;
                     67: 
                     68:        if (!bDspEnabled)
                     69:        {
                     70:                fprintf(stderr, "DSP isn't present or initialized.\n");
                     71:                return DEBUGGER_CMDDONE;
                     72:        }
                     73: 
                     74:        if (nArgc == 1)
                     75:        {
                     76:                /* No parameter - dump all registers */
1.1.1.8 ! root       77:                DSP_DisasmRegisters(debugOutput);
        !            78:                fflush(debugOutput);
1.1       root       79:                return DEBUGGER_CMDDONE;
                     80:        }
                     81:        arg = psArgs[1];
                     82: 
                     83:        assign = strchr(arg, '=');
                     84:        if (!assign)
                     85:                goto error_msg;
                     86: 
                     87:        *assign++ = '\0';
                     88:        if (!Eval_Number(Str_Trim(assign), &value))
                     89:                goto error_msg;
                     90: 
                     91:        if (DSP_Disasm_SetRegister(Str_Trim(arg), value))
                     92:            return DEBUGGER_CMDDONE;
                     93: 
                     94: error_msg:
                     95:        fprintf(stderr,"\tError, usage: dr or dr xx=yyyy\n"
                     96:                "\tWhere: xx=A0-A2, B0-B2, X0, X1, Y0, Y1, R0-R7,\n"
                     97:                "\t       N0-N7, M0-M7, LA, LC, PC, SR, SP, OMR, SSH, SSL\n");
                     98: 
                     99:        return DEBUGGER_CMDDONE;
                    100: }
                    101: 
                    102: 
                    103: /**
1.1.1.2   root      104:  * Check whether given address matches any DSP symbol and whether
                    105:  * there's profiling information available for it.  If yes, show it.
1.1       root      106:  */
1.1.1.8 ! root      107: static void DebugDsp_ShowAddressInfo(Uint16 addr, FILE *fp)
1.1       root      108: {
1.1.1.4   root      109:        const char *symbol = Symbols_GetByDspAddress(addr);
1.1       root      110:        if (symbol)
1.1.1.8 ! root      111:                fprintf(fp, "%s:\n", symbol);
1.1       root      112: }
                    113: 
                    114: 
                    115: /**
                    116:  * DSP dissassemble - arg = starting address/range, or PC.
                    117:  */
                    118: int DebugDsp_DisAsm(int nArgc, char *psArgs[])
                    119: {
                    120:        Uint32 lower, upper;
                    121:        Uint16 dsp_disasm_upper = 0;
                    122: 
                    123:        if (!bDspEnabled)
                    124:        {
                    125:                fprintf(stderr, "DSP isn't present or initialized.\n");
                    126:                return DEBUGGER_CMDDONE;
                    127:        }
                    128: 
                    129:        if (nArgc > 1)
                    130:        {
1.1.1.2   root      131:                switch (Eval_Range(psArgs[1], &lower, &upper, true))
1.1       root      132:                {
                    133:                        case -1:
                    134:                                /* invalid value(s) */
                    135:                                return DEBUGGER_CMDDONE;
                    136:                        case 0:
                    137:                                /* single value */
                    138:                                break;
                    139:                        case 1:
                    140:                                /* range */
                    141:                                if (upper > 0xFFFF)
                    142:                                {
                    143:                                        fprintf(stderr,"Invalid address 0x%x!\n", upper);
                    144:                                        return DEBUGGER_CMDDONE;
                    145:                                }
                    146:                                dsp_disasm_upper = upper;
                    147:                                break;
                    148:                }
                    149: 
                    150:                if (lower > 0xFFFF)
                    151:                {
                    152:                        fprintf(stderr,"Invalid address 0x%x!\n", lower);
                    153:                        return DEBUGGER_CMDDONE;
                    154:                }
                    155:                dsp_disasm_addr = lower;
                    156:        }
                    157:        else
                    158:        {
                    159:                /* continue */
                    160:                if(!dsp_disasm_addr)
                    161:                {
                    162:                        dsp_disasm_addr = DSP_GetPC();
                    163:                }
                    164:        }
                    165:        if (!dsp_disasm_upper)
                    166:        {
                    167:                int lines = ConfigureParams.Debugger.nDisasmLines;
                    168:                if ( dsp_disasm_addr < (0xFFFF - lines))
                    169:                        dsp_disasm_upper = dsp_disasm_addr + lines;
                    170:                else
                    171:                        dsp_disasm_upper = 0xFFFF;
                    172:        }
1.1.1.8 ! root      173:        fprintf(debugOutput, "DSP disasm 0x%hx-0x%hx:\n", dsp_disasm_addr, dsp_disasm_upper);
1.1       root      174:        while (dsp_disasm_addr < dsp_disasm_upper) {
1.1.1.8 ! root      175:                DebugDsp_ShowAddressInfo(dsp_disasm_addr, debugOutput);
        !           176:                dsp_disasm_addr = DSP_DisasmAddress(debugOutput, dsp_disasm_addr, dsp_disasm_addr);
1.1       root      177:        }
1.1.1.8 ! root      178:        fflush(debugOutput);
1.1       root      179: 
                    180:        return DEBUGGER_CMDCONT;
                    181: }
                    182: 
                    183: 
                    184: /**
                    185:  * Do a DSP memory dump, args = starting address or range.
                    186:  * <x|y|p> <address>: dump from X, Y or P, starting from given address,
                    187:  * e.g. "x 200" or "p 200-300"
                    188:  */
                    189: int DebugDsp_MemDump(int nArgc, char *psArgs[])
                    190: {
                    191:        Uint32 lower, upper;
                    192:        Uint16 dsp_memdump_upper = 0;
1.1.1.6   root      193:        char *range, space;
1.1       root      194: 
                    195:        if (!bDspEnabled)
                    196:        {
                    197:                fprintf(stderr, "DSP isn't present or initialized.\n");
                    198:                return DEBUGGER_CMDDONE;
                    199:        }
1.1.1.6   root      200: 
                    201:        switch (nArgc)
1.1       root      202:        {
1.1.1.6   root      203:                case 1:
                    204:                        break;
                    205:                case 3: /* "x $200" */
                    206:                        space = psArgs[1][0];
                    207:                        range = psArgs[2];
                    208:                        break;
                    209:                case 2: /* "x:$200" */
                    210:                        if (psArgs[1][1] == ':')
                    211:                        {
                    212:                                space = psArgs[1][0];
                    213:                                range = psArgs[1] + 2;
                    214:                                break;
                    215:                        }
                    216:                        /* pass-through */
                    217:                default:
                    218:                        return DebugUI_PrintCmdHelp(psArgs[0]);
1.1       root      219:        }
                    220: 
1.1.1.6   root      221:        if (nArgc > 1)
1.1       root      222:        {
1.1.1.6   root      223:                space = toupper((unsigned char)space);
1.1       root      224:                switch (space)
                    225:                {
                    226:                case 'X':
                    227:                case 'Y':
                    228:                case 'P':
                    229:                        break;
                    230:                default:
                    231:                        fprintf(stderr,"Invalid DSP address space '%c'!\n", space);
                    232:                        return DEBUGGER_CMDDONE;
                    233:                }
1.1.1.6   root      234:                switch (Eval_Range(range, &lower, &upper, true))
1.1       root      235:                {
                    236:                case -1:
                    237:                        /* invalid value(s) */
                    238:                        return DEBUGGER_CMDDONE;
                    239:                case 0:
                    240:                        /* single value */
                    241:                        break;
                    242:                case 1:
                    243:                        /* range */
                    244:                        if (upper > 0xFFFF)
                    245:                        {
                    246:                                fprintf(stderr,"Invalid address 0x%x!\n", upper);
                    247:                                return DEBUGGER_CMDDONE;
                    248:                        }
                    249:                        dsp_memdump_upper = upper;
                    250:                        break;
                    251:                }
                    252:                if (lower > 0xFFFF)
                    253:                {
                    254:                        fprintf(stderr,"Invalid address 0x%x!\n", lower);
                    255:                        return DEBUGGER_CMDDONE;
                    256:                }
                    257:                dsp_memdump_addr = lower;
                    258:                dsp_mem_space = space;
1.1.1.6   root      259:        }
1.1       root      260: 
                    261:        if (!dsp_memdump_upper)
                    262:        {
                    263:                int lines = ConfigureParams.Debugger.nMemdumpLines;
                    264:                if ( dsp_memdump_addr < (0xFFFF - lines))
                    265:                        dsp_memdump_upper = dsp_memdump_addr + lines;
                    266:                else
                    267:                        dsp_memdump_upper = 0xFFFF;
                    268:        }
                    269: 
1.1.1.8 ! root      270:        fprintf(debugOutput, "DSP memdump from 0x%hx in '%c' address space:\n", dsp_memdump_addr, dsp_mem_space);
        !           271:        dsp_memdump_addr = DSP_DisasmMemory(debugOutput, dsp_memdump_addr, dsp_memdump_upper, dsp_mem_space);
        !           272:        fflush(debugOutput);
1.1       root      273: 
                    274:        return DEBUGGER_CMDCONT;
                    275: }
                    276: 
                    277: 
                    278: /**
                    279:  * Command: Continue DSP emulation / single-stepping
                    280:  */
                    281: static int DebugDsp_Continue(int nArgc, char *psArgv[])
                    282: {
                    283:        int steps = 0;
                    284:        
                    285:        if (nArgc > 1)
                    286:        {
                    287:                steps = atoi(psArgv[1]);
                    288:        }
                    289:        if (steps <= 0)
                    290:        {
                    291:                nDspSteps = 0;
                    292:                fprintf(stderr,"Returning to emulation...\n");
                    293:                return DEBUGGER_END;
                    294:        }
                    295:        nDspSteps = steps;
                    296:        fprintf(stderr,"Returning to emulation for %i DSP instructions...\n", steps);
                    297:        return DEBUGGER_END;
                    298: }
                    299: 
1.1.1.5   root      300: /**
                    301:  * Command: Single-step DSP
                    302:  */
                    303: static int DebugDsp_Step(int nArgc, char *psArgv[])
                    304: {
                    305:        nDspSteps = 1;
                    306:        return DEBUGGER_END;
                    307: }
                    308: 
1.1.1.6   root      309: 
                    310: /**
                    311:  * Readline match callback to list next command opcode types.
                    312:  * STATE = 0 -> different text from previous one.
                    313:  * Return next match or NULL if no matches.
                    314:  */
                    315: static char *DebugDsp_MatchNext(const char *text, int state)
                    316: {
                    317:        static const char* ntypes[] = {
                    318:                "branch", "exreturn", "return", "subcall", "subreturn"
                    319:        };
1.1.1.8 ! root      320:        return DebugUI_MatchHelper(ntypes, ARRAY_SIZE(ntypes), text, state);
1.1.1.6   root      321: }
                    322: 
1.1.1.5   root      323: /**
                    324:  * Command: Step DSP, but proceed through subroutines
                    325:  * Does this by temporary conditional breakpoint
                    326:  */
                    327: static int DebugDsp_Next(int nArgc, char *psArgv[])
                    328: {
1.1.1.6   root      329:        char command[40];
                    330:        if (nArgc > 1)
                    331:        {
                    332:                int optype;
                    333:                if(strcmp(psArgv[1], "branch") == 0)
                    334:                        optype = CALL_BRANCH;
                    335:                else if(strcmp(psArgv[1], "exreturn") == 0)
                    336:                        optype = CALL_EXCRETURN;
                    337:                else if(strcmp(psArgv[1], "subcall") == 0)
                    338:                        optype = CALL_SUBROUTINE;
                    339:                else if (strcmp(psArgv[1], "subreturn") == 0)
                    340:                        optype = CALL_SUBRETURN;
                    341:                else if (strcmp(psArgv[1], "return") == 0)
                    342:                        optype = CALL_SUBRETURN | CALL_EXCRETURN;
                    343:                else
                    344:                {
                    345:                        fprintf(stderr, "Unrecognized opcode type given!\n");
                    346:                        return DEBUGGER_CMDDONE;
                    347:                }
                    348:                sprintf(command, "DspOpcodeType & $%x > 0 :once :quiet\n", optype);
                    349:        }
                    350:        else
                    351:        {
                    352:                Uint32 optype;
                    353:                Uint16 nextpc;
                    354: 
                    355:                optype = DebugDsp_OpcodeType();
                    356:                /* can this instruction be stepped normally? */
                    357:                if (optype != CALL_SUBROUTINE && optype != CALL_EXCEPTION)
                    358:                {
                    359:                        nDspSteps = 1;
                    360:                        return DEBUGGER_END;
                    361:                }
                    362: 
                    363:                nextpc = DSP_GetNextPC(DSP_GetPC());
                    364:                sprintf(command, "pc=$%x :once :quiet\n", nextpc);
                    365:        }
                    366:        /* use breakpoint, not steps */
1.1.1.5   root      367:        if (BreakCond_Command(command, true)) {
1.1.1.6   root      368:                nDspSteps = 0;
1.1.1.5   root      369:                return DEBUGGER_END;
                    370:        }
                    371:        return DEBUGGER_CMDDONE;
                    372: }
                    373: 
1.1.1.6   root      374: /* helper to get instruction type, slightly simpler
                    375:  * version from one in profiledsp.c
                    376:  */
                    377: Uint32 DebugDsp_OpcodeType(void)
                    378: {
                    379:        const char *dummy;
                    380:        Uint32 opcode;
                    381: 
                    382:        /* 24-bit instruction opcode */
                    383:        opcode = DSP_ReadMemory(DSP_GetPC(), 'P', &dummy) & 0xFFFFFF;
                    384: 
                    385:        /* subroutine returns */
                    386:        if (opcode == 0xC) {    /* (just) RTS */
                    387:                return CALL_SUBRETURN;
                    388:        }
                    389:        if (
                    390:            /* unconditional subroutine calls */
                    391:            (opcode & 0xFFF000) == 0xD0000 ||   /* JSR   00001101 0000aaaa aaaaaaaa */
                    392:            (opcode & 0xFFC0FF) == 0xBC080 ||   /* JSR   00001011 11MMMRRR 10000000 */
                    393:            /* conditional subroutine calls */
                    394:            (opcode & 0xFF0000) == 0xF0000 ||   /* JSCC  00001111 CCCCaaaa aaaaaaaa */
                    395:            (opcode & 0xFFC0F0) == 0xBC0A0 ||   /* JSCC  00001011 11MMMRRR 1010CCCC */
                    396:            (opcode & 0xFFC0A0) == 0xB4080 ||   /* JSCLR 00001011 01MMMRRR 1S0bbbbb */
                    397:            (opcode & 0xFFC0A0) == 0xB0080 ||   /* JSCLR 00001011 00aaaaaa 1S0bbbbb */
                    398:            (opcode & 0xFFC0A0) == 0xB8080 ||   /* JSCLR 00001011 10pppppp 1S0bbbbb */
                    399:            (opcode & 0xFFC0E0) == 0xBC000 ||   /* JSCLR 00001011 11DDDDDD 000bbbbb */
                    400:            (opcode & 0xFFC0A0) == 0xB40A0 ||   /* JSSET 00001011 01MMMRRR 1S1bbbbb */
                    401:            (opcode & 0xFFC0A0) == 0xB00A0 ||   /* JSSET 00001011 00aaaaaa 1S1bbbbb */
                    402:            (opcode & 0xFFC0A0) == 0xB80A0 ||   /* JSSET 00001011 10pppppp 1S1bbbbb */
                    403:            (opcode & 0xFFC0E0) == 0xBC020) {   /* JSSET 00001011 11DDDDDD 001bbbbb */
                    404:                return CALL_SUBROUTINE;
                    405:        }
                    406:        /* exception handler returns */
                    407:        if (opcode == 0x4) {    /* (just) RTI */
                    408:                return CALL_EXCRETURN;
                    409:        }
                    410:        /* branches */
                    411:        if ((opcode & 0xFFF000) == 0xC0000 ||   /* JMP  00001100 0000aaaa aaaaaaaa */
                    412:            (opcode & 0xFFC0FF) == 0xAC080 ||   /* JMP  00001010 11MMMRRR 10000000 */
                    413:            (opcode & 0xFF0000) == 0xE0000 ||   /* JCC  00001110 CCCCaaaa aaaaaaaa */
                    414:            (opcode & 0xFFC0F0) == 0xAC0A0 ||   /* JCC  00001010 11MMMRRR 1010CCCC */
                    415:            (opcode & 0xFFC0A0) == 0xA8080 ||   /* JCLR 00001010 10pppppp 1S0bbbbb */
                    416:            (opcode & 0xFFC0A0) == 0xA4080 ||   /* JCLR 00001010 01MMMRRR 1S0bbbbb */
                    417:            (opcode & 0xFFC0A0) == 0xA0080 ||   /* JCLR 00001010 00aaaaaa 1S0bbbbb */
                    418:            (opcode & 0xFFC0E0) == 0xAC000 ||   /* JCLR 00001010 11dddddd 000bbbbb */
                    419:            (opcode & 0xFFC0A0) == 0xA80A0 ||   /* JSET 00001010 10pppppp 1S1bbbbb */
                    420:            (opcode & 0xFFC0A0) == 0xA40A0 ||   /* JSET 00001010 01MMMRRR 1S1bbbbb */
                    421:            (opcode & 0xFFC0A0) == 0xA00A0 ||   /* JSET 00001010 00aaaaaa 1S1bbbbb */
                    422:            (opcode & 0xFFC0E0) == 0xAC020 ||   /* JSET 00001010 11dddddd 001bbbbb */
                    423:            (opcode & 0xFF00F0) == 0x600A0 ||   /* REP  00000110 iiiiiiii 1010hhhh */
                    424:            (opcode & 0xFFC0FF) == 0x6C020 ||   /* REP  00000110 11dddddd 00100000 */
                    425:            (opcode & 0xFFC0BF) == 0x64020 ||   /* REP  00000110 01MMMRRR 0s100000 */
                    426:            (opcode & 0xFFC0BF) == 0x60020 ||   /* REP  00000110 00aaaaaa 0s100000 */
                    427:            (opcode & 0xFF00F0) == 0x60080 ||   /* DO/ENDO 00000110 iiiiiiii 1000hhhh */
                    428:            (opcode & 0xFFC0FF) == 0x6C000 ||   /* DO/ENDO 00000110 11DDDDDD 00000000 */
                    429:            (opcode & 0xFFC0BF) == 0x64000 ||   /* DO/ENDO 00000110 01MMMRRR 0S000000 */
                    430:            (opcode & 0xFFC0BF) == 0x60000) {   /* DO/ENDO 00000110 00aaaaaa 0S000000 */
                    431:                return CALL_BRANCH;
                    432:        }
                    433:        return CALL_UNKNOWN;
                    434: }
                    435: 
1.1       root      436: 
                    437: /**
1.1.1.2   root      438:  * DSP wrapper for BreakAddr_Command().
1.1       root      439:  */
                    440: static int DebugDsp_BreakAddr(int nArgc, char *psArgs[])
                    441: {
                    442:        BreakAddr_Command(psArgs[1], true);
                    443:        return DEBUGGER_CMDDONE;
                    444: }
                    445: 
                    446: /**
1.1.1.2   root      447:  * DSP wrapper for BreakCond_Command().
1.1       root      448:  */
                    449: static int DebugDsp_BreakCond(int nArgc, char *psArgs[])
                    450: {
                    451:        BreakCond_Command(psArgs[1], true);
                    452:        return DEBUGGER_CMDDONE;
                    453: }
                    454: 
1.1.1.2   root      455: /**
                    456:  * DSP wrapper for Profile_Command().
                    457:  */
                    458: static int DebugDsp_Profile(int nArgc, char *psArgs[])
                    459: {
1.1.1.5   root      460:        return Profile_Command(nArgc, psArgs, true);
1.1.1.2   root      461: }
                    462: 
1.1       root      463: 
                    464: /**
1.1.1.6   root      465:  * DSP instructions since continuing emulation
                    466:  */
                    467: static Uint32 nDspInstructions;
                    468: Uint32 DebugDsp_InstrCount(void)
                    469: {
                    470:        return nDspInstructions;
                    471: }
                    472: 
                    473: /**
1.1       root      474:  * This function is called after each DSP instruction when debugging is enabled.
                    475:  */
                    476: void DebugDsp_Check(void)
                    477: {
1.1.1.6   root      478:        nDspInstructions++;
1.1.1.2   root      479:        if (bDspProfiling)
                    480:        {
                    481:                Profile_DspUpdate();
                    482:        }
1.1.1.4   root      483:        if (LOG_TRACE_LEVEL((TRACE_DSP_DISASM|TRACE_DSP_SYMBOLS)))
                    484:        {
1.1.1.8 ! root      485:                DebugDsp_ShowAddressInfo(DSP_GetPC(), TraceFile);
1.1.1.4   root      486:        }
1.1       root      487:        if (nDspActiveCBs)
                    488:        {
                    489:                if (BreakCond_MatchDsp())
1.1.1.5   root      490:                {
1.1.1.3   root      491:                        DebugUI(REASON_DSP_BREAKPOINT);
1.1.1.5   root      492:                        /* make sure we don't decrease step count
                    493:                         * below, before even getting out of here
                    494:                         */
                    495:                        if (nDspSteps)
                    496:                                nDspSteps++;
                    497:                }
1.1       root      498:        }
                    499:        if (nDspSteps)
                    500:        {
1.1.1.5   root      501:                nDspSteps--;
1.1       root      502:                if (nDspSteps == 0)
1.1.1.3   root      503:                        DebugUI(REASON_DSP_STEPS);
                    504:        }
1.1.1.5   root      505:        if (History_TrackDsp())
1.1.1.3   root      506:        {
                    507:                History_AddDsp();
1.1       root      508:        }
                    509: }
                    510: 
                    511: 
                    512: /**
                    513:  * Should be called before returning back emulation to tell the DSP core
                    514:  * to call us after each instruction if "real-time" debugging like
                    515:  * breakpoints has been set.
                    516:  */
                    517: void DebugDsp_SetDebugging(void)
                    518: {
1.1.1.2   root      519:        bDspProfiling = Profile_DspStart();
1.1.1.7   root      520:        nDspActiveCBs = BreakCond_DspBreakPointCount();
1.1.1.2   root      521: 
1.1.1.5   root      522:        if (nDspActiveCBs || nDspSteps || bDspProfiling || History_TrackDsp()
1.1.1.4   root      523:            || LOG_TRACE_LEVEL((TRACE_DSP_DISASM|TRACE_DSP_SYMBOLS)))
1.1.1.6   root      524:        {
1.1       root      525:                DSP_SetDebugging(true);
1.1.1.6   root      526:                nDspInstructions = 0;
                    527:        }
1.1       root      528:        else
                    529:                DSP_SetDebugging(false);
                    530: }
                    531: 
                    532: 
                    533: static const dbgcommand_t dspcommands[] =
                    534: {
                    535:        { NULL, NULL, "DSP commands", NULL, NULL, NULL, false },
                    536:        { DebugDsp_BreakAddr, Symbols_MatchDspCodeAddress,
                    537:          "dspaddress", "da",
                    538:          "set DSP PC address breakpoints",
                    539:          BreakAddr_Description,
                    540:          true },
1.1.1.8 ! root      541:        /* currently no DSP variables, so checks that DSP symbol addresses */
        !           542:        { DebugDsp_BreakCond, Symbols_MatchDspAddress,
1.1       root      543:          "dspbreak", "db",
                    544:          "set/remove/list conditional DSP breakpoints",
                    545:          BreakCond_Description,
                    546:          true },
                    547:        { DebugDsp_DisAsm, Symbols_MatchDspCodeAddress,
                    548:          "dspdisasm", "dd",
                    549:          "disassemble DSP code",
                    550:          "[<start address>[-<end address>]]\n"
                    551:          "\tDisassemble from DSP-PC, otherwise at given address.",
                    552:          false },
                    553:        { DebugDsp_MemDump, Symbols_MatchDspDataAddress,
                    554:          "dspmemdump", "dm",
                    555:          "dump DSP memory",
                    556:          "[<x|y|p> <start address>[-<end address>]]\n"
                    557:          "\tdump DSP memory from given memory space and address, or\n"
                    558:          "\tcontinue from previous address if not specified.",
                    559:          false },
                    560:        { Symbols_Command, NULL,
                    561:          "dspsymbols", "",
                    562:          "load DSP symbols & their addresses",
                    563:          Symbols_Description,
                    564:          false },
1.1.1.2   root      565:        { DebugDsp_Profile, Profile_Match,
                    566:          "dspprofile", "dp",
                    567:          "profile DSP code",
                    568:          Profile_Description,
                    569:          false },
1.1       root      570:        { DebugDsp_Register, DebugDsp_MatchRegister,
                    571:          "dspreg", "dr",
                    572:          "read/write DSP registers",
                    573:          "[REG=value]"
                    574:          "\tSet or dump contents of DSP registers.",
                    575:          true },
1.1.1.5   root      576:        { DebugDsp_Step, NULL,
                    577:          "dspstep", "ds",
                    578:          "single-step DSP",
                    579:          "\n"
                    580:          "\tExecute next DSP instruction (equals 'dc 1')",
                    581:          false },
1.1.1.6   root      582:        { DebugDsp_Next, DebugDsp_MatchNext,
1.1.1.5   root      583:          "dspnext", "dn",
1.1.1.6   root      584:          "step DSP through subroutine calls / to given instruction type",
                    585:          "[instruction type]\n"
                    586:          "\tSame as 'dspstep' command if there are no subroutine calls.\n"
                    587:           "\tWhen there are, those calls are treated as one instruction.\n"
                    588:          "\tIf argument is given, continues until instruction of given\n"
                    589:          "\ttype is encountered.",
1.1.1.5   root      590:          false },
1.1       root      591:        { DebugDsp_Continue, NULL,
                    592:          "dspcont", "dc",
                    593:          "continue emulation / DSP single-stepping",
                    594:          "[steps]\n"
                    595:          "\tLeave debugger and continue emulation for <steps> DSP instructions\n"
                    596:          "\tor forever if no steps have been specified.",
                    597:          false }
                    598: };
                    599: 
                    600: 
                    601: /**
                    602:  * Should be called when debugger is first entered to initialize
                    603:  * DSP debugging variables.
                    604:  * 
                    605:  * if you want disassembly or memdumping to start/continue from
                    606:  * specific address, you can set them here.  If disassembly
                    607:  * address is zero, disassembling starts from PC.
                    608:  * 
                    609:  * returns number of DSP commands and pointer to array of them.
                    610:  */
                    611: int DebugDsp_Init(const dbgcommand_t **table)
                    612: {
                    613:        dsp_disasm_addr = 0;
                    614:        dsp_memdump_addr = 0;
                    615:        dsp_mem_space = 'P';
                    616: 
                    617:        *table = dspcommands;
1.1.1.8 ! root      618:        return ARRAY_SIZE(dspcommands);
1.1       root      619: }
                    620: 
                    621: /**
                    622:  * Should be called when debugger is re-entered to reset
                    623:  * relevant DSP debugging variables.
                    624:  */
                    625: void DebugDsp_InitSession(void)
                    626: {
                    627:        dsp_disasm_addr = DSP_GetPC();
1.1.1.2   root      628:        Profile_DspStop();
1.1       root      629: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.