Annotation of hatari/src/debugui.c, revision 1.1.1.10

1.1       root        1: /*
1.1.1.6   root        2:   Hatari - debugui.c
1.1       root        3: 
1.1.1.4   root        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: 
1.1.1.6   root        7:   debugui.c - this is the code for the mini-debugger. When the pause button is
                      8:   pressed, the emulator is (hopefully) halted and this little CLI can be used
                      9:   (in the terminal box) for debugging tasks like memory and register dumps.
1.1       root       10: */
1.1.1.10! root       11: const char DebugUI_fileid[] = "Hatari debugui.c : " __DATE__ " " __TIME__;
1.1       root       12: 
                     13: #include <ctype.h>
1.1.1.8   root       14: #include <stdio.h>
                     15: 
                     16: #include "config.h"
                     17: 
                     18: #if HAVE_LIBREADLINE
                     19: #include <readline/readline.h>
                     20: #include <readline/history.h>
                     21: #endif
1.1       root       22: 
                     23: #include "main.h"
1.1.1.9   root       24: #include "change.h"
1.1       root       25: #include "configuration.h"
1.1.1.9   root       26: #include "file.h"
1.1       root       27: #include "reset.h"
                     28: #include "m68000.h"
1.1.1.9   root       29: #include "str.h"
1.1.1.3   root       30: #include "stMemory.h"
1.1       root       31: #include "sound.h"
                     32: #include "tos.h"
1.1.1.4   root       33: #include "debugui.h"
1.1       root       34: 
1.1.1.8   root       35: #include "hatari-glue.h"
1.1       root       36: 
                     37: #define MEMDUMP_COLS   16      /* memdump, number of bytes per row */
                     38: #define MEMDUMP_ROWS   4       /* memdump, number of rows */
1.1.1.2   root       39: #define NON_PRINT_CHAR '.'     /* character to display for non-printables */
1.1       root       40: #define DISASM_INSTS   5       /* disasm - number of instructions */
                     41: 
1.1.1.9   root       42: static bool bMemDump;          /* has memdump been called? */
1.1.1.6   root       43: static unsigned long memdump_addr; /* memdump address */
                     44: static unsigned long disasm_addr;  /* disasm address */
                     45: 
1.1.1.9   root       46: static FILE *debugOutput;
1.1.1.2   root       47: 
                     48: 
1.1.1.6   root       49: 
                     50: /*-----------------------------------------------------------------------*/
1.1.1.8   root       51: /**
                     52:  * Get a hex adress range, eg. "fa0000-fa0100" 
                     53:  * returns -1 if not a range,
                     54:  * -2 if a range, but not a valid one.
                     55:  * 0 if OK.
                     56:  */
1.1.1.9   root       57: static int getRange(char *str, unsigned long *lower, unsigned long *upper)
1.1.1.6   root       58: {
1.1.1.9   root       59:        bool fDash = FALSE;
1.1.1.6   root       60:        int i=0;
                     61: 
                     62:        while (str[i] != '\0')
                     63:        {
                     64:                if (str[i] == '-')
                     65:                {
                     66:                        str[i] = ' ';
                     67:                        fDash = TRUE;
                     68:                }
                     69:                i++;
                     70:        }
                     71:        if (fDash == FALSE)
                     72:                return -1;
                     73: 
                     74:        i = sscanf(str, "%lx%lx", lower, upper);
                     75:        if (i != 2)
                     76:                return -2;
                     77:        if (*lower > *upper)
                     78:                return -3;
                     79:        return 0;
                     80: }
                     81: 
                     82: 
