1
2 /*
3
4 debug.c
5
6 This file supplies cingb with useful debug-information.
7
8 */
9
10
11 #include <stdio.h>
12
13 #include "globals.h"
14 #include "debug.h"
15 #include "z80.h"
16 #include "gameboy.h"
17
18 const char GB_SREG[][5]={"B","C","D","E","H","L","(HL)","A"};
19 const char GB_DREG[][3]={"BC","DE","HL","SP"};
20 const char GB_DPP[][3]={"BC","DE","HL","AF"};
21 const char GB_FJR[][4]={"","NZ,","Z,","NC,","C,"};
22 const char GB_FRET[][4]={"NZ","Z","NC","C"};
23 const char GB_ALU[][4]={"ADD","ADC","SUB","SBC","AND","XOR","OR","CP"};
24 const char GB_CBOPC[][7]={"RLC","RRC","RL","RR",
25 "SLA","SRA","SWAP","SRL",
26 "BIT 0,","BIT 1,","BIT 2,","BIT 3,",
27 "BIT 4,","BIT 5,","BIT 6,","BIT 7,",
28 "RES 0,","RES 1,","RES 2,","RES 3,",
29 "RES 4,","RES 5,","RES 6,","RES 7,",
30 "SET 0,","SET 1,","SET 2,","SET 3,",
31 "SET 4,","SET 5,","SET 6,","SET 7,"};
32
33
34 const char debugger_help1[]="\
35 b <addr> - set a breakpoint, at address <addr>\n\
36 c - clear breakpoint\n\
37 d <addr> - dump memory, at address <addr>\n\
38 e <addr> - edit ONE byte at address <addr>, write\n\
39 value (you'll be asked)\n\
40 g [<addr>] - go to address <addr>, without <addr> the\n";
41
42 const char debugger_help2[]="\
43 program will continue from PC\n\
44 h - display this help\n\
45 o <count> - skip over commands,\n\
46 count (decimal number)\n\
47 q - quits the debugger and closes everything\n\
48 v <addr> - view a value (byte), at address <addr>\n\
49 # - graphical lcd-dump\
50 ";
51
52 int FlagSet(int);
53
54
FlagSet(flag)55 int FlagSet(flag)
56 int flag;
57 {
58 return (Z80_REG.B.F & flag) > 0 ? 1 : 0;
59 }
60
DebugState(void)61 void DebugState(void)
62 {
63 fprintf(OUTSTREAM,
64 "AF:%04X BC:%04X DE:%04X HL:%04X SP:%04X Z:%i N:%i H:%i C:%i I:%i",
65 Z80_REG.W.AF,Z80_REG.W.BC,Z80_REG.W.DE,Z80_REG.W.HL,Z80_REG.W.SP,
66 FlagSet(FLAG_Z),FlagSet(FLAG_N),FlagSet(FLAG_H),FlagSet(FLAG_C),
67 Z80_IE);
68 fprintf(OUTSTREAM," ROM%03X RAM%02X\n",rombanknr,rambanknr);
69 fprintf(OUTSTREAM,"CLKS: %06X (%c) ",(unsigned int)Z80_CPUCLKS,
70 DBLSPEED ? 'D' : 'S');
71 fprintf(OUTSTREAM,"FF0F: %02X, FF40: %02X, FF41: %02X, ",
72 GetByteAt(0xff0f),
73 GetByteAt(0xff40),
74 GetByteAt(0xff41));
75 fprintf(OUTSTREAM,"FF44: %02X, FF45: %02X, FFFF: %02X\n",
76 GetByteAt(0xff44),
77 GetByteAt(0xff45),
78 GetByteAt(0xffff));
79
80 fprintf(OUTSTREAM,"%04X: %02X %02X %02X ",Z80_REG.W.PC,
81 GetByteAt(Z80_REG.W.PC),
82 GetByteAt(Z80_REG.W.PC+1),
83 GetByteAt(Z80_REG.W.PC+2)
84 );
85
86 switch (GetByteAt(Z80_REG.W.PC))
87 {
88 case 0x00:fprintf(OUTSTREAM,"NOP");
89 break;
90 case 0x01:
91 case 0x11:
92 case 0x21:
93 case 0x31:fprintf(OUTSTREAM,
94 "LD %s,%04X",GB_DREG[GetByteAt(Z80_REG.W.PC)
95 >> 4],GetWordAt(Z80_REG.W.PC+1));
96 break;
97 case 0x02:
98 case 0x12:fprintf(OUTSTREAM,"LD (%s),A",GB_DREG[GetByteAt(
99 Z80_REG.W.PC)>>4]);
100 break;
101 case 0x03:
102 case 0x13:
103 case 0x23:
104 case 0x33:fprintf(OUTSTREAM,
105 "INC %s",GB_DREG[GetByteAt(Z80_REG.W.PC)
106 >> 4]);
107 break;
108 case 0x04:
109 case 0x0C:
110 case 0x14:
111 case 0x1C:
112 case 0x24:
113 case 0x2C:
114 case 0x34:
115 case 0x3C:fprintf(OUTSTREAM,
116 "INC %s",GB_SREG[GetByteAt(Z80_REG.W.PC)
117 >> 3]);
118 break;
119 case 0x05:
120 case 0x0D:
121 case 0x15:
122 case 0x1D:
123 case 0x25:
124 case 0x2D:
125 case 0x35:
126 case 0x3D:fprintf(OUTSTREAM,
127 "DEC %s",GB_SREG[GetByteAt(Z80_REG.W.PC)
128 >> 3]);
129 break;
130 case 0x06:
131 case 0x0E:
132 case 0x16:
133 case 0x1E:
134 case 0x26:
135 case 0x2E:
136 case 0x36:
137 case 0x3E:fprintf(OUTSTREAM,
138 "LD %s,%02X",GB_SREG[GetByteAt(Z80_REG.W.PC)
139 >> 3],
140 GetByteAt(Z80_REG.W.PC+1));
141 break;
142 case 0x07:fprintf(OUTSTREAM,"RLCA");
143 break;
144 case 0x08:fprintf(OUTSTREAM,"LD (%04X),SP",
145 GetWordAt(Z80_REG.W.PC+1));
146 break;
147 case 0x09:
148 case 0x19:
149 case 0x29:
150 case 0x39:fprintf(OUTSTREAM,
151 "ADD HL,%s",GB_DREG[GetByteAt(Z80_REG.W.PC)
152 >>4]);
153 break;
154 case 0x0A:
155 case 0x1A:fprintf(OUTSTREAM,
156 "LD A,(%s)",GB_DREG[GetByteAt(Z80_REG.W.PC)
157 >>4]);
158 break;
159 case 0x0B:
160 case 0x1B:
161 case 0x2B:
162 case 0x3B:fprintf(OUTSTREAM,"DEC %s",
163 GB_DREG[GetByteAt(Z80_REG.W.PC)>>4]);
164 break;
165 case 0x0F:fprintf(OUTSTREAM,"RRCA");
166 break;
167 case 0x10:fprintf(OUTSTREAM,"STOP");
168 break;
169 case 0x17:fprintf(OUTSTREAM,"RLA");
170 break;
171 case 0x1F:fprintf(OUTSTREAM,"RRA");
172 break;
173 case 0x18:
174 case 0x20:
175 case 0x28:
176 case 0x30:
177 case 0x38:fprintf(OUTSTREAM,"JR %s%04X",
178 GB_FJR[(GetByteAt(Z80_REG.W.PC)
179 >>3)-3],Z80_REG.W.PC+
180 (signed char)(GetByteAt(Z80_REG.W.PC+1))+2);
181 break;
182 case 0x22:fprintf(OUTSTREAM,"LD (HLI),A");
183 break;
184 case 0x2A:fprintf(OUTSTREAM,"LD A,(HLI)");
185 break;
186 case 0x32:fprintf(OUTSTREAM,"LD (HLD),A");
187 break;
188 case 0x3A:fprintf(OUTSTREAM,"LD A,(HLD)");
189 break;
190 case 0x27:fprintf(OUTSTREAM,"DAA");
191 break;
192 case 0x2F:fprintf(OUTSTREAM,"CPL");
193 break;
194 case 0x37:fprintf(OUTSTREAM,"SCF");
195 break;
196 case 0x3F:fprintf(OUTSTREAM,"CCF");
197 break;
198 case 0x40:
199 case 0x41:
200 case 0x42:
201 case 0x43:
202 case 0x44:
203 case 0x45:
204 case 0x46:
205 case 0x47:
206 case 0x48:
207 case 0x49:
208 case 0x4A:
209 case 0x4B:
210 case 0x4C:
211 case 0x4D:
212 case 0x4E:
213 case 0x4F:
214 case 0x50:
215 case 0x51:
216 case 0x52:
217 case 0x53:
218 case 0x54:
219 case 0x55:
220 case 0x56:
221 case 0x57:
222 case 0x58:
223 case 0x59:
224 case 0x5A:
225 case 0x5B:
226 case 0x5C:
227 case 0x5D:
228 case 0x5E:
229 case 0x5F:
230 case 0x60:
231 case 0x61:
232 case 0x62:
233 case 0x63:
234 case 0x64:
235 case 0x65:
236 case 0x66:
237 case 0x67:
238 case 0x68:
239 case 0x69:
240 case 0x6A:
241 case 0x6B:
242 case 0x6C:
243 case 0x6D:
244 case 0x6E:
245 case 0x6F:
246 case 0x70:
247 case 0x71:
248 case 0x72:
249 case 0x73:
250 case 0x74:
251 case 0x75:
252 case 0x77:
253 case 0x78:
254 case 0x79:
255 case 0x7A:
256 case 0x7B:
257 case 0x7C:
258 case 0x7D:
259 case 0x7E:
260 case 0x7F:
261 fprintf(OUTSTREAM,"LD %s,%s",
262 GB_SREG[(GetByteAt(Z80_REG.W.PC) >> 3)-8],
263 GB_SREG[(GetByteAt(Z80_REG.W.PC) & 7)]);
264 break;
265 case 0x76:fprintf(OUTSTREAM,"HALT");
266 break;
267 case 0x80:
268 case 0x81:
269 case 0x82:
270 case 0x83:
271 case 0x84:
272 case 0x85:
273 case 0x86:
274 case 0x87:fprintf(OUTSTREAM,"ADD A,%s",
275 GB_SREG[GetByteAt(Z80_REG.W.PC)& 7]);
276 break;
277 case 0x88:
278 case 0x89:
279 case 0x8A:
280 case 0x8B:
281 case 0x8C:
282 case 0x8D:
283 case 0x8E:
284 case 0x8F:fprintf(OUTSTREAM,"ADC A,%s",
285 GB_SREG[GetByteAt(Z80_REG.W.PC)& 7]);
286 break;
287 case 0x90:
288 case 0x91:
289 case 0x92:
290 case 0x93:
291 case 0x94:
292 case 0x95:
293 case 0x96:
294 case 0x97:fprintf(OUTSTREAM,"SUB A,%s",
295 GB_SREG[GetByteAt(Z80_REG.W.PC)& 7]);
296 break;
297 case 0x98:
298 case 0x99:
299 case 0x9A:
300 case 0x9B:
301 case 0x9C:
302 case 0x9D:
303 case 0x9E:
304 case 0x9F:fprintf(OUTSTREAM,"SBC A,%s",
305 GB_SREG[GetByteAt(Z80_REG.W.PC)& 7]);
306 break;
307 case 0xA0:
308 case 0xA1:
309 case 0xA2:
310 case 0xA3:
311 case 0xA4:
312 case 0xA5:
313 case 0xA6:
314 case 0xA7:fprintf(OUTSTREAM,"AND A,%s",
315 GB_SREG[GetByteAt(Z80_REG.W.PC)& 7]);
316 break;
317 case 0xA8:
318 case 0xA9:
319 case 0xAA:
320 case 0xAB:
321 case 0xAC:
322 case 0xAD:
323 case 0xAE:
324 case 0xAF:fprintf(OUTSTREAM,"XOR A,%s",
325 GB_SREG[GetByteAt(Z80_REG.W.PC)& 7]);
326 break;
327 case 0xB0:
328 case 0xB1:
329 case 0xB2:
330 case 0xB3:
331 case 0xB4:
332 case 0xB5:
333 case 0xB6:
334 case 0xB7:fprintf(OUTSTREAM,"OR A,%s",
335 GB_SREG[GetByteAt(Z80_REG.W.PC)& 7]);
336 break;
337 case 0xB8:
338 case 0xB9:
339 case 0xBA:
340 case 0xBB:
341 case 0xBC:
342 case 0xBD:
343 case 0xBE:
344 case 0xBF:fprintf(OUTSTREAM,"CP A,%s",
345 GB_SREG[GetByteAt(Z80_REG.W.PC)& 7]);
346 break;
347 case 0xC0:
348 case 0xC8:
349 case 0xD0:
350 case 0xD8:fprintf(OUTSTREAM,"RET %s",
351 GB_FRET[(GetByteAt(Z80_REG.W.PC)>>3)&3]);
352 break;
353 case 0xC1:
354 case 0xD1:
355 case 0xE1:
356 case 0xF1:fprintf(OUTSTREAM,"POP %s",
357 GB_DPP[(GetByteAt(Z80_REG.W.PC)>>4)-0x0C]);
358 break;
359 case 0xC2:
360 case 0xCA:
361 case 0xD2:
362 case 0xDA:fprintf(OUTSTREAM,"JP %s,%04X",
363 GB_FRET[(GetByteAt(Z80_REG.W.PC)
364 >>3)&3],GetWordAt(Z80_REG.W.PC+1));
365 break;
366 case 0xC3:fprintf(OUTSTREAM,"JP %04X",
367 GetWordAt(Z80_REG.W.PC+1));
368 break;
369 case 0xC4:
370 case 0xCC:
371 case 0xD4:
372 case 0xDC:fprintf(OUTSTREAM,"CALL %s,%04X",
373 GB_FRET[(GetByteAt(Z80_REG.W.PC)>>3)&3],
374 GetWordAt(Z80_REG.W.PC+1));
375 break;
376 case 0xC5:
377 case 0xD5:
378 case 0xE5:
379 case 0xF5:fprintf(OUTSTREAM,"PUSH %s",
380 GB_DPP[(GetByteAt(Z80_REG.W.PC)
381 >>4)-0x0C]);
382 break;
383 case 0xC6:
384 case 0xCE:
385 case 0xD6:
386 case 0xDE:
387 case 0xE6:
388 case 0xEE:
389 case 0xF6:
390 case 0xFE:fprintf(OUTSTREAM,"%s A,%02X",
391 GB_ALU[(GetByteAt(Z80_REG.W.PC)
392 >>3)&7],GetByteAt(Z80_REG.W.PC+1));
393 break;
394 case 0xC7:
395 case 0xCF:
396 case 0xD7:
397 case 0xDF:
398 case 0xE7:
399 case 0xEF:
400 case 0xF7:
401 case 0xFF:fprintf(OUTSTREAM,"RST %02X",
402 ((GetByteAt(Z80_REG.W.PC)>>3)&7)<<3);
403 break;
404 case 0xC9:fprintf(OUTSTREAM,"RET");
405 break;
406 case 0xCB:fprintf(OUTSTREAM,"%s %s",
407 GB_CBOPC[GetByteAt(Z80_REG.W.PC+1)
408 >>3],GB_SREG[GetByteAt(Z80_REG.W.PC+1)&7]);
409 break;
410 case 0xCD:fprintf(OUTSTREAM,"CALL %04X",
411 GetWordAt(Z80_REG.W.PC+1));
412 break;
413 case 0xD9:fprintf(OUTSTREAM,"RETI");
414 break;
415 case 0xE0:fprintf(OUTSTREAM,"LDH (%02X),A",
416 GetByteAt(Z80_REG.W.PC+1));
417 break;
418 case 0xE2:fprintf(OUTSTREAM,"LDH (C),A");
419 break;
420 case 0xE8:fprintf(OUTSTREAM,"ADD SP,%02X",
421 GetByteAt(Z80_REG.W.PC+1));
422 break;
423 case 0xE9:fprintf(OUTSTREAM,"JP (HL)");
424 break;
425 case 0xEA:fprintf(OUTSTREAM,"LD (%04X),A",
426 GetWordAt(Z80_REG.W.PC+1));
427 break;
428 case 0xF0:fprintf(OUTSTREAM,"LDH A,(%02X)",
429 GetByteAt(Z80_REG.W.PC+1));
430 break;
431 case 0xF2:fprintf(OUTSTREAM,"LDH A,(C)");
432 break;
433 case 0xF3:fprintf(OUTSTREAM,"DI");
434 break;
435 case 0xFB:fprintf(OUTSTREAM,"EI");
436 break;
437 case 0xF8:fprintf(OUTSTREAM,"LD HL,SP+%02X",
438 GetByteAt(Z80_REG.W.PC+1));
439 break;
440 case 0xF9:fprintf(OUTSTREAM,"LD SP,HL");
441 break;
442 case 0xFA:fprintf(OUTSTREAM,"LD A,(%04X)",
443 GetWordAt(Z80_REG.W.PC+1));
444 break;
445 default:fprintf(OUTSTREAM,"*** illegal opcode: 0x%02X ***",
446 GetByteAt(Z80_REG.W.PC));
447 break;
448 }
449 }
450
451