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

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

unix.superglobalmegacorp.com

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