1.1.1.2   root       83: /*-----------------------------------------------------------------------*/
1.1.1.8   root       84: /**
1.1.1.9   root       85:  * Open given log file.
1.1.1.8   root       86:  */
1.1.1.9   root       87: static void DebugUI_SetLogFile(const char *logpath)
1.1.1.6   root       88: {
1.1.1.9   root       89:        File_Close(debugOutput);
                     90:        debugOutput = File_Open(logpath, "w");
                     91:        if (debugOutput)
                     92:                fprintf(stderr, "Debug log '%s' opened\n", logpath);
                     93:        else
                     94:                debugOutput = stderr;
                     95: }
                     96: 
                     97: 
                     98: /*-----------------------------------------------------------------------*/
                     99: /**
                    100:  * Close a log file if open, and set it to default stream.
                    101:  */
                    102: static void DebugUI_SetLogDefault(void)
                    103: {
                    104:        if (debugOutput != stderr)
                    105:        {
                    106:                if (debugOutput)
                    107:                {
                    108:                        File_Close(debugOutput);
                    109:                        fprintf(stderr, "Debug log closed.\n");
                    110:                }
                    111:                debugOutput = stderr;
                    112:        }
1.1.1.2   root      113: }
                    114: 
1.1.1.6   root      115: 
1.1       root      116: /*-----------------------------------------------------------------------*/
1.1.1.8   root      117: /**
                    118:  * Load a binary file to a memory address.
                    119:  */
1.1.1.6   root      120: static void DebugUI_LoadBin(char *args)
                    121: {
                    122:        FILE *fp;
                    123:        unsigned char c;
                    124:        char dummy[100];
                    125:        char filename[200];
                    126:        unsigned long address;
                    127:        int i=0;
                    128: 
                    129:        if (sscanf(args, "%s%s%lx", dummy, filename, &address) != 3)
                    130:        {
                    131:                fprintf(stderr, "Invalid arguments!\n");
                    132:                return;
                    133:        }
                    134:        address &= 0x00FFFFFF;
                    135:        if ((fp = fopen(filename, "rb")) == NULL)
                    136:        {
                    137:                fprintf(stderr,"Cannot open file!\n");
                    138:        }
                    139: 
                    140:        c = fgetc(fp);
                    141:        while (!feof(fp))
                    142:        {
                    143:                i++;
                    144:                STMemory_WriteByte(address++, c);
                    145:                c = fgetc(fp);
                    146:        }
                    147:        fprintf(stderr,"  Read 0x%x bytes.\n", i);
                    148:        fclose(fp);
1.1       root      149: }
                    150: 
1.1.1.6   root      151: 
1.1       root      152: /*-----------------------------------------------------------------------*/
1.1.1.8   root      153: /**
                    154:  * Dump memory from an address to a binary file.
                    155:  */
1.1.1.6   root      156: static void DebugUI_SaveBin(char *args)
                    157: {
                    158:        FILE *fp;
                    159:        unsigned char c;
                    160:        char filename[200];
                    161:        char dummy[100];
                    162:        unsigned long address;
                    163:        unsigned long bytes, i=0;
                    164: 
                    165:        if (sscanf(args, "%s%s%lx%lx", dummy, filename, &address, &bytes) != 4)
                    166:        {
1.1.1.9   root      167:                fprintf(stderr, "  Invalid arguments!\n");
1.1.1.6   root      168:                return;
                    169:        }
                    170:        address &= 0x00FFFFFF;
                    171:        if ((fp = fopen(filename, "wb")) == NULL)
                    172:        {
                    173:                fprintf(stderr,"  Cannot open file!\n");
                    174:        }
                    175: 
                    176:        while (i < bytes)
                    177:        {
                    178:                c = STMemory_ReadByte(address++);
                    179:                fputc(c, fp);
                    180:                i++;
                    181:        }
                    182:        fclose(fp);
                    183:        fprintf(stderr, "  Wrote 0x%lx bytes.\n", bytes);
1.1       root      184: }
                    185: 
1.1.1.6   root      186: 
1.1       root      187: /*-----------------------------------------------------------------------*/
1.1.1.8   root      188: /**
                    189:  * Do a register dump.
                    190:  */
1.1.1.4   root      191: static void DebugUI_RegDump(void)
1.1       root      192: {
1.1.1.6   root      193:        uaecptr nextpc;
                    194:        /* use the UAE function instead */
1.1.1.9   root      195:        m68k_dumpstate(debugOutput, &nextpc);
                    196:        fflush(debugOutput);
1.1       root      197: }
                    198: 
                    199: 
                    200: /*-----------------------------------------------------------------------*/
