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

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

unix.superglobalmegacorp.com

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