|
|
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.1.7 ! root 517: nDspActiveCBs = BreakCond_DspBreakPointCount();
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.