2 * mon_z80.cpp - Z80 disassembler
4 * cxmon (C) 1997-2000 Christian Bauer, Marc Hellwig
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* Hacked by Michael Hope <michaelh@juju.net.nz> into rrgb. */
22 //#include "sysdeps.h"
29 extern "C" uint8
mon_read_byte(uint32 addr
);
32 //#include "mon_disass.h"
44 A_HL
, // hl or ix or iy
46 A_REG1
, // 8-bit register (bits 0..2 of opcode) or (hl)/(ix+d)/(iy+d)
47 A_REG1X
, // 8-bit register (bits 0..2 of opcode) or (hl)/(ix+d)/(iy+d), don't substitute h or l on prefixes
48 A_REG2
, // 8-bit register (bits 3..5 of opcode) or (hl)/(ix+d)/(iy+d)
49 A_REG2X
, // 8-bit register (bits 3..5 of opcode) or (hl)/(ix+d)/(iy+d), don't substitute h or l on prefixes
50 A_REG3
, // 16-bit register (bits 4..5 of opcode) bc/de/hl/sp
51 A_REG4
, // 16-bit register (bits 4..5 of opcode) bc/de/hl/af
52 A_COND
, // condition code (bits 3..5 of opcode)
53 A_COND2
, // condition code (bits 3..4 of opcode)
54 A_BIT
, // bit number (bits 3..5 of opcode)
58 A_HL_IND
, // (hl) or (ix) or (iy)
66 M_ADC
, M_ADD
, M_AND
, M_BIT
, M_CALL
, M_CCF
, M_CP
, M_CPD
, M_CPDR
, M_CPI
,
67 M_CPIR
, M_CPL
, M_DAA
, M_DEC
, M_DI
, M_DJNZ
, M_EI
, M_EX
, M_EXX
, M_HALT
,
68 M_IM0
, M_IM1
, M_IM2
, M_IN
, M_INC
, M_IND
, M_INDR
, M_INI
, M_INIR
, M_JP
,
69 M_JR
, M_LD
, M_LDD
, M_LDDR
, M_LDI
, M_LDIR
, M_NEG
, M_NOP
, M_OR
, M_OTDR
,
70 M_OTIR
, M_OUT
, M_OUTD
, M_OUTI
, M_POP
, M_PUSH
, M_RES
, M_RET
, M_RETI
,
71 M_RETN
, M_RL
, M_RLA
, M_RLC
, M_RLCA
, M_RLD
, M_RR
, M_RRA
, M_RRC
, M_RRCA
,
72 M_RRD
, M_RST
, M_SBC
, M_SCF
, M_SET
, M_SL1
, M_SLA
, M_SRA
, M_SRL
, M_SUB
,
79 // Chars for each mnemonic
80 static const char mnem_1
[] = "aaabccccccccddddeeehiiiiiiiiijjlllllnnoooooopprrrrrrrrrrrrrrrssssssssx?";
81 static const char mnem_2
[] = "ddniacppppppaeijixxammmnnnnnnprdddddeorttuuuoueeeelllllrrrrrsbcellrruo ";
82 static const char mnem_3
[] = "cddtlf ddiilac n xl cddii ddiigp ditttpssttt accd accdtcft1aalbr ";
83 static const char mnem_4
[] = " l r r z t012 r r r r rr di h in a a ";
85 // Mnemonic for each opcode
86 static const char mnemonic
[256] = {
87 M_NOP
, M_LD
, M_LD
, M_INC
, M_INC
, M_DEC
, M_LD
, M_RLCA
, // 00
88 M_EX
, M_ADD
, M_LD
, M_DEC
, M_INC
, M_DEC
, M_LD
, M_RRCA
,
89 M_DJNZ
, M_LD
, M_LD
, M_INC
, M_INC
, M_DEC
, M_LD
, M_RLA
, // 10
90 M_JR
, M_ADD
, M_LD
, M_DEC
, M_INC
, M_DEC
, M_LD
, M_RRA
,
91 M_JR
, M_LD
, M_LD
, M_INC
, M_INC
, M_DEC
, M_LD
, M_DAA
, // 20
92 M_JR
, M_ADD
, M_LD
, M_DEC
, M_INC
, M_DEC
, M_LD
, M_CPL
,
93 M_JR
, M_LD
, M_LD
, M_INC
, M_INC
, M_DEC
, M_LD
, M_SCF
, // 30
94 M_JR
, M_ADD
, M_LD
, M_DEC
, M_INC
, M_DEC
, M_LD
, M_CCF
,
95 M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, // 40
96 M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
,
97 M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, // 50
98 M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
,
99 M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, // 60
100 M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
,
101 M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_HALT
, M_LD
, // 70
102 M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
, M_LD
,
103 M_ADD
, M_ADD
, M_ADD
, M_ADD
, M_ADD
, M_ADD
, M_ADD
, M_ADD
, // 80
104 M_ADC
, M_ADC
, M_ADC
, M_ADC
, M_ADC
, M_ADC
, M_ADC
, M_ADC
,
105 M_SUB
, M_SUB
, M_SUB
, M_SUB
, M_SUB
, M_SUB
, M_SUB
, M_SUB
, // 90
106 M_SBC
, M_SBC
, M_SBC
, M_SBC
, M_SBC
, M_SBC
, M_SBC
, M_SBC
,
107 M_AND
, M_AND
, M_AND
, M_AND
, M_AND
, M_AND
, M_AND
, M_AND
, // a0
108 M_XOR
, M_XOR
, M_XOR
, M_XOR
, M_XOR
, M_XOR
, M_XOR
, M_XOR
,
109 M_OR
, M_OR
, M_OR
, M_OR
, M_OR
, M_OR
, M_OR
, M_OR
, // b0
110 M_CP
, M_CP
, M_CP
, M_CP
, M_CP
, M_CP
, M_CP
, M_CP
,
111 M_RET
, M_POP
, M_JP
, M_JP
, M_CALL
, M_PUSH
, M_ADD
, M_RST
, // c0
112 M_RET
, M_RET
, M_JP
, M_ILLEGAL
, M_CALL
, M_CALL
, M_ADC
, M_RST
,
113 M_RET
, M_POP
, M_JP
, M_OUT
, M_CALL
, M_PUSH
, M_SUB
, M_RST
, // d0
114 M_RET
, M_EXX
, M_JP
, M_IN
, M_CALL
, M_ILLEGAL
, M_SBC
, M_RST
,
115 M_RET
, M_POP
, M_JP
, M_EX
, M_CALL
, M_PUSH
, M_AND
, M_RST
, // e0
116 M_RET
, M_JP
, M_JP
, M_EX
, M_CALL
, M_ILLEGAL
, M_XOR
, M_RST
,
117 M_RET
, M_POP
, M_JP
, M_DI
, M_CALL
, M_PUSH
, M_OR
, M_RST
, // f0
118 M_RET
, M_LD
, M_JP
, M_EI
, M_CALL
, M_ILLEGAL
, M_CP
, M_RST
121 // Source/destination addressing modes for each opcode
122 #define A(d,s) (((A_ ## d) << 8) | (A_ ## s))
124 static const short adr_mode
[256] = {
125 A(IMPL
,IMPL
) , A(REG3
,IMM16
) , A(BC_IND
,A
) , A(REG3
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMM8
) , A(IMPL
,IMPL
) , // 00
126 A(AF_AF
,IMPL
) , A(HL
,REG3
) , A(A
,BC_IND
) , A(REG3
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMM8
) , A(IMPL
,IMPL
) ,
127 A(REL
,IMPL
) , A(REG3
,IMM16
) , A(DE_IND
,A
) , A(REG3
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMM8
) , A(IMPL
,IMPL
) , // 10
128 A(REL
,IMPL
) , A(HL
,REG3
) , A(A
,DE_IND
) , A(REG3
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMM8
) , A(IMPL
,IMPL
) ,
129 A(COND2
,REL
) , A(REG3
,IMM16
) , A(ABS16
,HL
) , A(REG3
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMM8
) , A(IMPL
,IMPL
) , // 20
130 A(COND2
,REL
) , A(HL
,REG3
) , A(HL
,ABS16
) , A(REG3
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMM8
) , A(IMPL
,IMPL
) ,
131 A(COND2
,REL
) , A(REG3
,IMM16
) , A(ABS16
,A
) , A(REG3
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMM8
) , A(IMPL
,IMPL
) , // 30
132 A(COND2
,REL
) , A(HL
,REG3
) , A(A
,ABS16
) , A(REG3
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMPL
) , A(REG2
,IMM8
) , A(IMPL
,IMPL
) ,
133 A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2X
,REG1
), A(REG2
,REG1
) , // 40
134 A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2X
,REG1
), A(REG2
,REG1
) ,
135 A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2X
,REG1
), A(REG2
,REG1
) , // 50
136 A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2X
,REG1
), A(REG2
,REG1
) ,
137 A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2X
,REG1
), A(REG2
,REG1
) , // 60
138 A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2X
,REG1
), A(REG2
,REG1
) ,
139 A(REG2
,REG1X
) , A(REG2
,REG1X
) , A(REG2
,REG1X
), A(REG2
,REG1X
), A(REG2
,REG1X
), A(REG2
,REG1X
), A(IMPL
,IMPL
) , A(REG2
,REG1X
), // 70
140 A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2
,REG1
) , A(REG2X
,REG1
), A(REG2
,REG1
) ,
141 A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , // 80
142 A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) ,
143 A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , // 90
144 A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) , A(A
,REG1
) ,
145 A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , // a0
146 A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) ,
147 A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , // b0
148 A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) , A(REG1
,IMPL
) ,
149 A(COND
,IMPL
) , A(REG4
,IMPL
) , A(COND
,IMM16
), A(IMM16
,IMPL
), A(COND
,IMM16
), A(REG4
,IMPL
) , A(A
,IMM8
) , A(RST
,IMPL
) , // c0
150 A(COND
,IMPL
) , A(IMPL
,IMPL
) , A(COND
,IMM16
), A(IMPL
,IMPL
) , A(COND
,IMM16
), A(IMM16
,IMPL
), A(A
,IMM8
) , A(RST
,IMPL
) ,
151 A(COND
,IMPL
) , A(REG4
,IMPL
) , A(COND
,IMM16
), A(ABS8
,A
) , A(COND
,IMM16
), A(REG4
,IMPL
) , A(IMM8
,IMPL
) , A(RST
,IMPL
) , // d0
152 A(COND
,IMPL
) , A(IMPL
,IMPL
) , A(COND
,IMM16
), A(A
,ABS8
) , A(COND
,IMM16
), A(IMPL
,IMPL
) , A(A
,IMM8
) , A(RST
,IMPL
) ,
153 A(COND
,IMPL
) , A(REG4
,IMPL
) , A(COND
,IMM16
), A(SP_IND
,HL
) , A(COND
,IMM16
), A(REG4
,IMPL
) , A(IMM8
,IMPL
) , A(RST
,IMPL
) , // e0
154 A(COND
,IMPL
) , A(HL_IND
,IMPL
), A(COND
,IMM16
), A(DE_HL
,IMPL
), A(COND
,IMM16
), A(IMPL
,IMPL
) , A(IMM8
,IMPL
) , A(RST
,IMPL
) ,
155 A(COND
,IMPL
) , A(REG4
,IMPL
) , A(COND
,IMM16
), A(IMPL
,IMPL
) , A(COND
,IMM16
), A(REG4
,IMPL
) , A(IMM8
,IMPL
) , A(RST
,IMPL
) , // f0
156 A(COND
,IMPL
) , A(SP
,HL
) , A(COND
,IMM16
), A(IMPL
,IMPL
) , A(COND
,IMM16
), A(IMPL
,IMPL
) , A(IMM8
,IMPL
) , A(RST
,IMPL
)
161 * sprintf into a "stream"
169 static int mon_sprintf(SFILE
*f
, const char *format
, ...)
173 va_start(args
, format
);
174 vsprintf(f
->current
, format
, args
);
175 f
->current
+= n
= strlen(f
->current
);
182 * Disassemble one instruction, return number of bytes
185 static const char *reg_name
[] = {"b", "c", "d", "e", "h", "l", "*", "a"};
186 static const char *reg_name_ix
[] = {"b", "c", "d", "e", "hx", "lx", "*", "a"}; // undoc
187 static const char *reg_name_iy
[] = {"b", "c", "d", "e", "hy", "ly", "*", "a"}; // undoc
188 static const char *reg_name_16
[] = {"bc", "de", "hl", "sp"};
189 static const char *reg_name_16_2
[] = {"bc", "de", "hl", "af"};
190 static const char *cond_name
[] = {"nz", "z", "nc", "c", "po", "pe", "p", "m"};
192 static void operand(SFILE
*f
, char mode
, uint32
&adr
, uint8 op
, bool ix
, bool iy
)
199 mon_sprintf(f
, "$%02x", mon_read_byte(adr
)); adr
++;
203 mon_sprintf(f
, "$%04x", (mon_read_byte(adr
+ 1) << 8) | mon_read_byte(adr
)); adr
+= 2;
207 mon_sprintf(f
, "($%02x)", mon_read_byte(adr
)); adr
++;
211 mon_sprintf(f
, "($%04x)", (mon_read_byte(adr
+ 1) << 8) | mon_read_byte(adr
)); adr
+= 2;
215 mon_sprintf(f
, "$%04x", (adr
+ 2 + (int8
)mon_read_byte(adr
)) & 0xffff); adr
++;
223 mon_sprintf(f
, ix
? "ix" : (iy
? "iy" : "hl"));
227 mon_sprintf(f
, "sp");
235 mon_sprintf(f
, "(%s+$%02x)", ix
? "ix" : "iy", mon_read_byte(adr
)); adr
++;
237 mon_sprintf(f
, "(hl)");
238 } else if (mode
== A_REG1
)
239 mon_sprintf(f
, "%s", ix
? reg_name_ix
[reg
] : (iy
? reg_name_iy
[reg
] : reg_name
[reg
]));
241 mon_sprintf(f
, "%s", reg_name
[reg
]);
247 int reg
= (op
>> 3) & 7;
250 mon_sprintf(f
, "(%s+$%02x)", ix
? "ix" : "iy", mon_read_byte(adr
)); adr
++;
252 mon_sprintf(f
, "(hl)");
253 } else if (mode
== A_REG2
)
254 mon_sprintf(f
, "%s", ix
? reg_name_ix
[reg
] : (iy
? reg_name_iy
[reg
] : reg_name
[reg
]));
256 mon_sprintf(f
, "%s", reg_name
[reg
]);
261 mon_sprintf(f
, reg_name_16
[(op
>> 4) & 3]);
265 mon_sprintf(f
, reg_name_16_2
[(op
>> 4) & 3]);
269 mon_sprintf(f
, cond_name
[(op
>> 3) & 7]);
273 mon_sprintf(f
, cond_name
[(op
>> 3) & 3]);
277 mon_sprintf(f
, "%d", (op
>> 3) & 7);
281 mon_sprintf(f
, "$%02x", op
& 0x38);
285 mon_sprintf(f
, "(bc)");
289 mon_sprintf(f
, "(de)");
293 mon_sprintf(f
, ix
? "(ix)" : (iy
? "(iy)" : "(hl)"));
297 mon_sprintf(f
, "(sp)");
301 mon_sprintf(f
, "de,hl");
305 mon_sprintf(f
, "af,af'");
310 static int print_instr(SFILE
*f
, int mnem
, char dst_mode
, char src_mode
, uint32 adr
, uint8 op
, bool ix
, bool iy
)
312 uint32 orig_adr
= adr
;
315 mon_sprintf(f
, "%c%c%c%c ", mnem_1
[mnem
], mnem_2
[mnem
], mnem_3
[mnem
], mnem_4
[mnem
]);
317 // Print destination operand
318 operand(f
, dst_mode
, adr
, op
, ix
, iy
);
320 // Print source operand
321 if (src_mode
!= A_IMPL
)
323 operand(f
, src_mode
, adr
, op
, ix
, iy
);
325 return adr
- orig_adr
;
328 static int disass_cb(SFILE
*f
, uint32 adr
, bool ix
, bool iy
)
335 op
= mon_read_byte(adr
+ 1);
338 op
= mon_read_byte(adr
);
342 // Decode mnemonic and addressing modes
343 char mnem
= 0, dst_mode
= A_IMPL
, src_mode
= A_IMPL
;
347 switch ((op
>> 3) & 7) {
348 case 0: mnem
= M_RLC
; break;
349 case 1: mnem
= M_RRC
; break;
350 case 2: mnem
= M_RL
; break;
351 case 3: mnem
= M_RR
; break;
352 case 4: mnem
= M_SLA
; break;
353 case 5: mnem
= M_SRA
; break;
354 case 6: mnem
= M_SL1
; break;
355 case 7: mnem
= M_SRL
; break;
359 mnem
= M_BIT
; dst_mode
= A_BIT
; src_mode
= A_REG1
;
362 mnem
= M_RES
; dst_mode
= A_BIT
; src_mode
= A_REG1
;
365 mnem
= M_SET
; dst_mode
= A_BIT
; src_mode
= A_REG1
;
370 print_instr(f
, mnem
, dst_mode
, src_mode
, adr
, op
, ix
, iy
);
374 static int disass_ed(SFILE
*f
, uint32 adr
)
377 uint8 op
= mon_read_byte(adr
);
379 // Decode mnemonic and addressing modes
380 char mnem
, dst_mode
= A_IMPL
, src_mode
= A_IMPL
;
389 mon_sprintf(f
, "in\t%s,(c)", reg_name
[(op
>> 3) & 7]);
392 mon_sprintf(f
, "in\t(c)");
402 mon_sprintf(f
, "out\t(c),%s", reg_name
[(op
>> 3) & 7]);
405 mon_sprintf(f
, "out\t(c),0");
412 mnem
= M_SBC
; dst_mode
= A_HL
; src_mode
= A_REG3
;
419 mnem
= M_LD
; dst_mode
= A_ABS16
; src_mode
= A_REG3
;
426 mnem
= M_ADC
; dst_mode
= A_HL
; src_mode
= A_REG3
;
433 mnem
= M_LD
; dst_mode
= A_REG3
; src_mode
= A_ABS16
;
456 case 0x4d: mnem
= M_RETI
; break;
474 mon_sprintf(f
, "ld\ti,a");
477 mon_sprintf(f
, "ld\tr,a");
480 mon_sprintf(f
, "ld\ta,i");
483 mon_sprintf(f
, "ld\ta,r");
486 case 0x67: mnem
= M_RRD
; break;
487 case 0x6f: mnem
= M_RLD
; break;
489 case 0xa0: mnem
= M_LDI
; break;
490 case 0xa1: mnem
= M_CPI
; break;
491 case 0xa2: mnem
= M_INI
; break;
492 case 0xa3: mnem
= M_OUTI
; break;
493 case 0xa8: mnem
= M_LDD
; break;
494 case 0xa9: mnem
= M_CPD
; break;
495 case 0xaa: mnem
= M_IND
; break;
496 case 0xab: mnem
= M_OUTD
; break;
497 case 0xb0: mnem
= M_LDIR
; break;
498 case 0xb1: mnem
= M_CPIR
; break;
499 case 0xb2: mnem
= M_INIR
; break;
500 case 0xb3: mnem
= M_OTIR
; break;
501 case 0xb8: mnem
= M_LDDR
; break;
502 case 0xb9: mnem
= M_CPDR
; break;
503 case 0xba: mnem
= M_INDR
; break;
504 case 0xbb: mnem
= M_OTDR
; break;
512 return print_instr(f
, mnem
, dst_mode
, src_mode
, adr
+ 1, op
, false, false) + 1;
515 static int disass(SFILE
*f
, uint32 adr
, bool ix
, bool iy
)
517 uint8 op
= mon_read_byte(adr
);
519 return disass_cb(f
, adr
+ 1, ix
, iy
) + 1;
521 return print_instr(f
, mnemonic
[op
], adr_mode
[op
] >> 8, adr_mode
[op
] & 0xff, adr
+ 1, op
, ix
, iy
) + 1;
524 extern "C" int disass_z80(FILE *f
, uint32 adr
)
528 SFILE sfile
= {buf
, buf
};
530 switch (mon_read_byte(adr
)) {
531 case 0xdd: // ix prefix
532 num
= disass(&sfile
, adr
+ 1, true, false) + 1;
535 num
= disass_ed(&sfile
, adr
+ 1) + 1;
537 case 0xfd: // iy prefix
538 num
= disass(&sfile
, adr
+ 1, false, true) + 1;
541 num
= disass(&sfile
, adr
, false, false);
545 for (int i
=0; i
<4; i
++) {
547 fprintf(f
, "%02x ", mon_read_byte(adr
+ i
));
552 fprintf(f
, "\t%s", buf
);