Annotation of hatari/src/debug/debugcpu.c, revision 1.1.1.3

1.1       root        1: /*
                      2:   Hatari - debugcpu.c
                      3: 
                      4:   This file is distributed under the GNU Public License, version 2 or at
                      5:   your option any later version. Read the file gpl.txt for details.
                      6: 
                      7:   debugcpu.c - function needed for the CPU debugging tasks like memory
                      8:   and register dumps.
                      9: */
                     10: const char DebugCpu_fileid[] = "Hatari debugcpu.c : " __DATE__ " " __TIME__;
                     11: 
                     12: #include <stdio.h>
                     13: 
                     14: #include "config.h"
                     15: 
                     16: #include "main.h"
                     17: #include "breakcond.h"
                     18: #include "configuration.h"
                     19: #include "debugui.h"
                     20: #include "debug_priv.h"
                     21: #include "debugcpu.h"
                     22: #include "evaluate.h"
                     23: #include "hatari-glue.h"
1.1.1.3 ! root       24: #include "history.h"
1.1       root       25: #include "log.h"
                     26: #include "m68000.h"
                     27: #include "memorySnapShot.h"
1.1.1.2   root       28: #include "profile.h"
1.1       root       29: #include "stMemory.h"
                     30: #include "str.h"
                     31: #include "symbols.h"
1.1.1.2   root       32: #include "68kDisass.h"
1.1       root       33: 
                     34: #define MEMDUMP_COLS   16      /* memdump, number of bytes per row */
                     35: #define NON_PRINT_CHAR '.'     /* character to display for non-printables */
                     36: 
                     37: static Uint32 disasm_addr;     /* disasm address */
                     38: static Uint32 memdump_addr;    /* memdump address */
                     39: 
