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