1.1.1.8   root      201: /**
                    202:  * Dissassemble - arg = starting address, or PC.
                    203:  */
1.1.1.9   root      204: static void DebugUI_DisAsm(char *arg, bool cont)
1.1.1.6   root      205: {
                    206:        int i,j;
                    207:        unsigned long disasm_upper;
                    208:        uaecptr nextpc;
1.1.1.9   root      209:        bool isRange = FALSE;
1.1.1.6   root      210: 
                    211:        if (cont != TRUE)
                    212:        {
                    213:                j = getRange(arg, &disasm_addr, &disasm_upper);
                    214: 
                    215:                if (j == -1)
                    216:                { /* single address, not a range */
1.1.1.9   root      217:                        if (!Str_IsHex(arg))
1.1.1.6   root      218:                        {
                    219:                                fprintf(stderr,"Invalid address!\n");
                    220:                                return;
                    221:                        }
                    222:                        i = sscanf(arg, "%lx", &disasm_addr);
                    223: 
                    224:                        if (i == 0)
                    225:                        {
                    226:                                fprintf(stderr,"Invalid address!\n");
                    227:                                return;
                    228:                        }
                    229:                } /* single address */
                    230:                else if (j == -2 || j == -3)
                    231:                {
                    232:                        fprintf(stderr,"Invalid range!\n");
                    233:                        return;
                    234:                }
                    235:                else
                    236:                { /* range */
                    237:                        isRange = TRUE;
                    238:                        disasm_upper &= 0x00FFFFFF;
                    239:                }
                    240:        }
                    241:        else /* continue*/
                    242:                if(!disasm_addr)
1.1.1.8   root      243:                        disasm_addr = M68000_GetPC();
1.1.1.6   root      244: 
                    245:        disasm_addr &= 0x00FFFFFF;
                    246: 
                    247:        /* output a single block. */
                    248:        if (isRange == FALSE)
                    249:        {
1.1.1.9   root      250:                m68k_disasm(debugOutput, (uaecptr)disasm_addr, &nextpc, DISASM_INSTS);
1.1.1.6   root      251:                disasm_addr = nextpc;
1.1.1.9   root      252:                fflush(debugOutput);
1.1.1.6   root      253:                return;
                    254:        }
                    255: 
                    256:        /* output a range */
                    257:        while (disasm_addr < disasm_upper)
                    258:        {
1.1.1.9   root      259:                m68k_disasm(debugOutput, (uaecptr)disasm_addr, &nextpc, 1);
1.1.1.6   root      260:                disasm_addr = nextpc;
                    261:        }
1.1.1.9   root      262:        fflush(debugOutput);
1.1.1.2   root      263: }
                    264: 
1.1.1.6   root      265: 
1.1.1.2   root      266: /*-----------------------------------------------------------------------*/
1.1.1.8   root      267: /**
                    268:  * Set a register: 
                    269:  */
