20 typedef struct smnemo mmnemo
;
21 typedef struct smnemo
*pmmnemo
;
29 typedef struct smnemo_exception mmnemo_exception
;
30 typedef struct smnemo_exception
*pmmnemo_exception
;
32 struct smnemo_exception
{
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] = {
52 { "LD\t%s,%s", BREG
, BREG
}
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
},
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
[] = {
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 },
96 { "RET\t%s", COND
, 0 },
97 { "POP\t%s", XWREG
, 0 },
98 { "JP\t%s,%s", COND
, WOP
},
100 { "CALL\t%s,%s", COND
, WOP
},
101 { "PUSH\t%s", XWREG
, 0 },
103 { "RST\t%s", BRST
, 0 },
104 { "RET\t%s", COND
, 0 },
106 { "JP\t%s,%s", COND
, WOP
},
108 { "CALL\t%s,%s", COND
, WOP
},
111 { "RST\t%s", BRST
, 0 }
114 mmnemo mnemo_00_40
[] = {
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 },
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 },
179 pmglobal sorted_globals
;
181 int format_label( char *buffer
, unsigned int addr
)
185 /* Try to find the label */
186 walk
= sorted_globals
;
189 if (walk
->addr
== addr
) {
190 strcpy( buffer
, walk
->name
);
193 walk
= walk
->sorted_next
;
195 sprintf( buffer
, "%04X", addr
);
199 int parse_label( char *buffer
)
204 /* Try to find the label */
205 walk
= sorted_globals
;
208 if (!strcmp(walk
->name
, buffer
)) {
211 walk
= walk
->sorted_next
;
213 /* No match - return hex value */
214 if (sscanf( buffer
, "%x", &tmp
)==1) {
220 int format_operand( char *buffer
, int op
, int reg
, UBYTE
*base
, int addr
)
224 strcpy( buffer
, word_regs
[reg
] );
227 strcpy( buffer
, word_regs
[reg
>>1] );
230 strcpy( buffer
, byte_regs
[(reg
*2)+1] );
233 strcpy( buffer
, byte_regs
[(reg
*2)] );
236 strcpy( buffer
, byte_regs
[reg
] );
239 strcpy( buffer
, conditions
[reg
] );
242 sprintf( buffer
,"%02X", (*base
-0xc0)&0xf8);
245 sprintf( buffer
, "%i", (int)((signed char)base
[1]) );
248 sprintf( buffer
, "%04X", 2+addr
+(int)((signed char)base
[1]) );
251 sprintf( buffer
, "%u", reg
);
254 sprintf( buffer
, "%02X", base
[1]);
257 format_label( buffer
, base
[1]|(((unsigned int)base
[2])<<8));
265 int print_code( int offset
, int reg1
, int reg2
, pmmnemo mnemo
, UBYTE
*base
, int addr
)
267 char op1
[40], op2
[40];
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
);
278 int handle_exception( UBYTE
*base
, pmmnemo_exception except
, int addr
)
281 pmmnemo_exception walk_except
;
282 char op1
[40], op2
[40];
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
);
301 int disass( char *buffer
, UBYTE
*base
, int addr
)
308 if (format_label( addr_name
, addr
)==0) {
309 printf("%s:\n", addr_name
);
311 printf("%04X", addr
);
317 if ((sub
&0x07)==0x07) {
318 return print_code( op
>>3, 0, 0, mnemo_07_40
, base
, addr
);
321 if ((sub
&0x07)==0x00) {
322 return print_code( op
>>3, 0, 0, mnemo_00_40
, base
, addr
);
325 if (!(tmp
=handle_exception( base
, mnemo_exceptions_40
, addr
)))
326 return print_code( op
&0x0f, op
>>4, 0, mnemo_40
, base
, addr
);
334 if (op
<0x40) { /* <0x80 */
335 return print_code( 0, op
>>3, op
&0x07, mnemo_80
, base
, addr
);
339 if (op
<0x40) { /* <0xC0 */
340 return print_code( op
>>3, op
&0x07, 0, mnemo_C0
, base
, addr
);
344 /* Handle CB opcodes */
347 return 1+print_code( *base
>>3, *base
&0x07, 0, mnemo_CB_40
, base
, addr
);
349 return 1+print_code( (*base
-0x40)>>6, (*base
>>3)&0x07, *base
&0x07, mnemo_CB_C7
, base
, addr
);
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 */
358 return print_code( op
&0x0f, op
>>3, 0, mnemo_FF
, base
, addr
);