Annotation of uae/src/debug.c, revision 1.1.1.7

1.1.1.3   root        1:  /*
1.1       root        2:   * UAE - The Un*x Amiga Emulator
1.1.1.3   root        3:   *
1.1       root        4:   * Debugger
1.1.1.3   root        5:   *
1.1       root        6:   * (c) 1995 Bernd Schmidt
1.1.1.3   root        7:   *
1.1       root        8:   */
                      9: 
                     10: #include "sysconfig.h"
                     11: #include "sysdeps.h"
                     12: 
                     13: #include <ctype.h>
                     14: #include <signal.h>
                     15: 
                     16: #include "config.h"
                     17: #include "options.h"
1.1.1.3   root       18: #include "threaddep/penguin.h"
                     19: #include "uae.h"
1.1       root       20: #include "memory.h"
                     21: #include "custom.h"
1.1.1.2   root       22: #include "readcpu.h"
1.1       root       23: #include "newcpu.h"
                     24: #include "debug.h"
                     25: #include "cia.h"
                     26: #include "xwin.h"
                     27: #include "gui.h"
                     28: 
                     29: static int debugger_active = 0;
1.1.1.3   root       30: static uaecptr skipaddr;
1.1       root       31: static int do_skip;
                     32: int debugging = 0;
                     33: 
1.1.1.7 ! root       34: static FILE *logfile;
        !            35: 
1.1.1.4   root       36: void activate_debugger (void)
1.1       root       37: {
1.1.1.7 ! root       38:     if (logfile)
        !            39:        fclose (logfile);
        !            40:     logfile = 0;
1.1       root       41:     do_skip = 0;
                     42:     if (debugger_active)
                     43:        return;
                     44:     debugger_active = 1;
                     45:     regs.spcflags |= SPCFLAG_BRK;
                     46:     debugging = 1;
1.1.1.5   root       47:     /* use_debugger = 1; */
1.1       root       48: }
                     49: 
                     50: int firsthist = 0;
                     51: int lasthist = 0;
                     52: #ifdef NEED_TO_DEBUG_BADLY
                     53: struct regstruct history[MAX_HIST];
                     54: union flagu historyf[MAX_HIST];
                     55: #else
1.1.1.3   root       56: uaecptr history[MAX_HIST];
1.1       root       57: #endif
                     58: 
1.1.1.4   root       59: static void ignore_ws (char **c)
1.1       root       60: {
                     61:     while (**c && isspace(**c)) (*c)++;
                     62: }
                     63: 
1.1.1.4   root       64: static uae_u32 readhex (char **c)
1.1       root       65: {
1.1.1.3   root       66:     uae_u32 val = 0;
1.1       root       67:     char nc;
                     68: 
1.1.1.4   root       69:     ignore_ws (c);
1.1.1.3   root       70: 
1.1.1.4   root       71:     while (isxdigit(nc = **c)) {
1.1       root       72:        (*c)++;
                     73:        val *= 16;
                     74:        nc = toupper(nc);
                     75:        if (isdigit(nc)) {
                     76:            val += nc - '0';
                     77:        } else {
                     78:            val += nc - 'A' + 10;
                     79:        }
                     80:     }
                     81:     return val;
                     82: }
                     83: 
1.1.1.4   root       84: static char next_char( char **c)
1.1       root       85: {
1.1.1.4   root       86:     ignore_ws (c);
1.1       root       87:     return *(*c)++;
                     88: }
                     89: 
1.1.1.4   root       90: static int more_params (char **c)
1.1       root       91: {
1.1.1.4   root       92:     ignore_ws (c);
1.1       root       93:     return (**c) != 0;
                     94: }
                     95: 
1.1.1.4   root       96: static void dumpmem (uaecptr addr, uaecptr *nxmem, int lines)
1.1       root       97: {
                     98:     broken_in = 0;
1.1.1.4   root       99:     for (;lines-- && !broken_in;) {
1.1       root      100:        int i;
1.1.1.4   root      101:        printf ("%08lx ", addr);
                    102:        for (i = 0; i < 16; i++) {
                    103:            printf ("%04x ", get_word(addr)); addr += 2;
1.1       root      104:        }
1.1.1.4   root      105:        printf ("\n");
1.1       root      106:     }
                    107:     *nxmem = addr;
                    108: }
                    109: 