1.1.1.6   root      270: static void DebugUI_RegSet(char *arg)
                    271: {
                    272:        int i;
1.1.1.9   root      273:        bool s = FALSE;
1.1.1.6   root      274:        char reg[4];
                    275:        long value;
                    276: 
                    277:        for (i=0;i<4;i++)
                    278:                reg[i] = 0;
                    279:        i=0;
                    280:        while (arg[i] != '\0')
                    281:        {
                    282:                if(arg[i] == '=')
                    283:                {
                    284:                        arg[i] = ' ';
                    285:                        s = TRUE;
                    286:                }
                    287:                i++;
                    288:        }
                    289: 
                    290:        if (s == FALSE)
                    291:        {
                    292:                fprintf(stderr,"\tError, usage: r or r xx=yyyy\n\tWhere: xx=A0-A7, D0-D7, PC or SR and yyyy is a hex value.\n");
                    293:                return;
                    294:        }
                    295: 
                    296:        if (sscanf(arg, "%s%lx", reg, &value) == 2)
                    297:                s = TRUE;
                    298:        else
                    299:                s = FALSE;
                    300:        if (s == FALSE)
                    301:        {
                    302:                fprintf(stderr,"\tError, usage: r or r xx=yyyy\n\tWhere: xx=A0-A7, D0-D7, PC or SR and yyyy is a hex value.\n");
                    303:                return;
                    304:        }
1.1.1.2   root      305: 
1.1.1.6   root      306:        for (i=0;i<4;i++)
                    307:                reg[i] = toupper(reg[i]);
                    308: 
                    309:        /* set SR and update conditional flags for the UAE CPU core. */
                    310:        if (reg[0] == 'S' && reg[1] == 'R')
                    311:        {
1.1.1.8   root      312:                M68000_SetSR(value);
1.1.1.6   root      313:        }
                    314:        else if (reg[0] == 'P' && reg[1] == 'C')   /* set PC? */
                    315:        {
1.1.1.8   root      316:                M68000_SetPC(value);
1.1.1.6   root      317:        }
                    318:        else if (reg[0] == 'D')  /* Data regs? */
                    319:        {
                    320:                switch (reg[1])
                    321:                {
                    322:                 case '0':
                    323:                        Regs[REG_D0] = value;
                    324:                        break;
                    325:                 case '1':
                    326:                        Regs[REG_D1] = value;
                    327:                        break;
                    328:                 case '2':
                    329:                        Regs[REG_D2] = value;
                    330:                        break;
                    331:                 case '3':
                    332:                        Regs[REG_D3] = value;
                    333:                        break;
                    334:                 case '4':
                    335:                        Regs[REG_D4] = value;
                    336:                        break;
                    337:                 case '5':
                    338:                        Regs[REG_D5] = value;
                    339:                        break;
                    340:                 case '6':
                    341:                        Regs[REG_D6] = value;
                    342:                        break;
                    343:                 case '7':
                    344:                        Regs[REG_D7] = value;
                    345:                        break;
                    346: 
                    347:                 default:
                    348:                        fprintf(stderr,"\tBad data register, valid values are 0-7\n");
                    349:                        break;
                    350:                }
                    351:        }
                    352:        else if(reg[0] == 'A')  /* Address regs? */
                    353:        {
                    354:                switch( reg[1] )
                    355:                {
                    356:                 case '0':
                    357:                        Regs[REG_A0] = value;
                    358:                        break;
                    359:                 case '1':
                    360:                        Regs[REG_A1] = value;
                    361:                        break;
                    362:                 case '2':
                    363:                        Regs[REG_A2] = value;
                    364:                        break;
                    365:                 case '3':
                    366:                        Regs[REG_A3] = value;
                    367:                        break;
                    368:                 case '4':
                    369:                        Regs[REG_A4] = value;
                    370:                        break;
                    371:                 case '5':
                    372:                        Regs[REG_A5] = value;
                    373:                        break;
                    374:                 case '6':
                    375:                        Regs[REG_A6] = value;
                    376:                        break;
                    377:                 case '7':
                    378:                        Regs[REG_A7] = value;
                    379:                        break;
                    380: 
                    381:                 default:
                    382:                        fprintf(stderr,"\tBad address register, valid values are 0-7\n");
                    383:                        break;
                    384:                }
                    385:        }
                    386:        else
                    387:        {
                    388:                fprintf(stderr, "\t Bad register!\n");
                    389:        }
1.1       root      390: }
                    391: 
1.1.1.6   root      392: 
1.1       root      393: /*-----------------------------------------------------------------------*/
1.1.1.8   root      394: /**
                    395:  * Do a memory dump, args = starting address.
                    396:  */