1.1.1.2   root       40: static bool bCpuProfiling;     /* Whether CPU profiling is activated */
1.1       root       41: static int nCpuActiveCBs = 0;  /* Amount of active conditional breakpoints */
                     42: static int nCpuSteps = 0;      /* Amount of steps for CPU single-stepping */
                     43: 
                     44: 
                     45: /**
                     46:  * Load a binary file to a memory address.
                     47:  */
                     48: static int DebugCpu_LoadBin(int nArgc, char *psArgs[])
                     49: {
                     50:        FILE *fp;
                     51:        unsigned char c;
                     52:        Uint32 address;
                     53:        int i=0;
                     54: 
                     55:        if (nArgc < 3)
                     56:        {
                     57:                DebugUI_PrintCmdHelp(psArgs[0]);
                     58:                return DEBUGGER_CMDDONE;
                     59:        }
                     60: 
                     61:        if (!Eval_Number(psArgs[2], &address))
                     62:        {
                     63:                fprintf(stderr, "Invalid address!\n");
                     64:                return DEBUGGER_CMDDONE;
                     65:        }
                     66:        address &= 0x00FFFFFF;
                     67: 
                     68:        if ((fp = fopen(psArgs[1], "rb")) == NULL)
                     69:        {
                     70:                fprintf(stderr, "Cannot open file '%s'!\n", psArgs[1]);
                     71:                return DEBUGGER_CMDDONE;
                     72:        }
                     73: 
                     74:        c = fgetc(fp);
                     75:        while (!feof(fp))
                     76:        {
                     77:                i++;
                     78:                STMemory_WriteByte(address++, c);
                     79:                c = fgetc(fp);
                     80:        }
                     81:        fprintf(stderr,"  Read 0x%x bytes.\n", i);
                     82:        fclose(fp);
                     83: 
                     84:        return DEBUGGER_CMDDONE;
                     85: }
                     86: 
                     87: 
                     88: /**
                     89:  * Dump memory from an address to a binary file.
                     90:  */
                     91: static int DebugCpu_SaveBin(int nArgc, char *psArgs[])
                     92: {
                     93:        FILE *fp;
                     94:        unsigned char c;
                     95:        Uint32 address;
                     96:        Uint32 bytes, i = 0;
                     97: 
                     98:        if (nArgc < 4)
                     99:        {
                    100:                DebugUI_PrintCmdHelp(psArgs[0]);
                    101:                return DEBUGGER_CMDDONE;
                    102:        }
                    103: 
                    104:        if (!Eval_Number(psArgs[2], &address))
                    105:        {
                    106:                fprintf(stderr, "  Invalid address!\n");
                    107:                return DEBUGGER_CMDDONE;
                    108:        }
                    109:        address &= 0x00FFFFFF;
                    110: 
                    111:        if (!Eval_Number(psArgs[3], &bytes))
                    112:        {
                    113:                fprintf(stderr, "  Invalid length!\n");
                    114:                return DEBUGGER_CMDDONE;
                    115:        }
                    116: 
                    117:        if ((fp = fopen(psArgs[1], "wb")) == NULL)
                    118:        {
                    119:                fprintf(stderr,"  Cannot open file '%s'!\n", psArgs[1]);
                    120:                return DEBUGGER_CMDDONE;
                    121:        }
                    122: 
                    123:        while (i < bytes)
                    124:        {
                    125:                c = STMemory_ReadByte(address++);
                    126:                fputc(c, fp);
                    127:                i++;
                    128:        }
                    129:        fclose(fp);
                    130:        fprintf(stderr, "  Wrote 0x%x bytes.\n", bytes);
                    131: 
                    132:        return DEBUGGER_CMDDONE;
                    133: }
                    134: 
                    135: 
                    136: /**
1.1.1.2   root      137:  * Check whether given address matches any CPU symbol and whether
                    138:  * there's profiling information available for it.  If yes, show it.
1.1       root      139:  */
1.1.1.2   root      140: static void DebugCpu_ShowAddressInfo(Uint32 addr)
1.1       root      141: {
1.1.1.2   root      142:        Uint32 count, cycles;
                    143:        const char *symbol;
                    144:        bool shown = false;
                    145: 
                    146:        symbol = Symbols_GetByCpuAddress(addr);
1.1       root      147:        if (symbol)
1.1.1.2   root      148:        {
                    149:                fprintf(debugOutput, "%s", symbol);
                    150:                shown = true;
                    151:        }
                    152:        if (Profile_CpuAddressData(addr, &count, &cycles))
                    153:        {
                    154:                fprintf(debugOutput, "%s%d/%d times/cycles",
                    155:                        (shown ? ", " : ""), count, cycles);
                    156:                shown = true;
                    157:        }
                    158:        if (shown)
                    159:                fprintf(debugOutput, ":\n");
1.1       root      160: }
                    161: 
                    162: /**
                    163:  * Dissassemble - arg = starting address, or PC.
                    164:  */
                    165: int DebugCpu_DisAsm(int nArgc, char *psArgs[])
                    166: {
                    167:        Uint32 disasm_upper = 0;
                    168:        int insts, max_insts;
                    169:        uaecptr nextpc;
                    170: 
                    171:        if (nArgc > 1)
                    172:        {
1.1.1.2   root      173:                switch (Eval_Range(psArgs[1], &disasm_addr, &disasm_upper, false))
1.1       root      174:                {
                    175:                case -1:
                    176:                        /* invalid value(s) */
                    177:                        return DEBUGGER_CMDDONE;
                    178:                case 0:
                    179:                        /* single value */
                    180:                        break;
                    181:                case 1:
                    182:                        /* range */
                    183:                        disasm_upper &= 0x00FFFFFF;
                    184:                        break;
                    185:                }
                    186:        }
                    187:        else
                    188:        {
                    189:                /* continue */
                    190:                if(!disasm_addr)
                    191:                        disasm_addr = M68000_GetPC();
                    192:        }
                    193:        disasm_addr &= 0x00FFFFFF;
                    194: 
                    195:        /* limit is topmost address or instruction count */
                    196:        if (disasm_upper)
                    197:        {
                    198:                max_insts = INT_MAX;
                    199:        }
                    200:        else
                    201:        {
                    202:                disasm_upper = 0x00FFFFFF;
                    203:                max_insts = ConfigureParams.Debugger.nDisasmLines;
                    204:        }
                    205: 
                    206:        /* output a range */
                    207:        for (insts = 0; insts < max_insts && disasm_addr < disasm_upper; insts++)
                    208:        {
1.1.1.2   root      209:                DebugCpu_ShowAddressInfo(disasm_addr);
                    210:                Disasm(debugOutput, (uaecptr)disasm_addr, &nextpc, 1, DISASM_ENGINE_EXT);
1.1       root      211:                disasm_addr = nextpc;
                    212:        }
                    213:        fflush(debugOutput);
                    214: 
                    215:        return DEBUGGER_CMDCONT;
                    216: }
                    217: 
                    218: 
                    219: /**
                    220:  * Readline match callback to list register names usable within debugger.
                    221:  * STATE = 0 -> different text from previous one.
                    222:  * Return next match or NULL if no matches.
                    223:  */
                    224: static char *DebugCpu_MatchRegister(const char *text, int state)
                    225: {
                    226:        static const char regs[][3] = {
                    227:                "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
                    228:                "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
                    229:                "pc", "sr"
                    230:        };
                    231:        static int i, len;
                    232:        
                    233:        if (!state)
                    234:        {
                    235:                /* first match */
                    236:                i = 0;
                    237:                len = strlen(text);
                    238:                if (len > 2)
                    239:                        return NULL;
                    240:        }
                    241:        /* next match */
                    242:        while (i < ARRAYSIZE(regs)) {
                    243:                if (strncasecmp(regs[i++], text, len) == 0)
                    244:                        return (strdup(regs[i-1]));
                    245:        }
                    246:        return NULL;
                    247: }
                    248: 
                    249: 
                    250: /**
                    251:  * Set address of the named register to given argument.
                    252:  * Return register size in bits or zero for uknown register name.
                    253:  * Handles D0-7 data and A0-7 address registers, but not PC & SR
                    254:  * registers as they need to be accessed using UAE accessors.
                    255:  */
                    256: int DebugCpu_GetRegisterAddress(const char *reg, Uint32 **addr)
                    257: {
                    258:        char r0, r1;
                    259:        if (!reg[0] || !reg[1] || reg[2])
                    260:                return 0;
                    261:        
                    262:        r0 = toupper(reg[0]);
                    263:        r1 = toupper(reg[1]);
                    264: 
                    265:        if (r0 == 'D')  /* Data regs? */
                    266:        {
                    267:                if (r1 >= '0' && r1 <= '7')
                    268:                {
                    269:                        *addr = &(Regs[REG_D0 + r1 - '0']);
                    270:                        return 32;
                    271:                }
                    272:                fprintf(stderr,"\tBad data register, valid values are 0-7\n");
                    273:                return 0;
                    274:        }
                    275:        if(r0 == 'A')  /* Address regs? */
                    276:        {
                    277:                if (r1 >= '0' && r1 <= '7')
                    278:                {
                    279:                        *addr = &(Regs[REG_A0 + r1 - '0']);
                    280:                        return 32;
                    281:                }
                    282:                fprintf(stderr,"\tBad address register, valid values are 0-7\n");
                    283:                return 0;
                    284:        }
                    285:        return 0;
                    286: }
                    287: 
                    288: 
                    289: /**
                    290:  * Dump or set CPU registers
                    291:  */
                    292: int DebugCpu_Register(int nArgc, char *psArgs[])
                    293: {
                    294:        char reg[3], *assign;
                    295:        Uint32 value;
                    296:        char *arg;
                    297: 
                    298:        /* If no parameter has been given, simply dump all registers */
                    299:        if (nArgc == 1)
                    300:        {
                    301:                uaecptr nextpc;
                    302:                /* use the UAE function instead */
                    303:                m68k_dumpstate(debugOutput, &nextpc);
                    304:                fflush(debugOutput);
                    305:                return DEBUGGER_CMDDONE;
                    306:        }
                    307: 
                    308:        arg = psArgs[1];
                    309: 
                    310:        assign = strchr(arg, '=');
                    311:        if (!assign)
                    312:        {
                    313:                goto error_msg;
                    314:        }
                    315: 
                    316:        *assign++ = '\0';
                    317:        if (!Eval_Number(Str_Trim(assign), &value))
                    318:        {
                    319:                goto error_msg;
                    320:        }
                    321: 
                    322:        arg = Str_Trim(arg);
                    323:        if (strlen(arg) != 2)
                    324:        {
                    325:                goto error_msg;
                    326:        }
                    327:        reg[0] = toupper(arg[0]);
                    328:        reg[1] = toupper(arg[1]);
                    329:        reg[2] = '\0';
                    330:        
                    331:        /* set SR and update conditional flags for the UAE CPU core. */
                    332:        if (reg[0] == 'S' && reg[1] == 'R')
                    333:        {
                    334:                M68000_SetSR(value);
                    335:        }
                    336:        else if (reg[0] == 'P' && reg[1] == 'C')   /* set PC? */
                    337:        {
                    338:                M68000_SetPC(value);
                    339:        }
                    340:        else
                    341:        {
                    342:                Uint32 *regaddr;
                    343:                /* check&set data and address registers */
                    344:                if (DebugCpu_GetRegisterAddress(reg, &regaddr))
                    345:                {
                    346:                        *regaddr = value;
                    347:                }
                    348:                else
                    349:                {
                    350:                        goto error_msg;
                    351:                }
                    352:        }
                    353:        return DEBUGGER_CMDDONE;
                    354: 
                    355: error_msg:
                    356:        fprintf(stderr,"\tError, usage: r or r xx=yyyy\n\tWhere: xx=A0-A7, D0-D7, PC or SR.\n");
                    357:        return DEBUGGER_CMDDONE;
                    358: }
                    359: 
                    360: 
                    361: /**
1.1.1.2   root      362:  * CPU wrapper for BreakAddr_Command().
1.1       root      363:  */
                    364: static int DebugCpu_BreakAddr(int nArgc, char *psArgs[])
                    365: {
                    366:        BreakAddr_Command(psArgs[1], false);
                    367:        return DEBUGGER_CMDDONE;
                    368: }
                    369: 
                    370: /**
1.1.1.2   root      371:  * CPU wrapper for BreakCond_Command().
1.1       root      372:  */
                    373: static int DebugCpu_BreakCond(int nArgc, char *psArgs[])
                    374: {
                    375:        BreakCond_Command(psArgs[1], false);
                    376:        return DEBUGGER_CMDDONE;
                    377: }
                    378: 
