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

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

unix.superglobalmegacorp.com

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