1.1.1.9   root      397: static void DebugUI_MemDump(char *arg, bool cont)
1.1.1.6   root      398: {
                    399:        int i,j;
                    400:        char c;
1.1.1.9   root      401:        bool isRange = FALSE;
1.1.1.6   root      402:        unsigned long memdump_upper;
1.1.1.2   root      403: 
1.1.1.6   root      404:        if (cont != TRUE)
                    405:        {
                    406:                j = getRange(arg, &memdump_addr, &memdump_upper);
                    407: 
                    408:                if (j == -1)
                    409:                { /* single address, not a range */
1.1.1.9   root      410:                        if (!Str_IsHex(arg))
1.1.1.6   root      411:                        {
                    412:                                bMemDump = FALSE;
                    413:                                fprintf(stderr, "Invalid address!\n");
                    414:                                return;
                    415:                        }
                    416:                        i = sscanf(arg, "%lx", &memdump_addr);
                    417: 
                    418:                        if (i == 0)
                    419:                        {
                    420:                                bMemDump = FALSE;
                    421:                                fprintf(stderr, "Invalid address!\n");
                    422:                                return;
                    423:                        }
                    424:                } /* single address */
                    425:                else if (j == -2 || j == -3)
                    426:                {
                    427:                        fprintf(stderr, "Invalid range!\n");
                    428:                        return;
                    429:                }
                    430:                else
                    431:                { /* range */
                    432:                        isRange = TRUE;
                    433:                        memdump_upper &= 0x00FFFFFF;
                    434:                }
                    435:        } /* continue */
                    436: 
                    437:        memdump_addr &= 0x00FFFFFF;
                    438:        bMemDump = TRUE;
                    439: 
                    440:        if (isRange != TRUE)
                    441:        {
                    442:                for (j=0;j<MEMDUMP_ROWS;j++)
                    443:                {
1.1.1.9   root      444:                        fprintf(debugOutput, "%6.6lX: ", memdump_addr); /* print address */
1.1.1.6   root      445:                        for (i = 0; i < MEMDUMP_COLS; i++)               /* print hex data */
1.1.1.9   root      446:                                fprintf(debugOutput, "%2.2x ", STMemory_ReadByte(memdump_addr++));
                    447:                        fprintf(debugOutput, "  ");                     /* print ASCII data */
1.1.1.6   root      448:                        for (i = 0; i < MEMDUMP_COLS; i++)
                    449:                        {
                    450:                                c = STMemory_ReadByte(memdump_addr-MEMDUMP_COLS+i);
1.1.1.8   root      451:                                if (!isprint((unsigned)c))
1.1.1.6   root      452:                                        c = NON_PRINT_CHAR;         /* non-printable as dots */
1.1.1.9   root      453:                                fprintf(debugOutput,"%c", c);
1.1.1.6   root      454:                        }
1.1.1.9   root      455:                        fprintf(debugOutput, "\n");        /* newline */
1.1.1.6   root      456:                }
1.1.1.9   root      457:                fflush(debugOutput);
1.1.1.6   root      458:                return;
                    459:        } /* not a range */
                    460: 
                    461:        while (memdump_addr < memdump_upper)
                    462:        {
1.1.1.9   root      463:                fprintf(debugOutput, "%6.6lX: ", memdump_addr); /* print address */
1.1.1.6   root      464:                for (i = 0; i < MEMDUMP_COLS; i++)               /* print hex data */
1.1.1.9   root      465:                        fprintf(debugOutput, "%2.2x ", STMemory_ReadByte(memdump_addr++));
                    466:                fprintf(debugOutput, "  ");                     /* print ASCII data */
1.1.1.6   root      467:                for (i = 0; i < MEMDUMP_COLS; i++)
                    468:                {
                    469:                        c = STMemory_ReadByte(memdump_addr-MEMDUMP_COLS+i);
1.1.1.8   root      470:                        if(!isprint((unsigned)c))
1.1.1.6   root      471:                                c = NON_PRINT_CHAR;             /* non-printable as dots */
1.1.1.9   root      472:                        fprintf(debugOutput,"%c", c);
1.1.1.6   root      473:                }
1.1.1.9   root      474:                fprintf(debugOutput, "\n");            /* newline */
1.1.1.6   root      475:        } /* while */
1.1.1.9   root      476:        fflush(debugOutput);
1.1.1.2   root      477: } /* end of memdump */
1.1       root      478: 
1.1.1.6   root      479: 
1.1       root      480: /*-----------------------------------------------------------------------*/
1.1.1.8   root      481: /**
                    482:  * Do a memory write, arg = starting address, followed by bytes.
                    483:  */
                    484: static void DebugUI_MemWrite(char *arg)