1.1.1.2   root      379: /**
                    380:  * CPU wrapper for Profile_Command().
                    381:  */
                    382: static int DebugCpu_Profile(int nArgc, char *psArgs[])
                    383: {
                    384:        Profile_Command(nArgc, psArgs, false);
                    385:        return DEBUGGER_CMDDONE;
                    386: }
                    387: 
1.1       root      388: 
                    389: /**
                    390:  * Do a memory dump, args = starting address.
                    391:  */
                    392: int DebugCpu_MemDump(int nArgc, char *psArgs[])
                    393: {
                    394:        int i;
                    395:        char c;
                    396:        Uint32 memdump_upper = 0;
                    397: 
                    398:        if (nArgc > 1)
                    399:        {
1.1.1.2   root      400:                switch (Eval_Range(psArgs[1], &memdump_addr, &memdump_upper, false))
1.1       root      401:                {
                    402:                case -1:
                    403:                        /* invalid value(s) */
                    404:                        return DEBUGGER_CMDDONE;
                    405:                case 0:
                    406:                        /* single value */
                    407:                        break;
                    408:                case 1:
                    409:                        /* range */
                    410:                        break;
                    411:                }
                    412:        } /* continue */
                    413:        memdump_addr &= 0x00FFFFFF;
                    414: 
                    415:        if (!memdump_upper)
                    416:        {
                    417:                memdump_upper = memdump_addr + MEMDUMP_COLS * ConfigureParams.Debugger.nMemdumpLines;
                    418:        }
                    419:        memdump_upper &= 0x00FFFFFF;
                    420: 
                    421:        while (memdump_addr < memdump_upper)
                    422:        {
                    423:                fprintf(debugOutput, "%6.6X: ", memdump_addr); /* print address */
                    424:                for (i = 0; i < MEMDUMP_COLS; i++)               /* print hex data */
                    425:                        fprintf(debugOutput, "%2.2x ", STMemory_ReadByte(memdump_addr++));
                    426:                fprintf(debugOutput, "  ");                     /* print ASCII data */
                    427:                for (i = 0; i < MEMDUMP_COLS; i++)
                    428:                {
                    429:                        c = STMemory_ReadByte(memdump_addr-MEMDUMP_COLS+i);
                    430:                        if(!isprint((unsigned)c))
                    431:                                c = NON_PRINT_CHAR;             /* non-printable as dots */
                    432:                        fprintf(debugOutput,"%c", c);
                    433:                }
                    434:                fprintf(debugOutput, "\n");            /* newline */
                    435:        } /* while */
                    436:        fflush(debugOutput);
                    437: 
                    438:        return DEBUGGER_CMDCONT;
                    439: }
                    440: 
                    441: 
                    442: /**
                    443:  * Command: Write to memory, arg = starting address, followed by bytes.
                    444:  */
                    445: static int DebugCpu_MemWrite(int nArgc, char *psArgs[])
                    446: {
                    447:        int i, numBytes;
                    448:        Uint32 write_addr, d;
                    449:        unsigned char bytes[256]; /* store bytes */
                    450: 
                    451:        if (nArgc < 3)
                    452:        {
                    453:                DebugUI_PrintCmdHelp(psArgs[0]);
                    454:                return DEBUGGER_CMDDONE;
                    455:        }
                    456: 
                    457:        /* Read address */
                    458:        if (!Eval_Number(psArgs[1], &write_addr))
                    459:        {
                    460:                fprintf(stderr, "Bad address!\n");
                    461:                return DEBUGGER_CMDDONE;
                    462:        }
                    463: 
                    464:        write_addr &= 0x00FFFFFF;
                    465:        numBytes = 0;
                    466: 
                    467:        /* get bytes data */
                    468:        for (i = 2; i < nArgc; i++)
                    469:        {
                    470:                if (!Eval_Number(psArgs[i], &d) || d > 255)
                    471:                {
                    472:                        fprintf(stderr, "Bad byte argument: '%s'!\n", psArgs[i]);
                    473:                        return DEBUGGER_CMDDONE;
                    474:                }
                    475: 
                    476:                bytes[numBytes] = d & 0x0FF;
                    477:                numBytes++;
                    478:        }
                    479: 
                    480:        /* write the data */
                    481:        for (i = 0; i < numBytes; i++)
                    482:                STMemory_WriteByte(write_addr + i, bytes[i]);
                    483: 
                    484:        return DEBUGGER_CMDDONE;
                    485: }
                    486: 
                    487: 
                    488: /**
                    489:  * Command: Continue CPU emulation / single-stepping
                    490:  */
                    491: static int DebugCpu_Continue(int nArgc, char *psArgv[])
                    492: {
                    493:        int steps = 0;
                    494:        
                    495:        if (nArgc > 1)
                    496:        {
                    497:                steps = atoi(psArgv[1]);
                    498:        }
                    499:        if (steps <= 0)
                    500:        {
                    501:                nCpuSteps = 0;
                    502:                fprintf(stderr,"Returning to emulation...\n");
                    503:                return DEBUGGER_END;
                    504:        }
                    505:        nCpuSteps = steps;
                    506:        fprintf(stderr,"Returning to emulation for %i CPU instructions...\n", steps);
                    507:        return DEBUGGER_END;
                    508: }
                    509: 
                    510: 
                    511: /**
                    512:  * This function is called after each CPU instruction when debugging is enabled.
                    513:  */
                    514: void DebugCpu_Check(void)
                    515: {
1.1.1.2   root      516:        if (bCpuProfiling)
                    517:        {
                    518:                Profile_CpuUpdate();
                    519:        }
1.1       root      520:        if (LOG_TRACE_LEVEL(TRACE_CPU_DISASM))
                    521:        {
1.1.1.2   root      522:                DebugCpu_ShowAddressInfo(M68000_GetPC());
1.1       root      523:        }
                    524:        if (nCpuActiveCBs)
                    525:        {
                    526:                if (BreakCond_MatchCpu())
1.1.1.3 ! root      527:                        DebugUI(REASON_CPU_BREAKPOINT);
1.1       root      528:        }
                    529:        if (nCpuSteps)
                    530:        {
                    531:                nCpuSteps -= 1;
                    532:                if (nCpuSteps == 0)
1.1.1.3 ! root      533:                        DebugUI(REASON_CPU_STEPS);
        !           534:        }
        !           535:        if (bHistoryEnabled)
        !           536:        {
        !           537:                History_AddCpu();
1.1       root      538:        }
                    539: }
                    540: 
                    541: /**
                    542:  * Should be called before returning back emulation to tell the CPU core
                    543:  * to call us after each instruction if "real-time" debugging like
                    544:  * breakpoints has been set.
                    545:  */
                    546: void DebugCpu_SetDebugging(void)
                    547: {
1.1.1.2   root      548:        bCpuProfiling = Profile_CpuStart();
1.1       root      549:        nCpuActiveCBs = BreakCond_BreakPointCount(false);
1.1.1.2   root      550: 
1.1.1.3 ! root      551:        if (nCpuActiveCBs || nCpuSteps || bCpuProfiling || bHistoryEnabled)
1.1       root      552:                M68000_SetSpecial(SPCFLAG_DEBUGGER);
                    553:        else
                    554:                M68000_UnsetSpecial(SPCFLAG_DEBUGGER);
                    555: }
                    556: 
                    557: 
                    558: static const dbgcommand_t cpucommands[] =
                    559: {
                    560:        { NULL, NULL, "CPU commands", NULL, NULL, NULL, false },
                    561:        /* NULL as match function will complete file names */
                    562:        { DebugCpu_BreakAddr, Symbols_MatchCpuCodeAddress,
                    563:          "address", "a",
                    564:          "set CPU PC address breakpoints",
                    565:          BreakAddr_Description,
                    566:          true  },
                    567:        { DebugCpu_BreakCond, BreakCond_MatchCpuVariable,
                    568:          "breakpoint", "b",
                    569:          "set/remove/list conditional CPU breakpoints",
                    570:          BreakCond_Description,
                    571:          true },
                    572:        { DebugCpu_DisAsm, Symbols_MatchCpuCodeAddress,
                    573:          "disasm", "d",
                    574:          "disassemble from PC, or given address",
                    575:          "[<start address>[-<end address>]]\n"
                    576:          "\tIf no address is given, this command disassembles from the last\n"
                    577:          "\tposition or from current PC if no last position is available.",
                    578:          false },
1.1.1.2   root      579:        { DebugCpu_Profile, Profile_Match,
                    580:          "profile", "",
                    581:          "profile CPU code",
                    582:          Profile_Description,
                    583:          false },
1.1       root      584:        { DebugCpu_Register, DebugCpu_MatchRegister,
                    585:          "cpureg", "r",
                    586:          "dump register values or set register to value",
                    587:          "[REG=value]\n"
                    588:          "\tSet CPU register to value or dumps all register if no parameter\n"
                    589:          "\thas been specified.",
                    590:          true },
                    591:        { DebugCpu_MemDump, Symbols_MatchCpuDataAddress,
                    592:          "memdump", "m",
                    593:          "dump memory",
                    594:          "[<start address>[-<end address>]]\n"
                    595:          "\tdump memory at address or continue dump from previous address.",
                    596:          false },
                    597:        { DebugCpu_MemWrite, Symbols_MatchCpuAddress,
                    598:          "memwrite", "w",
                    599:          "write bytes to memory",
                    600:          "address byte1 [byte2 ...]\n"
                    601:          "\tWrite bytes to a memory address, bytes are space separated\n"
                    602:          "\thexadecimals.",
                    603:          false },
                    604:        { DebugCpu_LoadBin, NULL,
                    605:          "loadbin", "l",
                    606:          "load a file into memory",
                    607:          "filename address\n"
                    608:          "\tLoad the file <filename> into memory starting at <address>.",
                    609:          false },
                    610:        { DebugCpu_SaveBin, NULL,
                    611:          "savebin", "s",
                    612:          "save memory to a file",
                    613:          "filename address length\n"
                    614:          "\tSave the memory block at <address> with given <length> to\n"
                    615:          "\tthe file <filename>.",
                    616:          false },
                    617:        { Symbols_Command, NULL,
                    618:          "symbols", "",
                    619:          "load CPU symbols & their addresses",
                    620:          Symbols_Description,
                    621:          false },
                    622:        { DebugCpu_Continue, NULL,
                    623:          "cont", "c",
                    624:          "continue emulation / CPU single-stepping",
                    625:          "[steps]\n"
                    626:          "\tLeave debugger and continue emulation for <steps> CPU instructions\n"
                    627:          "\tor forever if no steps have been specified.",
                    628:          false }
                    629: };
                    630: 
                    631: 
                    632: /**
                    633:  * Should be called when debugger is first entered to initialize
                    634:  * CPU debugging variables.
                    635:  * 
                    636:  * if you want disassembly or memdumping to start/continue from
                    637:  * specific address, you can set them here.  If disassembly
                    638:  * address is zero, disassembling starts from PC.
                    639:  * 
                    640:  * returns number of CPU commands and pointer to array of them.
                    641:  */
                    642: int DebugCpu_Init(const dbgcommand_t **table)
                    643: {
                    644:        memdump_addr = 0;
                    645:        disasm_addr = 0;
                    646:        
                    647:        *table = cpucommands;
                    648:        return ARRAYSIZE(cpucommands);
                    649: }
                    650: 
                    651: /**
                    652:  * Should be called when debugger is re-entered to reset
                    653:  * relevant CPU debugging variables.
                    654:  */
                    655: void DebugCpu_InitSession(void)
                    656: {
                    657:        disasm_addr = M68000_GetPC();
1.1.1.2   root      658:        Profile_CpuStop();
1.1       root      659: }

unix.superglobalmegacorp.com

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