Mercurial > vba-clojure
comparison src/gb/gbDis.cpp @ 17:75e5bb1e0aa1
going to now integrate the gb src tree since it has no dependencies
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 11:44:47 -0600 |
parents | f9f4f1b99eed |
children |
comparison
equal
deleted
inserted
replaced
16:9e598342e182 | 17:75e5bb1e0aa1 |
---|---|
1 #include <cstdio> | |
2 #include <cstring> | |
3 | |
4 #include "gbGlobals.h" | |
5 | |
6 typedef struct | |
7 { | |
8 u8 mask; | |
9 u8 value; | |
10 char *mnen; | |
11 } GBOPCODE; | |
12 | |
13 static char *registers[] = | |
14 { "B", "C", "D", "E", "H", "L", "(HL)", "A" }; | |
15 | |
16 static char *registers16[] = | |
17 { "BC", "DE", "HL", "SP", // for some operations | |
18 "BC", "DE", "HL", "AF" }; // for push/pop | |
19 | |
20 static char *cond[] = | |
21 { "NZ", "Z", "NC", "C" }; | |
22 | |
23 static char hexDigits[16] = { | |
24 '0', '1', '2', '3', '4', '5', '6', '7', | |
25 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' | |
26 }; | |
27 | |
28 static GBOPCODE opcodes[] = { | |
29 { 0xff, 0x00, "NOP" }, | |
30 { 0xcf, 0x01, "LD %R4,%W" }, | |
31 { 0xff, 0x02, "LD (BC),A" }, | |
32 { 0xcf, 0x03, "INC %R4" }, | |
33 { 0xc7, 0x04, "INC %r3" }, | |
34 { 0xc7, 0x05, "DEC %r3" }, | |
35 { 0xc7, 0x06, "LD %r3,%B" }, | |
36 { 0xff, 0x07, "RLCA" }, | |
37 { 0xff, 0x08, "LD (%W),SP" }, | |
38 { 0xcf, 0x09, "ADD HL,%R4" }, | |
39 { 0xff, 0x0a, "LD A,(BC)" }, | |
40 { 0xcf, 0x0b, "DEC %R4" }, | |
41 { 0xff, 0x0f, "RRCA" }, | |
42 { 0xff, 0x10, "STOP" }, | |
43 { 0xff, 0x12, "LD (DE),A" }, | |
44 { 0xff, 0x17, "RLA" }, | |
45 { 0xff, 0x18, "JR %d" }, | |
46 { 0xff, 0x1a, "LD A,(DE)" }, | |
47 { 0xff, 0x1f, "RRA" }, | |
48 { 0xe7, 0x20, "JR %c3,%d" }, | |
49 { 0xff, 0x22, "LDI (HL),A" }, | |
50 { 0xff, 0x27, "DAA" }, | |
51 { 0xff, 0x2a, "LDI A,(HL)" }, | |
52 { 0xff, 0x2f, "CPL" }, | |
53 { 0xff, 0x32, "LDD (HL),A" }, | |
54 { 0xff, 0x37, "SCF" }, | |
55 { 0xff, 0x3a, "LDD A,(HL)" }, | |
56 { 0xff, 0x3f, "CCF" }, | |
57 { 0xff, 0x76, "HALT" }, | |
58 { 0xc0, 0x40, "LD %r3,%r0" }, | |
59 { 0xf8, 0x80, "ADD A,%r0" }, | |
60 { 0xf8, 0x88, "ADC A,%r0" }, | |
61 { 0xf8, 0x90, "SUB %r0" }, | |
62 { 0xf8, 0x98, "SBC A,%r0" }, | |
63 { 0xf8, 0xa0, "AND %r0" }, | |
64 { 0xf8, 0xa8, "XOR %r0" }, | |
65 { 0xf8, 0xb0, "OR %r0" }, | |
66 { 0xf8, 0xb8, "CP %r0" }, | |
67 { 0xe7, 0xc0, "RET %c3" }, | |
68 { 0xcf, 0xc1, "POP %t4" }, | |
69 { 0xe7, 0xc2, "JP %c3,%W" }, | |
70 { 0xff, 0xc3, "JP %W" }, | |
71 { 0xe7, 0xc4, "CALL %c3,%W" }, | |
72 { 0xcf, 0xc5, "PUSH %t4" }, | |
73 { 0xff, 0xc6, "ADD A,%B" }, | |
74 { 0xc7, 0xc7, "RST %P" }, | |
75 { 0xff, 0xc9, "RET" }, | |
76 { 0xff, 0xcd, "CALL %W" }, | |
77 { 0xff, 0xce, "ADC %B" }, | |
78 { 0xff, 0xd6, "SUB %B" }, | |
79 { 0xff, 0xd9, "RETI" }, | |
80 { 0xff, 0xde, "SBC %B" }, | |
81 { 0xff, 0xe0, "LD (FF%B),A" }, | |
82 { 0xff, 0xe2, "LD (FF00h+C),A" }, | |
83 { 0xff, 0xe6, "AND %B" }, | |
84 { 0xff, 0xe8, "ADD SP,%D" }, | |
85 { 0xff, 0xe9, "LD PC,HL" }, | |
86 { 0xff, 0xea, "LD (%W),A" }, | |
87 { 0xff, 0xee, "XOR %B" }, | |
88 { 0xff, 0xf0, "LD A,(FF%B)" }, | |
89 { 0xff, 0xf2, "LD A,(FF00h+C)" }, | |
90 { 0xff, 0xf3, "DI" }, | |
91 { 0xff, 0xf6, "OR %B" }, | |
92 { 0xff, 0xf8, "LD HL,SP%D" }, | |
93 { 0xff, 0xf9, "LD SP,HL" }, | |
94 { 0xff, 0xfa, "LD A,(%W)" }, | |
95 { 0xff, 0xfb, "EI" }, | |
96 { 0xff, 0xfe, "CP %B" }, | |
97 { 0x00, 0x00, "DB %B" } | |
98 }; | |
99 | |
100 static GBOPCODE cbOpcodes[] = { | |
101 { 0xf8, 0x00, "RLC %r0" }, | |
102 { 0xf8, 0x08, "RRC %r0" }, | |
103 { 0xf8, 0x10, "RL %r0" }, | |
104 { 0xf8, 0x18, "RR %r0" }, | |
105 { 0xf8, 0x20, "SLA %r0" }, | |
106 { 0xf8, 0x28, "SRA %r0" }, | |
107 { 0xf8, 0x30, "SWAP %r0" }, | |
108 { 0xf8, 0x38, "SRL %r0" }, | |
109 { 0xc0, 0x40, "BIT %b,%r0" }, | |
110 { 0xc0, 0x80, "RES %b,%r0" }, | |
111 { 0xc0, 0xc0, "SET %b,%r0" }, | |
112 { 0x00, 0x00, "DB CBh,%B" } | |
113 }; | |
114 | |
115 static char *addHex(char *p, u8 value) | |
116 { | |
117 *p++ = hexDigits[value >> 4]; | |
118 *p++ = hexDigits[value & 15]; | |
119 return p; | |
120 } | |
121 | |
122 static char *addHex16(char *p, u16 value) | |
123 { | |
124 p = addHex(p, value>>8); | |
125 return addHex(p, value & 255); | |
126 } | |
127 | |
128 static char *addStr(char *p, char *s) | |
129 { | |
130 while (*s) | |
131 { | |
132 *p++ = *s++; | |
133 } | |
134 return p; | |
135 } | |
136 | |
137 int gbDis(char *buffer, u16 address) | |
138 { | |
139 char *p = buffer; | |
140 int instr = 1; | |
141 u16 addr = address; | |
142 sprintf(p, "%04x ", address); | |
143 p += 12; | |
144 | |
145 u8 opcode = gbReadMemoryQuick(address); | |
146 address++; | |
147 char * mnen; | |
148 GBOPCODE *op; | |
149 if (opcode == 0xcb) | |
150 { | |
151 opcode = gbReadMemoryQuick(address); | |
152 address++; | |
153 instr++; | |
154 op = cbOpcodes; | |
155 } | |
156 else | |
157 { | |
158 op = opcodes; | |
159 } | |
160 while (op->value != (opcode & op->mask)) | |
161 op++; | |
162 mnen = op->mnen; | |
163 | |
164 u8 b0, b1; | |
165 s8 disp; | |
166 int shift; | |
167 | |
168 while (*mnen) | |
169 { | |
170 if (*mnen == '%') | |
171 { | |
172 mnen++; | |
173 switch (*mnen++) | |
174 { | |
175 case 'W': | |
176 b0 = gbReadMemoryQuick(address); | |
177 address++; | |
178 b1 = gbReadMemoryQuick(address); | |
179 address++; | |
180 p = addHex16(p, b0|b1<<8); | |
181 instr += 2; | |
182 *p++ = 'h'; | |
183 break; | |
184 case 'B': | |
185 p = addHex(p, gbReadMemoryQuick(address)); | |
186 *p++ = 'h'; | |
187 address++; | |
188 instr++; | |
189 break; | |
190 case 'D': | |
191 disp = gbReadMemoryQuick(address); | |
192 if (disp >= 0) | |
193 *p++ = '+'; | |
194 p += sprintf(p, "%d", disp); | |
195 instr++; | |
196 break; | |
197 case 'd': | |
198 disp = gbReadMemoryQuick(address); | |
199 address++; | |
200 p = addHex16(p, address+disp); | |
201 *p++ = 'h'; | |
202 instr++; | |
203 break; | |
204 case 'b': | |
205 // kind of a hack, but it works :-) | |
206 *p++ = hexDigits[(opcode >> 3) & 7]; | |
207 break; | |
208 case 'r': | |
209 shift = *mnen++ - '0'; | |
210 p = addStr(p, registers[(opcode >> shift) & 7]); | |
211 break; | |
212 case 'R': | |
213 shift = *mnen++ - '0'; | |
214 p = addStr(p, registers16[(opcode >> shift) & 3]); | |
215 break; | |
216 case 't': | |
217 shift = *mnen++ - '0'; | |
218 p = addStr(p, registers16[4+((opcode >> shift) & 3)]); | |
219 break; | |
220 case 'P': | |
221 p = addHex(p, ((opcode >> 3) & 7) * 8); | |
222 break; | |
223 case 'c': | |
224 shift = *mnen++ - '0'; | |
225 p = addStr(p, cond[(opcode >> shift) & 3]); | |
226 break; | |
227 } | |
228 } | |
229 else | |
230 *p++ = *mnen++; | |
231 } | |
232 for (int i = 0; i < instr; i++) | |
233 { | |
234 u16 a = addr + i; | |
235 addHex(buffer+5+i*2, gbReadMemoryQuick(a)); | |
236 } | |
237 *p = 0; | |
238 return instr; | |
239 } |