1.1       root      485: {
1.1.1.6   root      486:        int i, j, numBytes;
                    487:        long write_addr;
                    488:        unsigned char bytes[300]; /* store bytes */
                    489:        char temp[15];
                    490:        int d;
                    491: 
                    492:        numBytes = 0;
                    493:        i = 0;
                    494: 
1.1.1.9   root      495:        Str_Trunc(arg);
1.1.1.6   root      496:        while (arg[i] == ' ')
                    497:                i++; /* skip spaces */
                    498:        while (arg[i] != ' ')
                    499:                i++; /* skip command */
                    500:        while (arg[i] == ' ')
                    501:                i++; /* skip spaces */
                    502: 
                    503:        j = 0;
1.1.1.8   root      504:        while (isxdigit((unsigned)arg[i]) && j < 14) /* get address */
1.1.1.6   root      505:                temp[j++] = arg[i++];
                    506:        temp[j] = '\0';
                    507:        j = sscanf(temp, "%lx", &write_addr);
                    508: 
                    509:        /* if next char is not valid, or it's not a valid address */
                    510:        if ((arg[i] != '\0' && arg[i] != ' ') || (j == 0))
                    511:        {
                    512:                fprintf(stderr, "Bad address!\n");
                    513:                return;
                    514:        }
                    515: 
                    516:        write_addr &= 0x00FFFFFF;
                    517: 
                    518:        while (arg[i] == ' ')
                    519:                i++; /* skip spaces */
                    520: 
                    521:        /* get bytes data */
                    522:        while (arg[i] != '\0')
                    523:        {
                    524:                j = 0;
1.1.1.8   root      525:                while(isxdigit((unsigned)arg[i]) && j < 14) /* get byte */
1.1.1.6   root      526:                        temp[j++] = arg[i++];
                    527:                temp[j] = '\0';
                    528: 
                    529:                /* if next char is not a null or a space - it's not valid. */
                    530:                if (arg[i] != '\0' && arg[i] != ' ')
                    531:                {
                    532:                        fprintf(stderr, "Bad byte argument: %c\n", arg[i]);
                    533:                        return;
                    534:                }
                    535: 
                    536:                if (temp[0] != '\0')
                    537:                {
                    538:                        if (sscanf(temp,"%x", &d) != 1)
                    539:                        {
                    540:                                fprintf(stderr, "Bad byte argument!\n");
                    541:                                return;
                    542:                        }
                    543:                }
                    544: 
                    545:                bytes[numBytes] = (d&0x0FF);
                    546:                numBytes++;
                    547:                while (arg[i] == ' ')
                    548:                        i++; /* skip any spaces */
                    549:        }
                    550: 
                    551:        /* write the data */
                    552:        for (i = 0; i < numBytes; i++)
                    553:                STMemory_WriteByte(write_addr + i, bytes[i]);
1.1       root      554: }
                    555: 
1.1.1.6   root      556: 
1.1       root      557: /*-----------------------------------------------------------------------*/
1.1.1.8   root      558: /**
                    559:  * Print help.
                    560:  */
