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

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

unix.superglobalmegacorp.com

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