1.1.1.3   root      110: static void foundmod (uae_u32 ptr, char *type)
1.1.1.2   root      111: {
1.1.1.3   root      112:     char name[21];
                    113:     uae_u8 *ptr2 = chipmemory + ptr;
                    114:     int i,length;
                    115: 
                    116:     printf ("Found possible %s module at 0x%lx.\n", type, ptr);
                    117:     memcpy (name, ptr2, 20);
                    118:     name[20] = '\0';
                    119: 
                    120:     /* Browse playlist */
                    121:     length = 0;
                    122:     for (i = 0x3b8; i < 0x438; i++)
                    123:        if (ptr2[i] > length)
                    124:            length = ptr2[i];
                    125: 
                    126:     length = (length+1)*1024 + 0x43c;
                    127: 
                    128:     /* Add sample lengths */
                    129:     ptr2 += 0x2A;
1.1.1.4   root      130:     for (i = 0; i < 31; i++, ptr2 += 30)
1.1.1.3   root      131:        length += 2*((ptr2[0]<<8)+ptr2[1]);
1.1.1.2   root      132:     
1.1.1.4   root      133:     printf ("Name \"%s\", Length 0x%lx bytes.\n", name, length);
1.1.1.3   root      134: }
                    135: 
1.1.1.4   root      136: static void modulesearch (void)
1.1.1.3   root      137: {
                    138:     uae_u8 *p = get_real_address (0);
                    139:     uae_u32 ptr;
                    140: 
1.1.1.4   root      141:     for (ptr = 0; ptr < allocated_chipmem - 40; ptr += 2, p += 2) {
1.1.1.2   root      142:        /* Check for Mahoney & Kaktus */
                    143:        /* Anyone got the format of old 15 Sample (SoundTracker)modules? */
1.1.1.3   root      144:        if (ptr >= 0x438 && p[0] == 'M' && p[1] == '.' && p[2] == 'K' && p[3] == '.')
                    145:            foundmod (ptr - 0x438, "ProTracker (31 samples)");
                    146: 
                    147:        if (ptr >= 0x438 && p[0] == 'F' && p[1] == 'L' && p[2] == 'T' && p[3] == '4')
                    148:            foundmod (ptr - 0x438, "Startrekker");
                    149: 
                    150:        if (strncmp ((char *)p, "SMOD", 4) == 0) {
                    151:            printf ("Found possible FutureComposer 1.3 module at 0x%lx, length unknown.\n", ptr);
                    152:        }
                    153:        if (strncmp ((char *)p, "FC14", 4) == 0) {
                    154:            printf ("Found possible FutureComposer 1.4 module at 0x%lx, length unknown.\n", ptr);
                    155:        }
                    156:        if (p[0] == 0x48 && p[1] == 0xe7 && p[4] == 0x61 && p[5] == 0
                    157:            && p[8] == 0x4c && p[9] == 0xdf && p[12] == 0x4e && p[13] == 0x75
                    158:            && p[14] == 0x48 && p[15] == 0xe7 && p[18] == 0x61 && p[19] == 0
                    159:            && p[22] == 0x4c && p[23] == 0xdf && p[26] == 0x4e && p[27] == 0x75) {
                    160:            printf ("Found possible Whittaker module at 0x%lx, length unknown.\n", ptr);
                    161:        }
                    162:        if (p[4] == 0x41 && p[5] == 0xFA) {
                    163:            int i;
                    164: 
                    165:            for (i = 0; i < 0x240; i += 2)
                    166:                if (p[i] == 0xE7 && p[i + 1] == 0x42 && p[i + 2] == 0x41 && p[i + 3] == 0xFA)
                    167:                    break;
                    168:            if (i < 0x240) {
                    169:                uae_u8 *p2 = p + i + 4;
                    170:                for (i = 0; i < 0x30; i += 2)
                    171:                    if (p2[i] == 0xD1 && p2[i + 1] == 0xFA) {
                    172:                        printf ("Found possible MarkII module at %lx, length unknown.\n", ptr);
                    173:                    }
                    174:            }
                    175:                
1.1.1.2   root      176:        }
                    177:     }
                    178: }
                    179: 