1.1.1.4   root      561: static void DebugUI_Help(void)
1.1       root      562: {
1.1.1.6   root      563:        fprintf(stderr, "---- debug mode commands ----\n"
                    564:                " d [address]- disassemble from PC, or given address. \n"
                    565:                " r [REG=value] - dump register values/ set register to value \n"
                    566:                " m [address] - dump memory at address, \n\tm alone continues from previous address.\n"
                    567:                " w address bytes - write bytes to a memory address, bytes are space separated. \n"
                    568:                " f [filename] - open log file, no argument closes the log file\n"
                    569:                "   Output of reg & mem dumps and disassembly will be written to the log\n"
                    570:                " l filename address - load a file into memory starting at address. \n"
                    571:                " s filename address length - dump length bytes from memory to a file. \n"
1.1.1.9   root      572:                " o [command line] - set Hatari command line options\n\n"
1.1.1.8   root      573:                " q - quit emulator\n"
                    574:                " c - continue emulation\n\n"
1.1.1.6   root      575:                " Adresses may be given as a range e.g. fc0000-fc0100\nAll values in hexadecimal.\n"
                    576:                "-----------------------------\n"
                    577:                "\n");
1.1       root      578: }
                    579: 
1.1.1.9   root      580: 
1.1       root      581: /*-----------------------------------------------------------------------*/
1.1.1.8   root      582: /**
1.1.1.9   root      583:  * Parse and return debug command.
1.1.1.8   root      584:  */
1.1.1.9   root      585: int DebugUI_ParseCommand(char *input)
1.1.1.6   root      586: {
                    587:        char command[255], arg[255];
1.1.1.8   root      588:        static char lastcommand = 0;
1.1.1.9   root      589:        int i, retval;
1.1.1.6   root      590: 
1.1.1.9   root      591:        /* Used for 'm' and 'd' to continue at last pos */
                    592:        command[0] = lastcommand;
1.1.1.8   root      593:        command[1] = 0;
                    594:        arg[0] = 0;
1.1.1.9   root      595:        i = sscanf(input, "%s%s", command, arg);
                    596:        Str_ToLower(command);
1.1       root      597: 
1.1.1.6   root      598:        if (i == 0)
                    599:        {
                    600:                fprintf(stderr, "  Unknown command.\n");
                    601:                return DEBUG_CMD;
                    602:        }
1.1.1.9   root      603:        if (!debugOutput) {
                    604:                DebugUI_SetLogDefault();
                    605:        }
1.1.1.6   root      606: 
1.1.1.8   root      607:        lastcommand = 0;
                    608:        retval = DEBUG_CMD;                /* Default return value */
                    609: 
1.1.1.6   root      610:        switch (command[0])
                    611:        {
1.1.1.8   root      612:         case 'c':
                    613:                retval = DEBUG_QUIT;
                    614:                break;
                    615: 
1.1.1.6   root      616:         case 'q':
1.1.1.8   root      617:                bQuitProgram = TRUE;
                    618:                M68000_SetSpecial(SPCFLAG_BRK);   /* Assure that CPU core shuts down */
                    619:                retval = DEBUG_QUIT;
1.1.1.6   root      620:                break;
                    621: 
                    622:         case 'h':
                    623:         case '?':
                    624:                DebugUI_Help(); /* get help */
                    625:                break;
                    626: 
                    627:         case 'o':
1.1.1.9   root      628:                Change_ApplyCommandline(input+1);
1.1.1.6   root      629:                break;
                    630: 
                    631:         case 'd':
                    632:                if (i < 2)  /* no arg? */
                    633:                        DebugUI_DisAsm(arg, TRUE);    /* No arg - disassemble at PC */
                    634:                else
                    635:                        DebugUI_DisAsm(arg, FALSE);   /* disasm at address. */
1.1.1.8   root      636:                lastcommand = 'd';
1.1.1.6   root      637:                break;
                    638: 
                    639:         case 'm':
                    640:                if (i < 2)
                    641:                {  /* no arg? */
                    642:                        if (bMemDump == FALSE)
                    643:                                fprintf(stderr,"  Usage: m address\n");
1.1.1.8   root      644:                        else
                    645:                                DebugUI_MemDump(arg, TRUE);   /* No arg - continue memdump */
1.1.1.6   root      646:                }
                    647:                else
                    648:                        DebugUI_MemDump(arg, FALSE);  /* new memdump */
1.1.1.8   root      649:                lastcommand = 'm';
1.1.1.6   root      650:                break;
                    651: 
                    652:         case 'f':
                    653:                if (i < 2)
1.1.1.9   root      654:                        DebugUI_SetLogDefault();
1.1.1.6   root      655:                else
1.1.1.9   root      656:                        DebugUI_SetLogFile(arg);
1.1.1.6   root      657:                break;
                    658: 
                    659:         case 'w':
1.1.1.8   root      660:                if (i < 2)    /* not enough args? */
1.1.1.6   root      661:                        fprintf(stderr, "  Usage: w address bytes\n");
1.1.1.8   root      662:                else
1.1.1.9   root      663:                        DebugUI_MemWrite(input);
1.1.1.6   root      664:                break;
                    665: 
                    666:         case 'r':
                    667:                if (i < 2)
1.1.1.8   root      668:                        DebugUI_RegDump();  /* no arg - dump regs */
                    669:                else
                    670:                        DebugUI_RegSet(arg);
1.1.1.6   root      671:                break;
                    672: 
                    673:         case 'l':
1.1.1.8   root      674:                if (i < 2)    /* not enough args? */
1.1.1.6   root      675:                        fprintf(stderr,"  Usage: l filename address\n");
1.1.1.8   root      676:                else
1.1.1.9   root      677:                        DebugUI_LoadBin(input);
1.1.1.6   root      678:                break;
                    679: 
                    680:         case 's':
1.1.1.8   root      681:                if (i < 2)    /* not enough args? */
1.1.1.6   root      682:                        fprintf(stderr,"  Usage: s filename address bytes\n");
1.1.1.8   root      683:                else
1.1.1.9   root      684:                        DebugUI_SaveBin(input);
1.1.1.6   root      685:                break;
                    686: 
                    687:         default:
1.1.1.8   root      688:                if (command[0])
                    689:                        fprintf(stderr,"  Unknown command: '%s'\n", command);
1.1.1.6   root      690:                break;
                    691:        }
                    692: 
1.1.1.9   root      693:        return retval;
                    694: }
                    695: 
                    696: /*-----------------------------------------------------------------------*/
                    697: /**
                    698:  * Get a UI command, parse and return it.
                    699:  */
                    700: static int DebugUI_GetCommand(void)
                    701: {
                    702:        char *input;
                    703:        int retval;
1.1.1.8   root      704: 
1.1.1.9   root      705: #if HAVE_LIBREADLINE
                    706:        input = readline("> ");
                    707:        if (!input)
                    708:                return DEBUG_QUIT;
                    709:        if (input[0] != 0)
                    710:                add_history(input);
                    711: #else
                    712:        fprintf(stderr, "> ");
                    713:        input = malloc(256);
                    714:        if (!input)
                    715:                return DEBUG_QUIT;
                    716:        input[0] = '\0';
                    717:        fgets(input, 256, stdin);
                    718: #endif
                    719:        retval = DebugUI_ParseCommand(input);
                    720: 
                    721:        free(input);
1.1.1.8   root      722:        return retval;
1.1       root      723: }
                    724: 
                    725: 
                    726: /*-----------------------------------------------------------------------*/
1.1.1.8   root      727: /**
                    728:  * Debug UI
                    729:  */
1.1.1.4   root      730: void DebugUI(void)
1.1       root      731: {
1.1.1.6   root      732:        bMemDump = FALSE;
                    733:        disasm_addr = 0;
1.1.1.2   root      734: 
1.1.1.8   root      735:        fprintf(stderr, "\nYou have entered debug mode. Type c to continue emulation, h for help."
                    736:                        "\n----------------------------------------------------------------------\n");
1.1.1.9   root      737:        while (DebugUI_GetCommand() != DEBUG_QUIT)
1.1.1.6   root      738:                ;
                    739:        fprintf(stderr,"Returning to emulation...\n------------------------------\n\n");
1.1.1.9   root      740:        DebugUI_SetLogDefault();
1.1       root      741: }

unix.superglobalmegacorp.com

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