Hackfix and re-enable strtoull and wcstoull, see bug #3798.
[sdcc.git] / sdcc-extra / emu / rrgb / disgb.c
blob266e013537619ed901629ae871380adfd4c4cc9e
1 #include <stdio.h>
2 #include <string.h>
3 #include "parse_map.h"
4 #include "disgb.h"
6 #define WREG 1
7 #define HREG 2
8 #define LREG 3
9 #define BREG 4
10 #define COND 5
11 #define BRST 8
12 #define WOP 6
13 #define BOP 7
14 #define XWREG 9
15 #define SBOP 10
16 #define BREL 11
17 #define SBIT 12
20 typedef struct smnemo mmnemo;
21 typedef struct smnemo *pmmnemo;
23 struct smnemo {
24 char text[20];
25 int op1;
26 int op2;
29 typedef struct smnemo_exception mmnemo_exception;
30 typedef struct smnemo_exception *pmmnemo_exception;
32 struct smnemo_exception {
33 char text[20];
34 int op1;
35 int op2;
36 int opcode;
39 char byte_regs[][5] = {
40 "B", "C", "D", "E", "H", "L", "(HL)", "A"
43 char word_regs[][3] = {
44 "BC", "DE", "HL", "SP"
47 char conditions[][3] = {
48 "NZ", "Z", "NC", "C"
51 mmnemo mnemo_80[] = {
52 { "LD\t%s,%s", BREG, BREG }
55 mmnemo mnemo_40[] = {
56 { "SPECIAL", 0, 0 },
57 { "LD\t%s,%s", WREG, WOP },
58 { "LD\t(%s),A", WREG, 0 },
59 { "INC\t%s", WREG, 0 },
60 { "INC\t%s", HREG, 0 },
61 { "DEC\t%s", HREG, 0 },
62 { "LD\t%s,%s", HREG, BOP },
63 { "SPECIAL", 0, 0 },
64 { "SPECIAL", 0, 0 },
65 { "ADD\tHL,%s", WREG, 0 },
66 { "LD\tA,(%s)", WREG, 0 },
67 { "DEC\t%s", WREG, 0 },
68 { "INC\t%s", LREG, 0 },
69 { "DEC\t%s", LREG, 0 },
70 { "LD\t%s,%s", LREG, BOP }
73 mmnemo mnemo_07_40[] = {
74 { "RLCA", 0, 0 },
75 { "RRCA", 0, 0 },
76 { "RLA", 0, 0 },
77 { "RRA", 0, 0 },
78 { "DAA", 0, 0 },
79 { "CPL", 0, 0 },
80 { "SCF", 0, 0 },
81 { "CCF", 0, 0 }
84 mmnemo mnemo_C0[] = {
85 { "ADD\tA,%s", BREG, 0 },
86 { "ADC\tA,%s", BREG, 0 },
87 { "SUB\tA,%s", BREG, 0 },
88 { "SBC\tA,%s", BREG, 0 },
89 { "AND\t%s", BREG, 0 },
90 { "XOR\t%s", BREG, 0 },
91 { "OR\t%s", BREG, 0 },
92 { "CP\t%s", BREG, 0 }
95 mmnemo mnemo_FF[] = {
96 { "RET\t%s", COND, 0 },
97 { "POP\t%s", XWREG, 0 },
98 { "JP\t%s,%s", COND, WOP },
99 { "SPECIAL", 0, 0 },
100 { "CALL\t%s,%s", COND, WOP },
101 { "PUSH\t%s", XWREG, 0 },
102 { "SPECIAL", 0, 0 },
103 { "RST\t%s", BRST, 0 },
104 { "RET\t%s", COND, 0 },
105 { "SPECIAL", 0, 0 },
106 { "JP\t%s,%s", COND, WOP },
107 { "CB ops", 0, 0 },
108 { "CALL\t%s,%s", COND, WOP },
109 { "SPECIAL", 0, 0 },
110 { "SPECIAL", 0, 0 },
111 { "RST\t%s", BRST, 0 }
114 mmnemo mnemo_00_40[] = {
115 { "NOP", 0, 0 },
116 { "STOP", BOP, 0 },
117 { "JR\t%s", BREL, 0 },
118 { "JR\tNZ,%s", BREL, 0 },
119 { "JR\tZ,%s", BREL, 0 },
120 { "JR\tNC,%s", BREL, 0 },
121 { "JR\tC,%s", BREL, 0 }
124 mmnemo mnemo_CB_40[] = {
125 { "RLC\t%s", BREG, 0 },
126 { "RRC\t%s", BREG, 0 },
127 { "RL\t%s", BREG, 0 },
128 { "RR\t%s", BREG, 0 },
129 { "SLA\t%s", BREG, 0 },
130 { "SRA\t%s", BREG, 0 },
131 { "SWAP\t%s", BREG, 0 },
132 { "SRL\t%s", BREG, 0 },
135 mmnemo mnemo_CB_C7[] = {
136 { "BIT\t%s,%s", SBIT, BREG },
137 { "RES\t%s,%s", SBIT, BREG },
138 { "SET\t%s,%s", SBIT, BREG }
141 mmnemo_exception mnemo_exceptions_40[] = {
142 { "LDI\t(HL),A", 0, 0, 0x22 },
143 { "LDI\tA,(HL)", 0, 0, 0x2A },
144 { "LDD\t(HL),A", 0, 0, 0x32 },
145 { "LDD\tA,(HL)", 0, 0, 0x3A },
146 { "", -1, -1, -1 }
149 mmnemo_exception mnemo_exceptions_FF[] = {
150 { "JP\t%s", WOP, 0, 0xC3 },
151 { "ADD\tA,%s", BOP, 0, 0xC6 },
152 { "RET", 0, 0, 0xC9 },
153 { "CALL\t%s", WOP, 0, 0xCD },
154 { "ADC\tA,%s", BOP, 0, 0xCE },
155 { "SUB\t%s", BOP, 0, 0xD6 },
156 { "RETI", 0, 0, 0xD9 },
157 { "LD\t(FF00h+%s),A", BOP, 0, 0xE0 },
158 { "LD\t(FF00h+C),A", 0, 0, 0xE2 },
159 { "AND\t%s", BOP, 0, 0xE6 },
160 { "ADD\tSP,%s", SBOP, 0, 0xE8 },
161 { "JP\t(HL)", 0, 0, 0xE9 },
162 { "LD\t(%s),A", WOP, 0, 0xEA },
163 { "XOR\t%s", BOP, 0, 0xEE },
164 { "LD\tA,(FF00h+%s)", BOP, 0, 0xF0 },
165 { "POP\tAF", 0, 0, 0xF1 },
166 { "LD\tA,(C)", 0, 0, 0xF2 },
167 { "DI", 0, 0, 0xF3 },
168 { "PUSH\tAF", 0, 0, 0xF5 },
169 { "OR\t%s", BOP, 0, 0xF6 },
170 { "LD\tHL,SP+%s", SBOP, 0, 0xF8 },
171 { "LD\tSP,HL", 0, 0, 0xF9 },
172 { "LD\tA,(%s)", WOP, 0, 0xFA },
173 { "EI", 0, 0, 0xFB },
174 { "CP\t%s", BOP, 0, 0xFE },
175 { "", -1, -1, -1 }
178 pmarea areas;
179 pmglobal sorted_globals;
181 int format_label( char *buffer, unsigned int addr )
183 pmglobal walk;
185 /* Try to find the label */
186 walk = sorted_globals;
188 while (walk) {
189 if (walk->addr == addr) {
190 strcpy( buffer, walk->name );
191 return 0;
193 walk = walk->sorted_next;
195 sprintf( buffer, "%04X", addr );
196 return -1;
199 int parse_label( char *buffer )
201 pmglobal walk;
202 int tmp;
204 /* Try to find the label */
205 walk = sorted_globals;
207 while (walk) {
208 if (!strcmp(walk->name, buffer )) {
209 return walk->addr;
211 walk = walk->sorted_next;
213 /* No match - return hex value */
214 if (sscanf( buffer, "%x", &tmp )==1) {
215 return tmp;
217 return -1;
220 int format_operand( char *buffer, int op, int reg, UBYTE *base, int addr )
222 switch (op) {
223 case WREG:
224 strcpy( buffer, word_regs[reg] );
225 return 0;
226 case XWREG:
227 strcpy( buffer, word_regs[reg>>1] );
228 return 0;
229 case LREG:
230 strcpy( buffer, byte_regs[(reg*2)+1] );
231 return 0;
232 case HREG:
233 strcpy( buffer, byte_regs[(reg*2)] );
234 return 0;
235 case BREG:
236 strcpy( buffer, byte_regs[reg] );
237 return 0;
238 case COND:
239 strcpy( buffer, conditions[reg] );
240 return 0;
241 case BRST:
242 sprintf( buffer,"%02X", (*base-0xc0)&0xf8);
243 return 0;
244 case SBOP:
245 sprintf( buffer, "%i", (int)((signed char)base[1]) );
246 return 1;
247 case BREL:
248 sprintf( buffer, "%04X", 2+addr+(int)((signed char)base[1]) );
249 return 1;
250 case SBIT:
251 sprintf( buffer, "%u", reg );
252 return 0;
253 case BOP:
254 sprintf( buffer, "%02X", base[1]);
255 return 1;
256 case WOP:
257 format_label( buffer, base[1]|(((unsigned int)base[2])<<8));
258 return 2;
259 default:
260 buffer[0] = '\0';
262 return 0;
265 int print_code( int offset, int reg1, int reg2, pmmnemo mnemo, UBYTE *base, int addr )
267 char op1[40], op2[40];
268 int total = 1;
270 total += format_operand( op1, mnemo[offset].op1, reg1, base, addr );
271 total += format_operand( op2, mnemo[offset].op2, reg2, base, addr );
273 printf( mnemo[offset].text, op1, op2 );
274 printf("\n");
275 return total;
278 int handle_exception( UBYTE *base, pmmnemo_exception except, int addr )
281 pmmnemo_exception walk_except;
282 char op1[40], op2[40];
283 int total;
285 total = 0;
287 walk_except = except;
288 while ((walk_except->opcode!=-1)&&(!total)) {
289 if (walk_except->opcode == *base ) {
290 total = 1+format_operand( op1, walk_except->op1, 0, base, addr );
291 total += format_operand( op2, walk_except->op2, 0, base, addr );
293 printf( walk_except->text, op1, op2 );
294 printf("\n");
296 walk_except++;
298 return total;
301 int disass( char *buffer, UBYTE *base, int addr )
303 int sub;
304 int op = *base;
305 int tmp;
306 char addr_name[50];
308 if (format_label( addr_name, addr )==0) {
309 printf("%s:\n", addr_name );
311 printf("%04X", addr );
313 printf("\t");
315 if (op<0x40) {
316 sub = op & 0x0f;
317 if ((sub&0x07)==0x07) {
318 return print_code( op>>3, 0, 0, mnemo_07_40, base, addr );
320 else {
321 if ((sub&0x07)==0x00) {
322 return print_code( op>>3, 0, 0, mnemo_00_40, base, addr );
324 else {
325 if (!(tmp=handle_exception( base, mnemo_exceptions_40, addr )))
326 return print_code( op&0x0f, op>>4, 0, mnemo_40, base, addr );
327 else
328 return tmp;
332 else {
333 op -=0x40;
334 if (op<0x40) { /* <0x80 */
335 return print_code( 0, op>>3, op&0x07, mnemo_80, base, addr );
337 else {
338 op-=0x040;
339 if (op<0x40) { /* <0xC0 */
340 return print_code( op>>3, op&0x07, 0, mnemo_C0, base, addr );
342 else {
343 if (*base==0x0cb) {
344 /* Handle CB opcodes */
345 base++;
346 if (*base<0x40)
347 return 1+print_code( *base>>3, *base&0x07, 0, mnemo_CB_40, base, addr );
348 else
349 return 1+print_code( (*base-0x40)>>6, (*base>>3)&0x07, *base&0x07, mnemo_CB_C7, base, addr );
351 else {
353 /* Check to see if it's an exception to the rule */
355 if (!(tmp=handle_exception( base, mnemo_exceptions_FF, addr ))) {
356 /* Not an exception - handle normally */
357 op-=0x40;
358 return print_code( op&0x0f, op>>3, 0, mnemo_FF, base, addr );
360 else
361 return tmp;