1.1.1.4   root      180: /* cheat-search by Holger Jakob */
                    181: static void cheatsearch (char **c)
                    182: {
                    183:     uae_u8 *p = get_real_address (0);
                    184:     static uae_u32 *vlist = NULL;
                    185:     uae_u32 ptr;
                    186:     uae_u32 val = 0;
                    187:     uae_u32 type = 0; /* not yet */
                    188:     uae_u32 count = 0;
                    189:     uae_u32 fcount = 0;
                    190:     uae_u32 full = 0;
                    191:     char nc;
                    192: 
                    193:     ignore_ws (c);
                    194: 
                    195:     while (isxdigit (nc = **c)) {
                    196:        (*c)++;
                    197:        val *= 10;
                    198:        nc = toupper (nc);
                    199:        if (isdigit (nc)) {
                    200:            val += nc - '0';
                    201:        }
                    202:     }
                    203:     if (vlist == NULL) {
                    204:        vlist = malloc (256*4);
                    205:        if (vlist != 0) {
                    206:            for (count = 0; count<255; count++)
                    207:                vlist[count] = 0;
                    208:            count = 0;
                    209:            for (ptr = 0; ptr < allocated_chipmem - 40; ptr += 2, p += 2) {
                    210:                if (ptr >= 0x438 && p[3] == (val & 0xff)
                    211:                    && p[2] == (val >> 8 & 0xff)
                    212:                    && p[1] == (val >> 16 & 0xff)
                    213:                    && p[0] == (val >> 24 & 0xff))
                    214:                {
                    215:                    if (count < 255) {
                    216:                        vlist[count++]=ptr;
                    217:                        printf ("%08x: %x%x%x%x\n",ptr,p[0],p[1],p[2],p[3]);
                    218:                    } else
                    219:                        full = 1;
                    220:                }
                    221:            }
                    222:            printf ("Found %d possible addresses with %d\n",count,val);
                    223:            printf ("Now continue with 'g' and use 'C' with a different value\n");
                    224:        }
                    225:     } else {
                    226:        for (count = 0; count<255; count++) {
                    227:            if (p[vlist[count]+3] == (val & 0xff)
                    228:                && p[vlist[count]+2] == (val>>8 & 0xff) 
                    229:                && p[vlist[count]+1] == (val>>16 & 0xff)
                    230:                && p[vlist[count]] == (val>>24 & 0xff))
                    231:            {
                    232:                fcount++;
                    233:                printf ("%08x: %x%x%x%x\n", vlist[count], p[vlist[count]],
                    234:                        p[vlist[count]+1], p[vlist[count]+2], p[vlist[count]+3]);
                    235:            }
                    236:        }
                    237:        printf ("%d hits of %d found\n",fcount,val);
                    238:        free (vlist);
                    239:        vlist = NULL;
                    240:     }
                    241: }
                    242: 
                    243: static void writeintomem (char **c)
                    244: {
                    245:     uae_u8 *p = get_real_address (0);
                    246:     uae_u32 addr = 0;
                    247:     uae_u32 val = 0;
                    248:     char nc;
                    249: 
                    250:     ignore_ws(c);
                    251:     while (isxdigit(nc = **c)) {
                    252:        (*c)++;
                    253:        addr *= 16;
                    254:        nc = toupper(nc);
                    255:        if (isdigit(nc)) {
                    256:            addr += nc - '0';
                    257:        } else {
                    258:            addr += nc - 'A' + 10;
                    259:        }
                    260:     }
                    261:     ignore_ws(c);
                    262:     while (isxdigit(nc = **c)) {
                    263:        (*c)++;
                    264:        val *= 10;
                    265:        nc = toupper(nc);
                    266:        if (isdigit(nc)) {
                    267:            val += nc - '0';
                    268:        }
                    269:     }
                    270: 
                    271:     if (addr < allocated_chipmem) {
                    272:       p[addr] = val>>24 & 0xff;
                    273:       p[addr+1] = val>>16 & 0xff;
                    274:       p[addr+2] = val>>8 & 0xff;
                    275:       p[addr+3] = val & 0xff;
                    276:       printf("Wrote %d at %08x\n",val,addr);
                    277:     } else
                    278:       printf("Invalid address %08x\n",addr);
                    279: }
