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

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

unix.superglobalmegacorp.com

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