|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Debugger
5: *
6: * (c) 1995 Bernd Schmidt
7: *
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"
18: #include "memory.h"
19: #include "custom.h"
1.1.1.2 ! root 20: #include "readcpu.h"
1.1 root 21: #include "newcpu.h"
22: #include "debug.h"
23: #include "cia.h"
24: #include "xwin.h"
25: #include "gui.h"
26:
27: static int debugger_active = 0;
28: static CPTR skipaddr;
29: static int do_skip;
30: int debugging = 0;
31:
32: void activate_debugger(void)
33: {
34: do_skip = 0;
35: if (debugger_active)
36: return;
37: debugger_active = 1;
38: regs.spcflags |= SPCFLAG_BRK;
39: debugging = 1;
40: use_debugger = 1;
41: }
42:
43: int firsthist = 0;
44: int lasthist = 0;
45: #ifdef NEED_TO_DEBUG_BADLY
46: struct regstruct history[MAX_HIST];
47: union flagu historyf[MAX_HIST];
48: #else
49: CPTR history[MAX_HIST];
50: #endif
51:
52: static void ignore_ws(char **c)
53: {
54: while (**c && isspace(**c)) (*c)++;
55: }
56:
57: static ULONG readhex(char **c)
58: {
59: ULONG val = 0;
60: char nc;
61:
62: ignore_ws(c);
63:
64: while (isxdigit(nc = **c)){
65: (*c)++;
66: val *= 16;
67: nc = toupper(nc);
68: if (isdigit(nc)) {
69: val += nc - '0';
70: } else {
71: val += nc - 'A' + 10;
72: }
73: }
74: return val;
75: }
76:
77: static char next_char(char **c)
78: {
79: ignore_ws(c);
80: return *(*c)++;
81: }
82:
83: static int more_params(char **c)
84: {
85: ignore_ws(c);
86: return (**c) != 0;
87: }
88:
89: static void dumpmem(CPTR addr, CPTR *nxmem, int lines)
90: {
91: broken_in = 0;
92: for (;lines-- && !broken_in;){
93: int i;
94: printf("%08lx ", addr);
95: for(i=0; i< 16; i++) {
96: printf("%04x ", get_word(addr)); addr += 2;
97: }
98: printf("\n");
99: }
100: *nxmem = addr;
101: }
102:
1.1.1.2 ! root 103: static void modulesearch(void)
! 104: {
! 105: ULONG ptr;
! 106:
! 107: for(ptr=0x438;ptr<chipmem_size;ptr+=4) {
! 108: /* Check for Mahoney & Kaktus */
! 109: /* Anyone got the format of old 15 Sample (SoundTracker)modules? */
! 110: if(chipmemory[ptr] == 'M' && chipmemory[ptr+1] == '.'
! 111: && chipmemory[ptr+2] == 'K' && chipmemory[ptr+3] == '.')
! 112: {
! 113: char name[21];
! 114: UBYTE *ptr2 = &chipmemory[ptr-0x438];
! 115: int i,j,length;
! 116:
! 117: printf("Found possible ProTracker (31 samples) module at 0x%lx.\n",ptr-0x438);
! 118: memcpy(name,ptr2,20);
! 119: name[20] = '\0';
! 120:
! 121: /* Browse playlist */
! 122: ptr2 += 0x3b8;
! 123: i = ptr2[-2]; /* length of playlist */
! 124: length = 0;
! 125: while(i--)
! 126: if((j=*ptr2++)>length)
! 127: length=j;
! 128:
! 129: length = (length+1)*1024+0x43c;
! 130:
! 131: /* Add sample lengths */
! 132: ptr2 = &chipmemory[ptr-0x438+0x2a];
! 133: for(i=0;i<31;i++,ptr2+=30)
! 134: length += 2*((ptr2[0]<<8)+ptr2[1]);
! 135:
! 136: printf("Name \"%s\", Length %ld (0x%lx) bytes.\n", name, length, length);
! 137: }
! 138: }
! 139: }
! 140:
1.1 root 141: void debug(void)
142: {
143: char input[80],c;
144: CPTR nextpc,nxdis,nxmem;
145:
146: bogusframe = 1;
147:
148: if (do_skip && (m68k_getpc() != skipaddr/* || regs.a[0] != 0x1e558*/)) {
149: regs.spcflags |= SPCFLAG_BRK;
150: return;
151: }
152: do_skip = 0;
153:
154: #ifdef NEED_TO_DEBUG_BADLY
155: history[lasthist] = regs;
156: historyf[lasthist] = regflags;
157: #else
158: history[lasthist] = m68k_getpc();
159: #endif
160: if (++lasthist == MAX_HIST) lasthist = 0;
161: if (lasthist == firsthist) {
162: if (++firsthist == MAX_HIST) firsthist = 0;
163: }
164:
165: m68k_dumpstate(&nextpc);
166: nxdis = nextpc; nxmem = 0;
167:
168: for(;;){
169: char cmd,*inptr;
170:
171: printf(">");
1.1.1.2 ! root 172: fflush (stdout);
! 173: if (fgets(input, 80, stdin) == 0)
! 174: return;
1.1 root 175: inptr = input;
176: cmd = next_char(&inptr);
177: switch(cmd){
178: case 'q': quit_program = 1; debugging = 0; regs.spcflags |= SPCFLAG_BRK; return;
179: case 'c': dumpcia(); dumpcustom(); break;
180: case 'r': m68k_dumpstate(&nextpc); break;
1.1.1.2 ! root 181: case 'M': modulesearch(); break;
1.1 root 182: case 'd':
183: {
184: ULONG daddr;
185: int count;
186:
187: if (more_params(&inptr))
188: daddr = readhex(&inptr);
189: else
190: daddr = nxdis;
191: if (more_params(&inptr))
192: count = readhex(&inptr);
193: else
194: count = 10;
195: m68k_disasm(daddr, &nxdis, count);
196: }
197: break;
198: case 't': regs.spcflags |= SPCFLAG_BRK; return;
199: case 'z':
200: skipaddr = nextpc;
201: do_skip = 1;
202: regs.spcflags |= SPCFLAG_BRK;
203: return;
204:
205: case 'f':
206: skipaddr = readhex(&inptr);
207: do_skip = 1;
208: regs.spcflags |= SPCFLAG_BRK;
209: return;
210:
211: case 'g':
212: if (more_params (&inptr))
213: m68k_setpc (readhex (&inptr));
214: debugger_active = 0;
215: debugging = 0;
216: return;
217:
218: case 'H':
219: {
220: int count;
221: int temp;
222: #ifdef NEED_TO_DEBUG_BADLY
223: struct regstruct save_regs = regs;
224: union flagu save_flags = regflags;
225: #endif
226:
227: if (more_params(&inptr))
228: count = readhex(&inptr);
229: else
230: count = 10;
231: if (count < 0)
232: break;
233: temp = lasthist;
234: while (count-- > 0 && temp != firsthist) {
235: if (temp == 0) temp = MAX_HIST-1; else temp--;
236: }
237: while (temp != lasthist) {
238: #ifdef NEED_TO_DEBUG_BADLY
239: regs = history[temp];
240: regflags = historyf[temp];
241: m68k_dumpstate(NULL);
242: #else
243: m68k_disasm(history[temp], NULL, 1);
244: #endif
245: if (++temp == MAX_HIST) temp = 0;
246: }
247: #ifdef NEED_TO_DEBUG_BADLY
248: regs = save_regs;
249: regflags = save_flags;
250: #endif
251: }
252: break;
253: case 'm':
254: {
255: ULONG maddr; int lines;
256: if (more_params(&inptr))
257: maddr = readhex(&inptr);
258: else
259: maddr = nxmem;
260: if (more_params(&inptr))
261: lines = readhex(&inptr);
262: else
263: lines = 16;
264: dumpmem(maddr, &nxmem, lines);
265: }
266: break;
267: case 'h':
268: case '?':
269: {
270: printf (" HELP for UAE Debugger\n");
271: printf (" -----------------------\n\n");
272: printf (" g: <address> ");
1.1.1.2 ! root 273: printf("Start execution at the current address or <address>\n");
1.1 root 274: printf (" c: ");
1.1.1.2 ! root 275: printf("Dump state of the CIA and custom chips\n");
1.1 root 276: printf (" r: ");
277: printf("Dump state of the CPU\n");
278: printf (" m <address> <lines>: ");
279: printf ("Memory dump starting at <address>\n");
280: printf (" d <address> <lines>: ");
281: printf ("Disassembly starting at <address>\n");
282: printf (" t: ");
283: printf ("Step one instruction\n");
284: printf (" z: ");
285: printf ("Step through one instruction - useful for JSR, DBRA etc\n");
286: printf (" f <address>: ");
287: printf ("Step forward until PC == <address>\n");
288: printf (" H <count>: ");
1.1.1.2 ! root 289: printf ("Show PC history <count> instructions\n");
! 290: printf (" M: ");
! 291: printf ("Search for *Tracker sound modules\n");
1.1 root 292: printf (" h,?: ");
293: printf ("Show this help page\n");
294: printf (" q: ");
295: printf ("Quit the emulator. You don't want to use this command.\n\n");
296: }
297: break;
298:
299: }
300: }
301: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.