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

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;
                     42:     use_debugger = 1;
                     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) {
        !           313:         case 'c': dumpcia (); dumpcustom (); break;
        !           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.