|
|
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: 34: void activate_debugger(void) 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: 54: static void ignore_ws(char **c) 55: { 56: while (**c && isspace(**c)) (*c)++; 57: } 58: 1.1.1.3 ! 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: 64: ignore_ws(c); 1.1.1.3 ! root 65: 1.1 root 66: while (isxdigit(nc = **c)){ 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: 79: static char next_char(char **c) 80: { 81: ignore_ws(c); 82: return *(*c)++; 83: } 84: 85: static int more_params(char **c) 86: { 87: ignore_ws(c); 88: return (**c) != 0; 89: } 90: 1.1.1.3 ! root 91: static void dumpmem(uaecptr addr, uaecptr *nxmem, int lines) 1.1 root 92: { 93: broken_in = 0; 94: for (;lines-- && !broken_in;){ 95: int i; 96: printf("%08lx ", addr); 97: for(i=0; i< 16; i++) { 98: printf("%04x ", get_word(addr)); addr += 2; 99: } 100: printf("\n"); 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; ! 125: for(i = 0; i < 31; i++, ptr2 += 30) ! 126: length += 2*((ptr2[0]<<8)+ptr2[1]); 1.1.1.2 root 127: 1.1.1.3 ! root 128: printf("Name \"%s\", Length 0x%lx bytes.\n", name, length); ! 129: } ! 130: ! 131: static void modulesearch(void) ! 132: { ! 133: uae_u8 *p = get_real_address (0); ! 134: uae_u32 ptr; ! 135: ! 136: for (ptr = 0; ptr < chipmem_size - 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 root 175: void debug(void) 176: { 177: char input[80],c; 1.1.1.3 ! root 178: uaecptr nextpc,nxdis,nxmem; 1.1 root 179: 180: bogusframe = 1; 1.1.1.3 ! root 181: 1.1 root 182: if (do_skip && (m68k_getpc() != skipaddr/* || regs.a[0] != 0x1e558*/)) { 183: regs.spcflags |= SPCFLAG_BRK; 184: return; 185: } 186: do_skip = 0; 187: 188: #ifdef NEED_TO_DEBUG_BADLY 189: history[lasthist] = regs; 190: historyf[lasthist] = regflags; 191: #else 192: history[lasthist] = m68k_getpc(); 193: #endif 194: if (++lasthist == MAX_HIST) lasthist = 0; 195: if (lasthist == firsthist) { 196: if (++firsthist == MAX_HIST) firsthist = 0; 197: } 198: 199: m68k_dumpstate(&nextpc); 200: nxdis = nextpc; nxmem = 0; 201: 202: for(;;){ 203: char cmd,*inptr; 1.1.1.3 ! root 204: 1.1 root 205: printf(">"); 1.1.1.2 root 206: fflush (stdout); 207: if (fgets(input, 80, stdin) == 0) 208: return; 1.1 root 209: inptr = input; 210: cmd = next_char(&inptr); 211: switch(cmd){ 212: case 'c': dumpcia(); dumpcustom(); break; 213: case 'r': m68k_dumpstate(&nextpc); break; 1.1.1.2 root 214: case 'M': modulesearch(); break; 1.1.1.3 ! root 215: case 'S': ! 216: { ! 217: uae_u8 *memp; ! 218: uae_u32 src, len; ! 219: char *name; ! 220: FILE *fp; ! 221: ! 222: if (!more_params (&inptr)) ! 223: goto S_argh; ! 224: ! 225: name = inptr; ! 226: while (*inptr != '\0' && !isspace (*inptr)) ! 227: inptr++; ! 228: if (!isspace (*inptr)) ! 229: goto S_argh; ! 230: ! 231: *inptr = '\0'; ! 232: inptr++; ! 233: if (!more_params (&inptr)) ! 234: goto S_argh; ! 235: src = readhex (&inptr); ! 236: if (!more_params (&inptr)) ! 237: goto S_argh; ! 238: len = readhex (&inptr); ! 239: if (! valid_address (src, len)) { ! 240: printf ("Invalid memory block\n"); ! 241: break; ! 242: } ! 243: memp = get_real_address (src); ! 244: fp = fopen (name, "w"); ! 245: if (fp == NULL) { ! 246: printf ("Couldn't open file\n"); ! 247: break; ! 248: } ! 249: if (fwrite (memp, 1, len, fp) != len) { ! 250: printf ("Error writing file\n"); ! 251: } ! 252: fclose (fp); ! 253: break; ! 254: ! 255: S_argh: ! 256: printf ("S command needs more arguments!\n"); ! 257: break; ! 258: } ! 259: case 'd': 1.1 root 260: { 1.1.1.3 ! root 261: uae_u32 daddr; 1.1 root 262: int count; 1.1.1.3 ! root 263: 1.1 root 264: if (more_params(&inptr)) 265: daddr = readhex(&inptr); 1.1.1.3 ! root 266: else 1.1 root 267: daddr = nxdis; 268: if (more_params(&inptr)) 1.1.1.3 ! root 269: count = readhex(&inptr); 1.1 root 270: else 271: count = 10; 272: m68k_disasm(daddr, &nxdis, count); 273: } 274: break; 275: case 't': regs.spcflags |= SPCFLAG_BRK; return; 276: case 'z': 277: skipaddr = nextpc; 278: do_skip = 1; 279: regs.spcflags |= SPCFLAG_BRK; 280: return; 281: 1.1.1.3 ! root 282: case 'f': 1.1 root 283: skipaddr = readhex(&inptr); 284: do_skip = 1; 285: regs.spcflags |= SPCFLAG_BRK; 286: return; 287: 1.1.1.3 ! root 288: case 'q': uae_quit(); ! 289: debugger_active = 0; ! 290: debugging = 0; ! 291: return; ! 292: 1.1 root 293: case 'g': 294: if (more_params (&inptr)) 295: m68k_setpc (readhex (&inptr)); 1.1.1.3 ! root 296: fill_prefetch_0 (); 1.1 root 297: debugger_active = 0; 298: debugging = 0; 299: return; 300: 301: case 'H': 302: { 303: int count; 304: int temp; 305: #ifdef NEED_TO_DEBUG_BADLY 306: struct regstruct save_regs = regs; 307: union flagu save_flags = regflags; 308: #endif 309: 1.1.1.3 ! root 310: if (more_params(&inptr)) ! 311: count = readhex(&inptr); ! 312: else 1.1 root 313: count = 10; 1.1.1.3 ! root 314: if (count < 0) 1.1 root 315: break; 1.1.1.3 ! root 316: temp = lasthist; ! 317: while (count-- > 0 && temp != firsthist) { 1.1 root 318: if (temp == 0) temp = MAX_HIST-1; else temp--; 1.1.1.3 ! root 319: } ! 320: while (temp != lasthist) { 1.1 root 321: #ifdef NEED_TO_DEBUG_BADLY 322: regs = history[temp]; 323: regflags = historyf[temp]; 324: m68k_dumpstate(NULL); 325: #else 326: m68k_disasm(history[temp], NULL, 1); 327: #endif 328: if (++temp == MAX_HIST) temp = 0; 1.1.1.3 ! root 329: } 1.1 root 330: #ifdef NEED_TO_DEBUG_BADLY 331: regs = save_regs; 332: regflags = save_flags; 333: #endif 334: } 335: break; 336: case 'm': 337: { 1.1.1.3 ! root 338: uae_u32 maddr; int lines; 1.1 root 339: if (more_params(&inptr)) 1.1.1.3 ! root 340: maddr = readhex(&inptr); ! 341: else 1.1 root 342: maddr = nxmem; 343: if (more_params(&inptr)) 1.1.1.3 ! root 344: lines = readhex(&inptr); ! 345: else 1.1 root 346: lines = 16; 347: dumpmem(maddr, &nxmem, lines); 348: } 349: break; 1.1.1.3 ! root 350: case 'h': ! 351: case '?': 1.1 root 352: { 1.1.1.3 ! root 353: printf (" HELP for UAE Debugger\n"); ! 354: printf (" -----------------------\n\n"); ! 355: printf (" g: <address> Start execution at the current address or <address>\n"); ! 356: printf (" c: Dump state of the CIA and custom chips\n"); ! 357: printf (" r: Dump state of the CPU\n"); ! 358: printf (" m <address> <lines>: Memory dump starting at <address>\n"); ! 359: printf (" d <address> <lines>: Disassembly starting at <address>\n"); ! 360: printf (" t: Step one instruction\n"); ! 361: printf (" z: Step through one instruction - useful for JSR, DBRA etc\n"); ! 362: printf (" f <address>: Step forward until PC == <address>\n"); ! 363: printf (" H <count>: Show PC history <count> instructions\n"); ! 364: printf (" M: Search for *Tracker sound modules\n"); ! 365: printf (" S <file> <addr> <n>: Save a block of Amiga memory\n"); ! 366: printf (" h,?: Show this help page\n"); ! 367: printf (" q: Quit the emulator. You don't want to use this command.\n\n"); ! 368: } ! 369: break; ! 370: 1.1 root 371: } 372: } 373: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.