Annotation of previous_trunk/src/debug/debugcpu.c, revision 1.1

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

unix.superglobalmegacorp.com

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