1.1.1.7 ! root      280: 
1.1.1.4   root      281: void debug (void)
1.1       root      282: {
1.1.1.4   root      283:     char input[80];
1.1.1.3   root      284:     uaecptr nextpc,nxdis,nxmem;
1.1       root      285: 
                    286:     bogusframe = 1;
1.1.1.3   root      287: 
1.1.1.7 ! root      288:     if (do_skip && skipaddr == 0xC0DEDBAD) {
        !           289:        m68k_dumpstate (logfile, &nextpc);
        !           290:     }
        !           291: 
1.1       root      292:     if (do_skip && (m68k_getpc() != skipaddr/* || regs.a[0] != 0x1e558*/)) {
                    293:        regs.spcflags |= SPCFLAG_BRK;
                    294:        return;
                    295:     }
                    296:     do_skip = 0;
                    297: 
                    298: #ifdef NEED_TO_DEBUG_BADLY
                    299:     history[lasthist] = regs;
                    300:     historyf[lasthist] = regflags;
                    301: #else
                    302:     history[lasthist] = m68k_getpc();
                    303: #endif
                    304:     if (++lasthist == MAX_HIST) lasthist = 0;
                    305:     if (lasthist == firsthist) {
                    306:        if (++firsthist == MAX_HIST) firsthist = 0;
                    307:     }
                    308: 
1.1.1.7 ! root      309:     m68k_dumpstate (stdout, &nextpc);
1.1       root      310:     nxdis = nextpc; nxmem = 0;
                    311: 
1.1.1.4   root      312:     for (;;) {
                    313:        char cmd, *inptr;
1.1.1.3   root      314: 
1.1.1.4   root      315:        printf (">");
1.1.1.2   root      316:        fflush (stdout);
1.1.1.4   root      317:        if (fgets (input, 80, stdin) == 0)
1.1.1.2   root      318:            return;
1.1       root      319:        inptr = input;
1.1.1.4   root      320:        cmd = next_char (&inptr);
                    321:        switch (cmd) {
1.1.1.6   root      322:         case 'c': dumpcia (); dumpdisk (); dumpcustom (); break;
1.1.1.7 ! root      323:         case 'r': m68k_dumpstate (stdout, &nextpc); break;
1.1.1.4   root      324:         case 'M': modulesearch (); break;
                    325:         case 'C': cheatsearch (&inptr); break; 
                    326:         case 'W': writeintomem (&inptr); break;
1.1.1.3   root      327:         case 'S':
                    328:            {
                    329:                uae_u8 *memp;
                    330:                uae_u32 src, len;
                    331:                char *name;
                    332:                FILE *fp;
                    333: 
                    334:                if (!more_params (&inptr))
                    335:                    goto S_argh;
                    336: 
                    337:                name = inptr;
                    338:                while (*inptr != '\0' && !isspace (*inptr))
                    339:                    inptr++;
                    340:                if (!isspace (*inptr))
                    341:                    goto S_argh;
                    342: 
                    343:                *inptr = '\0';
                    344:                inptr++;
                    345:                if (!more_params (&inptr))
                    346:                    goto S_argh;
                    347:                src = readhex (&inptr);
                    348:                if (!more_params (&inptr))
                    349:                    goto S_argh;
                    350:                len = readhex (&inptr);
                    351:                if (! valid_address (src, len)) {
                    352:                    printf ("Invalid memory block\n");
                    353:                    break;
                    354:                }
                    355:                memp = get_real_address (src);
                    356:                fp = fopen (name, "w");
                    357:                if (fp == NULL) {
                    358:                    printf ("Couldn't open file\n");
                    359:                    break;
                    360:                }
                    361:                if (fwrite (memp, 1, len, fp) != len) {
                    362:                    printf ("Error writing file\n");
                    363:                }
                    364:                fclose (fp);
                    365:                break;
                    366: 
                    367:                S_argh:
                    368:                printf ("S command needs more arguments!\n");
                    369:                break;
                    370:            }
                    371:         case 'd':
1.1       root      372:            {
1.1.1.3   root      373:                uae_u32 daddr;
1.1       root      374:                int count;
1.1.1.3   root      375: 
1.1       root      376:                if (more_params(&inptr))
                    377:                    daddr = readhex(&inptr);
1.1.1.3   root      378:                else
1.1       root      379:                    daddr = nxdis;
                    380:                if (more_params(&inptr))
1.1.1.3   root      381:                    count = readhex(&inptr);
1.1       root      382:                else
                    383:                    count = 10;
1.1.1.7 ! root      384:                m68k_disasm (stdout, daddr, &nxdis, count);
1.1       root      385:            }
                    386:            break;
                    387:         case 't': regs.spcflags |= SPCFLAG_BRK; return;
                    388:         case 'z':
                    389:            skipaddr = nextpc;
                    390:            do_skip = 1;
                    391:            regs.spcflags |= SPCFLAG_BRK;
                    392:            return;
                    393: 
1.1.1.3   root      394:         case 'f':
1.1.1.7 ! root      395:            skipaddr = readhex (&inptr);
1.1       root      396:            do_skip = 1;
                    397:            regs.spcflags |= SPCFLAG_BRK;
1.1.1.7 ! root      398:            if (skipaddr == 0xC0DEDBAD)
        !           399:                logfile = fopen ("uae.trace", "w");
1.1       root      400:            return;
                    401: 
1.1.1.3   root      402:         case 'q': uae_quit();
                    403:            debugger_active = 0;
                    404:            debugging = 0;
                    405:            return;
                    406: 
1.1       root      407:         case 'g':
                    408:            if (more_params (&inptr))
                    409:                m68k_setpc (readhex (&inptr));
1.1.1.3   root      410:            fill_prefetch_0 ();
1.1       root      411:            debugger_active = 0;
                    412:            debugging = 0;
                    413:            return;
                    414: 
                    415:         case 'H':
                    416:            {
                    417:                int count;
                    418:                int temp;
                    419: #ifdef NEED_TO_DEBUG_BADLY
                    420:                struct regstruct save_regs = regs;
                    421:                union flagu save_flags = regflags;
                    422: #endif
                    423: 
1.1.1.3   root      424:                if (more_params(&inptr))
                    425:                    count = readhex(&inptr);
                    426:                else
1.1       root      427:                    count = 10;
1.1.1.3   root      428:                if (count < 0)
1.1       root      429:                    break;
1.1.1.3   root      430:                temp = lasthist;
                    431:                while (count-- > 0 && temp != firsthist) {
1.1       root      432:                    if (temp == 0) temp = MAX_HIST-1; else temp--;
1.1.1.3   root      433:                }
                    434:                while (temp != lasthist) {
1.1       root      435: #ifdef NEED_TO_DEBUG_BADLY
                    436:                    regs = history[temp];
                    437:                    regflags = historyf[temp];
1.1.1.7 ! root      438:                    m68k_dumpstate (NULL);
1.1       root      439: #else
1.1.1.7 ! root      440:                    m68k_disasm (stdout, history[temp], NULL, 1);
1.1       root      441: #endif
                    442:                    if (++temp == MAX_HIST) temp = 0;
1.1.1.3   root      443:                }
1.1       root      444: #ifdef NEED_TO_DEBUG_BADLY
                    445:                regs = save_regs;
                    446:                regflags = save_flags;
                    447: #endif
                    448:            }
                    449:            break;
                    450:         case 'm':
                    451:            {
1.1.1.3   root      452:                uae_u32 maddr; int lines;
1.1       root      453:                if (more_params(&inptr))
1.1.1.3   root      454:                    maddr = readhex(&inptr);
                    455:                else
1.1       root      456:                    maddr = nxmem;
                    457:                if (more_params(&inptr))
1.1.1.3   root      458:                    lines = readhex(&inptr);
                    459:                else
1.1       root      460:                    lines = 16;
                    461:                dumpmem(maddr, &nxmem, lines);
                    462:            }
                    463:            break;
1.1.1.3   root      464:          case 'h':
                    465:          case '?':
1.1       root      466:            {
1.1.1.3   root      467:                printf ("          HELP for UAE Debugger\n");
                    468:                printf ("         -----------------------\n\n");
                    469:                printf ("  g: <address>          Start execution at the current address or <address>\n");
                    470:                printf ("  c:                    Dump state of the CIA and custom chips\n");
                    471:                printf ("  r:                    Dump state of the CPU\n");
                    472:                printf ("  m <address> <lines>:  Memory dump starting at <address>\n");
                    473:                printf ("  d <address> <lines>:  Disassembly starting at <address>\n");
                    474:                printf ("  t:                    Step one instruction\n");
                    475:                printf ("  z:                    Step through one instruction - useful for JSR, DBRA etc\n");
                    476:                printf ("  f <address>:          Step forward until PC == <address>\n");
                    477:                printf ("  H <count>:            Show PC history <count> instructions\n");
                    478:                printf ("  M:                    Search for *Tracker sound modules\n");
1.1.1.4   root      479:                printf ("  C <value>:            Search for values like energy or lifes in games\n");
                    480:                printf ("  W <address> <value>:  Write into Amiga memory\n");
1.1.1.3   root      481:                printf ("  S <file> <addr> <n>:  Save a block of Amiga memory\n");
                    482:                printf ("  h,?:                  Show this help page\n");
                    483:                printf ("  q:                    Quit the emulator. You don't want to use this command.\n\n");
                    484:            }
                    485:            break;
                    486: 
1.1       root      487:        }
                    488:     }
                    489: }

unix.superglobalmegacorp.com

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