|
|
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"
20: #include "newcpu.h"
21: #include "debug.h"
22: #include "cia.h"
23: #include "xwin.h"
24: #include "gui.h"
25:
26: static int debugger_active = 0;
27: static CPTR skipaddr;
28: static int do_skip;
29: int debugging = 0;
30:
31: void activate_debugger(void)
32: {
33: do_skip = 0;
34: if (debugger_active)
35: return;
36: debugger_active = 1;
37: regs.spcflags |= SPCFLAG_BRK;
38: debugging = 1;
39: use_debugger = 1;
40: }
41:
42: int firsthist = 0;
43: int lasthist = 0;
44: #ifdef NEED_TO_DEBUG_BADLY
45: struct regstruct history[MAX_HIST];
46: union flagu historyf[MAX_HIST];
47: #else
48: CPTR history[MAX_HIST];
49: #endif
50:
51: static void ignore_ws(char **c)
52: {
53: while (**c && isspace(**c)) (*c)++;
54: }
55:
56: static ULONG readhex(char **c)
57: {
58: ULONG val = 0;
59: char nc;
60:
61: ignore_ws(c);
62:
63: while (isxdigit(nc = **c)){
64: (*c)++;
65: val *= 16;
66: nc = toupper(nc);
67: if (isdigit(nc)) {
68: val += nc - '0';
69: } else {
70: val += nc - 'A' + 10;
71: }
72: }
73: return val;
74: }
75:
76: static char next_char(char **c)
77: {
78: ignore_ws(c);
79: return *(*c)++;
80: }
81:
82: static int more_params(char **c)
83: {
84: ignore_ws(c);
85: return (**c) != 0;
86: }
87:
88: static void dumpmem(CPTR addr, CPTR *nxmem, int lines)
89: {
90: broken_in = 0;
91: for (;lines-- && !broken_in;){
92: int i;
93: printf("%08lx ", addr);
94: for(i=0; i< 16; i++) {
95: printf("%04x ", get_word(addr)); addr += 2;
96: }
97: printf("\n");
98: }
99: *nxmem = addr;
100: }
101:
102: void debug(void)
103: {
104: char input[80],c;
105: CPTR nextpc,nxdis,nxmem;
106:
107: bogusframe = 1;
108:
109: if (do_skip && (m68k_getpc() != skipaddr/* || regs.a[0] != 0x1e558*/)) {
110: regs.spcflags |= SPCFLAG_BRK;
111: return;
112: }
113: do_skip = 0;
114:
115: #ifdef NEED_TO_DEBUG_BADLY
116: history[lasthist] = regs;
117: historyf[lasthist] = regflags;
118: #else
119: history[lasthist] = m68k_getpc();
120: #endif
121: if (++lasthist == MAX_HIST) lasthist = 0;
122: if (lasthist == firsthist) {
123: if (++firsthist == MAX_HIST) firsthist = 0;
124: }
125:
126: m68k_dumpstate(&nextpc);
127: nxdis = nextpc; nxmem = 0;
128:
129: for(;;){
130: char cmd,*inptr;
131:
132: printf(">");
133: fgets(input, 80, stdin);
134: inptr = input;
135: cmd = next_char(&inptr);
136: switch(cmd){
137: case 'q': quit_program = 1; debugging = 0; regs.spcflags |= SPCFLAG_BRK; return;
138: case 'c': dumpcia(); dumpcustom(); break;
139: case 'r': m68k_dumpstate(&nextpc); break;
140: case 'd':
141: {
142: ULONG daddr;
143: int count;
144:
145: if (more_params(&inptr))
146: daddr = readhex(&inptr);
147: else
148: daddr = nxdis;
149: if (more_params(&inptr))
150: count = readhex(&inptr);
151: else
152: count = 10;
153: m68k_disasm(daddr, &nxdis, count);
154: }
155: break;
156: case 't': regs.spcflags |= SPCFLAG_BRK; return;
157: case 'z':
158: skipaddr = nextpc;
159: do_skip = 1;
160: regs.spcflags |= SPCFLAG_BRK;
161: return;
162:
163: case 'f':
164: skipaddr = readhex(&inptr);
165: do_skip = 1;
166: regs.spcflags |= SPCFLAG_BRK;
167: return;
168:
169: case 'g':
170: if (more_params (&inptr))
171: m68k_setpc (readhex (&inptr));
172: debugger_active = 0;
173: debugging = 0;
174: return;
175:
176: case 'H':
177: {
178: int count;
179: int temp;
180: #ifdef NEED_TO_DEBUG_BADLY
181: struct regstruct save_regs = regs;
182: union flagu save_flags = regflags;
183: #endif
184:
185: if (more_params(&inptr))
186: count = readhex(&inptr);
187: else
188: count = 10;
189: if (count < 0)
190: break;
191: temp = lasthist;
192: while (count-- > 0 && temp != firsthist) {
193: if (temp == 0) temp = MAX_HIST-1; else temp--;
194: }
195: while (temp != lasthist) {
196: #ifdef NEED_TO_DEBUG_BADLY
197: regs = history[temp];
198: regflags = historyf[temp];
199: m68k_dumpstate(NULL);
200: #else
201: m68k_disasm(history[temp], NULL, 1);
202: #endif
203: if (++temp == MAX_HIST) temp = 0;
204: }
205: #ifdef NEED_TO_DEBUG_BADLY
206: regs = save_regs;
207: regflags = save_flags;
208: #endif
209: }
210: break;
211: case 'm':
212: {
213: ULONG maddr; int lines;
214: if (more_params(&inptr))
215: maddr = readhex(&inptr);
216: else
217: maddr = nxmem;
218: if (more_params(&inptr))
219: lines = readhex(&inptr);
220: else
221: lines = 16;
222: dumpmem(maddr, &nxmem, lines);
223: }
224: break;
225: case 'h':
226: case '?':
227: {
228: printf (" HELP for UAE Debugger\n");
229: printf (" -----------------------\n\n");
230: printf (" g: <address> ");
231: printf("Start execution at the current address or <address>.\n");
232: printf (" c: ");
233: printf("Dump state of the CIA and custom chips.\n");
234: printf (" r: ");
235: printf("Dump state of the CPU\n");
236: printf (" m <address> <lines>: ");
237: printf ("Memory dump starting at <address>\n");
238: printf (" d <address> <lines>: ");
239: printf ("Disassembly starting at <address>\n");
240: printf (" t: ");
241: printf ("Step one instruction\n");
242: printf (" z: ");
243: printf ("Step through one instruction - useful for JSR, DBRA etc\n");
244: printf (" f <address>: ");
245: printf ("Step forward until PC == <address>\n");
246: printf (" H <count>: ");
247: printf ("Show PC history <count> instructions.\n");
248: printf (" h,?: ");
249: printf ("Show this help page\n");
250: printf (" q: ");
251: printf ("Quit the emulator. You don't want to use this command.\n\n");
252: }
253: break;
254:
255: }
256: }
257: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.