1 /*****************************************************************************
2  *
3  *   z80.c
4  *   Portable Z80 emulator V3.5
5  *
6  *   Copyright Juergen Buchmueller, all rights reserved.
7  *
8  *   - This source code is released as freeware for non-commercial purposes.
9  *   - You are free to use and redistribute this code in modified or
10  *     unmodified form, provided you list me in the credits.
11  *   - If you modify this source code, you must add a notice to each modified
12  *     source file that it has been changed.  If you're a nice person, you
13  *     will clearly mark each change too.  :)
14  *   - If you wish to use this for commercial purposes, please contact me at
15  *     pullmoll@t-online.de
16  *   - The author of this copywritten work reserves the right to change the
17  *     terms of its usage and license at any time, including retroactively
18  *   - This entire notice must remain in the source code.
19  *
20  *   Changes in 3.7 [Aaron Giles]
21  *   - Changed NMI handling. NMIs are now latched in set_irq_state
22  *     but are not taken there. Instead they are taken at the start of the
23  *     execute loop.
24  *   - Changed IRQ handling. IRQ state is set in set_irq_state but not taken
25  *     except during the inner execute loop.
26  *   - Removed x86 assembly hacks and obsolete timing loop catchers.
27  *   Changes in 3.6
28  *   - Got rid of the code that would inexactly emulate a Z80, i.e. removed
29  *     all the #if Z80_EXACT #else branches.
30  *   - Removed leading underscores from local register name shortcuts as
31  *     this violates the C99 standard.
32  *   - Renamed the registers inside the Z80 context to lower case to avoid
33  *     ambiguities (shortcuts would have had the same names as the fields
34  *     of the structure).
35  *   Changes in 3.5
36  *   - Implemented OTIR, INIR, etc. without look-up table for PF flag.
37  *     [Ramsoft, Sean Young]
38  *   Changes in 3.4
39  *   - Removed Z80-MSX specific code as it's not needed any more.
40  *   - Implemented DAA without look-up table [Ramsoft, Sean Young]
41  *   Changes in 3.3
42  *   - Fixed undocumented flags XF & YF in the non-asm versions of CP,
43  *     and all the 16 bit arithmetic instructions. [Sean Young]
44  *   Changes in 3.2
45  *   - Fixed undocumented flags XF & YF of RRCA, and CF and HF of
46  *     INI/IND/OUTI/OUTD/INIR/INDR/OTIR/OTDR [Sean Young]
47  *   Changes in 3.1
48  *   - removed the REPEAT_AT_ONCE execution of LDIR/CPIR etc. opcodes
49  *     for readabilities sake and because the implementation was buggy
50  *     (and I was not able to find the difference)
51  *   Changes in 3.0
52  *   - 'finished' switch to dynamically overrideable cycle count tables
53  *   Changes in 2.9:
54  *   - added methods to access and override the cycle count tables
55  *   - fixed handling and timing of multiple DD/FD prefixed opcodes
56  *   Changes in 2.8:
57  *   - OUTI/OUTD/OTIR/OTDR also pre-decrement the B register now.
58  *     This was wrong because of a bug fix on the wrong side
59  *     (astrocade sound driver).
60  *   Changes in 2.7:
61  *    - removed z80_vm specific code, it's not needed (and never was).
62  *   Changes in 2.6:
63  *    - BUSY_LOOP_HACKS needed to call change_pc() earlier, before
64  *      checking the opcodes at the new address, because otherwise they
65  *      might access the old (wrong or even NULL) banked memory region.
66  *      Thanks to Sean Young for finding this nasty bug.
67  *   Changes in 2.5:
68  *    - Burning cycles always adjusts the ICount by a multiple of 4.
69  *    - In REPEAT_AT_ONCE cases the R register wasn't incremented twice
70  *      per repetition as it should have been. Those repeated opcodes
71  *      could also underflow the ICount.
72  *    - Simplified TIME_LOOP_HACKS for BC and added two more for DE + HL
73  *      timing loops. I think those hacks weren't endian safe before too.
74  *   Changes in 2.4:
75  *    - z80_reset zaps the entire context, sets IX and IY to 0xffff(!) and
76  *      sets the Z flag. With these changes the Tehkan World Cup driver
77  *      _seems_ to work again.
78  *   Changes in 2.3:
79  *    - External termination of the execution loop calls z80_burn() and
80  *      z80_vm_burn() to burn an amount of cycles (R adjustment)
81  *    - Shortcuts which burn CPU cycles (BUSY_LOOP_HACKS and TIME_LOOP_HACKS)
82  *      now also adjust the R register depending on the skipped opcodes.
83  *   Changes in 2.2:
84  *    - Fixed bugs in CPL, SCF and CCF instructions flag handling.
85  *    - Changed variable EA and ARG16() function to UINT32; this
86  *      produces slightly more efficient code.
87  *    - The DD/FD XY CB opcodes where XY is 40-7F and Y is not 6/E
88  *      are changed to calls to the X6/XE opcodes to reduce object size.
89  *      They're hardly ever used so this should not yield a speed penalty.
90  *   New in 2.0:
91  *    - Optional more exact Z80 emulation (#define Z80_EXACT 1) according
92  *      to a detailed description by Sean Young which can be found at:
93  *      http://www.msxnet.org/tech/z80-documented.pdf
94  *****************************************************************************/
95 
96 #include "burnint.h"
97 #include "z80.h"
98 #include <stddef.h>
99 
100 #define	FALSE			0
101 #define TRUE			1
102 #define Z80_INLINE		static
103 #define change_pc(newpc)
104 //Z80.pc.w.l = (newpc)
105 
106 static Z80ReadIoHandler Z80IORead;
107 static Z80WriteIoHandler Z80IOWrite;
108 static Z80ReadProgHandler Z80ProgramRead;
109 static Z80WriteProgHandler Z80ProgramWrite;
110 static Z80ReadOpHandler Z80CPUReadOp;
111 static Z80ReadOpArgHandler Z80CPUReadOpArg;
112 
113 #define Z80Vector Z80.vector
114 
115 #define VERBOSE 0
116 
117 #define LOG(x)	//do { if (VERBOSE) logerror x; } while (0)
118 
119 /* execute main opcodes inside a big switch statement */
120 #ifndef BIG_SWITCH
121 #define BIG_SWITCH			1
122 #endif
123 
124 /* big flags array for ADD/ADC/SUB/SBC/CP results */
125 #define BIG_FLAGS_ARRAY		1
126 
127 /* on JP and JR opcodes check for tight loops */
128 #define BUSY_LOOP_HACKS     0
129 
130 // SpecZ80
131 static void eat_cycles(int type, int cycles);
132 static void capture_opcode_history_start(UINT16 reg_bc, UINT16 reg_ir);
133 static void capture_opcode_history_finish();
134 static void parse_script(const char *script_desc, CM_SCRIPT_BREAKDOWN *breakdown);
135 static bool find_script();
136 static void run_script();
137 static int  get_ula_delay();
138 static int  get_memory_access_delay(UINT16 pc_address);
139 static void store_rwinfo(UINT16 addr, UINT8 val, UINT16 flags, const char *dbg);
140 
141 static int		m_ula_variant;			// ULA_VARIANT_SINCLAIR  | ULA_VARIANT_AMSTRAD
142 static const char*	m_ula_delay_sequence;		// "654321200"           | "10765432"
143 static const char*	m_contended_banks;		// "1357"                | "4567"
144 static int		m_contended_banks_length;
145 static CM_SCRIPT	m_scripts[MAX_CM_SCRIPTS];	// "pc:4,pc+1:4,ir:1" etc...
146 static int 		m_cycles_contention_start;
147 static int 		m_cycles_per_line;
148 static int 		m_cycles_per_frame;
149 static void		(*m_raster_cb)(int); 			//Let the driver know a good time (in T-States) to update the video raster position.
150 static OPCODE_HISTORY	m_opcode_history;		// A list of reads/writes per opcode.
151 static int		m_tstate_counter;		// The current t-state / cpu cycle.
152 static int		m_selected_bank; 		// What ram bank 7ffd port has selected.
153 
154 /****************************************************************************/
155 /* The Z80 registers. HALT is set to 1 when the CPU is halted, the refresh  */
156 /* register is calculated as follows: refresh=(Z80.r&127)|(Z80.r2&128)      */
157 /****************************************************************************/
158 #define CF	0x01
159 #define NF	0x02
160 #define PF	0x04
161 #define VF	PF
162 #define XF	0x08
163 #define HF	0x10
164 #define YF	0x20
165 #define ZF	0x40
166 #define SF	0x80
167 
168 #define INT_IRQ 0x01
169 #define NMI_IRQ 0x02
170 
171 #define PRVPC Z80.prvpc.d		/* previous program counter */
172 
173 #define PCD	Z80.pc.d
174 #define PC Z80.pc.w.l
175 
176 #define SPD Z80.sp.d
177 #define SP Z80.sp.w.l
178 
179 #define AFD Z80.af.d
180 #define AF Z80.af.w.l
181 #define A Z80.af.b.h
182 #define F Z80.af.b.l
183 
184 #define BCD Z80.bc.d
185 #define BC Z80.bc.w.l
186 #define B Z80.bc.b.h
187 #define C Z80.bc.b.l
188 
189 #define DED Z80.de.d
190 #define DE Z80.de.w.l
191 #define D Z80.de.b.h
192 #define E Z80.de.b.l
193 
194 #define HLD Z80.hl.d
195 #define HL Z80.hl.w.l
196 #define H Z80.hl.b.h
197 #define L Z80.hl.b.l
198 
199 #define IXD Z80.ix.d
200 #define IX Z80.ix.w.l
201 #define HX Z80.ix.b.h
202 #define LX Z80.ix.b.l
203 
204 #define IYD Z80.iy.d
205 #define IY Z80.iy.w.l
206 #define HY Z80.iy.b.h
207 #define LY Z80.iy.b.l
208 
209 #define WZ     Z80.wz.w.l
210 #define WZ_H    Z80.wz.b.h
211 #define WZ_L    Z80.wz.b.l
212 
213 
214 #define I Z80.i
215 #define R Z80.r
216 #define R2 Z80.r2
217 #define IM Z80.im
218 #define IFF1 Z80.iff1
219 #define IFF2 Z80.iff2
220 #define HALT Z80.halt
221 
222 static Z80_Regs Z80;
223 #define EA Z80.EA
224 
225 void (*z80edfe_callback)(Z80_Regs *Regs) = NULL;
226 
227 static UINT8 SZ[256];		/* zero and sign flags */
228 static UINT8 SZ_BIT[256];	/* zero, sign and parity/overflow (=zero) flags for BIT opcode */
229 static UINT8 SZP[256];		/* zero, sign and parity flags */
230 static UINT8 SZHV_inc[256]; /* zero, sign, half carry and overflow flags INC r8 */
231 static UINT8 SZHV_dec[256]; /* zero, sign, half carry and overflow flags DEC r8 */
232 
233 #if BIG_FLAGS_ARRAY
234 static UINT8 *SZHVC_add = 0;
235 static UINT8 *SZHVC_sub = 0;
236 #endif
237 
238 static const UINT8 cc_op[0x100] = {
239  4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4,
240  8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4,
241  7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4,
242  7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4,
243  4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
244  4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
245  4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
246  7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4,
247  4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
248  4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
249  4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
250  4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
251  5,10,10,10,10,11, 7,11, 5,10,10, 0,10,17, 7,11,
252  5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 0, 7,11,
253  5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 0, 7,11,
254  5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11};
255 
256 static const UINT8 cc_cb[0x100] = {
257  8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
258  8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
259  8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
260  8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
261  8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
262  8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
263  8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
264  8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
265  8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
266  8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
267  8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
268  8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
269  8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
270  8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
271  8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
272  8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8};
273 
274 static const UINT8 cc_ed[0x100] = {
275  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
276  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
277  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
278  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
279 12,12,15,20, 8,14, 8, 9,12,12,15,20, 8,14, 8, 9,
280 12,12,15,20, 8,14, 8, 9,12,12,15,20, 8,14, 8, 9,
281 12,12,15,20, 8,14, 8,18,12,12,15,20, 8,14, 8,18,
282 12,12,15,20, 8,14, 8, 8,12,12,15,20, 8,14, 8, 8,
283  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
284  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
285 16,16,16,16, 8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8,
286 16,16,16,16, 8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8,
287  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
288  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
289  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
290  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
291 
292 static const UINT8 cc_xy[0x100] = {
293 	4+4,10+4, 7+4, 6+4, 4+4, 4+4, 7+4, 4+4, 4+4,11+4, 7+4, 6+4, 4+4, 4+4, 7+4, 4+4,
294 	8+4,10+4, 7+4, 6+4, 4+4, 4+4, 7+4, 4+4,12+4,11+4, 7+4, 6+4, 4+4, 4+4, 7+4, 4+4,
295 	7+4,10+4,16+4, 6+4, 4+4, 4+4, 7+4, 4+4, 7+4,11+4,16+4, 6+4, 4+4, 4+4, 7+4, 4+4,
296 	7+4,10+4,13+4, 6+4,23  ,23  ,19  , 4+4, 7+4,11+4,13+4, 6+4, 4+4, 4+4, 7+4, 4+4,
297 	4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4,
298 	4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4,
299 	4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4,
300 	19 ,19  ,19  ,19  ,19  ,19  , 4+4,19  , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4,
301 	4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4,
302 	4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4,
303 	4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4,
304 	4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19  , 4+4,
305 	5+4,10+4,10+4,10+4,10+4,11+4, 7+4,11+4, 5+4,10+4,10+4, 0  ,10+4,17+4, 7+4,11+4, /* cb -> cc_xycb */
306 	5+4,10+4,10+4,11+4,10+4,11+4, 7+4,11+4, 5+4, 4+4,10+4,11+4,10+4, 4  , 7+4,11+4, /* dd -> cc_xy again */
307 	5+4,10+4,10+4,19+4,10+4,11+4, 7+4,11+4, 5+4, 4+4,10+4, 4+4,10+4, 4  , 7+4,11+4, /* ed -> cc_ed */
308 	5+4,10+4,10+4, 4+4,10+4,11+4, 7+4,11+4, 5+4, 6+4,10+4, 4+4,10+4, 4  , 7+4,11+4  /* fd -> cc_xy again */
309 };
310 
311 static const UINT8 cc_xycb[0x100] = {
312 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
313 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
314 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
315 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
316 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
317 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
318 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
319 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
320 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
321 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
322 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
323 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
324 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
325 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
326 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
327 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23};
328 
329 /* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */
330 static const UINT8 cc_ex[0x100] = {
331  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332  5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* DJNZ */
333  5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,	/* JR NZ/JR Z */
334  5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,	/* JR NC/JR C */
335  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
336  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
338  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
339  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
340  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
341  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
342  5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0,	/* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */
343  6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
344  6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
345  6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
346  6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2};
347 
348 static const UINT8 cc_op_msx[0x100] = {
349 	4+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1, 4+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,
350 	8+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,12+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,
351 	7+1,10+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1, 7+1,11+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1,
352 	7+1,10+1,13+1, 6+1,11+1,11+1,10+1, 4+1, 7+1,11+1,13+1, 6+1, 4+1, 4+1, 7+1, 4+1,
353 	4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
354 	4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
355 	4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
356 	7+1, 7+1, 7+1, 7+1, 7+1, 7+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
357 	4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
358 	4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
359 	4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
360 	4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
361 	5+1,10+1,10+1,10+1,10+1,11+1, 7+1,11+1, 5+1,10+1,10+1, 0  ,10+1,17+1, 7+1,11+1,
362 	5+1,10+1,10+1,11+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1,11+1,10+1, 0  , 7+1,11+1,
363 	5+1,10+1,10+1,19+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1, 4+1,10+1, 0  , 7+1,11+1,
364 	5+1,10+1,10+1, 4+1,10+1,11+1, 7+1,11+1, 5+1, 6+1,10+1, 4+1,10+1, 0  , 7+1,11+1
365 };
366 
367 static const UINT8 cc_cb_msx[0x100] = {
368 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
369 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
370 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
371 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
372 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
373 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
374 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
375 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
376 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
377 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
378 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
379 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
380 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
381 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
382 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
383 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2
384 };
385 
386 static const UINT8 cc_ed_msx[0x100] = {
387 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
388 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
389 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
390 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
391 	12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,
392 	12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,
393 	12+2,12+2,15+2,20+2, 8+2,14+2, 8+2,18+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2,18+2,
394 	12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 8+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 8+2,
395 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
396 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
397 	16+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,16+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,
398 	16+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,16+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,
399 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
400 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
401 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
402 	8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2
403 };
404 
405 static const UINT8 cc_xy_msx[0x100] = {
406 	4+4+2,10+4+2, 7+4+2, 6+4+2, 4+4+2, 4+4+2, 7+4+2, 4+4+2, 4+4+2,11+4+2, 7+4+2, 6+4+2, 4+4+2, 4+4+2, 7+4+2, 4+4+2,
407 	8+4+2,10+4+2, 7+4+2, 6+4+2, 4+4+2, 4+4+2, 7+4+2, 4+4+2,12+4+2,11+4+2, 7+4+2, 6+4+2, 4+4+2, 4+4+2, 7+4+2, 4+4+2,
408 	7+4+2,10+4+2,16+4+2, 6+4+2, 4+4+2, 4+4+2, 7+4+2, 4+4+2, 7+4+2,11+4+2,16+4+2, 6+4+2, 4+4+2, 4+4+2, 7+4+2, 4+4+2,
409 	7+4+2,10+4+2,13+4+2, 6+4+2,23  +2,23  +2,19  +2, 4+4+2, 7+4+2,11+4+2,13+4+2, 6+4+2, 4+4+2, 4+4+2, 7+4+2, 4+4+2,
410 	4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2,
411 	4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2,
412 	4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2,
413 	19+2,   19+2,  19+2,  19+2,  19+2,  19+2, 4+4+2,  19+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2,
414 	4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2,
415 	4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2,
416 	4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2,
417 	4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2, 4+4+2,19  +2, 4+4+2,
418 	5+4+2,10+4+2,10+4+2,10+4+2,10+4+2,11+4+2, 7+4+2,11+4+2, 5+4+2,10+4+2,10+4+2, 0    ,10+4+2,17+4+2, 7+4+2,11+4+2,
419 	5+4+2,10+4+2,10+4+2,11+4+2,10+4+2,11+4+2, 7+4+2,11+4+2, 5+4+2, 4+4+2,10+4+2,11+4+2,10+4+2, 4  +1, 7+4+2,11+4+2,
420 	5+4+2,10+4+2,10+4+2,19+4+2,10+4+2,11+4+2, 7+4+2,11+4+2, 5+4+2, 4+4+2,10+4+2, 4+4+2,10+4+2, 4  +1, 7+4+2,11+4+2,
421 	5+4+2,10+4+2,10+4+2, 4+4+2,10+4+2,11+4+2, 7+4+2,11+4+2, 5+4+2, 6+4+2,10+4+2, 4+4+2,10+4+2, 4  +1, 7+4+2,11+4+2
422 };
423 
424 static const UINT8 cc_xycb_msx[0x100] = {
425 23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
426 23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
427 23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
428 23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
429 20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
430 20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
431 20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
432 20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
433 23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
434 23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
435 23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
436 23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
437 23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
438 23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
439 23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
440 23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2
441 };
442 
443 /* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */
444 static const UINT8 cc_ex_msx[0x100] = {
445 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
446 	5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DJNZ */
447 	5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, /* JR NZ/JR Z */
448 	5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, /* JR NC/JR C */
449 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
450 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
451 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
452 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
453 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
454 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
455 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
456 	5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, /* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */
457 	6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
458 	6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
459 	6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
460 	6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2+1
461 };
462 
463 
464 static const UINT8 *cc[6];
465 #define Z80_TABLE_dd	Z80_TABLE_xy
466 #define Z80_TABLE_fd	Z80_TABLE_xy
467 
468 enum ContendedMemoryID
469 {
470 	//37 different contended memory scripts (CM00 to CM36)
471 	CM00,CM01,CM02,CM03,CM04,CM05,CM06,CM07,CM08,CM09,
472 	CM10,CM11,CM12,CM13,CM14,CM15,CM16,CM17,CM18,CM19,
473 	CM20,CM21,CM22,CM23,CM24,CM25,CM26,CM27,CM28,CM29,
474 	CM30,CM31,CM32,CM33,CM34,CM35,CM36,
475 	OPII, //The opcode that follows the dd or fd should be treated standard opcode (cc_op[]) except it works on the IX or IY register instead.
476 	ILL1, //The opcode that follows the dd or fd should be treated standard opcode (cc_op[]). These are all undocumented.
477 	ILL2, //(Undocumented EDXX) Process these the same as CM01 (I could have put CM01 in the cc_ed_contended table instead of ILL2, but I think it was a good idea to be able to see there was a distinction).
478 	_CB_, //Go to the cc_cb_contended[] table
479 	_ED_, //Go to the cc_ed_contended[] table.
480 	_XY_, //Go to the cc_xy_contended[] table (for dd of fd prefixed opcodes)
481 	XYCB  //Use the cc_xycb_contended[] table (for ddcb or fdcb prefixed opcodes)
482 };
483 
484 
485 ///////////////////////////////////////////////////////
486 // Scripts derived from the SinclairFAQ              //
487 // https://faqwiki.zxnet.co.uk/wiki/Contended_memory //
488 ///////////////////////////////////////////////////////
489 CM_SCRIPT_DESCRIPTION cm_script_descriptions[MAX_CM_SCRIPTS] =
490 {
491         // ID	  Sinclair				Amstrad
492 	//						(If NULL, its the same as the Sinclair ULA)
493 	{/*CM00*/ "0:4",				NULL},
494 	{/*CM01*/ "0:4,1:4",				NULL},
495 	{/*CM02*/ "0:4,1:4,ir:1",			"0:4,1:5"},
496 	{/*CM03*/ "0:4,ir:1x2",				"0:6"},
497 	{/*CM04*/ "0:4,ir:1x7",				"0:11"},
498 	{/*CM05*/ "0:4,1:4,ir:1x7",			"0:4,1:11"},
499 	{/*CM06*/ "0:4,1:3",				NULL},
500 	{/*CM07*/ "0:4,1:3",				NULL},
501 	{/*CM08*/ "0:4,1:3",				NULL},
502 	{/*CM09*/ "0:4,1:4,2:3,2:1x5,3:3",		"0:4,1:4,2:8,3:3"},
503 	{/*CM10*/ "0:4,1:4,2:3,2:1",			"0:4,1:4,2:4"},
504 	{/*CM11*/ "0:4,1:4,2:3,3:3,3:1x2,4:3,4:1",	"0:4,1:4,2:3,3:5,4:4"},
505 	{/*CM12*/ "0:4,1:3,2:3",			NULL},
506 	{/*CM13*/ "0:4,1:3,2:3",			NULL},
507 	{/*CM14*/ "0:4,1:4,2:3,3:3,3:1x2,4:3",		"0:4,1:4,2:3,3:5,4:3"},
508 	{/*CM15*/ "0:4,1:3,2:3,3:3",			NULL},
509 	{/*CM16*/ "0:4,1:3,2:3,3:3,4:3",		NULL},
510 	{/*CM17*/ "0:4,1:4,2:3,3:3,4:3,5:3",		NULL},
511 	{/*CM18*/ "0:4,1:3,1:1,2:3",			"0:4,1:4,2:3"},
512 	{/*CM19*/ "0:4,1:4,2:3,2:1,3:3",		"0:4,1:4,2:4,3:3"},
513 	{/*CM20*/ "0:4,1:4,2:3,2:1x5,3:3,3:1,4:3",	"0:4,1:4,2:8,3:4,4:3"},
514 	{/*CM21*/ "0:4,1:4,2:3,3:3,3:1x2,4:3,4:1,5:3",	"0:4,1:4,2:3,3:5,4:4,5:3"},
515 	{/*CM22*/ "0:4,1:3,2:3",			NULL},
516 	{/*CM23*/ "0:4,1:4,2:3,3:3",			NULL},
517 	{/*CM24*/ "0:4,ir:1,[1:3,2:3]",			"0:5,[1:3,2:3"},
518 	{/*CM25*/ "0:4,ir:1,1:3,2:3",			NULL},
519 	{/*CM26*/ "0:4,1:3,2:3,[2:1,3:3,4:3]",		"0:4,1:3,2:3,[N:1,3:3,4:3]"},
520 	{/*CM27*/ "0:4,1:3,[1:1x5]",			"0:4,1:3,[N:5]"},
521 	{/*CM28*/ "0:4,ir:1,1:3,[1:1x5]",		"0:5,1:3,[N:5]"},
522 	{/*CM29*/ "0:4,1:4,2:3,2:1x4,3:3",		"0:4,1:4,2:7,3:3"},
523 	{/*CM30*/ "0:4,1:3,2:IO",			NULL},
524 	{/*CM31*/ "0:4,1:4,2:IO",			NULL},
525 	{/*CM32*/ "0:4,1:3,2:3,2:1,3:3,4:3,4:1x2",	"0:4,1:3,2:4,3:3,4:5"},
526 	{/*CM33*/ "0:4,1:4,2:3,3:3,3:1x2,[3:1x5]",	"0:4,1:4,2:3,3:5,[N:5]"},
527 	{/*CM34*/ "0:4,1:4,2:3,2:1x5,[2:1x5]",		"0:4,1:4,2:8,[N:5]"},
528 	{/*CM35*/ "0:4,1:4,ir:1,2:IO,3:3,[3:1x5]",	"0:4,1:5,2:IO,3:3,[N:5]"},
529 	{/*CM36*/ "0:4,1:4,ir:1,2:3,3:IO,[bc:1x5]",	"0:4,1:5,2:3,3:IO,[N:5]"}
530 };
531 
532 
533 static const int cc_op_contended[0x100] = {
534 /*	0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F */
535 /* 0 */	CM00,CM12,CM07,CM03,CM00,CM00,CM06,CM00,CM00,CM04,CM07,CM03,CM00,CM00,CM06,CM00,
536 /* 1 */	CM28,CM12,CM07,CM03,CM00,CM00,CM06,CM00,CM27,CM04,CM07,CM03,CM00,CM00,CM06,CM00,
537 /* 2 */	CM27,CM12,CM16,CM03,CM00,CM00,CM06,CM00,CM27,CM04,CM16,CM03,CM00,CM00,CM06,CM00,
538 /* 3 */	CM27,CM12,CM15,CM03,CM18,CM18,CM13,CM00,CM27,CM04,CM15,CM03,CM00,CM00,CM06,CM00,
539 /* 4 */	CM00,CM00,CM00,CM00,CM00,CM00,CM07,CM00,CM00,CM00,CM00,CM00,CM00,CM00,CM07,CM00,
540 /* 5 */	CM00,CM00,CM00,CM00,CM00,CM00,CM07,CM00,CM00,CM00,CM00,CM00,CM00,CM00,CM07,CM00,
541 /* 6 */	CM00,CM00,CM00,CM00,CM00,CM00,CM07,CM00,CM00,CM00,CM00,CM00,CM00,CM00,CM07,CM00,
542 /* 7 */	CM07,CM07,CM07,CM07,CM07,CM07,CM00,CM07,CM00,CM00,CM00,CM00,CM00,CM00,CM07,CM00,
543 /* 8 */	CM00,CM00,CM00,CM00,CM00,CM00,CM08,CM00,CM00,CM00,CM00,CM00,CM00,CM00,CM08,CM00,
544 /* 9 */	CM00,CM00,CM00,CM00,CM00,CM00,CM08,CM00,CM00,CM00,CM00,CM00,CM00,CM00,CM08,CM00,
545 /* A */	CM00,CM00,CM00,CM00,CM00,CM00,CM08,CM00,CM00,CM00,CM00,CM00,CM00,CM00,CM08,CM00,
546 /* B */	CM00,CM00,CM00,CM00,CM00,CM00,CM08,CM00,CM00,CM00,CM00,CM00,CM00,CM00,CM08,CM00,
547 /* C */	CM24,CM22,CM12,CM12,CM26,CM25,CM06,CM25,CM24,CM22,CM12,_CB_,CM26,CM26,CM06,CM25,
548 /* D */	CM24,CM22,CM12,CM30,CM26,CM25,CM06,CM25,CM24,CM00,CM12,CM30,CM26,_XY_,CM06,CM25,
549 /* E */	CM24,CM22,CM12,CM32,CM26,CM25,CM06,CM25,CM24,CM00,CM12,CM00,CM26,_ED_,CM06,CM25,
550 /* F */	CM24,CM22,CM12,CM00,CM26,CM25,CM06,CM25,CM24,CM03,CM12,CM00,CM26,_XY_,CM06,CM25
551 };
552 
553 static const int cc_ed_contended[0x100] = {
554 /*	0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F */
555 /* 0 */	ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,
556 /* 1 */	ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,
557 /* 2 */	ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,
558 /* 3 */	ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,
559 /* 4 */	CM31,CM31,CM05,CM17,CM01,CM23,CM01,CM02,CM31,CM31,CM05,CM17,CM01,CM23,CM01,CM02,
560 /* 5 */	CM31,CM31,CM05,CM17,CM01,CM23,CM01,CM02,CM31,CM31,CM05,CM17,CM01,CM23,CM01,CM02,
561 /* 6 */	CM31,CM31,CM05,CM17,CM01,CM23,CM01,CM29,CM31,CM31,CM05,CM17,CM01,CM23,CM01,CM29,
562 /* 7 */	CM31,CM31,CM05,CM17,CM01,CM23,CM01,ILL2,CM31,CM31,CM05,CM17,CM01,CM23,CM01,ILL2,
563 /* 8 */	ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,
564 /* 9 */	ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,
565 /* A */	CM33,CM34,CM35,CM36,ILL2,ILL2,ILL2,ILL2,CM33,CM34,CM35,CM36,ILL2,ILL2,ILL2,ILL2,
566 /* B */	CM33,CM34,CM35,CM36,ILL2,ILL2,ILL2,ILL2,CM33,CM34,CM35,CM36,ILL2,ILL2,ILL2,ILL2,
567 /* C */	ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,
568 /* D */	ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,
569 /* E */	ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,
570 /* F */	ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2,ILL2
571 };
572 
573 static const int cc_cb_contended[0x100] = {
574 /*	0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F */
575 /* 0 */	CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,
576 /* 1 */	CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,
577 /* 2 */	CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,
578 /* 3 */	CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,
579 /* 4 */	CM01,CM01,CM01,CM01,CM01,CM01,CM10,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM10,CM01,
580 /* 5 */	CM01,CM01,CM01,CM01,CM01,CM01,CM10,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM10,CM01,
581 /* 6 */	CM01,CM01,CM01,CM01,CM01,CM01,CM10,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM10,CM01,
582 /* 7 */	CM01,CM01,CM01,CM01,CM01,CM01,CM10,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM10,CM01,
583 /* 8 */	CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,
584 /* 9 */	CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,
585 /* A */	CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,
586 /* B */	CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,
587 /* C */	CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,
588 /* D */	CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,
589 /* E */	CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,
590 /* F */	CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,CM01,CM01,CM01,CM01,CM01,CM01,CM19,CM01,
591 };
592 
593 
594 //This is for opcodes that start with dd or fd (Saves us having a cc_dd_contended table and a
595 //cc_fd_contended table, which would both be identical). If the byte following the
596 //dd/fd falls on OPII or ILL1, then the opcode is processed by cc_op_contended[] + 4 tstates for
597 //reading the dd/fd.
598 static const int cc_xy_contended[0x100] = {
599 /*	0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F */
600 /* 0 */	ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,OPII,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,
601 /* 1 */	ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,OPII,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,
602 /* 2 */	ILL1,OPII,OPII,OPII,OPII,OPII,OPII,ILL1,ILL1,OPII,OPII,OPII,OPII,OPII,OPII,ILL1,
603 /* 3 */	ILL1,ILL1,ILL1,ILL1,CM20,CM20,CM14,ILL1,ILL1,OPII,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,
604 /* 4 */	ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,
605 /* 5 */	ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,
606 /* 6 */	OPII,OPII,OPII,OPII,OPII,OPII,CM09,OPII,OPII,OPII,OPII,OPII,OPII,OPII,CM09,OPII,
607 /* 7 */	CM09,CM09,CM09,CM09,CM09,CM09,ILL1,CM09,ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,
608 /* 8 */	ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,
609 /* 9 */	ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,
610 /* A */	ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,
611 /* B */	ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,ILL1,ILL1,ILL1,ILL1,OPII,OPII,CM09,ILL1,
612 /* C */	ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,XYCB,ILL1,ILL1,ILL1,ILL1,
613 /* D */	ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,
614 /* E */	ILL1,OPII,ILL1,OPII,ILL1,OPII,ILL1,ILL1,ILL1,OPII,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,
615 /* F */	ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1,OPII,ILL1,ILL1,ILL1,ILL1,ILL1,ILL1
616 };
617 
618 
619 //This is for opcodes that start with ddcb or fdcb (Saves us having a cc_ddcb_contended table and a
620 //cc_fdcb_contended table, which would both be identical).
621 static const int cc_xycb_contended[0x100] = {
622 /*	0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F */
623 /* 0 */	CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,
624 /* 1 */	CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,
625 /* 2 */	CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,
626 /* 3 */	CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,
627 /* 4 */	CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,
628 /* 5 */	CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,
629 /* 6 */	CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,
630 /* 7 */	CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,CM11,
631 /* 8 */	CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,
632 /* 9 */	CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,
633 /* A */	CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,
634 /* B */	CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,
635 /* C */	CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,
636 /* D */	CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,
637 /* E */	CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,
638 /* F */	CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21,CM21
639 };
640 
641 
642 static void take_interrupt(void);
643 //void Z80Burn(int cycles);
644 
645 typedef void (*funcptr)(void);
646 
647 #define PROTOTYPES(tablename,prefix) \
648 	Z80_INLINE void prefix##_00(void); Z80_INLINE void prefix##_01(void); Z80_INLINE void prefix##_02(void); Z80_INLINE void prefix##_03(void); \
649 	Z80_INLINE void prefix##_04(void); Z80_INLINE void prefix##_05(void); Z80_INLINE void prefix##_06(void); Z80_INLINE void prefix##_07(void); \
650 	Z80_INLINE void prefix##_08(void); Z80_INLINE void prefix##_09(void); Z80_INLINE void prefix##_0a(void); Z80_INLINE void prefix##_0b(void); \
651 	Z80_INLINE void prefix##_0c(void); Z80_INLINE void prefix##_0d(void); Z80_INLINE void prefix##_0e(void); Z80_INLINE void prefix##_0f(void); \
652 	Z80_INLINE void prefix##_10(void); Z80_INLINE void prefix##_11(void); Z80_INLINE void prefix##_12(void); Z80_INLINE void prefix##_13(void); \
653 	Z80_INLINE void prefix##_14(void); Z80_INLINE void prefix##_15(void); Z80_INLINE void prefix##_16(void); Z80_INLINE void prefix##_17(void); \
654 	Z80_INLINE void prefix##_18(void); Z80_INLINE void prefix##_19(void); Z80_INLINE void prefix##_1a(void); Z80_INLINE void prefix##_1b(void); \
655 	Z80_INLINE void prefix##_1c(void); Z80_INLINE void prefix##_1d(void); Z80_INLINE void prefix##_1e(void); Z80_INLINE void prefix##_1f(void); \
656 	Z80_INLINE void prefix##_20(void); Z80_INLINE void prefix##_21(void); Z80_INLINE void prefix##_22(void); Z80_INLINE void prefix##_23(void); \
657 	Z80_INLINE void prefix##_24(void); Z80_INLINE void prefix##_25(void); Z80_INLINE void prefix##_26(void); Z80_INLINE void prefix##_27(void); \
658 	Z80_INLINE void prefix##_28(void); Z80_INLINE void prefix##_29(void); Z80_INLINE void prefix##_2a(void); Z80_INLINE void prefix##_2b(void); \
659 	Z80_INLINE void prefix##_2c(void); Z80_INLINE void prefix##_2d(void); Z80_INLINE void prefix##_2e(void); Z80_INLINE void prefix##_2f(void); \
660 	Z80_INLINE void prefix##_30(void); Z80_INLINE void prefix##_31(void); Z80_INLINE void prefix##_32(void); Z80_INLINE void prefix##_33(void); \
661 	Z80_INLINE void prefix##_34(void); Z80_INLINE void prefix##_35(void); Z80_INLINE void prefix##_36(void); Z80_INLINE void prefix##_37(void); \
662 	Z80_INLINE void prefix##_38(void); Z80_INLINE void prefix##_39(void); Z80_INLINE void prefix##_3a(void); Z80_INLINE void prefix##_3b(void); \
663 	Z80_INLINE void prefix##_3c(void); Z80_INLINE void prefix##_3d(void); Z80_INLINE void prefix##_3e(void); Z80_INLINE void prefix##_3f(void); \
664 	Z80_INLINE void prefix##_40(void); Z80_INLINE void prefix##_41(void); Z80_INLINE void prefix##_42(void); Z80_INLINE void prefix##_43(void); \
665 	Z80_INLINE void prefix##_44(void); Z80_INLINE void prefix##_45(void); Z80_INLINE void prefix##_46(void); Z80_INLINE void prefix##_47(void); \
666 	Z80_INLINE void prefix##_48(void); Z80_INLINE void prefix##_49(void); Z80_INLINE void prefix##_4a(void); Z80_INLINE void prefix##_4b(void); \
667 	Z80_INLINE void prefix##_4c(void); Z80_INLINE void prefix##_4d(void); Z80_INLINE void prefix##_4e(void); Z80_INLINE void prefix##_4f(void); \
668 	Z80_INLINE void prefix##_50(void); Z80_INLINE void prefix##_51(void); Z80_INLINE void prefix##_52(void); Z80_INLINE void prefix##_53(void); \
669 	Z80_INLINE void prefix##_54(void); Z80_INLINE void prefix##_55(void); Z80_INLINE void prefix##_56(void); Z80_INLINE void prefix##_57(void); \
670 	Z80_INLINE void prefix##_58(void); Z80_INLINE void prefix##_59(void); Z80_INLINE void prefix##_5a(void); Z80_INLINE void prefix##_5b(void); \
671 	Z80_INLINE void prefix##_5c(void); Z80_INLINE void prefix##_5d(void); Z80_INLINE void prefix##_5e(void); Z80_INLINE void prefix##_5f(void); \
672 	Z80_INLINE void prefix##_60(void); Z80_INLINE void prefix##_61(void); Z80_INLINE void prefix##_62(void); Z80_INLINE void prefix##_63(void); \
673 	Z80_INLINE void prefix##_64(void); Z80_INLINE void prefix##_65(void); Z80_INLINE void prefix##_66(void); Z80_INLINE void prefix##_67(void); \
674 	Z80_INLINE void prefix##_68(void); Z80_INLINE void prefix##_69(void); Z80_INLINE void prefix##_6a(void); Z80_INLINE void prefix##_6b(void); \
675 	Z80_INLINE void prefix##_6c(void); Z80_INLINE void prefix##_6d(void); Z80_INLINE void prefix##_6e(void); Z80_INLINE void prefix##_6f(void); \
676 	Z80_INLINE void prefix##_70(void); Z80_INLINE void prefix##_71(void); Z80_INLINE void prefix##_72(void); Z80_INLINE void prefix##_73(void); \
677 	Z80_INLINE void prefix##_74(void); Z80_INLINE void prefix##_75(void); Z80_INLINE void prefix##_76(void); Z80_INLINE void prefix##_77(void); \
678 	Z80_INLINE void prefix##_78(void); Z80_INLINE void prefix##_79(void); Z80_INLINE void prefix##_7a(void); Z80_INLINE void prefix##_7b(void); \
679 	Z80_INLINE void prefix##_7c(void); Z80_INLINE void prefix##_7d(void); Z80_INLINE void prefix##_7e(void); Z80_INLINE void prefix##_7f(void); \
680 	Z80_INLINE void prefix##_80(void); Z80_INLINE void prefix##_81(void); Z80_INLINE void prefix##_82(void); Z80_INLINE void prefix##_83(void); \
681 	Z80_INLINE void prefix##_84(void); Z80_INLINE void prefix##_85(void); Z80_INLINE void prefix##_86(void); Z80_INLINE void prefix##_87(void); \
682 	Z80_INLINE void prefix##_88(void); Z80_INLINE void prefix##_89(void); Z80_INLINE void prefix##_8a(void); Z80_INLINE void prefix##_8b(void); \
683 	Z80_INLINE void prefix##_8c(void); Z80_INLINE void prefix##_8d(void); Z80_INLINE void prefix##_8e(void); Z80_INLINE void prefix##_8f(void); \
684 	Z80_INLINE void prefix##_90(void); Z80_INLINE void prefix##_91(void); Z80_INLINE void prefix##_92(void); Z80_INLINE void prefix##_93(void); \
685 	Z80_INLINE void prefix##_94(void); Z80_INLINE void prefix##_95(void); Z80_INLINE void prefix##_96(void); Z80_INLINE void prefix##_97(void); \
686 	Z80_INLINE void prefix##_98(void); Z80_INLINE void prefix##_99(void); Z80_INLINE void prefix##_9a(void); Z80_INLINE void prefix##_9b(void); \
687 	Z80_INLINE void prefix##_9c(void); Z80_INLINE void prefix##_9d(void); Z80_INLINE void prefix##_9e(void); Z80_INLINE void prefix##_9f(void); \
688 	Z80_INLINE void prefix##_a0(void); Z80_INLINE void prefix##_a1(void); Z80_INLINE void prefix##_a2(void); Z80_INLINE void prefix##_a3(void); \
689 	Z80_INLINE void prefix##_a4(void); Z80_INLINE void prefix##_a5(void); Z80_INLINE void prefix##_a6(void); Z80_INLINE void prefix##_a7(void); \
690 	Z80_INLINE void prefix##_a8(void); Z80_INLINE void prefix##_a9(void); Z80_INLINE void prefix##_aa(void); Z80_INLINE void prefix##_ab(void); \
691 	Z80_INLINE void prefix##_ac(void); Z80_INLINE void prefix##_ad(void); Z80_INLINE void prefix##_ae(void); Z80_INLINE void prefix##_af(void); \
692 	Z80_INLINE void prefix##_b0(void); Z80_INLINE void prefix##_b1(void); Z80_INLINE void prefix##_b2(void); Z80_INLINE void prefix##_b3(void); \
693 	Z80_INLINE void prefix##_b4(void); Z80_INLINE void prefix##_b5(void); Z80_INLINE void prefix##_b6(void); Z80_INLINE void prefix##_b7(void); \
694 	Z80_INLINE void prefix##_b8(void); Z80_INLINE void prefix##_b9(void); Z80_INLINE void prefix##_ba(void); Z80_INLINE void prefix##_bb(void); \
695 	Z80_INLINE void prefix##_bc(void); Z80_INLINE void prefix##_bd(void); Z80_INLINE void prefix##_be(void); Z80_INLINE void prefix##_bf(void); \
696 	Z80_INLINE void prefix##_c0(void); Z80_INLINE void prefix##_c1(void); Z80_INLINE void prefix##_c2(void); Z80_INLINE void prefix##_c3(void); \
697 	Z80_INLINE void prefix##_c4(void); Z80_INLINE void prefix##_c5(void); Z80_INLINE void prefix##_c6(void); Z80_INLINE void prefix##_c7(void); \
698 	Z80_INLINE void prefix##_c8(void); Z80_INLINE void prefix##_c9(void); Z80_INLINE void prefix##_ca(void); Z80_INLINE void prefix##_cb(void); \
699 	Z80_INLINE void prefix##_cc(void); Z80_INLINE void prefix##_cd(void); Z80_INLINE void prefix##_ce(void); Z80_INLINE void prefix##_cf(void); \
700 	Z80_INLINE void prefix##_d0(void); Z80_INLINE void prefix##_d1(void); Z80_INLINE void prefix##_d2(void); Z80_INLINE void prefix##_d3(void); \
701 	Z80_INLINE void prefix##_d4(void); Z80_INLINE void prefix##_d5(void); Z80_INLINE void prefix##_d6(void); Z80_INLINE void prefix##_d7(void); \
702 	Z80_INLINE void prefix##_d8(void); Z80_INLINE void prefix##_d9(void); Z80_INLINE void prefix##_da(void); Z80_INLINE void prefix##_db(void); \
703 	Z80_INLINE void prefix##_dc(void); Z80_INLINE void prefix##_dd(void); Z80_INLINE void prefix##_de(void); Z80_INLINE void prefix##_df(void); \
704 	Z80_INLINE void prefix##_e0(void); Z80_INLINE void prefix##_e1(void); Z80_INLINE void prefix##_e2(void); Z80_INLINE void prefix##_e3(void); \
705 	Z80_INLINE void prefix##_e4(void); Z80_INLINE void prefix##_e5(void); Z80_INLINE void prefix##_e6(void); Z80_INLINE void prefix##_e7(void); \
706 	Z80_INLINE void prefix##_e8(void); Z80_INLINE void prefix##_e9(void); Z80_INLINE void prefix##_ea(void); Z80_INLINE void prefix##_eb(void); \
707 	Z80_INLINE void prefix##_ec(void); Z80_INLINE void prefix##_ed(void); Z80_INLINE void prefix##_ee(void); Z80_INLINE void prefix##_ef(void); \
708 	Z80_INLINE void prefix##_f0(void); Z80_INLINE void prefix##_f1(void); Z80_INLINE void prefix##_f2(void); Z80_INLINE void prefix##_f3(void); \
709 	Z80_INLINE void prefix##_f4(void); Z80_INLINE void prefix##_f5(void); Z80_INLINE void prefix##_f6(void); Z80_INLINE void prefix##_f7(void); \
710 	Z80_INLINE void prefix##_f8(void); Z80_INLINE void prefix##_f9(void); Z80_INLINE void prefix##_fa(void); Z80_INLINE void prefix##_fb(void); \
711 	Z80_INLINE void prefix##_fc(void); Z80_INLINE void prefix##_fd(void); Z80_INLINE void prefix##_fe(void); Z80_INLINE void prefix##_ff(void); \
712 static const funcptr tablename[0x100] = {	\
713 	prefix##_00,prefix##_01,prefix##_02,prefix##_03,prefix##_04,prefix##_05,prefix##_06,prefix##_07, \
714 	prefix##_08,prefix##_09,prefix##_0a,prefix##_0b,prefix##_0c,prefix##_0d,prefix##_0e,prefix##_0f, \
715 	prefix##_10,prefix##_11,prefix##_12,prefix##_13,prefix##_14,prefix##_15,prefix##_16,prefix##_17, \
716 	prefix##_18,prefix##_19,prefix##_1a,prefix##_1b,prefix##_1c,prefix##_1d,prefix##_1e,prefix##_1f, \
717 	prefix##_20,prefix##_21,prefix##_22,prefix##_23,prefix##_24,prefix##_25,prefix##_26,prefix##_27, \
718 	prefix##_28,prefix##_29,prefix##_2a,prefix##_2b,prefix##_2c,prefix##_2d,prefix##_2e,prefix##_2f, \
719 	prefix##_30,prefix##_31,prefix##_32,prefix##_33,prefix##_34,prefix##_35,prefix##_36,prefix##_37, \
720 	prefix##_38,prefix##_39,prefix##_3a,prefix##_3b,prefix##_3c,prefix##_3d,prefix##_3e,prefix##_3f, \
721 	prefix##_40,prefix##_41,prefix##_42,prefix##_43,prefix##_44,prefix##_45,prefix##_46,prefix##_47, \
722 	prefix##_48,prefix##_49,prefix##_4a,prefix##_4b,prefix##_4c,prefix##_4d,prefix##_4e,prefix##_4f, \
723 	prefix##_50,prefix##_51,prefix##_52,prefix##_53,prefix##_54,prefix##_55,prefix##_56,prefix##_57, \
724 	prefix##_58,prefix##_59,prefix##_5a,prefix##_5b,prefix##_5c,prefix##_5d,prefix##_5e,prefix##_5f, \
725 	prefix##_60,prefix##_61,prefix##_62,prefix##_63,prefix##_64,prefix##_65,prefix##_66,prefix##_67, \
726 	prefix##_68,prefix##_69,prefix##_6a,prefix##_6b,prefix##_6c,prefix##_6d,prefix##_6e,prefix##_6f, \
727 	prefix##_70,prefix##_71,prefix##_72,prefix##_73,prefix##_74,prefix##_75,prefix##_76,prefix##_77, \
728 	prefix##_78,prefix##_79,prefix##_7a,prefix##_7b,prefix##_7c,prefix##_7d,prefix##_7e,prefix##_7f, \
729 	prefix##_80,prefix##_81,prefix##_82,prefix##_83,prefix##_84,prefix##_85,prefix##_86,prefix##_87, \
730 	prefix##_88,prefix##_89,prefix##_8a,prefix##_8b,prefix##_8c,prefix##_8d,prefix##_8e,prefix##_8f, \
731 	prefix##_90,prefix##_91,prefix##_92,prefix##_93,prefix##_94,prefix##_95,prefix##_96,prefix##_97, \
732 	prefix##_98,prefix##_99,prefix##_9a,prefix##_9b,prefix##_9c,prefix##_9d,prefix##_9e,prefix##_9f, \
733 	prefix##_a0,prefix##_a1,prefix##_a2,prefix##_a3,prefix##_a4,prefix##_a5,prefix##_a6,prefix##_a7, \
734 	prefix##_a8,prefix##_a9,prefix##_aa,prefix##_ab,prefix##_ac,prefix##_ad,prefix##_ae,prefix##_af, \
735 	prefix##_b0,prefix##_b1,prefix##_b2,prefix##_b3,prefix##_b4,prefix##_b5,prefix##_b6,prefix##_b7, \
736 	prefix##_b8,prefix##_b9,prefix##_ba,prefix##_bb,prefix##_bc,prefix##_bd,prefix##_be,prefix##_bf, \
737 	prefix##_c0,prefix##_c1,prefix##_c2,prefix##_c3,prefix##_c4,prefix##_c5,prefix##_c6,prefix##_c7, \
738 	prefix##_c8,prefix##_c9,prefix##_ca,prefix##_cb,prefix##_cc,prefix##_cd,prefix##_ce,prefix##_cf, \
739 	prefix##_d0,prefix##_d1,prefix##_d2,prefix##_d3,prefix##_d4,prefix##_d5,prefix##_d6,prefix##_d7, \
740 	prefix##_d8,prefix##_d9,prefix##_da,prefix##_db,prefix##_dc,prefix##_dd,prefix##_de,prefix##_df, \
741 	prefix##_e0,prefix##_e1,prefix##_e2,prefix##_e3,prefix##_e4,prefix##_e5,prefix##_e6,prefix##_e7, \
742 	prefix##_e8,prefix##_e9,prefix##_ea,prefix##_eb,prefix##_ec,prefix##_ed,prefix##_ee,prefix##_ef, \
743 	prefix##_f0,prefix##_f1,prefix##_f2,prefix##_f3,prefix##_f4,prefix##_f5,prefix##_f6,prefix##_f7, \
744 	prefix##_f8,prefix##_f9,prefix##_fa,prefix##_fb,prefix##_fc,prefix##_fd,prefix##_fe,prefix##_ff  \
745 }
746 
747 PROTOTYPES(Z80op,op);
748 PROTOTYPES(Z80cb,cb);
749 PROTOTYPES(Z80dd,dd);
750 PROTOTYPES(Z80ed,ed);
751 PROTOTYPES(Z80fd,fd);
752 PROTOTYPES(Z80xycb,xycb);
753 
754 /****************************************************************************/
755 /* Burn an odd amount of cycles, that is instructions taking something      */
756 /* different from 4 T-states per opcode (and R increment)                   */
757 /****************************************************************************/
758 #if 0
759 Z80_INLINE void BURNODD(int cycles, int opcodes, int cyclesum)
760 {
761 	if( cycles > 0 )
762 	{
763 		R += (cycles / cyclesum) * opcodes;
764 		Z80.ICount -= (cycles / cyclesum) * cyclesum;
765 	}
766 }
767 #endif
768 
769 /***************************************************************
770  * define an opcode function
771  ***************************************************************/
772 #define OP(prefix,opcode)  Z80_INLINE void prefix##_##opcode(void)
773 
774 /***************************************************************
775  * adjust cycle count by n T-states
776  ***************************************************************/
777 //#define CC(prefix,opcode) Z80.ICount -= cc[Z80_TABLE_##prefix][opcode]
778 #define CC(prefix,opcode) do { eat_cycles(CYCLES_EXEC, cc[Z80_TABLE_##prefix][opcode]); } while (0)
779 
780 /***************************************************************
781  * execute an opcode
782  ***************************************************************/
783 #define EXEC(prefix,opcode)										\
784 {																\
785 	unsigned op = opcode;										\
786 	CC(prefix,op);												\
787 	(*Z80##prefix[op])();										\
788 }
789 
790 #if BIG_SWITCH
791 #define EXEC_INLINE(prefix,opcode)								\
792 {																\
793 	unsigned op = opcode;										\
794 	CC(prefix,op);												\
795 	switch(op)													\
796 	{															\
797 	case 0x00:prefix##_##00();break; case 0x01:prefix##_##01();break; case 0x02:prefix##_##02();break; case 0x03:prefix##_##03();break; \
798 	case 0x04:prefix##_##04();break; case 0x05:prefix##_##05();break; case 0x06:prefix##_##06();break; case 0x07:prefix##_##07();break; \
799 	case 0x08:prefix##_##08();break; case 0x09:prefix##_##09();break; case 0x0a:prefix##_##0a();break; case 0x0b:prefix##_##0b();break; \
800 	case 0x0c:prefix##_##0c();break; case 0x0d:prefix##_##0d();break; case 0x0e:prefix##_##0e();break; case 0x0f:prefix##_##0f();break; \
801 	case 0x10:prefix##_##10();break; case 0x11:prefix##_##11();break; case 0x12:prefix##_##12();break; case 0x13:prefix##_##13();break; \
802 	case 0x14:prefix##_##14();break; case 0x15:prefix##_##15();break; case 0x16:prefix##_##16();break; case 0x17:prefix##_##17();break; \
803 	case 0x18:prefix##_##18();break; case 0x19:prefix##_##19();break; case 0x1a:prefix##_##1a();break; case 0x1b:prefix##_##1b();break; \
804 	case 0x1c:prefix##_##1c();break; case 0x1d:prefix##_##1d();break; case 0x1e:prefix##_##1e();break; case 0x1f:prefix##_##1f();break; \
805 	case 0x20:prefix##_##20();break; case 0x21:prefix##_##21();break; case 0x22:prefix##_##22();break; case 0x23:prefix##_##23();break; \
806 	case 0x24:prefix##_##24();break; case 0x25:prefix##_##25();break; case 0x26:prefix##_##26();break; case 0x27:prefix##_##27();break; \
807 	case 0x28:prefix##_##28();break; case 0x29:prefix##_##29();break; case 0x2a:prefix##_##2a();break; case 0x2b:prefix##_##2b();break; \
808 	case 0x2c:prefix##_##2c();break; case 0x2d:prefix##_##2d();break; case 0x2e:prefix##_##2e();break; case 0x2f:prefix##_##2f();break; \
809 	case 0x30:prefix##_##30();break; case 0x31:prefix##_##31();break; case 0x32:prefix##_##32();break; case 0x33:prefix##_##33();break; \
810 	case 0x34:prefix##_##34();break; case 0x35:prefix##_##35();break; case 0x36:prefix##_##36();break; case 0x37:prefix##_##37();break; \
811 	case 0x38:prefix##_##38();break; case 0x39:prefix##_##39();break; case 0x3a:prefix##_##3a();break; case 0x3b:prefix##_##3b();break; \
812 	case 0x3c:prefix##_##3c();break; case 0x3d:prefix##_##3d();break; case 0x3e:prefix##_##3e();break; case 0x3f:prefix##_##3f();break; \
813 	case 0x40:prefix##_##40();break; case 0x41:prefix##_##41();break; case 0x42:prefix##_##42();break; case 0x43:prefix##_##43();break; \
814 	case 0x44:prefix##_##44();break; case 0x45:prefix##_##45();break; case 0x46:prefix##_##46();break; case 0x47:prefix##_##47();break; \
815 	case 0x48:prefix##_##48();break; case 0x49:prefix##_##49();break; case 0x4a:prefix##_##4a();break; case 0x4b:prefix##_##4b();break; \
816 	case 0x4c:prefix##_##4c();break; case 0x4d:prefix##_##4d();break; case 0x4e:prefix##_##4e();break; case 0x4f:prefix##_##4f();break; \
817 	case 0x50:prefix##_##50();break; case 0x51:prefix##_##51();break; case 0x52:prefix##_##52();break; case 0x53:prefix##_##53();break; \
818 	case 0x54:prefix##_##54();break; case 0x55:prefix##_##55();break; case 0x56:prefix##_##56();break; case 0x57:prefix##_##57();break; \
819 	case 0x58:prefix##_##58();break; case 0x59:prefix##_##59();break; case 0x5a:prefix##_##5a();break; case 0x5b:prefix##_##5b();break; \
820 	case 0x5c:prefix##_##5c();break; case 0x5d:prefix##_##5d();break; case 0x5e:prefix##_##5e();break; case 0x5f:prefix##_##5f();break; \
821 	case 0x60:prefix##_##60();break; case 0x61:prefix##_##61();break; case 0x62:prefix##_##62();break; case 0x63:prefix##_##63();break; \
822 	case 0x64:prefix##_##64();break; case 0x65:prefix##_##65();break; case 0x66:prefix##_##66();break; case 0x67:prefix##_##67();break; \
823 	case 0x68:prefix##_##68();break; case 0x69:prefix##_##69();break; case 0x6a:prefix##_##6a();break; case 0x6b:prefix##_##6b();break; \
824 	case 0x6c:prefix##_##6c();break; case 0x6d:prefix##_##6d();break; case 0x6e:prefix##_##6e();break; case 0x6f:prefix##_##6f();break; \
825 	case 0x70:prefix##_##70();break; case 0x71:prefix##_##71();break; case 0x72:prefix##_##72();break; case 0x73:prefix##_##73();break; \
826 	case 0x74:prefix##_##74();break; case 0x75:prefix##_##75();break; case 0x76:prefix##_##76();break; case 0x77:prefix##_##77();break; \
827 	case 0x78:prefix##_##78();break; case 0x79:prefix##_##79();break; case 0x7a:prefix##_##7a();break; case 0x7b:prefix##_##7b();break; \
828 	case 0x7c:prefix##_##7c();break; case 0x7d:prefix##_##7d();break; case 0x7e:prefix##_##7e();break; case 0x7f:prefix##_##7f();break; \
829 	case 0x80:prefix##_##80();break; case 0x81:prefix##_##81();break; case 0x82:prefix##_##82();break; case 0x83:prefix##_##83();break; \
830 	case 0x84:prefix##_##84();break; case 0x85:prefix##_##85();break; case 0x86:prefix##_##86();break; case 0x87:prefix##_##87();break; \
831 	case 0x88:prefix##_##88();break; case 0x89:prefix##_##89();break; case 0x8a:prefix##_##8a();break; case 0x8b:prefix##_##8b();break; \
832 	case 0x8c:prefix##_##8c();break; case 0x8d:prefix##_##8d();break; case 0x8e:prefix##_##8e();break; case 0x8f:prefix##_##8f();break; \
833 	case 0x90:prefix##_##90();break; case 0x91:prefix##_##91();break; case 0x92:prefix##_##92();break; case 0x93:prefix##_##93();break; \
834 	case 0x94:prefix##_##94();break; case 0x95:prefix##_##95();break; case 0x96:prefix##_##96();break; case 0x97:prefix##_##97();break; \
835 	case 0x98:prefix##_##98();break; case 0x99:prefix##_##99();break; case 0x9a:prefix##_##9a();break; case 0x9b:prefix##_##9b();break; \
836 	case 0x9c:prefix##_##9c();break; case 0x9d:prefix##_##9d();break; case 0x9e:prefix##_##9e();break; case 0x9f:prefix##_##9f();break; \
837 	case 0xa0:prefix##_##a0();break; case 0xa1:prefix##_##a1();break; case 0xa2:prefix##_##a2();break; case 0xa3:prefix##_##a3();break; \
838 	case 0xa4:prefix##_##a4();break; case 0xa5:prefix##_##a5();break; case 0xa6:prefix##_##a6();break; case 0xa7:prefix##_##a7();break; \
839 	case 0xa8:prefix##_##a8();break; case 0xa9:prefix##_##a9();break; case 0xaa:prefix##_##aa();break; case 0xab:prefix##_##ab();break; \
840 	case 0xac:prefix##_##ac();break; case 0xad:prefix##_##ad();break; case 0xae:prefix##_##ae();break; case 0xaf:prefix##_##af();break; \
841 	case 0xb0:prefix##_##b0();break; case 0xb1:prefix##_##b1();break; case 0xb2:prefix##_##b2();break; case 0xb3:prefix##_##b3();break; \
842 	case 0xb4:prefix##_##b4();break; case 0xb5:prefix##_##b5();break; case 0xb6:prefix##_##b6();break; case 0xb7:prefix##_##b7();break; \
843 	case 0xb8:prefix##_##b8();break; case 0xb9:prefix##_##b9();break; case 0xba:prefix##_##ba();break; case 0xbb:prefix##_##bb();break; \
844 	case 0xbc:prefix##_##bc();break; case 0xbd:prefix##_##bd();break; case 0xbe:prefix##_##be();break; case 0xbf:prefix##_##bf();break; \
845 	case 0xc0:prefix##_##c0();break; case 0xc1:prefix##_##c1();break; case 0xc2:prefix##_##c2();break; case 0xc3:prefix##_##c3();break; \
846 	case 0xc4:prefix##_##c4();break; case 0xc5:prefix##_##c5();break; case 0xc6:prefix##_##c6();break; case 0xc7:prefix##_##c7();break; \
847 	case 0xc8:prefix##_##c8();break; case 0xc9:prefix##_##c9();break; case 0xca:prefix##_##ca();break; case 0xcb:prefix##_##cb();break; \
848 	case 0xcc:prefix##_##cc();break; case 0xcd:prefix##_##cd();break; case 0xce:prefix##_##ce();break; case 0xcf:prefix##_##cf();break; \
849 	case 0xd0:prefix##_##d0();break; case 0xd1:prefix##_##d1();break; case 0xd2:prefix##_##d2();break; case 0xd3:prefix##_##d3();break; \
850 	case 0xd4:prefix##_##d4();break; case 0xd5:prefix##_##d5();break; case 0xd6:prefix##_##d6();break; case 0xd7:prefix##_##d7();break; \
851 	case 0xd8:prefix##_##d8();break; case 0xd9:prefix##_##d9();break; case 0xda:prefix##_##da();break; case 0xdb:prefix##_##db();break; \
852 	case 0xdc:prefix##_##dc();break; case 0xdd:prefix##_##dd();break; case 0xde:prefix##_##de();break; case 0xdf:prefix##_##df();break; \
853 	case 0xe0:prefix##_##e0();break; case 0xe1:prefix##_##e1();break; case 0xe2:prefix##_##e2();break; case 0xe3:prefix##_##e3();break; \
854 	case 0xe4:prefix##_##e4();break; case 0xe5:prefix##_##e5();break; case 0xe6:prefix##_##e6();break; case 0xe7:prefix##_##e7();break; \
855 	case 0xe8:prefix##_##e8();break; case 0xe9:prefix##_##e9();break; case 0xea:prefix##_##ea();break; case 0xeb:prefix##_##eb();break; \
856 	case 0xec:prefix##_##ec();break; case 0xed:prefix##_##ed();break; case 0xee:prefix##_##ee();break; case 0xef:prefix##_##ef();break; \
857 	case 0xf0:prefix##_##f0();break; case 0xf1:prefix##_##f1();break; case 0xf2:prefix##_##f2();break; case 0xf3:prefix##_##f3();break; \
858 	case 0xf4:prefix##_##f4();break; case 0xf5:prefix##_##f5();break; case 0xf6:prefix##_##f6();break; case 0xf7:prefix##_##f7();break; \
859 	case 0xf8:prefix##_##f8();break; case 0xf9:prefix##_##f9();break; case 0xfa:prefix##_##fa();break; case 0xfb:prefix##_##fb();break; \
860 	case 0xfc:prefix##_##fc();break; case 0xfd:prefix##_##fd();break; case 0xfe:prefix##_##fe();break; case 0xff:prefix##_##ff();break; \
861 	}																																	\
862 }
863 #else
864 #define EXEC_Z80_INLINE EXEC
865 #endif
866 
867 
868 /***************************************************************
869  * Enter HALT state; write 1 to fake port on first execution
870  ***************************************************************/
871 #define ENTER_HALT {											\
872 	PC--;														\
873 	HALT = 1;													\
874 }
875 
876 /***************************************************************
877  * Leave HALT state; write 0 to fake port
878  ***************************************************************/
879 #define LEAVE_HALT {											\
880 	if( HALT )													\
881 	{															\
882 		HALT = 0;												\
883 		PC++;													\
884 	}															\
885 }
886 
887 /***************************************************************
888  * Input a byte from given I/O port
889  ***************************************************************/
IN(INT16 port)890 Z80_INLINE UINT8 IN(INT16 port)
891 {
892 	// For floating bus support, the read_byte triggers the
893 	// 'spectrum_port_ula_r' callback which will require the tstate
894 	// counter to be up-to-date.
895 	store_rwinfo(port, -1, RWINFO_READ|RWINFO_IO_PORT, "in port");
896 	return Z80IORead(port);
897 }
898 
899 /***************************************************************
900  * Output a byte to given I/O port
901  ***************************************************************/
902 //#define OUT(port,value) Z80IOWrite(port,value)
OUT(UINT16 port,UINT8 value)903 Z80_INLINE void OUT(UINT16 port, UINT8 value)
904 {
905 	store_rwinfo(port, value, RWINFO_WRITE|RWINFO_IO_PORT, "out port");
906 	Z80IOWrite(port, value);
907 }
908 
909 /***************************************************************
910  * Read a byte from given memory location
911  ***************************************************************/
912 //#define RM(addr) (UINT8)Z80ProgramRead(addr)
RM(UINT16 addr)913 Z80_INLINE UINT8 RM(UINT16 addr)
914 {
915 	UINT8 res = Z80ProgramRead(addr);
916 	store_rwinfo(addr, res, RWINFO_READ|RWINFO_MEMORY, "rm");
917 	return res;
918 }
919 
920 /***************************************************************
921  * Read a word from given memory location
922  ***************************************************************/
RM16(UINT32 addr,Z80_PAIR * r)923 Z80_INLINE void RM16( UINT32 addr, Z80_PAIR *r )
924 {
925 	r->b.l = RM(addr);
926 	r->b.h = RM((addr+1)&0xffff);
927 }
928 
929 /***************************************************************
930  * Write a byte to given memory location
931  ***************************************************************/
932 //#define WM(addr,value) Z80ProgramWrite(addr,value)
WM(UINT16 addr,UINT8 value)933 Z80_INLINE void WM(UINT16 addr, UINT8 value)
934 {
935 	store_rwinfo(addr, value, RWINFO_WRITE|RWINFO_MEMORY, "wm");
936 	Z80ProgramWrite(addr,value);
937 }
938 
939 #define cpu_readop(n) Z80CPUReadOp(n)
940 #define cpu_readop_arg(n) Z80CPUReadOpArg(n)
941 
942 /***************************************************************
943  * Write a word to given memory location
944  ***************************************************************/
WM16(UINT32 addr,Z80_PAIR * r)945 Z80_INLINE void WM16( UINT32 addr, Z80_PAIR *r )
946 {
947 	WM(addr,r->b.l);
948 	WM((addr+1)&0xffff,r->b.h);
949 }
950 
951 /***************************************************************
952  * ROP() is identical to RM() except it is used for
953  * reading opcodes. In case of system with memory mapped I/O,
954  * this function can be used to greatly speed up emulation
955  ***************************************************************/
ROP(void)956 Z80_INLINE UINT8 ROP(void)
957 {
958 	unsigned pc = PCD;
959 	PC++;
960 	UINT8 res = cpu_readop(pc);
961 	store_rwinfo(((PAIR*)(&pc))->w.l, res, RWINFO_READ|RWINFO_MEMORY, "rop");
962 	return res;
963 }
964 
965 /****************************************************************
966  * ARG() is identical to ROP() except it is used
967  * for reading opcode arguments. This difference can be used to
968  * support systems that use different encoding mechanisms for
969  * opcodes and opcode arguments
970  ***************************************************************/
ARG(void)971 Z80_INLINE UINT8 ARG(void)
972 {
973 	unsigned pc = PCD;
974 	PC++;
975 
976 	UINT8 res = cpu_readop_arg(pc);
977 	store_rwinfo(((PAIR*)(&pc))->w.l, res, RWINFO_READ|RWINFO_MEMORY, "arg");
978 
979 	return res;
980 }
981 
ARG16(void)982 Z80_INLINE UINT16 ARG16(void)
983 {
984 	unsigned pc1 = PCD;
985 	unsigned pc2 = (pc1+1)&0xffff;
986 	PC += 2;
987 	UINT8 res1 = cpu_readop_arg(pc1);
988 	store_rwinfo(((PAIR*)(&pc1))->w.l, res1, RWINFO_READ|RWINFO_MEMORY, "arg16 byte1");
989 	UINT8 res2 = cpu_readop_arg(pc2);
990 	store_rwinfo(((PAIR*)(&pc2))->w.l, res2, RWINFO_READ|RWINFO_MEMORY, "arg16 byte2");
991 
992 	return res1 | (res2 << 8);
993 }
994 
995 /***************************************************************
996  * Calculate the effective address EA of an opcode using
997  * IX+offset resp. IY+offset addressing.
998  ***************************************************************/
999 #define EAX EA = (UINT32)(UINT16)(IX + (INT8)ARG()); WZ = EA;
1000 #define EAY EA = (UINT32)(UINT16)(IY + (INT8)ARG()); WZ = EA;
1001 
1002 /***************************************************************
1003  * POP
1004  ***************************************************************/
1005 #define POP(DR) do { RM16( SPD, &Z80.DR ); SP += 2; } while (0)
1006 
1007 /***************************************************************
1008  * PUSH
1009  ***************************************************************/
1010 #define PUSH(SR) do { SP --; WM( SPD, Z80.SR.b.h ); SP --; WM( SPD, Z80.SR.b.l ); } while (0)
1011 
1012 /***************************************************************
1013  * JP
1014  ***************************************************************/
1015 #define JP {													\
1016 	PCD = ARG16();												\
1017 	WZ = PCD;													\
1018 	change_pc(PCD);												\
1019 }
1020 
1021 /***************************************************************
1022  * JP_COND
1023  ***************************************************************/
1024 
1025 #define JP_COND(cond)											\
1026 	if( cond )													\
1027 	{															\
1028 		PCD = ARG16();											\
1029 		WZ = PCD;												\
1030 		change_pc(PCD);											\
1031 	}															\
1032 	else														\
1033 	{															\
1034 		WZ = ARG16(); /* implicit do PC += 2 */                 \
1035 	}
1036 
1037 /***************************************************************
1038  * JR
1039  ***************************************************************/
1040 #define JR()													\
1041 {																\
1042 	INT8 arg = (INT8)ARG(); /* ARG() also increments PC */		\
1043 	PC += arg;				/* so don't do PC += ARG() */		\
1044 	WZ = PC;													\
1045 	change_pc(PCD);												\
1046 }
1047 
1048 /***************************************************************
1049  * JR_COND
1050  ***************************************************************/
1051 #define JR_COND(cond,opcode)									\
1052 	if( cond )													\
1053 	{															\
1054 		CC(ex,opcode);											\
1055 		m_opcode_history.do_optional = true;                    \
1056 		run_script();                                           \
1057 																\
1058 		JR()                                                    \
1059 	}															\
1060 	else                                                        \
1061 	{                                                           \
1062 		ARG();													\
1063 	}
1064 
1065 /***************************************************************
1066  * CALL
1067  ***************************************************************/
1068 #define CALL()													\
1069 	EA = ARG16();												\
1070 	WZ = EA;													\
1071 	PUSH( pc );													\
1072 	PCD = EA;													\
1073 	change_pc(PCD)
1074 
1075 /***************************************************************
1076  * CALL_COND
1077  ***************************************************************/
1078 #define CALL_COND(cond,opcode)									\
1079 	if( cond )													\
1080 	{															\
1081 		CC(ex,opcode);											\
1082 		m_opcode_history.do_optional = true;                    \
1083 		run_script();                                           \
1084 		EA = ARG16();											\
1085 	    WZ = EA;												\
1086 		PUSH( pc );												\
1087 		PCD = EA;												\
1088 		change_pc(PCD);											\
1089 	}															\
1090 	else														\
1091 	{															\
1092 		WZ = ARG16(); /* implicit call PC+=2; */				\
1093 	}
1094 
1095 /***************************************************************
1096  * RET_COND
1097  ***************************************************************/
1098 #define RET_COND(cond,opcode)									\
1099 	if( cond )													\
1100 	{															\
1101 		CC(ex,opcode);											\
1102 		m_opcode_history.do_optional = true;                    \
1103 		run_script();                                           \
1104 		POP( pc );												\
1105 		WZ = PC;												\
1106 		change_pc(PCD);											\
1107 	}
1108 
1109 // zx spectrum tapeload bios callback for opcode 0xc0 (ret nz) -dink sept.29 2020
RET_COND_SPECTRUM(int cond,UINT8 opcode)1110 static inline void RET_COND_SPECTRUM(int cond, UINT8 opcode)
1111 {
1112 	if (Z80.spectrum_mode && PRVPC == 0x056b /* LD-BYTES Hook */)
1113 	{
1114 		cond = Z80.spectrum_tape_cb();
1115 	}
1116 
1117 	if( cond )
1118 	{
1119 		CC(ex,opcode);
1120 		m_opcode_history.do_optional = true;
1121 		run_script();
1122 		POP( pc );
1123 		WZ = PC;
1124 		change_pc(PCD);
1125 	}
1126 }
1127 
1128 /***************************************************************
1129  * RETN
1130  ***************************************************************/
1131 #define RETN	{												\
1132 	LOG(("Z80 #%d RETN IFF1:%d IFF2:%d\n", cpu_getactivecpu(), IFF1, IFF2)); \
1133 	POP( pc );													\
1134 	WZ = PC;													\
1135 	change_pc(PCD);												\
1136 	IFF1 = IFF2;												\
1137 }
1138 
1139 /***************************************************************
1140  * RETI
1141  ***************************************************************/
1142 #define RETI	{												\
1143 	POP( pc );													\
1144 	WZ = PC;													\
1145 	change_pc(PCD);												\
1146 /* according to http://www.msxnet.org/tech/z80-documented.pdf */\
1147 	IFF1 = IFF2;												\
1148     if (Z80.daisy)												\
1149 		z80daisy_call_reti_device(Z80.daisy);					\
1150 }
1151 
1152 /***************************************************************
1153  * LD   R,A
1154  ***************************************************************/
1155 #define LD_R_A {												\
1156 	R = A;														\
1157 	R2 = A & 0x80;				/* keep bit 7 of R */			\
1158 }
1159 
1160 /***************************************************************
1161  * LD   A,R
1162  ***************************************************************/
1163 #define LD_A_R {												\
1164 	A = (R & 0x7f) | R2;										\
1165 	F = (F & CF) | SZ[A] | ( IFF2 << 2 );						\
1166 }
1167 
1168 /***************************************************************
1169  * LD   I,A
1170  ***************************************************************/
1171 #define LD_I_A {												\
1172 	I = A;														\
1173 }
1174 
1175 /***************************************************************
1176  * LD   A,I
1177  ***************************************************************/
1178 #define LD_A_I {												\
1179 	A = I;														\
1180 	F = (F & CF) | SZ[A] | ( IFF2 << 2 );						\
1181 }
1182 
1183 /***************************************************************
1184  * RST
1185  ***************************************************************/
1186 #define RST(addr)												\
1187 	PUSH( pc );													\
1188 	PCD = addr;													\
1189 	WZ = PC;													\
1190 	change_pc(PCD)
1191 
1192 /***************************************************************
1193  * INC  r8
1194  ***************************************************************/
INC(UINT8 value)1195 Z80_INLINE UINT8 INC(UINT8 value)
1196 {
1197 	UINT8 res = value + 1;
1198 	F = (F & CF) | SZHV_inc[res];
1199 	return (UINT8)res;
1200 }
1201 
1202 /***************************************************************
1203  * DEC  r8
1204  ***************************************************************/
DEC(UINT8 value)1205 Z80_INLINE UINT8 DEC(UINT8 value)
1206 {
1207 	UINT8 res = value - 1;
1208 	F = (F & CF) | SZHV_dec[res];
1209 	return res;
1210 }
1211 
1212 /***************************************************************
1213  * RLCA
1214  ***************************************************************/
1215 #define RLCA													\
1216 	A = (A << 1) | (A >> 7);									\
1217 	F = (F & (SF | ZF | PF)) | (A & (YF | XF | CF))
1218 
1219 /***************************************************************
1220  * RRCA
1221  ***************************************************************/
1222 #define RRCA													\
1223 	F = (F & (SF | ZF | PF)) | (A & CF);						\
1224 	A = (A >> 1) | (A << 7);									\
1225 	F |= (A & (YF | XF) )
1226 
1227 /***************************************************************
1228  * RLA
1229  ***************************************************************/
1230 #define RLA {													\
1231 	UINT8 res = (A << 1) | (F & CF);							\
1232 	UINT8 c = (A & 0x80) ? CF : 0;								\
1233 	F = (F & (SF | ZF | PF)) | c | (res & (YF | XF));			\
1234 	A = res;													\
1235 }
1236 
1237 /***************************************************************
1238  * RRA
1239  ***************************************************************/
1240 #define RRA {													\
1241 	UINT8 res = (A >> 1) | (F << 7);							\
1242 	UINT8 c = (A & 0x01) ? CF : 0;								\
1243 	F = (F & (SF | ZF | PF)) | c | (res & (YF | XF));			\
1244 	A = res;													\
1245 }
1246 
1247 /***************************************************************
1248  * RRD
1249  ***************************************************************/
1250 #define RRD {													\
1251 	UINT8 n = RM(HL);											\
1252 	WZ = HL+1;													\
1253 	WM( HL, (n >> 4) | (A << 4) );								\
1254 	A = (A & 0xf0) | (n & 0x0f);								\
1255 	F = (F & CF) | SZP[A];										\
1256 }
1257 
1258 /***************************************************************
1259  * RLD
1260  ***************************************************************/
1261 #define RLD {													\
1262 	UINT8 n = RM(HL);											\
1263 	WZ = HL+1;													\
1264 	WM( HL, (n << 4) | (A & 0x0f) );							\
1265 	A = (A & 0xf0) | (n >> 4);									\
1266 	F = (F & CF) | SZP[A];										\
1267 }
1268 
1269 /***************************************************************
1270  * ADD  A,n
1271  ***************************************************************/
1272 #if BIG_FLAGS_ARRAY
1273 #define ADD(value)												\
1274 {																\
1275 	UINT32 ah = AFD & 0xff00;									\
1276 	UINT32 res = (UINT8)((ah >> 8) + value);					\
1277 	F = SZHVC_add[ah | res];									\
1278 	A = res;													\
1279 }
1280 #else
1281 #define ADD(value)												\
1282 {																\
1283 	unsigned val = value;										\
1284 	unsigned res = A + val;										\
1285 	F = SZ[(UINT8)res] | ((res >> 8) & CF) |					\
1286 		((A ^ res ^ val) & HF) |								\
1287 		(((val ^ A ^ 0x80) & (val ^ res) & 0x80) >> 5);			\
1288 	A = (UINT8)res;												\
1289 }
1290 #endif
1291 
1292 /***************************************************************
1293  * ADC  A,n
1294  ***************************************************************/
1295 #if BIG_FLAGS_ARRAY
1296 #define ADC(value)												\
1297 {																\
1298 	UINT32 ah = AFD & 0xff00, c = AFD & 1;						\
1299 	UINT32 res = (UINT8)((ah >> 8) + value + c);				\
1300 	F = SZHVC_add[(c << 16) | ah | res];						\
1301 	A = res;													\
1302 }
1303 #else
1304 #define ADC(value)												\
1305 {																\
1306 	unsigned val = value;										\
1307 	unsigned res = A + val + (F & CF);							\
1308 	F = SZ[res & 0xff] | ((res >> 8) & CF) |					\
1309 		((A ^ res ^ val) & HF) |								\
1310 		(((val ^ A ^ 0x80) & (val ^ res) & 0x80) >> 5);			\
1311 	A = res;													\
1312 }
1313 #endif
1314 
1315 /***************************************************************
1316  * SUB  n
1317  ***************************************************************/
1318 #if BIG_FLAGS_ARRAY
1319 #define SUB(value)												\
1320 {																\
1321 	UINT32 ah = AFD & 0xff00;									\
1322 	UINT32 res = (UINT8)((ah >> 8) - value);					\
1323 	F = SZHVC_sub[ah | res];									\
1324 	A = res;													\
1325 }
1326 #else
1327 #define SUB(value)												\
1328 {																\
1329 	unsigned val = value;										\
1330 	unsigned res = A - val;										\
1331 	F = SZ[res & 0xff] | ((res >> 8) & CF) | NF |				\
1332 		((A ^ res ^ val) & HF) |								\
1333 		(((val ^ A) & (A ^ res) & 0x80) >> 5);					\
1334 	A = res;													\
1335 }
1336 #endif
1337 
1338 /***************************************************************
1339  * SBC  A,n
1340  ***************************************************************/
1341 #if BIG_FLAGS_ARRAY
1342 #define SBC(value)												\
1343 {																\
1344 	UINT32 ah = AFD & 0xff00, c = AFD & 1;						\
1345 	UINT32 res = (UINT8)((ah >> 8) - value - c);				\
1346 	F = SZHVC_sub[(c<<16) | ah | res];							\
1347 	A = res;													\
1348 }
1349 #else
1350 #define SBC(value)												\
1351 {																\
1352 	unsigned val = value;										\
1353 	unsigned res = A - val - (F & CF);							\
1354 	F = SZ[res & 0xff] | ((res >> 8) & CF) | NF |				\
1355 		((A ^ res ^ val) & HF) |								\
1356 		(((val ^ A) & (A ^ res) & 0x80) >> 5);					\
1357 	A = res;													\
1358 }
1359 #endif
1360 
1361 /***************************************************************
1362  * NEG
1363  ***************************************************************/
1364 #define NEG {													\
1365 	UINT8 value = A;											\
1366 	A = 0;														\
1367 	SUB(value);													\
1368 }
1369 
1370 /***************************************************************
1371  * DAA
1372  ***************************************************************/
1373 #define DAA {													\
1374 	UINT8 a = A;                                                \
1375 	if (F & NF) {                                               \
1376 		if ((F&HF) | ((A&0xf)>9)) a-=6;                         \
1377 		if ((F&CF) | (A>0x99)) a-=0x60;                         \
1378 	}                                                           \
1379 	else {                                                      \
1380 		if ((F&HF) | ((A&0xf)>9)) a+=6;                         \
1381 		if ((F&CF) | (A>0x99)) a+=0x60;                         \
1382 	}                                                           \
1383 																\
1384 	F = (F&(CF|NF)) | (A>0x99) | ((A^a)&HF) | SZP[a];           \
1385 	A = a;                                                      \
1386 }
1387 
1388 /***************************************************************
1389  * AND  n
1390  ***************************************************************/
1391 #define AND(value)												\
1392 	A &= value;													\
1393 	F = SZP[A] | HF
1394 
1395 /***************************************************************
1396  * OR   n
1397  ***************************************************************/
1398 #define OR(value)												\
1399 	A |= value;													\
1400 	F = SZP[A]
1401 
1402 /***************************************************************
1403  * XOR  n
1404  ***************************************************************/
1405 #define XOR(value)												\
1406 	A ^= value;													\
1407 	F = SZP[A]
1408 
1409 /***************************************************************
1410  * CP   n
1411  ***************************************************************/
1412 #if BIG_FLAGS_ARRAY
1413 #define CP(value)												\
1414 {																\
1415 	unsigned val = value;										\
1416 	UINT32 ah = AFD & 0xff00;									\
1417 	UINT32 res = (UINT8)((ah >> 8) - val);						\
1418 	F = (SZHVC_sub[ah | res] & ~(YF | XF)) |					\
1419 		(val & (YF | XF));										\
1420 }
1421 #else
1422 #define CP(value)												\
1423 {																\
1424 	unsigned val = value;										\
1425 	unsigned res = A - val;										\
1426 	F = (SZ[res & 0xff] & (SF | ZF)) |							\
1427 		(val & (YF | XF)) | ((res >> 8) & CF) | NF |			\
1428 		((A ^ res ^ val) & HF) |								\
1429 		((((val ^ A) & (A ^ res)) >> 5) & VF);					\
1430 }
1431 #endif
1432 
1433 /***************************************************************
1434  * EX   AF,AF'
1435  ***************************************************************/
1436 #define EX_AF {													\
1437 	Z80_PAIR tmp;													\
1438 	tmp = Z80.af; Z80.af = Z80.af2; Z80.af2 = tmp;				\
1439 }
1440 
1441 /***************************************************************
1442  * EX   DE,HL
1443  ***************************************************************/
1444 #define EX_DE_HL {												\
1445 	Z80_PAIR tmp;													\
1446 	tmp = Z80.de; Z80.de = Z80.hl; Z80.hl = tmp;				\
1447 }
1448 
1449 /***************************************************************
1450  * EXX
1451  ***************************************************************/
1452 #define EXX {													\
1453 	Z80_PAIR tmp;													\
1454 	tmp = Z80.bc; Z80.bc = Z80.bc2; Z80.bc2 = tmp;				\
1455 	tmp = Z80.de; Z80.de = Z80.de2; Z80.de2 = tmp;				\
1456 	tmp = Z80.hl; Z80.hl = Z80.hl2; Z80.hl2 = tmp;				\
1457 }
1458 
1459 /***************************************************************
1460  * EX   (SP),r16
1461  ***************************************************************/
1462 #define EXSP(DR)												\
1463 {																\
1464 	Z80_PAIR tmp = { { 0, 0, 0, 0 } };								\
1465 	RM16( SPD, &tmp );											\
1466 	WM16( SPD, &Z80.DR );										\
1467 	Z80.DR = tmp;												\
1468 	WZ = Z80.DR.d;													\
1469 }
1470 
1471 
1472 /***************************************************************
1473  * ADD16
1474  ***************************************************************/
1475 #define ADD16(DR,SR)											\
1476 {																\
1477 	UINT32 res = Z80.DR.d + Z80.SR.d;							\
1478 	WZ = Z80.DR.d + 1;												\
1479 	F = (F & (SF | ZF | VF)) |									\
1480 		(((Z80.DR.d ^ res ^ Z80.SR.d) >> 8) & HF) |				\
1481 		((res >> 16) & CF) | ((res >> 8) & (YF | XF));			\
1482 	Z80.DR.w.l = (UINT16)res;									\
1483 }
1484 
1485 /***************************************************************
1486  * ADC  r16,r16
1487  ***************************************************************/
1488 #define ADC16(Reg)												\
1489 {																\
1490 	UINT32 res = HLD + Z80.Reg.d + (F & CF);					\
1491 	WZ = HL + 1;												\
1492 	F = (((HLD ^ res ^ Z80.Reg.d) >> 8) & HF) |					\
1493 		((res >> 16) & CF) |									\
1494 		((res >> 8) & (SF | YF | XF)) |							\
1495 		((res & 0xffff) ? 0 : ZF) |								\
1496 		(((Z80.Reg.d ^ HLD ^ 0x8000) & (Z80.Reg.d ^ res) & 0x8000) >> 13); \
1497 	HL = (UINT16)res;											\
1498 }
1499 
1500 /***************************************************************
1501  * SBC  r16,r16
1502  ***************************************************************/
1503 #define SBC16(Reg)												\
1504 {																\
1505 	UINT32 res = HLD - Z80.Reg.d - (F & CF);					\
1506 	WZ = HL + 1;												\
1507 	F = (((HLD ^ res ^ Z80.Reg.d) >> 8) & HF) | NF |			\
1508 		((res >> 16) & CF) |									\
1509 		((res >> 8) & (SF | YF | XF)) |							\
1510 		((res & 0xffff) ? 0 : ZF) |								\
1511 		(((Z80.Reg.d ^ HLD) & (HLD ^ res) &0x8000) >> 13);		\
1512 	HL = (UINT16)res;											\
1513 }
1514 
1515 /***************************************************************
1516  * RLC  r8
1517  ***************************************************************/
RLC(UINT8 value)1518 Z80_INLINE UINT8 RLC(UINT8 value)
1519 {
1520 	unsigned res = value;
1521 	unsigned c = (res & 0x80) ? CF : 0;
1522 	res = ((res << 1) | (res >> 7)) & 0xff;
1523 	F = SZP[res] | c;
1524 	return res;
1525 }
1526 
1527 /***************************************************************
1528  * RRC  r8
1529  ***************************************************************/
RRC(UINT8 value)1530 Z80_INLINE UINT8 RRC(UINT8 value)
1531 {
1532 	unsigned res = value;
1533 	unsigned c = (res & 0x01) ? CF : 0;
1534 	res = ((res >> 1) | (res << 7)) & 0xff;
1535 	F = SZP[res] | c;
1536 	return res;
1537 }
1538 
1539 /***************************************************************
1540  * RL   r8
1541  ***************************************************************/
RL(UINT8 value)1542 Z80_INLINE UINT8 RL(UINT8 value)
1543 {
1544 	unsigned res = value;
1545 	unsigned c = (res & 0x80) ? CF : 0;
1546 	res = ((res << 1) | (F & CF)) & 0xff;
1547 	F = SZP[res] | c;
1548 	return res;
1549 }
1550 
1551 /***************************************************************
1552  * RR   r8
1553  ***************************************************************/
RR(UINT8 value)1554 Z80_INLINE UINT8 RR(UINT8 value)
1555 {
1556 	unsigned res = value;
1557 	unsigned c = (res & 0x01) ? CF : 0;
1558 	res = ((res >> 1) | (F << 7)) & 0xff;
1559 	F = SZP[res] | c;
1560 	return res;
1561 }
1562 
1563 /***************************************************************
1564  * SLA  r8
1565  ***************************************************************/
SLA(UINT8 value)1566 Z80_INLINE UINT8 SLA(UINT8 value)
1567 {
1568 	unsigned res = value;
1569 	unsigned c = (res & 0x80) ? CF : 0;
1570 	res = (res << 1) & 0xff;
1571 	F = SZP[res] | c;
1572 	return res;
1573 }
1574 
1575 /***************************************************************
1576  * SRA  r8
1577  ***************************************************************/
SRA(UINT8 value)1578 Z80_INLINE UINT8 SRA(UINT8 value)
1579 {
1580 	unsigned res = value;
1581 	unsigned c = (res & 0x01) ? CF : 0;
1582 	res = ((res >> 1) | (res & 0x80)) & 0xff;
1583 	F = SZP[res] | c;
1584 	return res;
1585 }
1586 
1587 /***************************************************************
1588  * SLL  r8
1589  ***************************************************************/
SLL(UINT8 value)1590 Z80_INLINE UINT8 SLL(UINT8 value)
1591 {
1592 	unsigned res = value;
1593 	unsigned c = (res & 0x80) ? CF : 0;
1594 	res = ((res << 1) | 0x01) & 0xff;
1595 	F = SZP[res] | c;
1596 	return res;
1597 }
1598 
1599 /***************************************************************
1600  * SRL  r8
1601  ***************************************************************/
SRL(UINT8 value)1602 Z80_INLINE UINT8 SRL(UINT8 value)
1603 {
1604 	unsigned res = value;
1605 	unsigned c = (res & 0x01) ? CF : 0;
1606 	res = (res >> 1) & 0xff;
1607 	F = SZP[res] | c;
1608 	return res;
1609 }
1610 
1611 /***************************************************************
1612  * BIT  bit,r8
1613  ***************************************************************/
1614 #undef BIT
1615 #define BIT(bit,reg)											\
1616     F = (F & CF) | HF | (SZ_BIT[reg & (1<<bit)] & ~(YF|XF)) | (reg & (YF|XF));
1617 
1618 
1619 
1620 /***************************************************************
1621  * BIT  bit,(HL)
1622  ***************************************************************/
1623 #define BIT_HL(bit,reg)											\
1624 	F = (F & CF) | HF | (SZ_BIT[reg & (1<<bit)] & ~(YF|XF)) | (WZ_H & (YF|XF));
1625 
1626 /***************************************************************
1627  * BIT  bit,(IX/Y+o)
1628  ***************************************************************/
1629 
1630 #define BIT_XY(bit,reg)											\
1631 	F = (F & CF) | HF | (SZ_BIT[reg & (1<<bit)] & ~(YF|XF)) | ((EA>>8) & (YF|XF))
1632 
1633 /***************************************************************
1634  * RES  bit,r8
1635  ***************************************************************/
RES(UINT8 bit,UINT8 value)1636 Z80_INLINE UINT8 RES(UINT8 bit, UINT8 value)
1637 {
1638 	return value & ~(1<<bit);
1639 }
1640 
1641 /***************************************************************
1642  * SET  bit,r8
1643  ***************************************************************/
SET(UINT8 bit,UINT8 value)1644 Z80_INLINE UINT8 SET(UINT8 bit, UINT8 value)
1645 {
1646 	return value | (1<<bit);
1647 }
1648 
1649 /***************************************************************
1650  * LDI
1651  ***************************************************************/
1652 #define LDI {													\
1653 	UINT8 io = RM(HL);											\
1654 	WM( DE, io );												\
1655 	F &= SF | ZF | CF;											\
1656 	if( (A + io) & 0x02 ) F |= YF; /* bit 1 -> flag 5 */		\
1657 	if( (A + io) & 0x08 ) F |= XF; /* bit 3 -> flag 3 */		\
1658 	HL++; DE++; BC--;											\
1659 	if( BC ) F |= VF;											\
1660 }
1661 
1662 /***************************************************************
1663  * CPI
1664  ***************************************************************/
1665 #define CPI {													\
1666 	UINT8 val = RM(HL);											\
1667 	UINT8 res = A - val;										\
1668 	WZ++;														\
1669 	HL++; BC--;													\
1670 	F = (F & CF) | (SZ[res]&~(YF|XF)) | ((A^val^res)&HF) | NF;	\
1671 	if( F & HF ) res -= 1;										\
1672 	if( res & 0x02 ) F |= YF; /* bit 1 -> flag 5 */				\
1673 	if( res & 0x08 ) F |= XF; /* bit 3 -> flag 3 */				\
1674 	if( BC ) F |= VF;											\
1675 }
1676 
1677 /***************************************************************
1678  * INI
1679  ***************************************************************/
1680 #define INI {													\
1681 	unsigned t;													\
1682 	UINT8 io = IN(BC);											\
1683 	WZ = BC + 1;												\
1684 	B--;														\
1685 	WM( HL, io );												\
1686 	HL++;														\
1687 	F = SZ[B];													\
1688 	t = (unsigned)((C + 1) & 0xff) + (unsigned)io;				\
1689 	if( io & SF ) F |= NF;										\
1690 	if( t & 0x100 ) F |= HF | CF;								\
1691 	F |= SZP[(UINT8)(t & 0x07) ^ B] & PF;						\
1692 }
1693 
1694 /***************************************************************
1695  * OUTI
1696  ***************************************************************/
1697 #define OUTI {													\
1698 	unsigned t;													\
1699 	UINT8 io = RM(HL);											\
1700 	B--;														\
1701 	WZ = BC + 1;												\
1702 	OUT( BC, io );												\
1703 	HL++;														\
1704 	F = SZ[B];													\
1705 	t = (unsigned)L + (unsigned)io;								\
1706 	if( io & SF ) F |= NF;										\
1707 	if( t & 0x100 ) F |= HF | CF;								\
1708 	F |= SZP[(UINT8)(t & 0x07) ^ B] & PF;						\
1709 }
1710 
1711 /***************************************************************
1712  * LDD
1713  ***************************************************************/
1714 #define LDD {													\
1715 	UINT8 io = RM(HL);											\
1716 	WM( DE, io );												\
1717 	F &= SF | ZF | CF;											\
1718 	if( (A + io) & 0x02 ) F |= YF; /* bit 1 -> flag 5 */		\
1719 	if( (A + io) & 0x08 ) F |= XF; /* bit 3 -> flag 3 */		\
1720 	HL--; DE--; BC--;											\
1721 	if( BC ) F |= VF;											\
1722 }
1723 
1724 /***************************************************************
1725  * CPD
1726  ***************************************************************/
1727 #define CPD {													\
1728 	UINT8 val = RM(HL);											\
1729 	UINT8 res = A - val;										\
1730 	WZ--;														\
1731 	HL--; BC--;													\
1732 	F = (F & CF) | (SZ[res]&~(YF|XF)) | ((A^val^res)&HF) | NF;	\
1733 	if( F & HF ) res -= 1;										\
1734 	if( res & 0x02 ) F |= YF; /* bit 1 -> flag 5 */				\
1735 	if( res & 0x08 ) F |= XF; /* bit 3 -> flag 3 */				\
1736 	if( BC ) F |= VF;											\
1737 }
1738 
1739 /***************************************************************
1740  * IND
1741  ***************************************************************/
1742 #define IND {													\
1743 	unsigned t;													\
1744 	UINT8 io = IN(BC);											\
1745 	WZ = BC - 1;												\
1746 	B--;														\
1747 	WM( HL, io );												\
1748 	HL--;														\
1749 	F = SZ[B];													\
1750 	t = ((unsigned)(C - 1) & 0xff) + (unsigned)io;				\
1751 	if( io & SF ) F |= NF;										\
1752 	if( t & 0x100 ) F |= HF | CF;								\
1753 	F |= SZP[(UINT8)(t & 0x07) ^ B] & PF;						\
1754 }
1755 
1756 /***************************************************************
1757  * OUTD
1758  ***************************************************************/
1759 #define OUTD {													\
1760 	unsigned t;													\
1761 	UINT8 io = RM(HL);											\
1762 	B--;														\
1763 	WZ = BC - 1;												\
1764 	OUT( BC, io );												\
1765 	HL--;														\
1766 	F = SZ[B];													\
1767 	t = (unsigned)L + (unsigned)io;								\
1768 	if( io & SF ) F |= NF;										\
1769 	if( t & 0x100 ) F |= HF | CF;								\
1770 	F |= SZP[(UINT8)(t & 0x07) ^ B] & PF;						\
1771 }
1772 
1773 /***************************************************************
1774  * LDIR
1775  ***************************************************************/
1776 #define LDIR													\
1777 	LDI;														\
1778 	if( BC )													\
1779 	{															\
1780 		CC(ex,0xb0);											\
1781 		m_opcode_history.do_optional = true;                    \
1782 		run_script();                                           \
1783 		PC -= 2;												\
1784 		WZ = PC + 1;											\
1785 	}
1786 
1787 /***************************************************************
1788  * CPIR
1789  ***************************************************************/
1790 #define CPIR													\
1791 	CPI;														\
1792 	if( BC && !(F & ZF) )										\
1793 	{															\
1794 		CC(ex,0xb1);											\
1795 		m_opcode_history.do_optional = true;                    \
1796 		run_script();                                           \
1797 		PC -= 2;												\
1798 		WZ = PC + 1;											\
1799 	}
1800 
1801 /***************************************************************
1802  * INIR
1803  ***************************************************************/
1804 #define INIR													\
1805 	INI;														\
1806 	if( B )														\
1807 	{															\
1808 		CC(ex,0xb2);											\
1809 		m_opcode_history.do_optional = true;                    \
1810 		run_script();                                           \
1811 		PC -= 2;												\
1812 	}
1813 
1814 /***************************************************************
1815  * OTIR
1816  ***************************************************************/
1817 #define OTIR													\
1818 	OUTI;														\
1819 	if( B )														\
1820 	{															\
1821 		CC(ex,0xb3);											\
1822 		m_opcode_history.do_optional = true;                    \
1823 		run_script();                                           \
1824 		PC -= 2;												\
1825 	}
1826 
1827 /***************************************************************
1828  * LDDR
1829  ***************************************************************/
1830 #define LDDR													\
1831 	LDD;														\
1832 	if( BC )													\
1833 	{															\
1834 		CC(ex,0xb8);											\
1835 		m_opcode_history.do_optional = true;                    \
1836 		run_script();                                           \
1837 		PC -= 2;												\
1838 		WZ = PC + 1;											\
1839 	}
1840 
1841 /***************************************************************
1842  * CPDR
1843  ***************************************************************/
1844 #define CPDR													\
1845 	CPD;														\
1846 	if( BC && !(F & ZF) )										\
1847 	{															\
1848 		CC(ex,0xb9);											\
1849 		m_opcode_history.do_optional = true;                    \
1850 		run_script();                                           \
1851 		PC -= 2;												\
1852 		WZ = PC + 1;											\
1853 	}
1854 
1855 /***************************************************************
1856  * INDR
1857  ***************************************************************/
1858 #define INDR													\
1859 	IND;														\
1860 	if( B )														\
1861 	{															\
1862 		CC(ex,0xba);											\
1863 		m_opcode_history.do_optional = true;                    \
1864 		run_script();                                           \
1865 		PC -= 2;												\
1866 	}
1867 
1868 /***************************************************************
1869  * OTDR
1870  ***************************************************************/
1871 #define OTDR													\
1872 	OUTD;														\
1873 	if( B )														\
1874 	{															\
1875 		CC(ex,0xbb);											\
1876 		m_opcode_history.do_optional = true;                    \
1877 		run_script();                                           \
1878 		PC -= 2;												\
1879 	}
1880 
1881 /***************************************************************
1882  * EI
1883  ***************************************************************/
1884 #define EI {													\
1885 	IFF1 = IFF2 = 1;											\
1886 	Z80.after_ei = TRUE;										\
1887 }
1888 
1889 /**********************************************************
1890  * opcodes with CB prefix
1891  * rotate, shift and bit operations
1892  **********************************************************/
1893 OP(cb,00) { B = RLC(B);											} /* RLC  B           */
1894 OP(cb,01) { C = RLC(C);											} /* RLC  C           */
1895 OP(cb,02) { D = RLC(D);											} /* RLC  D           */
1896 OP(cb,03) { E = RLC(E);											} /* RLC  E           */
1897 OP(cb,04) { H = RLC(H);											} /* RLC  H           */
1898 OP(cb,05) { L = RLC(L);											} /* RLC  L           */
1899 OP(cb,06) { WM( HL, RLC(RM(HL)) );								} /* RLC  (HL)        */
1900 OP(cb,07) { A = RLC(A);											} /* RLC  A           */
1901 
1902 OP(cb,08) { B = RRC(B);											} /* RRC  B           */
1903 OP(cb,09) { C = RRC(C);											} /* RRC  C           */
1904 OP(cb,0a) { D = RRC(D);											} /* RRC  D           */
1905 OP(cb,0b) { E = RRC(E);											} /* RRC  E           */
1906 OP(cb,0c) { H = RRC(H);											} /* RRC  H           */
1907 OP(cb,0d) { L = RRC(L);											} /* RRC  L           */
1908 OP(cb,0e) { WM( HL, RRC(RM(HL)) );								} /* RRC  (HL)        */
1909 OP(cb,0f) { A = RRC(A);											} /* RRC  A           */
1910 
1911 OP(cb,10) { B = RL(B);											} /* RL   B           */
1912 OP(cb,11) { C = RL(C);											} /* RL   C           */
1913 OP(cb,12) { D = RL(D);											} /* RL   D           */
1914 OP(cb,13) { E = RL(E);											} /* RL   E           */
1915 OP(cb,14) { H = RL(H);											} /* RL   H           */
1916 OP(cb,15) { L = RL(L);											} /* RL   L           */
1917 OP(cb,16) { WM( HL, RL(RM(HL)) );								} /* RL   (HL)        */
1918 OP(cb,17) { A = RL(A);											} /* RL   A           */
1919 
1920 OP(cb,18) { B = RR(B);											} /* RR   B           */
1921 OP(cb,19) { C = RR(C);											} /* RR   C           */
1922 OP(cb,1a) { D = RR(D);											} /* RR   D           */
1923 OP(cb,1b) { E = RR(E);											} /* RR   E           */
1924 OP(cb,1c) { H = RR(H);											} /* RR   H           */
1925 OP(cb,1d) { L = RR(L);											} /* RR   L           */
1926 OP(cb,1e) { WM( HL, RR(RM(HL)) );								} /* RR   (HL)        */
1927 OP(cb,1f) { A = RR(A);											} /* RR   A           */
1928 
1929 OP(cb,20) { B = SLA(B);											} /* SLA  B           */
1930 OP(cb,21) { C = SLA(C);											} /* SLA  C           */
1931 OP(cb,22) { D = SLA(D);											} /* SLA  D           */
1932 OP(cb,23) { E = SLA(E);											} /* SLA  E           */
1933 OP(cb,24) { H = SLA(H);											} /* SLA  H           */
1934 OP(cb,25) { L = SLA(L);											} /* SLA  L           */
1935 OP(cb,26) { WM( HL, SLA(RM(HL)) );								} /* SLA  (HL)        */
1936 OP(cb,27) { A = SLA(A);											} /* SLA  A           */
1937 
1938 OP(cb,28) { B = SRA(B);											} /* SRA  B           */
1939 OP(cb,29) { C = SRA(C);											} /* SRA  C           */
1940 OP(cb,2a) { D = SRA(D);											} /* SRA  D           */
1941 OP(cb,2b) { E = SRA(E);											} /* SRA  E           */
1942 OP(cb,2c) { H = SRA(H);											} /* SRA  H           */
1943 OP(cb,2d) { L = SRA(L);											} /* SRA  L           */
1944 OP(cb,2e) { WM( HL, SRA(RM(HL)) );								} /* SRA  (HL)        */
1945 OP(cb,2f) { A = SRA(A);											} /* SRA  A           */
1946 
1947 OP(cb,30) { B = SLL(B);											} /* SLL  B           */
1948 OP(cb,31) { C = SLL(C);											} /* SLL  C           */
1949 OP(cb,32) { D = SLL(D);											} /* SLL  D           */
1950 OP(cb,33) { E = SLL(E);											} /* SLL  E           */
1951 OP(cb,34) { H = SLL(H);											} /* SLL  H           */
1952 OP(cb,35) { L = SLL(L);											} /* SLL  L           */
1953 OP(cb,36) { WM( HL, SLL(RM(HL)) );								} /* SLL  (HL)        */
1954 OP(cb,37) { A = SLL(A);											} /* SLL  A           */
1955 
1956 OP(cb,38) { B = SRL(B);											} /* SRL  B           */
1957 OP(cb,39) { C = SRL(C);											} /* SRL  C           */
1958 OP(cb,3a) { D = SRL(D);											} /* SRL  D           */
1959 OP(cb,3b) { E = SRL(E);											} /* SRL  E           */
1960 OP(cb,3c) { H = SRL(H);											} /* SRL  H           */
1961 OP(cb,3d) { L = SRL(L);											} /* SRL  L           */
1962 OP(cb,3e) { WM( HL, SRL(RM(HL)) );								} /* SRL  (HL)        */
1963 OP(cb,3f) { A = SRL(A);											} /* SRL  A           */
1964 
1965 OP(cb,40) { BIT(0,B);											} /* BIT  0,B         */
1966 OP(cb,41) { BIT(0,C);											} /* BIT  0,C         */
1967 OP(cb,42) { BIT(0,D);											} /* BIT  0,D         */
1968 OP(cb,43) { BIT(0,E);											} /* BIT  0,E         */
1969 OP(cb,44) { BIT(0,H);											} /* BIT  0,H         */
1970 OP(cb,45) { BIT(0,L);											} /* BIT  0,L         */
1971 OP(cb,46) { BIT_HL(0,RM(HL));										} /* BIT  0,(HL)      */
1972 OP(cb,47) { BIT(0,A);											} /* BIT  0,A         */
1973 
1974 OP(cb,48) { BIT(1,B);											} /* BIT  1,B         */
1975 OP(cb,49) { BIT(1,C);											} /* BIT  1,C         */
1976 OP(cb,4a) { BIT(1,D);											} /* BIT  1,D         */
1977 OP(cb,4b) { BIT(1,E);											} /* BIT  1,E         */
1978 OP(cb,4c) { BIT(1,H);											} /* BIT  1,H         */
1979 OP(cb,4d) { BIT(1,L);											} /* BIT  1,L         */
1980 OP(cb,4e) { BIT_HL(1,RM(HL));										} /* BIT  1,(HL)      */
1981 OP(cb,4f) { BIT(1,A);											} /* BIT  1,A         */
1982 
1983 OP(cb,50) { BIT(2,B);											} /* BIT  2,B         */
1984 OP(cb,51) { BIT(2,C);											} /* BIT  2,C         */
1985 OP(cb,52) { BIT(2,D);											} /* BIT  2,D         */
1986 OP(cb,53) { BIT(2,E);											} /* BIT  2,E         */
1987 OP(cb,54) { BIT(2,H);											} /* BIT  2,H         */
1988 OP(cb,55) { BIT(2,L);											} /* BIT  2,L         */
1989 OP(cb,56) { BIT_HL(2,RM(HL));									} /* BIT  2,(HL)      */
1990 OP(cb,57) { BIT(2,A);											} /* BIT  2,A         */
1991 
1992 OP(cb,58) { BIT(3,B);											} /* BIT  3,B         */
1993 OP(cb,59) { BIT(3,C);											} /* BIT  3,C         */
1994 OP(cb,5a) { BIT(3,D);											} /* BIT  3,D         */
1995 OP(cb,5b) { BIT(3,E);											} /* BIT  3,E         */
1996 OP(cb,5c) { BIT(3,H);											} /* BIT  3,H         */
1997 OP(cb,5d) { BIT(3,L);											} /* BIT  3,L         */
1998 OP(cb,5e) { BIT_HL(3,RM(HL));									} /* BIT  3,(HL)      */
1999 OP(cb,5f) { BIT(3,A);											} /* BIT  3,A         */
2000 
2001 OP(cb,60) { BIT(4,B);											} /* BIT  4,B         */
2002 OP(cb,61) { BIT(4,C);											} /* BIT  4,C         */
2003 OP(cb,62) { BIT(4,D);											} /* BIT  4,D         */
2004 OP(cb,63) { BIT(4,E);											} /* BIT  4,E         */
2005 OP(cb,64) { BIT(4,H);											} /* BIT  4,H         */
2006 OP(cb,65) { BIT(4,L);											} /* BIT  4,L         */
2007 OP(cb,66) { BIT_HL(4,RM(HL));									} /* BIT  4,(HL)      */
2008 OP(cb,67) { BIT(4,A);											} /* BIT  4,A         */
2009 
2010 OP(cb,68) { BIT(5,B);											} /* BIT  5,B         */
2011 OP(cb,69) { BIT(5,C);											} /* BIT  5,C         */
2012 OP(cb,6a) { BIT(5,D);											} /* BIT  5,D         */
2013 OP(cb,6b) { BIT(5,E);											} /* BIT  5,E         */
2014 OP(cb,6c) { BIT(5,H);											} /* BIT  5,H         */
2015 OP(cb,6d) { BIT(5,L);											} /* BIT  5,L         */
2016 OP(cb,6e) { BIT_HL(5,RM(HL));									} /* BIT  5,(HL)      */
2017 OP(cb,6f) { BIT(5,A);											} /* BIT  5,A         */
2018 
2019 OP(cb,70) { BIT(6,B);											} /* BIT  6,B         */
2020 OP(cb,71) { BIT(6,C);											} /* BIT  6,C         */
2021 OP(cb,72) { BIT(6,D);											} /* BIT  6,D         */
2022 OP(cb,73) { BIT(6,E);											} /* BIT  6,E         */
2023 OP(cb,74) { BIT(6,H);											} /* BIT  6,H         */
2024 OP(cb,75) { BIT(6,L);											} /* BIT  6,L         */
2025 OP(cb,76) { BIT_HL(6,RM(HL));									} /* BIT  6,(HL)      */
2026 OP(cb,77) { BIT(6,A);											} /* BIT  6,A         */
2027 
2028 OP(cb,78) { BIT(7,B);											} /* BIT  7,B         */
2029 OP(cb,79) { BIT(7,C);											} /* BIT  7,C         */
2030 OP(cb,7a) { BIT(7,D);											} /* BIT  7,D         */
2031 OP(cb,7b) { BIT(7,E);											} /* BIT  7,E         */
2032 OP(cb,7c) { BIT(7,H);											} /* BIT  7,H         */
2033 OP(cb,7d) { BIT(7,L);											} /* BIT  7,L         */
2034 OP(cb,7e) { BIT_HL(7,RM(HL));									} /* BIT  7,(HL)      */
2035 OP(cb,7f) { BIT(7,A);											} /* BIT  7,A         */
2036 
2037 OP(cb,80) { B = RES(0,B);										} /* RES  0,B         */
2038 OP(cb,81) { C = RES(0,C);										} /* RES  0,C         */
2039 OP(cb,82) { D = RES(0,D);										} /* RES  0,D         */
2040 OP(cb,83) { E = RES(0,E);										} /* RES  0,E         */
2041 OP(cb,84) { H = RES(0,H);										} /* RES  0,H         */
2042 OP(cb,85) { L = RES(0,L);										} /* RES  0,L         */
2043 OP(cb,86) { WM( HL, RES(0,RM(HL)) );							} /* RES  0,(HL)      */
2044 OP(cb,87) { A = RES(0,A);										} /* RES  0,A         */
2045 
2046 OP(cb,88) { B = RES(1,B);										} /* RES  1,B         */
2047 OP(cb,89) { C = RES(1,C);										} /* RES  1,C         */
2048 OP(cb,8a) { D = RES(1,D);										} /* RES  1,D         */
2049 OP(cb,8b) { E = RES(1,E);										} /* RES  1,E         */
2050 OP(cb,8c) { H = RES(1,H);										} /* RES  1,H         */
2051 OP(cb,8d) { L = RES(1,L);										} /* RES  1,L         */
2052 OP(cb,8e) { WM( HL, RES(1,RM(HL)) );							} /* RES  1,(HL)      */
2053 OP(cb,8f) { A = RES(1,A);										} /* RES  1,A         */
2054 
2055 OP(cb,90) { B = RES(2,B);										} /* RES  2,B         */
2056 OP(cb,91) { C = RES(2,C);										} /* RES  2,C         */
2057 OP(cb,92) { D = RES(2,D);										} /* RES  2,D         */
2058 OP(cb,93) { E = RES(2,E);										} /* RES  2,E         */
2059 OP(cb,94) { H = RES(2,H);										} /* RES  2,H         */
2060 OP(cb,95) { L = RES(2,L);										} /* RES  2,L         */
2061 OP(cb,96) { WM( HL, RES(2,RM(HL)) );							} /* RES  2,(HL)      */
2062 OP(cb,97) { A = RES(2,A);										} /* RES  2,A         */
2063 
2064 OP(cb,98) { B = RES(3,B);										} /* RES  3,B         */
2065 OP(cb,99) { C = RES(3,C);										} /* RES  3,C         */
2066 OP(cb,9a) { D = RES(3,D);										} /* RES  3,D         */
2067 OP(cb,9b) { E = RES(3,E);										} /* RES  3,E         */
2068 OP(cb,9c) { H = RES(3,H);										} /* RES  3,H         */
2069 OP(cb,9d) { L = RES(3,L);										} /* RES  3,L         */
2070 OP(cb,9e) { WM( HL, RES(3,RM(HL)) );							} /* RES  3,(HL)      */
2071 OP(cb,9f) { A = RES(3,A);										} /* RES  3,A         */
2072 
OP(cb,a0)2073 OP(cb,a0) { B = RES(4,B);										} /* RES  4,B         */
OP(cb,a1)2074 OP(cb,a1) { C = RES(4,C);										} /* RES  4,C         */
OP(cb,a2)2075 OP(cb,a2) { D = RES(4,D);										} /* RES  4,D         */
OP(cb,a3)2076 OP(cb,a3) { E = RES(4,E);										} /* RES  4,E         */
OP(cb,a4)2077 OP(cb,a4) { H = RES(4,H);										} /* RES  4,H         */
OP(cb,a5)2078 OP(cb,a5) { L = RES(4,L);										} /* RES  4,L         */
OP(cb,a6)2079 OP(cb,a6) { WM( HL, RES(4,RM(HL)) );							} /* RES  4,(HL)      */
OP(cb,a7)2080 OP(cb,a7) { A = RES(4,A);										} /* RES  4,A         */
2081 
OP(cb,a8)2082 OP(cb,a8) { B = RES(5,B);										} /* RES  5,B         */
OP(cb,a9)2083 OP(cb,a9) { C = RES(5,C);										} /* RES  5,C         */
OP(cb,aa)2084 OP(cb,aa) { D = RES(5,D);										} /* RES  5,D         */
OP(cb,ab)2085 OP(cb,ab) { E = RES(5,E);										} /* RES  5,E         */
OP(cb,ac)2086 OP(cb,ac) { H = RES(5,H);										} /* RES  5,H         */
OP(cb,ad)2087 OP(cb,ad) { L = RES(5,L);										} /* RES  5,L         */
OP(cb,ae)2088 OP(cb,ae) { WM( HL, RES(5,RM(HL)) );							} /* RES  5,(HL)      */
OP(cb,af)2089 OP(cb,af) { A = RES(5,A);										} /* RES  5,A         */
2090 
OP(cb,b0)2091 OP(cb,b0) { B = RES(6,B);										} /* RES  6,B         */
OP(cb,b1)2092 OP(cb,b1) { C = RES(6,C);										} /* RES  6,C         */
OP(cb,b2)2093 OP(cb,b2) { D = RES(6,D);										} /* RES  6,D         */
OP(cb,b3)2094 OP(cb,b3) { E = RES(6,E);										} /* RES  6,E         */
OP(cb,b4)2095 OP(cb,b4) { H = RES(6,H);										} /* RES  6,H         */
OP(cb,b5)2096 OP(cb,b5) { L = RES(6,L);										} /* RES  6,L         */
OP(cb,b6)2097 OP(cb,b6) { WM( HL, RES(6,RM(HL)) );							} /* RES  6,(HL)      */
OP(cb,b7)2098 OP(cb,b7) { A = RES(6,A);										} /* RES  6,A         */
2099 
OP(cb,b8)2100 OP(cb,b8) { B = RES(7,B);										} /* RES  7,B         */
OP(cb,b9)2101 OP(cb,b9) { C = RES(7,C);										} /* RES  7,C         */
OP(cb,ba)2102 OP(cb,ba) { D = RES(7,D);										} /* RES  7,D         */
OP(cb,bb)2103 OP(cb,bb) { E = RES(7,E);										} /* RES  7,E         */
OP(cb,bc)2104 OP(cb,bc) { H = RES(7,H);										} /* RES  7,H         */
OP(cb,bd)2105 OP(cb,bd) { L = RES(7,L);										} /* RES  7,L         */
OP(cb,be)2106 OP(cb,be) { WM( HL, RES(7,RM(HL)) );							} /* RES  7,(HL)      */
OP(cb,bf)2107 OP(cb,bf) { A = RES(7,A);										} /* RES  7,A         */
2108 
OP(cb,c0)2109 OP(cb,c0) { B = SET(0,B);										} /* SET  0,B         */
OP(cb,c1)2110 OP(cb,c1) { C = SET(0,C);										} /* SET  0,C         */
OP(cb,c2)2111 OP(cb,c2) { D = SET(0,D);										} /* SET  0,D         */
OP(cb,c3)2112 OP(cb,c3) { E = SET(0,E);										} /* SET  0,E         */
OP(cb,c4)2113 OP(cb,c4) { H = SET(0,H);										} /* SET  0,H         */
OP(cb,c5)2114 OP(cb,c5) { L = SET(0,L);										} /* SET  0,L         */
OP(cb,c6)2115 OP(cb,c6) { WM( HL, SET(0,RM(HL)) );							} /* SET  0,(HL)      */
OP(cb,c7)2116 OP(cb,c7) { A = SET(0,A);										} /* SET  0,A         */
2117 
OP(cb,c8)2118 OP(cb,c8) { B = SET(1,B);										} /* SET  1,B         */
OP(cb,c9)2119 OP(cb,c9) { C = SET(1,C);										} /* SET  1,C         */
OP(cb,ca)2120 OP(cb,ca) { D = SET(1,D);										} /* SET  1,D         */
OP(cb,cb)2121 OP(cb,cb) { E = SET(1,E);										} /* SET  1,E         */
OP(cb,cc)2122 OP(cb,cc) { H = SET(1,H);										} /* SET  1,H         */
OP(cb,cd)2123 OP(cb,cd) { L = SET(1,L);										} /* SET  1,L         */
OP(cb,ce)2124 OP(cb,ce) { WM( HL, SET(1,RM(HL)) );							} /* SET  1,(HL)      */
OP(cb,cf)2125 OP(cb,cf) { A = SET(1,A);										} /* SET  1,A         */
2126 
OP(cb,d0)2127 OP(cb,d0) { B = SET(2,B);										} /* SET  2,B         */
OP(cb,d1)2128 OP(cb,d1) { C = SET(2,C);										} /* SET  2,C         */
OP(cb,d2)2129 OP(cb,d2) { D = SET(2,D);										} /* SET  2,D         */
OP(cb,d3)2130 OP(cb,d3) { E = SET(2,E);										} /* SET  2,E         */
OP(cb,d4)2131 OP(cb,d4) { H = SET(2,H);										} /* SET  2,H         */
OP(cb,d5)2132 OP(cb,d5) { L = SET(2,L);										} /* SET  2,L         */
OP(cb,d6)2133 OP(cb,d6) { WM( HL, SET(2,RM(HL)) );							} /* SET  2,(HL)      */
OP(cb,d7)2134 OP(cb,d7) { A = SET(2,A);										} /* SET  2,A         */
2135 
OP(cb,d8)2136 OP(cb,d8) { B = SET(3,B);										} /* SET  3,B         */
OP(cb,d9)2137 OP(cb,d9) { C = SET(3,C);										} /* SET  3,C         */
OP(cb,da)2138 OP(cb,da) { D = SET(3,D);										} /* SET  3,D         */
OP(cb,db)2139 OP(cb,db) { E = SET(3,E);										} /* SET  3,E         */
OP(cb,dc)2140 OP(cb,dc) { H = SET(3,H);										} /* SET  3,H         */
OP(cb,dd)2141 OP(cb,dd) { L = SET(3,L);										} /* SET  3,L         */
OP(cb,de)2142 OP(cb,de) { WM( HL, SET(3,RM(HL)) );							} /* SET  3,(HL)      */
OP(cb,df)2143 OP(cb,df) { A = SET(3,A);										} /* SET  3,A         */
2144 
OP(cb,e0)2145 OP(cb,e0) { B = SET(4,B);										} /* SET  4,B         */
OP(cb,e1)2146 OP(cb,e1) { C = SET(4,C);										} /* SET  4,C         */
OP(cb,e2)2147 OP(cb,e2) { D = SET(4,D);										} /* SET  4,D         */
OP(cb,e3)2148 OP(cb,e3) { E = SET(4,E);										} /* SET  4,E         */
OP(cb,e4)2149 OP(cb,e4) { H = SET(4,H);										} /* SET  4,H         */
OP(cb,e5)2150 OP(cb,e5) { L = SET(4,L);										} /* SET  4,L         */
OP(cb,e6)2151 OP(cb,e6) { WM( HL, SET(4,RM(HL)) );							} /* SET  4,(HL)      */
OP(cb,e7)2152 OP(cb,e7) { A = SET(4,A);										} /* SET  4,A         */
2153 
OP(cb,e8)2154 OP(cb,e8) { B = SET(5,B);										} /* SET  5,B         */
OP(cb,e9)2155 OP(cb,e9) { C = SET(5,C);										} /* SET  5,C         */
OP(cb,ea)2156 OP(cb,ea) { D = SET(5,D);										} /* SET  5,D         */
OP(cb,eb)2157 OP(cb,eb) { E = SET(5,E);										} /* SET  5,E         */
OP(cb,ec)2158 OP(cb,ec) { H = SET(5,H);										} /* SET  5,H         */
OP(cb,ed)2159 OP(cb,ed) { L = SET(5,L);										} /* SET  5,L         */
OP(cb,ee)2160 OP(cb,ee) { WM( HL, SET(5,RM(HL)) );							} /* SET  5,(HL)      */
OP(cb,ef)2161 OP(cb,ef) { A = SET(5,A);										} /* SET  5,A         */
2162 
OP(cb,f0)2163 OP(cb,f0) { B = SET(6,B);										} /* SET  6,B         */
OP(cb,f1)2164 OP(cb,f1) { C = SET(6,C);										} /* SET  6,C         */
OP(cb,f2)2165 OP(cb,f2) { D = SET(6,D);										} /* SET  6,D         */
OP(cb,f3)2166 OP(cb,f3) { E = SET(6,E);										} /* SET  6,E         */
OP(cb,f4)2167 OP(cb,f4) { H = SET(6,H);										} /* SET  6,H         */
OP(cb,f5)2168 OP(cb,f5) { L = SET(6,L);										} /* SET  6,L         */
OP(cb,f6)2169 OP(cb,f6) { WM( HL, SET(6,RM(HL)) );							} /* SET  6,(HL)      */
OP(cb,f7)2170 OP(cb,f7) { A = SET(6,A);										} /* SET  6,A         */
2171 
OP(cb,f8)2172 OP(cb,f8) { B = SET(7,B);										} /* SET  7,B         */
OP(cb,f9)2173 OP(cb,f9) { C = SET(7,C);										} /* SET  7,C         */
OP(cb,fa)2174 OP(cb,fa) { D = SET(7,D);										} /* SET  7,D         */
OP(cb,fb)2175 OP(cb,fb) { E = SET(7,E);										} /* SET  7,E         */
OP(cb,fc)2176 OP(cb,fc) { H = SET(7,H);										} /* SET  7,H         */
OP(cb,fd)2177 OP(cb,fd) { L = SET(7,L);										} /* SET  7,L         */
OP(cb,fe)2178 OP(cb,fe) { WM( HL, SET(7,RM(HL)) );							} /* SET  7,(HL)      */
OP(cb,ff)2179 OP(cb,ff) { A = SET(7,A);										} /* SET  7,A         */
2180 
2181 
2182 /**********************************************************
2183 * opcodes with DD/FD CB prefix
2184 * rotate, shift and bit operations with (IX+o)
2185 **********************************************************/
2186 OP(xycb,00) { B = RLC( RM(EA) ); WM( EA,B );					} /* RLC  B=(XY+o)    */
2187 OP(xycb,01) { C = RLC( RM(EA) ); WM( EA,C );					} /* RLC  C=(XY+o)    */
2188 OP(xycb,02) { D = RLC( RM(EA) ); WM( EA,D );					} /* RLC  D=(XY+o)    */
2189 OP(xycb,03) { E = RLC( RM(EA) ); WM( EA,E );					} /* RLC  E=(XY+o)    */
2190 OP(xycb,04) { H = RLC( RM(EA) ); WM( EA,H );					} /* RLC  H=(XY+o)    */
2191 OP(xycb,05) { L = RLC( RM(EA) ); WM( EA,L );					} /* RLC  L=(XY+o)    */
2192 OP(xycb,06) { WM( EA, RLC( RM(EA) ) );							} /* RLC  (XY+o)      */
2193 OP(xycb,07) { A = RLC( RM(EA) ); WM( EA,A );					} /* RLC  A=(XY+o)    */
2194 
2195 OP(xycb,08) { B = RRC( RM(EA) ); WM( EA,B );					} /* RRC  B=(XY+o)    */
2196 OP(xycb,09) { C = RRC( RM(EA) ); WM( EA,C );					} /* RRC  C=(XY+o)    */
2197 OP(xycb,0a) { D = RRC( RM(EA) ); WM( EA,D );					} /* RRC  D=(XY+o)    */
2198 OP(xycb,0b) { E = RRC( RM(EA) ); WM( EA,E );					} /* RRC  E=(XY+o)    */
2199 OP(xycb,0c) { H = RRC( RM(EA) ); WM( EA,H );					} /* RRC  H=(XY+o)    */
2200 OP(xycb,0d) { L = RRC( RM(EA) ); WM( EA,L );					} /* RRC  L=(XY+o)    */
2201 OP(xycb,0e) { WM( EA,RRC( RM(EA) ) );							} /* RRC  (XY+o)      */
2202 OP(xycb,0f) { A = RRC( RM(EA) ); WM( EA,A );					} /* RRC  A=(XY+o)    */
2203 
2204 OP(xycb,10) { B = RL( RM(EA) ); WM( EA,B );						} /* RL   B=(XY+o)    */
2205 OP(xycb,11) { C = RL( RM(EA) ); WM( EA,C );						} /* RL   C=(XY+o)    */
2206 OP(xycb,12) { D = RL( RM(EA) ); WM( EA,D );						} /* RL   D=(XY+o)    */
2207 OP(xycb,13) { E = RL( RM(EA) ); WM( EA,E );						} /* RL   E=(XY+o)    */
2208 OP(xycb,14) { H = RL( RM(EA) ); WM( EA,H );						} /* RL   H=(XY+o)    */
2209 OP(xycb,15) { L = RL( RM(EA) ); WM( EA,L );						} /* RL   L=(XY+o)    */
2210 OP(xycb,16) { WM( EA,RL( RM(EA) ) );							} /* RL   (XY+o)      */
2211 OP(xycb,17) { A = RL( RM(EA) ); WM( EA,A );						} /* RL   A=(XY+o)    */
2212 
2213 OP(xycb,18) { B = RR( RM(EA) ); WM( EA,B );						} /* RR   B=(XY+o)    */
2214 OP(xycb,19) { C = RR( RM(EA) ); WM( EA,C );						} /* RR   C=(XY+o)    */
2215 OP(xycb,1a) { D = RR( RM(EA) ); WM( EA,D );						} /* RR   D=(XY+o)    */
2216 OP(xycb,1b) { E = RR( RM(EA) ); WM( EA,E );						} /* RR   E=(XY+o)    */
2217 OP(xycb,1c) { H = RR( RM(EA) ); WM( EA,H );						} /* RR   H=(XY+o)    */
2218 OP(xycb,1d) { L = RR( RM(EA) ); WM( EA,L );						} /* RR   L=(XY+o)    */
2219 OP(xycb,1e) { WM( EA,RR( RM(EA) ) );							} /* RR   (XY+o)      */
2220 OP(xycb,1f) { A = RR( RM(EA) ); WM( EA,A );						} /* RR   A=(XY+o)    */
2221 
2222 OP(xycb,20) { B = SLA( RM(EA) ); WM( EA,B );					} /* SLA  B=(XY+o)    */
2223 OP(xycb,21) { C = SLA( RM(EA) ); WM( EA,C );					} /* SLA  C=(XY+o)    */
2224 OP(xycb,22) { D = SLA( RM(EA) ); WM( EA,D );					} /* SLA  D=(XY+o)    */
2225 OP(xycb,23) { E = SLA( RM(EA) ); WM( EA,E );					} /* SLA  E=(XY+o)    */
2226 OP(xycb,24) { H = SLA( RM(EA) ); WM( EA,H );					} /* SLA  H=(XY+o)    */
2227 OP(xycb,25) { L = SLA( RM(EA) ); WM( EA,L );					} /* SLA  L=(XY+o)    */
2228 OP(xycb,26) { WM( EA,SLA( RM(EA) ) );							} /* SLA  (XY+o)      */
2229 OP(xycb,27) { A = SLA( RM(EA) ); WM( EA,A );					} /* SLA  A=(XY+o)    */
2230 
2231 OP(xycb,28) { B = SRA( RM(EA) ); WM( EA,B );					} /* SRA  B=(XY+o)    */
2232 OP(xycb,29) { C = SRA( RM(EA) ); WM( EA,C );					} /* SRA  C=(XY+o)    */
2233 OP(xycb,2a) { D = SRA( RM(EA) ); WM( EA,D );					} /* SRA  D=(XY+o)    */
2234 OP(xycb,2b) { E = SRA( RM(EA) ); WM( EA,E );					} /* SRA  E=(XY+o)    */
2235 OP(xycb,2c) { H = SRA( RM(EA) ); WM( EA,H );					} /* SRA  H=(XY+o)    */
2236 OP(xycb,2d) { L = SRA( RM(EA) ); WM( EA,L );					} /* SRA  L=(XY+o)    */
2237 OP(xycb,2e) { WM( EA,SRA( RM(EA) ) );							} /* SRA  (XY+o)      */
2238 OP(xycb,2f) { A = SRA( RM(EA) ); WM( EA,A );					} /* SRA  A=(XY+o)    */
2239 
2240 OP(xycb,30) { B = SLL( RM(EA) ); WM( EA,B );					} /* SLL  B=(XY+o)    */
2241 OP(xycb,31) { C = SLL( RM(EA) ); WM( EA,C );					} /* SLL  C=(XY+o)    */
2242 OP(xycb,32) { D = SLL( RM(EA) ); WM( EA,D );					} /* SLL  D=(XY+o)    */
2243 OP(xycb,33) { E = SLL( RM(EA) ); WM( EA,E );					} /* SLL  E=(XY+o)    */
2244 OP(xycb,34) { H = SLL( RM(EA) ); WM( EA,H );					} /* SLL  H=(XY+o)    */
2245 OP(xycb,35) { L = SLL( RM(EA) ); WM( EA,L );					} /* SLL  L=(XY+o)    */
2246 OP(xycb,36) { WM( EA,SLL( RM(EA) ) );							} /* SLL  (XY+o)      */
2247 OP(xycb,37) { A = SLL( RM(EA) ); WM( EA,A );					} /* SLL  A=(XY+o)    */
2248 
2249 OP(xycb,38) { B = SRL( RM(EA) ); WM( EA,B );					} /* SRL  B=(XY+o)    */
2250 OP(xycb,39) { C = SRL( RM(EA) ); WM( EA,C );					} /* SRL  C=(XY+o)    */
2251 OP(xycb,3a) { D = SRL( RM(EA) ); WM( EA,D );					} /* SRL  D=(XY+o)    */
2252 OP(xycb,3b) { E = SRL( RM(EA) ); WM( EA,E );					} /* SRL  E=(XY+o)    */
2253 OP(xycb,3c) { H = SRL( RM(EA) ); WM( EA,H );					} /* SRL  H=(XY+o)    */
2254 OP(xycb,3d) { L = SRL( RM(EA) ); WM( EA,L );					} /* SRL  L=(XY+o)    */
2255 OP(xycb,3e) { WM( EA,SRL( RM(EA) ) );							} /* SRL  (XY+o)      */
2256 OP(xycb,3f) { A = SRL( RM(EA) ); WM( EA,A );					} /* SRL  A=(XY+o)    */
2257 
2258 OP(xycb,40) { xycb_46();										} /* BIT  0,(XY+o)    */
2259 OP(xycb,41) { xycb_46();										} /* BIT  0,(XY+o)    */
2260 OP(xycb,42) { xycb_46();										} /* BIT  0,(XY+o)    */
2261 OP(xycb,43) { xycb_46();										} /* BIT  0,(XY+o)    */
2262 OP(xycb,44) { xycb_46();										} /* BIT  0,(XY+o)    */
2263 OP(xycb,45) { xycb_46();										} /* BIT  0,(XY+o)    */
2264 OP(xycb,46) { BIT_XY(0,RM(EA));									} /* BIT  0,(XY+o)    */
2265 OP(xycb,47) { xycb_46();										} /* BIT  0,(XY+o)    */
2266 
2267 OP(xycb,48) { xycb_4e();										} /* BIT  1,(XY+o)    */
2268 OP(xycb,49) { xycb_4e();										} /* BIT  1,(XY+o)    */
2269 OP(xycb,4a) { xycb_4e();										} /* BIT  1,(XY+o)    */
2270 OP(xycb,4b) { xycb_4e();										} /* BIT  1,(XY+o)    */
2271 OP(xycb,4c) { xycb_4e();										} /* BIT  1,(XY+o)    */
2272 OP(xycb,4d) { xycb_4e();										} /* BIT  1,(XY+o)    */
2273 OP(xycb,4e) { BIT_XY(1,RM(EA));									} /* BIT  1,(XY+o)    */
2274 OP(xycb,4f) { xycb_4e();										} /* BIT  1,(XY+o)    */
2275 
2276 OP(xycb,50) { xycb_56();										} /* BIT  2,(XY+o)    */
2277 OP(xycb,51) { xycb_56();										} /* BIT  2,(XY+o)    */
2278 OP(xycb,52) { xycb_56();										} /* BIT  2,(XY+o)    */
2279 OP(xycb,53) { xycb_56();										} /* BIT  2,(XY+o)    */
2280 OP(xycb,54) { xycb_56();										} /* BIT  2,(XY+o)    */
2281 OP(xycb,55) { xycb_56();										} /* BIT  2,(XY+o)    */
2282 OP(xycb,56) { BIT_XY(2,RM(EA));									} /* BIT  2,(XY+o)    */
2283 OP(xycb,57) { xycb_56();										} /* BIT  2,(XY+o)    */
2284 
2285 OP(xycb,58) { xycb_5e();										} /* BIT  3,(XY+o)    */
2286 OP(xycb,59) { xycb_5e();										} /* BIT  3,(XY+o)    */
2287 OP(xycb,5a) { xycb_5e();										} /* BIT  3,(XY+o)    */
2288 OP(xycb,5b) { xycb_5e();										} /* BIT  3,(XY+o)    */
2289 OP(xycb,5c) { xycb_5e();										} /* BIT  3,(XY+o)    */
2290 OP(xycb,5d) { xycb_5e();										} /* BIT  3,(XY+o)    */
2291 OP(xycb,5e) { BIT_XY(3,RM(EA));									} /* BIT  3,(XY+o)    */
2292 OP(xycb,5f) { xycb_5e();										} /* BIT  3,(XY+o)    */
2293 
2294 OP(xycb,60) { xycb_66();										} /* BIT  4,(XY+o)    */
2295 OP(xycb,61) { xycb_66();										} /* BIT  4,(XY+o)    */
2296 OP(xycb,62) { xycb_66();										} /* BIT  4,(XY+o)    */
2297 OP(xycb,63) { xycb_66();										} /* BIT  4,(XY+o)    */
2298 OP(xycb,64) { xycb_66();										} /* BIT  4,(XY+o)    */
2299 OP(xycb,65) { xycb_66();										} /* BIT  4,(XY+o)    */
2300 OP(xycb,66) { BIT_XY(4,RM(EA));									} /* BIT  4,(XY+o)    */
2301 OP(xycb,67) { xycb_66();										} /* BIT  4,(XY+o)    */
2302 
2303 OP(xycb,68) { xycb_6e();										} /* BIT  5,(XY+o)    */
2304 OP(xycb,69) { xycb_6e();										} /* BIT  5,(XY+o)    */
2305 OP(xycb,6a) { xycb_6e();										} /* BIT  5,(XY+o)    */
2306 OP(xycb,6b) { xycb_6e();										} /* BIT  5,(XY+o)    */
2307 OP(xycb,6c) { xycb_6e();										} /* BIT  5,(XY+o)    */
2308 OP(xycb,6d) { xycb_6e();										} /* BIT  5,(XY+o)    */
2309 OP(xycb,6e) { BIT_XY(5,RM(EA));									} /* BIT  5,(XY+o)    */
2310 OP(xycb,6f) { xycb_6e();										} /* BIT  5,(XY+o)    */
2311 
2312 OP(xycb,70) { xycb_66();										} /* BIT  6,(XY+o)    */
2313 OP(xycb,71) { xycb_66();										} /* BIT  6,(XY+o)    */
2314 OP(xycb,72) { xycb_66();										} /* BIT  6,(XY+o)    */
2315 OP(xycb,73) { xycb_66();										} /* BIT  6,(XY+o)    */
2316 OP(xycb,74) { xycb_66();										} /* BIT  6,(XY+o)    */
2317 OP(xycb,75) { xycb_66();										} /* BIT  6,(XY+o)    */
2318 OP(xycb,76) { BIT_XY(6,RM(EA));									} /* BIT  6,(XY+o)    */
2319 OP(xycb,77) { xycb_66();										} /* BIT  6,(XY+o)    */
2320 
2321 OP(xycb,78) { xycb_7e();										} /* BIT  7,(XY+o)    */
2322 OP(xycb,79) { xycb_7e();										} /* BIT  7,(XY+o)    */
2323 OP(xycb,7a) { xycb_7e();										} /* BIT  7,(XY+o)    */
2324 OP(xycb,7b) { xycb_7e();										} /* BIT  7,(XY+o)    */
2325 OP(xycb,7c) { xycb_7e();										} /* BIT  7,(XY+o)    */
2326 OP(xycb,7d) { xycb_7e();										} /* BIT  7,(XY+o)    */
2327 OP(xycb,7e) { BIT_XY(7,RM(EA));									} /* BIT  7,(XY+o)    */
2328 OP(xycb,7f) { xycb_7e();										} /* BIT  7,(XY+o)    */
2329 
2330 OP(xycb,80) { B = RES(0, RM(EA) ); WM( EA,B );					} /* RES  0,B=(XY+o)  */
2331 OP(xycb,81) { C = RES(0, RM(EA) ); WM( EA,C );					} /* RES  0,C=(XY+o)  */
2332 OP(xycb,82) { D = RES(0, RM(EA) ); WM( EA,D );					} /* RES  0,D=(XY+o)  */
2333 OP(xycb,83) { E = RES(0, RM(EA) ); WM( EA,E );					} /* RES  0,E=(XY+o)  */
2334 OP(xycb,84) { H = RES(0, RM(EA) ); WM( EA,H );					} /* RES  0,H=(XY+o)  */
2335 OP(xycb,85) { L = RES(0, RM(EA) ); WM( EA,L );					} /* RES  0,L=(XY+o)  */
2336 OP(xycb,86) { WM( EA, RES(0,RM(EA)) );							} /* RES  0,(XY+o)    */
2337 OP(xycb,87) { A = RES(0, RM(EA) ); WM( EA,A );					} /* RES  0,A=(XY+o)  */
2338 
2339 OP(xycb,88) { B = RES(1, RM(EA) ); WM( EA,B );					} /* RES  1,B=(XY+o)  */
2340 OP(xycb,89) { C = RES(1, RM(EA) ); WM( EA,C );					} /* RES  1,C=(XY+o)  */
2341 OP(xycb,8a) { D = RES(1, RM(EA) ); WM( EA,D );					} /* RES  1,D=(XY+o)  */
2342 OP(xycb,8b) { E = RES(1, RM(EA) ); WM( EA,E );					} /* RES  1,E=(XY+o)  */
2343 OP(xycb,8c) { H = RES(1, RM(EA) ); WM( EA,H );					} /* RES  1,H=(XY+o)  */
2344 OP(xycb,8d) { L = RES(1, RM(EA) ); WM( EA,L );					} /* RES  1,L=(XY+o)  */
2345 OP(xycb,8e) { WM( EA, RES(1,RM(EA)) );							} /* RES  1,(XY+o)    */
2346 OP(xycb,8f) { A = RES(1, RM(EA) ); WM( EA,A );					} /* RES  1,A=(XY+o)  */
2347 
2348 OP(xycb,90) { B = RES(2, RM(EA) ); WM( EA,B );					} /* RES  2,B=(XY+o)  */
2349 OP(xycb,91) { C = RES(2, RM(EA) ); WM( EA,C );					} /* RES  2,C=(XY+o)  */
2350 OP(xycb,92) { D = RES(2, RM(EA) ); WM( EA,D );					} /* RES  2,D=(XY+o)  */
2351 OP(xycb,93) { E = RES(2, RM(EA) ); WM( EA,E );					} /* RES  2,E=(XY+o)  */
2352 OP(xycb,94) { H = RES(2, RM(EA) ); WM( EA,H );					} /* RES  2,H=(XY+o)  */
2353 OP(xycb,95) { L = RES(2, RM(EA) ); WM( EA,L );					} /* RES  2,L=(XY+o)  */
2354 OP(xycb,96) { WM( EA, RES(2,RM(EA)) );							} /* RES  2,(XY+o)    */
2355 OP(xycb,97) { A = RES(2, RM(EA) ); WM( EA,A );					} /* RES  2,A=(XY+o)  */
2356 
2357 OP(xycb,98) { B = RES(3, RM(EA) ); WM( EA,B );					} /* RES  3,B=(XY+o)  */
2358 OP(xycb,99) { C = RES(3, RM(EA) ); WM( EA,C );					} /* RES  3,C=(XY+o)  */
2359 OP(xycb,9a) { D = RES(3, RM(EA) ); WM( EA,D );					} /* RES  3,D=(XY+o)  */
2360 OP(xycb,9b) { E = RES(3, RM(EA) ); WM( EA,E );					} /* RES  3,E=(XY+o)  */
2361 OP(xycb,9c) { H = RES(3, RM(EA) ); WM( EA,H );					} /* RES  3,H=(XY+o)  */
2362 OP(xycb,9d) { L = RES(3, RM(EA) ); WM( EA,L );					} /* RES  3,L=(XY+o)  */
2363 OP(xycb,9e) { WM( EA, RES(3,RM(EA)) );							} /* RES  3,(XY+o)    */
2364 OP(xycb,9f) { A = RES(3, RM(EA) ); WM( EA,A );					} /* RES  3,A=(XY+o)  */
2365 
OP(xycb,a0)2366 OP(xycb,a0) { B = RES(4, RM(EA) ); WM( EA,B );					} /* RES  4,B=(XY+o)  */
OP(xycb,a1)2367 OP(xycb,a1) { C = RES(4, RM(EA) ); WM( EA,C );					} /* RES  4,C=(XY+o)  */
OP(xycb,a2)2368 OP(xycb,a2) { D = RES(4, RM(EA) ); WM( EA,D );					} /* RES  4,D=(XY+o)  */
OP(xycb,a3)2369 OP(xycb,a3) { E = RES(4, RM(EA) ); WM( EA,E );					} /* RES  4,E=(XY+o)  */
OP(xycb,a4)2370 OP(xycb,a4) { H = RES(4, RM(EA) ); WM( EA,H );					} /* RES  4,H=(XY+o)  */
OP(xycb,a5)2371 OP(xycb,a5) { L = RES(4, RM(EA) ); WM( EA,L );					} /* RES  4,L=(XY+o)  */
OP(xycb,a6)2372 OP(xycb,a6) { WM( EA, RES(4,RM(EA)) );							} /* RES  4,(XY+o)    */
OP(xycb,a7)2373 OP(xycb,a7) { A = RES(4, RM(EA) ); WM( EA,A );					} /* RES  4,A=(XY+o)  */
2374 
OP(xycb,a8)2375 OP(xycb,a8) { B = RES(5, RM(EA) ); WM( EA,B );					} /* RES  5,B=(XY+o)  */
OP(xycb,a9)2376 OP(xycb,a9) { C = RES(5, RM(EA) ); WM( EA,C );					} /* RES  5,C=(XY+o)  */
OP(xycb,aa)2377 OP(xycb,aa) { D = RES(5, RM(EA) ); WM( EA,D );					} /* RES  5,D=(XY+o)  */
OP(xycb,ab)2378 OP(xycb,ab) { E = RES(5, RM(EA) ); WM( EA,E );					} /* RES  5,E=(XY+o)  */
OP(xycb,ac)2379 OP(xycb,ac) { H = RES(5, RM(EA) ); WM( EA,H );					} /* RES  5,H=(XY+o)  */
OP(xycb,ad)2380 OP(xycb,ad) { L = RES(5, RM(EA) ); WM( EA,L );					} /* RES  5,L=(XY+o)  */
OP(xycb,ae)2381 OP(xycb,ae) { WM( EA, RES(5,RM(EA)) );							} /* RES  5,(XY+o)    */
OP(xycb,af)2382 OP(xycb,af) { A = RES(5, RM(EA) ); WM( EA,A );					} /* RES  5,A=(XY+o)  */
2383 
OP(xycb,b0)2384 OP(xycb,b0) { B = RES(6, RM(EA) ); WM( EA,B );					} /* RES  6,B=(XY+o)  */
OP(xycb,b1)2385 OP(xycb,b1) { C = RES(6, RM(EA) ); WM( EA,C );					} /* RES  6,C=(XY+o)  */
OP(xycb,b2)2386 OP(xycb,b2) { D = RES(6, RM(EA) ); WM( EA,D );					} /* RES  6,D=(XY+o)  */
OP(xycb,b3)2387 OP(xycb,b3) { E = RES(6, RM(EA) ); WM( EA,E );					} /* RES  6,E=(XY+o)  */
OP(xycb,b4)2388 OP(xycb,b4) { H = RES(6, RM(EA) ); WM( EA,H );					} /* RES  6,H=(XY+o)  */
OP(xycb,b5)2389 OP(xycb,b5) { L = RES(6, RM(EA) ); WM( EA,L );					} /* RES  6,L=(XY+o)  */
OP(xycb,b6)2390 OP(xycb,b6) { WM( EA, RES(6,RM(EA)) );							} /* RES  6,(XY+o)    */
OP(xycb,b7)2391 OP(xycb,b7) { A = RES(6, RM(EA) ); WM( EA,A );					} /* RES  6,A=(XY+o)  */
2392 
OP(xycb,b8)2393 OP(xycb,b8) { B = RES(7, RM(EA) ); WM( EA,B );					} /* RES  7,B=(XY+o)  */
OP(xycb,b9)2394 OP(xycb,b9) { C = RES(7, RM(EA) ); WM( EA,C );					} /* RES  7,C=(XY+o)  */
OP(xycb,ba)2395 OP(xycb,ba) { D = RES(7, RM(EA) ); WM( EA,D );					} /* RES  7,D=(XY+o)  */
OP(xycb,bb)2396 OP(xycb,bb) { E = RES(7, RM(EA) ); WM( EA,E );					} /* RES  7,E=(XY+o)  */
OP(xycb,bc)2397 OP(xycb,bc) { H = RES(7, RM(EA) ); WM( EA,H );					} /* RES  7,H=(XY+o)  */
OP(xycb,bd)2398 OP(xycb,bd) { L = RES(7, RM(EA) ); WM( EA,L );					} /* RES  7,L=(XY+o)  */
OP(xycb,be)2399 OP(xycb,be) { WM( EA, RES(7,RM(EA)) );							} /* RES  7,(XY+o)    */
OP(xycb,bf)2400 OP(xycb,bf) { A = RES(7, RM(EA) ); WM( EA,A );					} /* RES  7,A=(XY+o)  */
2401 
OP(xycb,c0)2402 OP(xycb,c0) { B = SET(0, RM(EA) ); WM( EA,B );					} /* SET  0,B=(XY+o)  */
OP(xycb,c1)2403 OP(xycb,c1) { C = SET(0, RM(EA) ); WM( EA,C );					} /* SET  0,C=(XY+o)  */
OP(xycb,c2)2404 OP(xycb,c2) { D = SET(0, RM(EA) ); WM( EA,D );					} /* SET  0,D=(XY+o)  */
OP(xycb,c3)2405 OP(xycb,c3) { E = SET(0, RM(EA) ); WM( EA,E );					} /* SET  0,E=(XY+o)  */
OP(xycb,c4)2406 OP(xycb,c4) { H = SET(0, RM(EA) ); WM( EA,H );					} /* SET  0,H=(XY+o)  */
OP(xycb,c5)2407 OP(xycb,c5) { L = SET(0, RM(EA) ); WM( EA,L );					} /* SET  0,L=(XY+o)  */
OP(xycb,c6)2408 OP(xycb,c6) { WM( EA, SET(0,RM(EA)) );							} /* SET  0,(XY+o)    */
OP(xycb,c7)2409 OP(xycb,c7) { A = SET(0, RM(EA) ); WM( EA,A );					} /* SET  0,A=(XY+o)  */
2410 
OP(xycb,c8)2411 OP(xycb,c8) { B = SET(1, RM(EA) ); WM( EA,B );					} /* SET  1,B=(XY+o)  */
OP(xycb,c9)2412 OP(xycb,c9) { C = SET(1, RM(EA) ); WM( EA,C );					} /* SET  1,C=(XY+o)  */
OP(xycb,ca)2413 OP(xycb,ca) { D = SET(1, RM(EA) ); WM( EA,D );					} /* SET  1,D=(XY+o)  */
OP(xycb,cb)2414 OP(xycb,cb) { E = SET(1, RM(EA) ); WM( EA,E );					} /* SET  1,E=(XY+o)  */
OP(xycb,cc)2415 OP(xycb,cc) { H = SET(1, RM(EA) ); WM( EA,H );					} /* SET  1,H=(XY+o)  */
OP(xycb,cd)2416 OP(xycb,cd) { L = SET(1, RM(EA) ); WM( EA,L );					} /* SET  1,L=(XY+o)  */
OP(xycb,ce)2417 OP(xycb,ce) { WM( EA, SET(1,RM(EA)) );							} /* SET  1,(XY+o)    */
OP(xycb,cf)2418 OP(xycb,cf) { A = SET(1, RM(EA) ); WM( EA,A );					} /* SET  1,A=(XY+o)  */
2419 
OP(xycb,d0)2420 OP(xycb,d0) { B = SET(2, RM(EA) ); WM( EA,B );					} /* SET  2,B=(XY+o)  */
OP(xycb,d1)2421 OP(xycb,d1) { C = SET(2, RM(EA) ); WM( EA,C );					} /* SET  2,C=(XY+o)  */
OP(xycb,d2)2422 OP(xycb,d2) { D = SET(2, RM(EA) ); WM( EA,D );					} /* SET  2,D=(XY+o)  */
OP(xycb,d3)2423 OP(xycb,d3) { E = SET(2, RM(EA) ); WM( EA,E );					} /* SET  2,E=(XY+o)  */
OP(xycb,d4)2424 OP(xycb,d4) { H = SET(2, RM(EA) ); WM( EA,H );					} /* SET  2,H=(XY+o)  */
OP(xycb,d5)2425 OP(xycb,d5) { L = SET(2, RM(EA) ); WM( EA,L );					} /* SET  2,L=(XY+o)  */
OP(xycb,d6)2426 OP(xycb,d6) { WM( EA, SET(2,RM(EA)) );							} /* SET  2,(XY+o)    */
OP(xycb,d7)2427 OP(xycb,d7) { A = SET(2, RM(EA) ); WM( EA,A );					} /* SET  2,A=(XY+o)  */
2428 
OP(xycb,d8)2429 OP(xycb,d8) { B = SET(3, RM(EA) ); WM( EA,B );					} /* SET  3,B=(XY+o)  */
OP(xycb,d9)2430 OP(xycb,d9) { C = SET(3, RM(EA) ); WM( EA,C );					} /* SET  3,C=(XY+o)  */
OP(xycb,da)2431 OP(xycb,da) { D = SET(3, RM(EA) ); WM( EA,D );					} /* SET  3,D=(XY+o)  */
OP(xycb,db)2432 OP(xycb,db) { E = SET(3, RM(EA) ); WM( EA,E );					} /* SET  3,E=(XY+o)  */
OP(xycb,dc)2433 OP(xycb,dc) { H = SET(3, RM(EA) ); WM( EA,H );					} /* SET  3,H=(XY+o)  */
OP(xycb,dd)2434 OP(xycb,dd) { L = SET(3, RM(EA) ); WM( EA,L );					} /* SET  3,L=(XY+o)  */
OP(xycb,de)2435 OP(xycb,de) { WM( EA, SET(3,RM(EA)) );							} /* SET  3,(XY+o)    */
OP(xycb,df)2436 OP(xycb,df) { A = SET(3, RM(EA) ); WM( EA,A );					} /* SET  3,A=(XY+o)  */
2437 
OP(xycb,e0)2438 OP(xycb,e0) { B = SET(4, RM(EA) ); WM( EA,B );					} /* SET  4,B=(XY+o)  */
OP(xycb,e1)2439 OP(xycb,e1) { C = SET(4, RM(EA) ); WM( EA,C );					} /* SET  4,C=(XY+o)  */
OP(xycb,e2)2440 OP(xycb,e2) { D = SET(4, RM(EA) ); WM( EA,D );					} /* SET  4,D=(XY+o)  */
OP(xycb,e3)2441 OP(xycb,e3) { E = SET(4, RM(EA) ); WM( EA,E );					} /* SET  4,E=(XY+o)  */
OP(xycb,e4)2442 OP(xycb,e4) { H = SET(4, RM(EA) ); WM( EA,H );					} /* SET  4,H=(XY+o)  */
OP(xycb,e5)2443 OP(xycb,e5) { L = SET(4, RM(EA) ); WM( EA,L );					} /* SET  4,L=(XY+o)  */
OP(xycb,e6)2444 OP(xycb,e6) { WM( EA, SET(4,RM(EA)) );							} /* SET  4,(XY+o)    */
OP(xycb,e7)2445 OP(xycb,e7) { A = SET(4, RM(EA) ); WM( EA,A );					} /* SET  4,A=(XY+o)  */
2446 
OP(xycb,e8)2447 OP(xycb,e8) { B = SET(5, RM(EA) ); WM( EA,B );					} /* SET  5,B=(XY+o)  */
OP(xycb,e9)2448 OP(xycb,e9) { C = SET(5, RM(EA) ); WM( EA,C );					} /* SET  5,C=(XY+o)  */
OP(xycb,ea)2449 OP(xycb,ea) { D = SET(5, RM(EA) ); WM( EA,D );					} /* SET  5,D=(XY+o)  */
OP(xycb,eb)2450 OP(xycb,eb) { E = SET(5, RM(EA) ); WM( EA,E );					} /* SET  5,E=(XY+o)  */
OP(xycb,ec)2451 OP(xycb,ec) { H = SET(5, RM(EA) ); WM( EA,H );					} /* SET  5,H=(XY+o)  */
OP(xycb,ed)2452 OP(xycb,ed) { L = SET(5, RM(EA) ); WM( EA,L );					} /* SET  5,L=(XY+o)  */
OP(xycb,ee)2453 OP(xycb,ee) { WM( EA, SET(5,RM(EA)) );							} /* SET  5,(XY+o)    */
OP(xycb,ef)2454 OP(xycb,ef) { A = SET(5, RM(EA) ); WM( EA,A );					} /* SET  5,A=(XY+o)  */
2455 
OP(xycb,f0)2456 OP(xycb,f0) { B = SET(6, RM(EA) ); WM( EA,B );					} /* SET  6,B=(XY+o)  */
OP(xycb,f1)2457 OP(xycb,f1) { C = SET(6, RM(EA) ); WM( EA,C );					} /* SET  6,C=(XY+o)  */
OP(xycb,f2)2458 OP(xycb,f2) { D = SET(6, RM(EA) ); WM( EA,D );					} /* SET  6,D=(XY+o)  */
OP(xycb,f3)2459 OP(xycb,f3) { E = SET(6, RM(EA) ); WM( EA,E );					} /* SET  6,E=(XY+o)  */
OP(xycb,f4)2460 OP(xycb,f4) { H = SET(6, RM(EA) ); WM( EA,H );					} /* SET  6,H=(XY+o)  */
OP(xycb,f5)2461 OP(xycb,f5) { L = SET(6, RM(EA) ); WM( EA,L );					} /* SET  6,L=(XY+o)  */
OP(xycb,f6)2462 OP(xycb,f6) { WM( EA, SET(6,RM(EA)) );								} /* SET  6,(XY+o)    */
OP(xycb,f7)2463 OP(xycb,f7) { A = SET(6, RM(EA) ); WM( EA,A );					} /* SET  6,A=(XY+o)  */
2464 
OP(xycb,f8)2465 OP(xycb,f8) { B = SET(7, RM(EA) ); WM( EA,B );					} /* SET  7,B=(XY+o)  */
OP(xycb,f9)2466 OP(xycb,f9) { C = SET(7, RM(EA) ); WM( EA,C );					} /* SET  7,C=(XY+o)  */
OP(xycb,fa)2467 OP(xycb,fa) { D = SET(7, RM(EA) ); WM( EA,D );					} /* SET  7,D=(XY+o)  */
OP(xycb,fb)2468 OP(xycb,fb) { E = SET(7, RM(EA) ); WM( EA,E );					} /* SET  7,E=(XY+o)  */
OP(xycb,fc)2469 OP(xycb,fc) { H = SET(7, RM(EA) ); WM( EA,H );					} /* SET  7,H=(XY+o)  */
OP(xycb,fd)2470 OP(xycb,fd) { L = SET(7, RM(EA) ); WM( EA,L );					} /* SET  7,L=(XY+o)  */
OP(xycb,fe)2471 OP(xycb,fe) { WM( EA, SET(7,RM(EA)) );							} /* SET  7,(XY+o)    */
OP(xycb,ff)2472 OP(xycb,ff) { A = SET(7, RM(EA) ); WM( EA,A );					} /* SET  7,A=(XY+o)  */
2473 
2474 OP(illegal,1) {
2475 //	logerror("Z80 #%d ill. opcode $%02x $%02x\n",
2476 //			cpu_getactivecpu(), cpu_readop((PCD-1)&0xffff), cpu_readop(PCD));
2477 }
2478 
2479 /**********************************************************
2480  * IX register related opcodes (DD prefix)
2481  **********************************************************/
2482 OP(dd,00) { illegal_1(); op_00();								} /* DB   DD          */
2483 OP(dd,01) { illegal_1(); op_01();								} /* DB   DD          */
2484 OP(dd,02) { illegal_1(); op_02();								} /* DB   DD          */
2485 OP(dd,03) { illegal_1(); op_03();								} /* DB   DD          */
2486 OP(dd,04) { illegal_1(); op_04();								} /* DB   DD          */
2487 OP(dd,05) { illegal_1(); op_05();								} /* DB   DD          */
2488 OP(dd,06) { illegal_1(); op_06();								} /* DB   DD          */
2489 OP(dd,07) { illegal_1(); op_07();								} /* DB   DD          */
2490 
2491 OP(dd,08) { illegal_1(); op_08();								} /* DB   DD          */
2492 OP(dd,09) { ADD16(ix,bc);									} /* ADD  IX,BC       */
2493 OP(dd,0a) { illegal_1(); op_0a();								} /* DB   DD          */
2494 OP(dd,0b) { illegal_1(); op_0b();								} /* DB   DD          */
2495 OP(dd,0c) { illegal_1(); op_0c();								} /* DB   DD          */
2496 OP(dd,0d) { illegal_1(); op_0d();								} /* DB   DD          */
2497 OP(dd,0e) { illegal_1(); op_0e();								} /* DB   DD          */
2498 OP(dd,0f) { illegal_1(); op_0f();								} /* DB   DD          */
2499 
2500 OP(dd,10) { illegal_1(); op_10();								} /* DB   DD          */
2501 OP(dd,11) { illegal_1(); op_11();								} /* DB   DD          */
2502 OP(dd,12) { illegal_1(); op_12();								} /* DB   DD          */
2503 OP(dd,13) { illegal_1(); op_13();								} /* DB   DD          */
2504 OP(dd,14) { illegal_1(); op_14();								} /* DB   DD          */
2505 OP(dd,15) { illegal_1(); op_15();								} /* DB   DD          */
2506 OP(dd,16) { illegal_1(); op_16();								} /* DB   DD          */
2507 OP(dd,17) { illegal_1(); op_17();								} /* DB   DD          */
2508 
2509 OP(dd,18) { illegal_1(); op_18();								} /* DB   DD          */
2510 OP(dd,19) { ADD16(ix,de);									} /* ADD  IX,DE       */
2511 OP(dd,1a) { illegal_1(); op_1a();								} /* DB   DD          */
2512 OP(dd,1b) { illegal_1(); op_1b();								} /* DB   DD          */
2513 OP(dd,1c) { illegal_1(); op_1c();								} /* DB   DD          */
2514 OP(dd,1d) { illegal_1(); op_1d();								} /* DB   DD          */
2515 OP(dd,1e) { illegal_1(); op_1e();								} /* DB   DD          */
2516 OP(dd,1f) { illegal_1(); op_1f();								} /* DB   DD          */
2517 
2518 OP(dd,20) { illegal_1(); op_20();								} /* DB   DD          */
2519 OP(dd,21) { IX = ARG16();									} /* LD   IX,w        */
2520 OP(dd,22) { EA = ARG16(); WM16( EA, &Z80.ix );  WZ = EA + 1;} /* LD   (w),IX      */
2521 OP(dd,23) { IX++;											} /* INC  IX          */
2522 OP(dd,24) { HX = INC(HX);									} /* INC  HX          */
2523 OP(dd,25) { HX = DEC(HX);									} /* DEC  HX          */
2524 OP(dd,26) { HX = ARG();									} /* LD   HX,n        */
2525 OP(dd,27) { illegal_1(); op_27();								} /* DB   DD          */
2526 
2527 OP(dd,28) { illegal_1(); op_28();								} /* DB   DD          */
2528 OP(dd,29) { ADD16(ix,ix);									} /* ADD  IX,IX       */
2529 OP(dd,2a) { EA = ARG16(); RM16( EA, &Z80.ix );	WZ = EA + 1;} /* LD   IX,(w)      */
2530 OP(dd,2b) { IX--;											} /* DEC  IX          */
2531 OP(dd,2c) { LX = INC(LX);									} /* INC  LX          */
2532 OP(dd,2d) { LX = DEC(LX);									} /* DEC  LX          */
2533 OP(dd,2e) { LX = ARG();									} /* LD   LX,n        */
2534 OP(dd,2f) { illegal_1(); op_2f();								} /* DB   DD          */
2535 
2536 OP(dd,30) { illegal_1(); op_30();								} /* DB   DD          */
2537 OP(dd,31) { illegal_1(); op_31();								} /* DB   DD          */
2538 OP(dd,32) { illegal_1(); op_32();								} /* DB   DD          */
2539 OP(dd,33) { illegal_1(); op_33();								} /* DB   DD          */
2540 OP(dd,34) { EAX; WM( EA, INC(RM(EA)) );					} /* INC  (IX+o)      */
2541 OP(dd,35) { EAX; WM( EA, DEC(RM(EA)) );					} /* DEC  (IX+o)      */
2542 OP(dd,36) { EAX; WM( EA, ARG() );							} /* LD   (IX+o),n    */
2543 OP(dd,37) { illegal_1(); op_37();								} /* DB   DD          */
2544 
2545 OP(dd,38) { illegal_1(); op_38();								} /* DB   DD          */
2546 OP(dd,39) { ADD16(ix,sp);									} /* ADD  IX,SP       */
2547 OP(dd,3a) { illegal_1(); op_3a();								} /* DB   DD          */
2548 OP(dd,3b) { illegal_1(); op_3b();								} /* DB   DD          */
2549 OP(dd,3c) { illegal_1(); op_3c();								} /* DB   DD          */
2550 OP(dd,3d) { illegal_1(); op_3d();								} /* DB   DD          */
2551 OP(dd,3e) { illegal_1(); op_3e();								} /* DB   DD          */
2552 OP(dd,3f) { illegal_1(); op_3f();								} /* DB   DD          */
2553 
2554 OP(dd,40) { illegal_1(); op_40();								} /* DB   DD          */
2555 OP(dd,41) { illegal_1(); op_41();								} /* DB   DD          */
2556 OP(dd,42) { illegal_1(); op_42();								} /* DB   DD          */
2557 OP(dd,43) { illegal_1(); op_43();								} /* DB   DD          */
2558 OP(dd,44) { B = HX;										} /* LD   B,HX        */
2559 OP(dd,45) { B = LX;										} /* LD   B,LX        */
2560 OP(dd,46) { EAX; B = RM(EA);								} /* LD   B,(IX+o)    */
2561 OP(dd,47) { illegal_1(); op_47();								} /* DB   DD          */
2562 
2563 OP(dd,48) { illegal_1(); op_48();								} /* DB   DD          */
2564 OP(dd,49) { illegal_1(); op_49();								} /* DB   DD          */
2565 OP(dd,4a) { illegal_1(); op_4a();								} /* DB   DD          */
2566 OP(dd,4b) { illegal_1(); op_4b();								} /* DB   DD          */
2567 OP(dd,4c) { C = HX;										} /* LD   C,HX        */
2568 OP(dd,4d) { C = LX;										} /* LD   C,LX        */
2569 OP(dd,4e) { EAX; C = RM(EA);								} /* LD   C,(IX+o)    */
2570 OP(dd,4f) { illegal_1(); op_4f();								} /* DB   DD          */
2571 
2572 OP(dd,50) { illegal_1(); op_50();								} /* DB   DD          */
2573 OP(dd,51) { illegal_1(); op_51();								} /* DB   DD          */
2574 OP(dd,52) { illegal_1(); op_52();								} /* DB   DD          */
2575 OP(dd,53) { illegal_1(); op_53();								} /* DB   DD          */
2576 OP(dd,54) { D = HX;										} /* LD   D,HX        */
2577 OP(dd,55) { D = LX;										} /* LD   D,LX        */
2578 OP(dd,56) { EAX; D = RM(EA);								} /* LD   D,(IX+o)    */
2579 OP(dd,57) { illegal_1(); op_57();								} /* DB   DD          */
2580 
2581 OP(dd,58) { illegal_1(); op_58();								} /* DB   DD          */
2582 OP(dd,59) { illegal_1(); op_59();								} /* DB   DD          */
2583 OP(dd,5a) { illegal_1(); op_5a();								} /* DB   DD          */
2584 OP(dd,5b) { illegal_1(); op_5b();								} /* DB   DD          */
2585 OP(dd,5c) { E = HX;										} /* LD   E,HX        */
2586 OP(dd,5d) { E = LX;										} /* LD   E,LX        */
2587 OP(dd,5e) { EAX; E = RM(EA);								} /* LD   E,(IX+o)    */
2588 OP(dd,5f) { illegal_1(); op_5f();								} /* DB   DD          */
2589 
2590 OP(dd,60) { HX = B;										} /* LD   HX,B        */
2591 OP(dd,61) { HX = C;										} /* LD   HX,C        */
2592 OP(dd,62) { HX = D;										} /* LD   HX,D        */
2593 OP(dd,63) { HX = E;										} /* LD   HX,E        */
2594 OP(dd,64) {														} /* LD   HX,HX       */
2595 OP(dd,65) { HX = LX;										} /* LD   HX,LX       */
2596 OP(dd,66) { EAX; H = RM(EA);								} /* LD   H,(IX+o)    */
2597 OP(dd,67) { HX = A;										} /* LD   HX,A        */
2598 
2599 OP(dd,68) { LX = B;										} /* LD   LX,B        */
2600 OP(dd,69) { LX = C;										} /* LD   LX,C        */
2601 OP(dd,6a) { LX = D;										} /* LD   LX,D        */
2602 OP(dd,6b) { LX = E;										} /* LD   LX,E        */
2603 OP(dd,6c) { LX = HX;										} /* LD   LX,HX       */
2604 OP(dd,6d) {														} /* LD   LX,LX       */
2605 OP(dd,6e) { EAX; L = RM(EA);								} /* LD   L,(IX+o)    */
2606 OP(dd,6f) { LX = A;										} /* LD   LX,A        */
2607 
2608 OP(dd,70) { EAX; WM( EA, B );								} /* LD   (IX+o),B    */
2609 OP(dd,71) { EAX; WM( EA, C );								} /* LD   (IX+o),C    */
2610 OP(dd,72) { EAX; WM( EA, D );								} /* LD   (IX+o),D    */
2611 OP(dd,73) { EAX; WM( EA, E );								} /* LD   (IX+o),E    */
2612 OP(dd,74) { EAX; WM( EA, H );								} /* LD   (IX+o),H    */
2613 OP(dd,75) { EAX; WM( EA, L );								} /* LD   (IX+o),L    */
2614 OP(dd,76) { illegal_1(); op_76();								} /* DB   DD          */
2615 OP(dd,77) { EAX; WM( EA, A );								} /* LD   (IX+o),A    */
2616 
2617 OP(dd,78) { illegal_1(); op_78();								} /* DB   DD          */
2618 OP(dd,79) { illegal_1(); op_79();								} /* DB   DD          */
2619 OP(dd,7a) { illegal_1(); op_7a();								} /* DB   DD          */
2620 OP(dd,7b) { illegal_1(); op_7b();								} /* DB   DD          */
2621 OP(dd,7c) { A = HX;										} /* LD   A,HX        */
2622 OP(dd,7d) { A = LX;										} /* LD   A,LX        */
2623 OP(dd,7e) { EAX; A = RM(EA);								} /* LD   A,(IX+o)    */
2624 OP(dd,7f) { illegal_1(); op_7f();								} /* DB   DD          */
2625 
2626 OP(dd,80) { illegal_1(); op_80();								} /* DB   DD          */
2627 OP(dd,81) { illegal_1(); op_81();								} /* DB   DD          */
2628 OP(dd,82) { illegal_1(); op_82();								} /* DB   DD          */
2629 OP(dd,83) { illegal_1(); op_83();								} /* DB   DD          */
2630 OP(dd,84) { ADD(HX);										} /* ADD  A,HX        */
2631 OP(dd,85) { ADD(LX);										} /* ADD  A,LX        */
2632 OP(dd,86) { EAX; ADD(RM(EA));								} /* ADD  A,(IX+o)    */
2633 OP(dd,87) { illegal_1(); op_87();								} /* DB   DD          */
2634 
2635 OP(dd,88) { illegal_1(); op_88();								} /* DB   DD          */
2636 OP(dd,89) { illegal_1(); op_89();								} /* DB   DD          */
2637 OP(dd,8a) { illegal_1(); op_8a();								} /* DB   DD          */
2638 OP(dd,8b) { illegal_1(); op_8b();								} /* DB   DD          */
2639 OP(dd,8c) { ADC(HX);										} /* ADC  A,HX        */
2640 OP(dd,8d) { ADC(LX);										} /* ADC  A,LX        */
2641 OP(dd,8e) { EAX; ADC(RM(EA));								} /* ADC  A,(IX+o)    */
2642 OP(dd,8f) { illegal_1(); op_8f();								} /* DB   DD          */
2643 
2644 OP(dd,90) { illegal_1(); op_90();								} /* DB   DD          */
2645 OP(dd,91) { illegal_1(); op_91();								} /* DB   DD          */
2646 OP(dd,92) { illegal_1(); op_92();								} /* DB   DD          */
2647 OP(dd,93) { illegal_1(); op_93();								} /* DB   DD          */
2648 OP(dd,94) { SUB(HX);										} /* SUB  HX          */
2649 OP(dd,95) { SUB(LX);										} /* SUB  LX          */
2650 OP(dd,96) { EAX; SUB(RM(EA));								} /* SUB  (IX+o)      */
2651 OP(dd,97) { illegal_1(); op_97();								} /* DB   DD          */
2652 
2653 OP(dd,98) { illegal_1(); op_98();								} /* DB   DD          */
2654 OP(dd,99) { illegal_1(); op_99();								} /* DB   DD          */
2655 OP(dd,9a) { illegal_1(); op_9a();								} /* DB   DD          */
2656 OP(dd,9b) { illegal_1(); op_9b();								} /* DB   DD          */
2657 OP(dd,9c) { SBC(HX);										} /* SBC  A,HX        */
2658 OP(dd,9d) { SBC(LX);										} /* SBC  A,LX        */
2659 OP(dd,9e) { EAX; SBC(RM(EA));								} /* SBC  A,(IX+o)    */
2660 OP(dd,9f) { illegal_1(); op_9f();								} /* DB   DD          */
2661 
OP(dd,a0)2662 OP(dd,a0) { illegal_1(); op_a0();								} /* DB   DD          */
OP(dd,a1)2663 OP(dd,a1) { illegal_1(); op_a1();								} /* DB   DD          */
OP(dd,a2)2664 OP(dd,a2) { illegal_1(); op_a2();								} /* DB   DD          */
OP(dd,a3)2665 OP(dd,a3) { illegal_1(); op_a3();								} /* DB   DD          */
OP(dd,a4)2666 OP(dd,a4) { AND(HX);										} /* AND  HX          */
OP(dd,a5)2667 OP(dd,a5) { AND(LX);										} /* AND  LX          */
OP(dd,a6)2668 OP(dd,a6) { EAX; AND(RM(EA));								} /* AND  (IX+o)      */
OP(dd,a7)2669 OP(dd,a7) { illegal_1(); op_a7();								} /* DB   DD          */
2670 
OP(dd,a8)2671 OP(dd,a8) { illegal_1(); op_a8();								} /* DB   DD          */
OP(dd,a9)2672 OP(dd,a9) { illegal_1(); op_a9();								} /* DB   DD          */
OP(dd,aa)2673 OP(dd,aa) { illegal_1(); op_aa();								} /* DB   DD          */
OP(dd,ab)2674 OP(dd,ab) { illegal_1(); op_ab();								} /* DB   DD          */
OP(dd,ac)2675 OP(dd,ac) { XOR(HX);										} /* XOR  HX          */
OP(dd,ad)2676 OP(dd,ad) { XOR(LX);										} /* XOR  LX          */
OP(dd,ae)2677 OP(dd,ae) { EAX; XOR(RM(EA));								} /* XOR  (IX+o)      */
OP(dd,af)2678 OP(dd,af) { illegal_1(); op_af();								} /* DB   DD          */
2679 
OP(dd,b0)2680 OP(dd,b0) { illegal_1(); op_b0();								} /* DB   DD          */
OP(dd,b1)2681 OP(dd,b1) { illegal_1(); op_b1();								} /* DB   DD          */
OP(dd,b2)2682 OP(dd,b2) { illegal_1(); op_b2();								} /* DB   DD          */
OP(dd,b3)2683 OP(dd,b3) { illegal_1(); op_b3();								} /* DB   DD          */
OP(dd,b4)2684 OP(dd,b4) { OR(HX);										} /* OR   HX          */
OP(dd,b5)2685 OP(dd,b5) { OR(LX);										} /* OR   LX          */
OP(dd,b6)2686 OP(dd,b6) { EAX; OR(RM(EA));								} /* OR   (IX+o)      */
OP(dd,b7)2687 OP(dd,b7) { illegal_1(); op_b7();								} /* DB   DD          */
2688 
OP(dd,b8)2689 OP(dd,b8) { illegal_1(); op_b8();								} /* DB   DD          */
OP(dd,b9)2690 OP(dd,b9) { illegal_1(); op_b9();								} /* DB   DD          */
OP(dd,ba)2691 OP(dd,ba) { illegal_1(); op_ba();								} /* DB   DD          */
OP(dd,bb)2692 OP(dd,bb) { illegal_1(); op_bb();								} /* DB   DD          */
OP(dd,bc)2693 OP(dd,bc) { CP(HX);										} /* CP   HX          */
OP(dd,bd)2694 OP(dd,bd) { CP(LX);										} /* CP   LX          */
OP(dd,be)2695 OP(dd,be) { EAX; CP(RM(EA));								} /* CP   (IX+o)      */
OP(dd,bf)2696 OP(dd,bf) { illegal_1(); op_bf();								} /* DB   DD          */
2697 
OP(dd,c0)2698 OP(dd,c0) { illegal_1(); op_c0();								} /* DB   DD          */
OP(dd,c1)2699 OP(dd,c1) { illegal_1(); op_c1();								} /* DB   DD          */
OP(dd,c2)2700 OP(dd,c2) { illegal_1(); op_c2();								} /* DB   DD          */
OP(dd,c3)2701 OP(dd,c3) { illegal_1(); op_c3();								} /* DB   DD          */
OP(dd,c4)2702 OP(dd,c4) { illegal_1(); op_c4();								} /* DB   DD          */
OP(dd,c5)2703 OP(dd,c5) { illegal_1(); op_c5();								} /* DB   DD          */
OP(dd,c6)2704 OP(dd,c6) { illegal_1(); op_c6();								} /* DB   DD          */
OP(dd,c7)2705 OP(dd,c7) { illegal_1(); op_c7();								}		  /* DB   DD          */
2706 
OP(dd,c8)2707 OP(dd,c8) { illegal_1(); op_c8();								} /* DB   DD          */
OP(dd,c9)2708 OP(dd,c9) { illegal_1(); op_c9();								} /* DB   DD          */
OP(dd,ca)2709 OP(dd,ca) { illegal_1(); op_ca();								} /* DB   DD          */
OP(dd,cb)2710 OP(dd,cb) { EAX; EXEC(xycb,ARG());							} /* **   DD CB xx    */
OP(dd,cc)2711 OP(dd,cc) { illegal_1(); op_cc();								} /* DB   DD          */
OP(dd,cd)2712 OP(dd,cd) { illegal_1(); op_cd();								} /* DB   DD          */
OP(dd,ce)2713 OP(dd,ce) { illegal_1(); op_ce();								} /* DB   DD          */
OP(dd,cf)2714 OP(dd,cf) { illegal_1(); op_cf();								} /* DB   DD          */
2715 
OP(dd,d0)2716 OP(dd,d0) { illegal_1(); op_d0();								} /* DB   DD          */
OP(dd,d1)2717 OP(dd,d1) { illegal_1(); op_d1();								} /* DB   DD          */
OP(dd,d2)2718 OP(dd,d2) { illegal_1(); op_d2();								} /* DB   DD          */
OP(dd,d3)2719 OP(dd,d3) { illegal_1(); op_d3();								} /* DB   DD          */
OP(dd,d4)2720 OP(dd,d4) { illegal_1(); op_d4();								} /* DB   DD          */
OP(dd,d5)2721 OP(dd,d5) { illegal_1(); op_d5();								} /* DB   DD          */
OP(dd,d6)2722 OP(dd,d6) { illegal_1(); op_d6();								} /* DB   DD          */
OP(dd,d7)2723 OP(dd,d7) { illegal_1(); op_d7();								} /* DB   DD          */
2724 
OP(dd,d8)2725 OP(dd,d8) { illegal_1(); op_d8();								} /* DB   DD          */
OP(dd,d9)2726 OP(dd,d9) { illegal_1(); op_d9();								} /* DB   DD          */
OP(dd,da)2727 OP(dd,da) { illegal_1(); op_da();								} /* DB   DD          */
OP(dd,db)2728 OP(dd,db) { illegal_1(); op_db();								} /* DB   DD          */
OP(dd,dc)2729 OP(dd,dc) { illegal_1(); op_dc();								} /* DB   DD          */
OP(dd,dd)2730 OP(dd,dd) { illegal_1(); op_dd();								} /* DB   DD          */
OP(dd,de)2731 OP(dd,de) { illegal_1(); op_de();								} /* DB   DD          */
OP(dd,df)2732 OP(dd,df) { illegal_1(); op_df();								} /* DB   DD          */
2733 
OP(dd,e0)2734 OP(dd,e0) { illegal_1(); op_e0();								} /* DB   DD          */
OP(dd,e1)2735 OP(dd,e1) { POP( ix );										} /* POP  IX          */
OP(dd,e2)2736 OP(dd,e2) { illegal_1(); op_e2();								} /* DB   DD          */
OP(dd,e3)2737 OP(dd,e3) { EXSP( ix );									} /* EX   (SP),IX     */
OP(dd,e4)2738 OP(dd,e4) { illegal_1(); op_e4();								} /* DB   DD          */
OP(dd,e5)2739 OP(dd,e5) { PUSH( ix );									} /* PUSH IX          */
OP(dd,e6)2740 OP(dd,e6) { illegal_1(); op_e6();								} /* DB   DD          */
OP(dd,e7)2741 OP(dd,e7) { illegal_1(); op_e7();								} /* DB   DD          */
2742 
OP(dd,e8)2743 OP(dd,e8) { illegal_1(); op_e8();								} /* DB   DD          */
OP(dd,e9)2744 OP(dd,e9) { PC = IX; change_pc(PCD);						} /* JP   (IX)        */
OP(dd,ea)2745 OP(dd,ea) { illegal_1(); op_ea();								} /* DB   DD          */
OP(dd,eb)2746 OP(dd,eb) { illegal_1(); op_eb();								} /* DB   DD          */
OP(dd,ec)2747 OP(dd,ec) { illegal_1(); op_ec();								} /* DB   DD          */
OP(dd,ed)2748 OP(dd,ed) { illegal_1(); op_ed();								} /* DB   DD          */
OP(dd,ee)2749 OP(dd,ee) { illegal_1(); op_ee();								} /* DB   DD          */
OP(dd,ef)2750 OP(dd,ef) { illegal_1(); op_ef();								} /* DB   DD          */
2751 
OP(dd,f0)2752 OP(dd,f0) { illegal_1(); op_f0();								} /* DB   DD          */
OP(dd,f1)2753 OP(dd,f1) { illegal_1(); op_f1();								} /* DB   DD          */
OP(dd,f2)2754 OP(dd,f2) { illegal_1(); op_f2();								} /* DB   DD          */
OP(dd,f3)2755 OP(dd,f3) { illegal_1(); op_f3();								} /* DB   DD          */
OP(dd,f4)2756 OP(dd,f4) { illegal_1(); op_f4();								} /* DB   DD          */
OP(dd,f5)2757 OP(dd,f5) { illegal_1(); op_f5();								} /* DB   DD          */
OP(dd,f6)2758 OP(dd,f6) { illegal_1(); op_f6();								} /* DB   DD          */
OP(dd,f7)2759 OP(dd,f7) { illegal_1(); op_f7();								} /* DB   DD          */
2760 
OP(dd,f8)2761 OP(dd,f8) { illegal_1(); op_f8();								} /* DB   DD          */
OP(dd,f9)2762 OP(dd,f9) { SP = IX;										} /* LD   SP,IX       */
OP(dd,fa)2763 OP(dd,fa) { illegal_1(); op_fa();								} /* DB   DD          */
OP(dd,fb)2764 OP(dd,fb) { illegal_1(); op_fb();								} /* DB   DD          */
OP(dd,fc)2765 OP(dd,fc) { illegal_1(); op_fc();								} /* DB   DD          */
OP(dd,fd)2766 OP(dd,fd) { illegal_1(); op_fd();								} /* DB   DD          */
OP(dd,fe)2767 OP(dd,fe) { illegal_1(); op_fe();								} /* DB   DD          */
OP(dd,ff)2768 OP(dd,ff) { illegal_1(); op_ff();								} /* DB   DD          */
2769 
2770 /**********************************************************
2771  * IY register related opcodes (FD prefix)
2772  **********************************************************/
2773 OP(fd,00) { illegal_1(); op_00();								} /* DB   FD          */
2774 OP(fd,01) { illegal_1(); op_01();								} /* DB   FD          */
2775 OP(fd,02) { illegal_1(); op_02();								} /* DB   FD          */
2776 OP(fd,03) { illegal_1(); op_03();								} /* DB   FD          */
2777 OP(fd,04) { illegal_1(); op_04();								} /* DB   FD          */
2778 OP(fd,05) { illegal_1(); op_05();								} /* DB   FD          */
2779 OP(fd,06) { illegal_1(); op_06();								} /* DB   FD          */
2780 OP(fd,07) { illegal_1(); op_07();								} /* DB   FD          */
2781 
2782 OP(fd,08) { illegal_1(); op_08();								} /* DB   FD          */
2783 OP(fd,09) { ADD16(iy,bc);									} /* ADD  IY,BC       */
2784 OP(fd,0a) { illegal_1(); op_0a();								} /* DB   FD          */
2785 OP(fd,0b) { illegal_1(); op_0b();								} /* DB   FD          */
2786 OP(fd,0c) { illegal_1(); op_0c();								} /* DB   FD          */
2787 OP(fd,0d) { illegal_1(); op_0d();								} /* DB   FD          */
2788 OP(fd,0e) { illegal_1(); op_0e();								} /* DB   FD          */
2789 OP(fd,0f) { illegal_1(); op_0f();								} /* DB   FD          */
2790 
2791 OP(fd,10) { illegal_1(); op_10();								} /* DB   FD          */
2792 OP(fd,11) { illegal_1(); op_11();								} /* DB   FD          */
2793 OP(fd,12) { illegal_1(); op_12();								} /* DB   FD          */
2794 OP(fd,13) { illegal_1(); op_13();								} /* DB   FD          */
2795 OP(fd,14) { illegal_1(); op_14();								} /* DB   FD          */
2796 OP(fd,15) { illegal_1(); op_15();								} /* DB   FD          */
2797 OP(fd,16) { illegal_1(); op_16();								} /* DB   FD          */
2798 OP(fd,17) { illegal_1(); op_17();								} /* DB   FD          */
2799 
2800 OP(fd,18) { illegal_1(); op_18();								} /* DB   FD          */
2801 OP(fd,19) { ADD16(iy,de);									} /* ADD  IY,DE       */
2802 OP(fd,1a) { illegal_1(); op_1a();								} /* DB   FD          */
2803 OP(fd,1b) { illegal_1(); op_1b();								} /* DB   FD          */
2804 OP(fd,1c) { illegal_1(); op_1c();								} /* DB   FD          */
2805 OP(fd,1d) { illegal_1(); op_1d();								} /* DB   FD          */
2806 OP(fd,1e) { illegal_1(); op_1e();								} /* DB   FD          */
2807 OP(fd,1f) { illegal_1(); op_1f();								} /* DB   FD          */
2808 
2809 OP(fd,20) { illegal_1(); op_20();								} /* DB   FD          */
2810 OP(fd,21) { IY = ARG16();									} /* LD   IY,w        */
2811 OP(fd,22) { EA = ARG16(); WM16( EA, &Z80.iy );	WZ = EA + 1;			} /* LD   (w),IY      */
2812 OP(fd,23) { IY++;											} /* INC  IY          */
2813 OP(fd,24) { HY = INC(HY);									} /* INC  HY          */
2814 OP(fd,25) { HY = DEC(HY);									} /* DEC  HY          */
2815 OP(fd,26) { HY = ARG();									} /* LD   HY,n        */
2816 OP(fd,27) { illegal_1(); op_27();								} /* DB   FD          */
2817 
2818 OP(fd,28) { illegal_1(); op_28();								} /* DB   FD          */
2819 OP(fd,29) { ADD16(iy,iy);									} /* ADD  IY,IY       */
2820 OP(fd,2a) { EA = ARG16(); RM16( EA, &Z80.iy );	WZ = EA + 1;			} /* LD   IY,(w)      */
2821 OP(fd,2b) { IY--;											} /* DEC  IY          */
2822 OP(fd,2c) { LY = INC(LY);									} /* INC  LY          */
2823 OP(fd,2d) { LY = DEC(LY);									} /* DEC  LY          */
2824 OP(fd,2e) { LY = ARG();									} /* LD   LY,n        */
2825 OP(fd,2f) { illegal_1(); op_2f();								} /* DB   FD          */
2826 
2827 OP(fd,30) { illegal_1(); op_30();								} /* DB   FD          */
2828 OP(fd,31) { illegal_1(); op_31();								} /* DB   FD          */
2829 OP(fd,32) { illegal_1(); op_32();								} /* DB   FD          */
2830 OP(fd,33) { illegal_1(); op_33();								} /* DB   FD          */
2831 OP(fd,34) { EAY; WM( EA, INC(RM(EA)) );					} /* INC  (IY+o)      */
2832 OP(fd,35) { EAY; WM( EA, DEC(RM(EA)) );					} /* DEC  (IY+o)      */
2833 OP(fd,36) { EAY; WM( EA, ARG() );							} /* LD   (IY+o),n    */
2834 OP(fd,37) { illegal_1(); op_37();								} /* DB   FD          */
2835 
2836 OP(fd,38) { illegal_1(); op_38();								} /* DB   FD          */
2837 OP(fd,39) { ADD16(iy,sp);									} /* ADD  IY,SP       */
2838 OP(fd,3a) { illegal_1(); op_3a();								} /* DB   FD          */
2839 OP(fd,3b) { illegal_1(); op_3b();								} /* DB   FD          */
2840 OP(fd,3c) { illegal_1(); op_3c();								} /* DB   FD          */
2841 OP(fd,3d) { illegal_1(); op_3d();								} /* DB   FD          */
2842 OP(fd,3e) { illegal_1(); op_3e();								} /* DB   FD          */
2843 OP(fd,3f) { illegal_1(); op_3f();								} /* DB   FD          */
2844 
2845 OP(fd,40) { illegal_1(); op_40();								} /* DB   FD          */
2846 OP(fd,41) { illegal_1(); op_41();								} /* DB   FD          */
2847 OP(fd,42) { illegal_1(); op_42();								} /* DB   FD          */
2848 OP(fd,43) { illegal_1(); op_43();								} /* DB   FD          */
2849 OP(fd,44) { B = HY;										} /* LD   B,HY        */
2850 OP(fd,45) { B = LY;										} /* LD   B,LY        */
2851 OP(fd,46) { EAY; B = RM(EA);								} /* LD   B,(IY+o)    */
2852 OP(fd,47) { illegal_1(); op_47();								} /* DB   FD          */
2853 
2854 OP(fd,48) { illegal_1(); op_48();								} /* DB   FD          */
2855 OP(fd,49) { illegal_1(); op_49();								} /* DB   FD          */
2856 OP(fd,4a) { illegal_1(); op_4a();								} /* DB   FD          */
2857 OP(fd,4b) { illegal_1(); op_4b();								} /* DB   FD          */
2858 OP(fd,4c) { C = HY;										} /* LD   C,HY        */
2859 OP(fd,4d) { C = LY;										} /* LD   C,LY        */
2860 OP(fd,4e) { EAY; C = RM(EA);								} /* LD   C,(IY+o)    */
2861 OP(fd,4f) { illegal_1(); op_4f();								} /* DB   FD          */
2862 
2863 OP(fd,50) { illegal_1(); op_50();								} /* DB   FD          */
2864 OP(fd,51) { illegal_1(); op_51();								} /* DB   FD          */
2865 OP(fd,52) { illegal_1(); op_52();								} /* DB   FD          */
2866 OP(fd,53) { illegal_1(); op_53();								} /* DB   FD          */
2867 OP(fd,54) { D = HY;										} /* LD   D,HY        */
2868 OP(fd,55) { D = LY;										} /* LD   D,LY        */
2869 OP(fd,56) { EAY; D = RM(EA);								} /* LD   D,(IY+o)    */
2870 OP(fd,57) { illegal_1(); op_57();								} /* DB   FD          */
2871 
2872 OP(fd,58) { illegal_1(); op_58();								} /* DB   FD          */
2873 OP(fd,59) { illegal_1(); op_59();								} /* DB   FD          */
2874 OP(fd,5a) { illegal_1(); op_5a();								} /* DB   FD          */
2875 OP(fd,5b) { illegal_1(); op_5b();								} /* DB   FD          */
2876 OP(fd,5c) { E = HY;										} /* LD   E,HY        */
2877 OP(fd,5d) { E = LY;										} /* LD   E,LY        */
2878 OP(fd,5e) { EAY; E = RM(EA);								} /* LD   E,(IY+o)    */
2879 OP(fd,5f) { illegal_1(); op_5f();								} /* DB   FD          */
2880 
2881 OP(fd,60) { HY = B;										} /* LD   HY,B        */
2882 OP(fd,61) { HY = C;										} /* LD   HY,C        */
2883 OP(fd,62) { HY = D;										} /* LD   HY,D        */
2884 OP(fd,63) { HY = E;										} /* LD   HY,E        */
2885 OP(fd,64) {												} /* LD   HY,HY       */
2886 OP(fd,65) { HY = LY;										} /* LD   HY,LY       */
2887 OP(fd,66) { EAY; H = RM(EA);								} /* LD   H,(IY+o)    */
2888 OP(fd,67) { HY = A;										} /* LD   HY,A        */
2889 
2890 OP(fd,68) { LY = B;										} /* LD   LY,B        */
2891 OP(fd,69) { LY = C;										} /* LD   LY,C        */
2892 OP(fd,6a) { LY = D;										} /* LD   LY,D        */
2893 OP(fd,6b) { LY = E;										} /* LD   LY,E        */
2894 OP(fd,6c) { LY = HY;										} /* LD   LY,HY       */
2895 OP(fd,6d) {												} /* LD   LY,LY       */
2896 OP(fd,6e) { EAY; L = RM(EA);								} /* LD   L,(IY+o)    */
2897 OP(fd,6f) { LY = A;										} /* LD   LY,A        */
2898 
2899 OP(fd,70) { EAY; WM( EA, B );								} /* LD   (IY+o),B    */
2900 OP(fd,71) { EAY; WM( EA, C );								} /* LD   (IY+o),C    */
2901 OP(fd,72) { EAY; WM( EA, D );								} /* LD   (IY+o),D    */
2902 OP(fd,73) { EAY; WM( EA, E );								} /* LD   (IY+o),E    */
2903 OP(fd,74) { EAY; WM( EA, H );								} /* LD   (IY+o),H    */
2904 OP(fd,75) { EAY; WM( EA, L );								} /* LD   (IY+o),L    */
2905 OP(fd,76) { illegal_1(); op_76();								} /* DB   FD          */
2906 OP(fd,77) { EAY; WM( EA, A );								} /* LD   (IY+o),A    */
2907 
2908 OP(fd,78) { illegal_1(); op_78();								} /* DB   FD          */
2909 OP(fd,79) { illegal_1(); op_79();								} /* DB   FD          */
2910 OP(fd,7a) { illegal_1(); op_7a();								} /* DB   FD          */
2911 OP(fd,7b) { illegal_1(); op_7b();								} /* DB   FD          */
2912 OP(fd,7c) { A = HY;										} /* LD   A,HY        */
2913 OP(fd,7d) { A = LY;										} /* LD   A,LY        */
2914 OP(fd,7e) { EAY; A = RM(EA);								} /* LD   A,(IY+o)    */
2915 OP(fd,7f) { illegal_1(); op_7f();								} /* DB   FD          */
2916 
2917 OP(fd,80) { illegal_1(); op_80();								} /* DB   FD          */
2918 OP(fd,81) { illegal_1(); op_81();								} /* DB   FD          */
2919 OP(fd,82) { illegal_1(); op_82();								} /* DB   FD          */
2920 OP(fd,83) { illegal_1(); op_83();								} /* DB   FD          */
2921 OP(fd,84) { ADD(HY);										} /* ADD  A,HY        */
2922 OP(fd,85) { ADD(LY);										} /* ADD  A,LY        */
2923 OP(fd,86) { EAY; ADD(RM(EA));								} /* ADD  A,(IY+o)    */
2924 OP(fd,87) { illegal_1(); op_87();								} /* DB   FD          */
2925 
2926 OP(fd,88) { illegal_1(); op_88();								} /* DB   FD          */
2927 OP(fd,89) { illegal_1(); op_89();								} /* DB   FD          */
2928 OP(fd,8a) { illegal_1(); op_8a();								} /* DB   FD          */
2929 OP(fd,8b) { illegal_1(); op_8b();								} /* DB   FD          */
2930 OP(fd,8c) { ADC(HY);										} /* ADC  A,HY        */
2931 OP(fd,8d) { ADC(LY);										} /* ADC  A,LY        */
2932 OP(fd,8e) { EAY; ADC(RM(EA));								} /* ADC  A,(IY+o)    */
2933 OP(fd,8f) { illegal_1(); op_8f();								} /* DB   FD          */
2934 
2935 OP(fd,90) { illegal_1(); op_90();								} /* DB   FD          */
2936 OP(fd,91) { illegal_1(); op_91();								} /* DB   FD          */
2937 OP(fd,92) { illegal_1(); op_92();								} /* DB   FD          */
2938 OP(fd,93) { illegal_1(); op_93();								} /* DB   FD          */
2939 OP(fd,94) { SUB(HY);										} /* SUB  HY          */
2940 OP(fd,95) { SUB(LY);										} /* SUB  LY          */
2941 OP(fd,96) { EAY; SUB(RM(EA));								} /* SUB  (IY+o)      */
2942 OP(fd,97) { illegal_1(); op_97();								} /* DB   FD          */
2943 
2944 OP(fd,98) { illegal_1(); op_98();								} /* DB   FD          */
2945 OP(fd,99) { illegal_1(); op_99();								} /* DB   FD          */
2946 OP(fd,9a) { illegal_1(); op_9a();								} /* DB   FD          */
2947 OP(fd,9b) { illegal_1(); op_9b();								} /* DB   FD          */
2948 OP(fd,9c) { SBC(HY);										} /* SBC  A,HY        */
2949 OP(fd,9d) { SBC(LY);										} /* SBC  A,LY        */
2950 OP(fd,9e) { EAY; SBC(RM(EA));								} /* SBC  A,(IY+o)    */
2951 OP(fd,9f) { illegal_1(); op_9f();								} /* DB   FD          */
2952 
OP(fd,a0)2953 OP(fd,a0) { illegal_1(); op_a0();								} /* DB   FD          */
OP(fd,a1)2954 OP(fd,a1) { illegal_1(); op_a1();								} /* DB   FD          */
OP(fd,a2)2955 OP(fd,a2) { illegal_1(); op_a2();								} /* DB   FD          */
OP(fd,a3)2956 OP(fd,a3) { illegal_1(); op_a3();								} /* DB   FD          */
OP(fd,a4)2957 OP(fd,a4) { AND(HY);										} /* AND  HY          */
OP(fd,a5)2958 OP(fd,a5) { AND(LY);										} /* AND  LY          */
OP(fd,a6)2959 OP(fd,a6) { EAY; AND(RM(EA));								} /* AND  (IY+o)      */
OP(fd,a7)2960 OP(fd,a7) { illegal_1(); op_a7();								} /* DB   FD          */
2961 
OP(fd,a8)2962 OP(fd,a8) { illegal_1(); op_a8();								} /* DB   FD          */
OP(fd,a9)2963 OP(fd,a9) { illegal_1(); op_a9();								} /* DB   FD          */
OP(fd,aa)2964 OP(fd,aa) { illegal_1(); op_aa();								} /* DB   FD          */
OP(fd,ab)2965 OP(fd,ab) { illegal_1(); op_ab();								} /* DB   FD          */
OP(fd,ac)2966 OP(fd,ac) { XOR(HY);										} /* XOR  HY          */
OP(fd,ad)2967 OP(fd,ad) { XOR(LY);										} /* XOR  LY          */
OP(fd,ae)2968 OP(fd,ae) { EAY; XOR(RM(EA));								} /* XOR  (IY+o)      */
OP(fd,af)2969 OP(fd,af) { illegal_1(); op_af();								} /* DB   FD          */
2970 
OP(fd,b0)2971 OP(fd,b0) { illegal_1(); op_b0();								} /* DB   FD          */
OP(fd,b1)2972 OP(fd,b1) { illegal_1(); op_b1();								} /* DB   FD          */
OP(fd,b2)2973 OP(fd,b2) { illegal_1(); op_b2();								} /* DB   FD          */
OP(fd,b3)2974 OP(fd,b3) { illegal_1(); op_b3();								} /* DB   FD          */
OP(fd,b4)2975 OP(fd,b4) { OR(HY);										} /* OR   HY          */
OP(fd,b5)2976 OP(fd,b5) { OR(LY);										} /* OR   LY          */
OP(fd,b6)2977 OP(fd,b6) { EAY; OR(RM(EA));								} /* OR   (IY+o)      */
OP(fd,b7)2978 OP(fd,b7) { illegal_1(); op_b7();								} /* DB   FD          */
2979 
OP(fd,b8)2980 OP(fd,b8) { illegal_1(); op_b8();								} /* DB   FD          */
OP(fd,b9)2981 OP(fd,b9) { illegal_1(); op_b9();								} /* DB   FD          */
OP(fd,ba)2982 OP(fd,ba) { illegal_1(); op_ba();								} /* DB   FD          */
OP(fd,bb)2983 OP(fd,bb) { illegal_1(); op_bb();								} /* DB   FD          */
OP(fd,bc)2984 OP(fd,bc) { CP(HY);										} /* CP   HY          */
OP(fd,bd)2985 OP(fd,bd) { CP(LY);										} /* CP   LY          */
OP(fd,be)2986 OP(fd,be) { EAY; CP(RM(EA));								} /* CP   (IY+o)      */
OP(fd,bf)2987 OP(fd,bf) { illegal_1(); op_bf();								} /* DB   FD          */
2988 
OP(fd,c0)2989 OP(fd,c0) { illegal_1(); op_c0();								} /* DB   FD          */
OP(fd,c1)2990 OP(fd,c1) { illegal_1(); op_c1();								} /* DB   FD          */
OP(fd,c2)2991 OP(fd,c2) { illegal_1(); op_c2();								} /* DB   FD          */
OP(fd,c3)2992 OP(fd,c3) { illegal_1(); op_c3();								} /* DB   FD          */
OP(fd,c4)2993 OP(fd,c4) { illegal_1(); op_c4();								} /* DB   FD          */
OP(fd,c5)2994 OP(fd,c5) { illegal_1(); op_c5();								} /* DB   FD          */
OP(fd,c6)2995 OP(fd,c6) { illegal_1(); op_c6();								} /* DB   FD          */
OP(fd,c7)2996 OP(fd,c7) { illegal_1(); op_c7();								} /* DB   FD          */
2997 
OP(fd,c8)2998 OP(fd,c8) { illegal_1(); op_c8();								} /* DB   FD          */
OP(fd,c9)2999 OP(fd,c9) { illegal_1(); op_c9();								} /* DB   FD          */
OP(fd,ca)3000 OP(fd,ca) { illegal_1(); op_ca();								} /* DB   FD          */
OP(fd,cb)3001 OP(fd,cb) { EAY; EXEC(xycb,ARG());							} /* **   FD CB xx    */
OP(fd,cc)3002 OP(fd,cc) { illegal_1(); op_cc();								} /* DB   FD          */
OP(fd,cd)3003 OP(fd,cd) { illegal_1(); op_cd();								} /* DB   FD          */
OP(fd,ce)3004 OP(fd,ce) { illegal_1(); op_ce();								} /* DB   FD          */
OP(fd,cf)3005 OP(fd,cf) { illegal_1(); op_cf();								} /* DB   FD          */
3006 
OP(fd,d0)3007 OP(fd,d0) { illegal_1(); op_d0();								} /* DB   FD          */
OP(fd,d1)3008 OP(fd,d1) { illegal_1(); op_d1();								} /* DB   FD          */
OP(fd,d2)3009 OP(fd,d2) { illegal_1(); op_d2();								} /* DB   FD          */
OP(fd,d3)3010 OP(fd,d3) { illegal_1(); op_d3();								} /* DB   FD          */
OP(fd,d4)3011 OP(fd,d4) { illegal_1(); op_d4();								} /* DB   FD          */
OP(fd,d5)3012 OP(fd,d5) { illegal_1(); op_d5();								} /* DB   FD          */
OP(fd,d6)3013 OP(fd,d6) { illegal_1(); op_d6();								} /* DB   FD          */
OP(fd,d7)3014 OP(fd,d7) { illegal_1(); op_d7();								} /* DB   FD          */
3015 
OP(fd,d8)3016 OP(fd,d8) { illegal_1(); op_d8();								} /* DB   FD          */
OP(fd,d9)3017 OP(fd,d9) { illegal_1(); op_d9();								} /* DB   FD          */
OP(fd,da)3018 OP(fd,da) { illegal_1(); op_da();								} /* DB   FD          */
OP(fd,db)3019 OP(fd,db) { illegal_1(); op_db();								} /* DB   FD          */
OP(fd,dc)3020 OP(fd,dc) { illegal_1(); op_dc();								} /* DB   FD          */
OP(fd,dd)3021 OP(fd,dd) { illegal_1(); op_dd();								} /* DB   FD          */
OP(fd,de)3022 OP(fd,de) { illegal_1(); op_de();								} /* DB   FD          */
OP(fd,df)3023 OP(fd,df) { illegal_1(); op_df();								} /* DB   FD          */
3024 
OP(fd,e0)3025 OP(fd,e0) { illegal_1(); op_e0();								} /* DB   FD          */
OP(fd,e1)3026 OP(fd,e1) { POP( iy );										} /* POP  IY          */
OP(fd,e2)3027 OP(fd,e2) { illegal_1(); op_e2();								} /* DB   FD          */
OP(fd,e3)3028 OP(fd,e3) { EXSP( iy );									} /* EX   (SP),IY     */
OP(fd,e4)3029 OP(fd,e4) { illegal_1(); op_e4();								} /* DB   FD          */
OP(fd,e5)3030 OP(fd,e5) { PUSH( iy );									} /* PUSH IY          */
OP(fd,e6)3031 OP(fd,e6) { illegal_1(); op_e6();								} /* DB   FD          */
OP(fd,e7)3032 OP(fd,e7) { illegal_1(); op_e7();								} /* DB   FD          */
3033 
OP(fd,e8)3034 OP(fd,e8) { illegal_1(); op_e8();								} /* DB   FD          */
OP(fd,e9)3035 OP(fd,e9) { PC = IY; change_pc(PCD);						} /* JP   (IY)        */
OP(fd,ea)3036 OP(fd,ea) { illegal_1(); op_ea();								} /* DB   FD          */
OP(fd,eb)3037 OP(fd,eb) { illegal_1(); op_eb();								} /* DB   FD          */
OP(fd,ec)3038 OP(fd,ec) { illegal_1(); op_ec();								} /* DB   FD          */
OP(fd,ed)3039 OP(fd,ed) { illegal_1(); op_ed();								} /* DB   FD          */
OP(fd,ee)3040 OP(fd,ee) { illegal_1(); op_ee();								} /* DB   FD          */
OP(fd,ef)3041 OP(fd,ef) { illegal_1(); op_ef();								} /* DB   FD          */
3042 
OP(fd,f0)3043 OP(fd,f0) { illegal_1(); op_f0();								} /* DB   FD          */
OP(fd,f1)3044 OP(fd,f1) { illegal_1(); op_f1();								} /* DB   FD          */
OP(fd,f2)3045 OP(fd,f2) { illegal_1(); op_f2();								} /* DB   FD          */
OP(fd,f3)3046 OP(fd,f3) { illegal_1(); op_f3();								} /* DB   FD          */
OP(fd,f4)3047 OP(fd,f4) { illegal_1(); op_f4();								} /* DB   FD          */
OP(fd,f5)3048 OP(fd,f5) { illegal_1(); op_f5();								} /* DB   FD          */
OP(fd,f6)3049 OP(fd,f6) { illegal_1(); op_f6();								} /* DB   FD          */
OP(fd,f7)3050 OP(fd,f7) { illegal_1(); op_f7();								} /* DB   FD          */
3051 
OP(fd,f8)3052 OP(fd,f8) { illegal_1(); op_f8();								} /* DB   FD          */
OP(fd,f9)3053 OP(fd,f9) { SP = IY;										} /* LD   SP,IY       */
OP(fd,fa)3054 OP(fd,fa) { illegal_1(); op_fa();								} /* DB   FD          */
OP(fd,fb)3055 OP(fd,fb) { illegal_1(); op_fb();								} /* DB   FD          */
OP(fd,fc)3056 OP(fd,fc) { illegal_1(); op_fc();								} /* DB   FD          */
OP(fd,fd)3057 OP(fd,fd) { illegal_1(); op_fd();								} /* DB   FD          */
OP(fd,fe)3058 OP(fd,fe) { illegal_1(); op_fe();								} /* DB   FD          */
OP(fd,ff)3059 OP(fd,ff) { illegal_1(); op_ff();								} /* DB   FD          */
3060 
3061 OP(illegal,2)
3062 {
3063 //	logerror("Z80 #%d ill. opcode $ed $%02x\n",
3064 //			cpu_getactivecpu(), cpu_readop((PCD-1)&0xffff));
3065 }
3066 
3067 /**********************************************************
3068  * special opcodes (ED prefix)
3069  **********************************************************/
3070 OP(ed,00) { illegal_2();										} /* DB   ED          */
3071 OP(ed,01) { illegal_2();										} /* DB   ED          */
3072 OP(ed,02) { illegal_2();										} /* DB   ED          */
3073 OP(ed,03) { illegal_2();										} /* DB   ED          */
3074 OP(ed,04) { illegal_2();										} /* DB   ED          */
3075 OP(ed,05) { illegal_2();										} /* DB   ED          */
3076 OP(ed,06) { illegal_2();										} /* DB   ED          */
3077 OP(ed,07) { illegal_2();										} /* DB   ED          */
3078 
3079 OP(ed,08) { illegal_2();										} /* DB   ED          */
3080 OP(ed,09) { illegal_2();										} /* DB   ED          */
3081 OP(ed,0a) { illegal_2();										} /* DB   ED          */
3082 OP(ed,0b) { illegal_2();										} /* DB   ED          */
3083 OP(ed,0c) { illegal_2();										} /* DB   ED          */
3084 OP(ed,0d) { illegal_2();										} /* DB   ED          */
3085 OP(ed,0e) { illegal_2();										} /* DB   ED          */
3086 OP(ed,0f) { illegal_2();										} /* DB   ED          */
3087 
3088 OP(ed,10) { illegal_2();										} /* DB   ED          */
3089 OP(ed,11) { illegal_2();										} /* DB   ED          */
3090 OP(ed,12) { illegal_2();										} /* DB   ED          */
3091 OP(ed,13) { illegal_2();										} /* DB   ED          */
3092 OP(ed,14) { illegal_2();										} /* DB   ED          */
3093 OP(ed,15) { illegal_2();										} /* DB   ED          */
3094 OP(ed,16) { illegal_2();										} /* DB   ED          */
3095 OP(ed,17) { illegal_2();										} /* DB   ED          */
3096 
3097 OP(ed,18) { illegal_2();										} /* DB   ED          */
3098 OP(ed,19) { illegal_2();										} /* DB   ED          */
3099 OP(ed,1a) { illegal_2();										} /* DB   ED          */
3100 OP(ed,1b) { illegal_2();										} /* DB   ED          */
3101 OP(ed,1c) { illegal_2();										} /* DB   ED          */
3102 OP(ed,1d) { illegal_2();										} /* DB   ED          */
3103 OP(ed,1e) { illegal_2();										} /* DB   ED          */
3104 OP(ed,1f) { illegal_2();										} /* DB   ED          */
3105 
3106 OP(ed,20) { illegal_2();										} /* DB   ED          */
3107 OP(ed,21) { illegal_2();										} /* DB   ED          */
3108 OP(ed,22) { illegal_2();										} /* DB   ED          */
3109 OP(ed,23) { illegal_2();										} /* DB   ED          */
3110 OP(ed,24) { illegal_2();										} /* DB   ED          */
3111 OP(ed,25) { illegal_2();										} /* DB   ED          */
3112 OP(ed,26) { illegal_2();										} /* DB   ED          */
3113 OP(ed,27) { illegal_2();										} /* DB   ED          */
3114 
3115 OP(ed,28) { illegal_2();										} /* DB   ED          */
3116 OP(ed,29) { illegal_2();										} /* DB   ED          */
3117 OP(ed,2a) { illegal_2();										} /* DB   ED          */
3118 OP(ed,2b) { illegal_2();										} /* DB   ED          */
3119 OP(ed,2c) { illegal_2();										} /* DB   ED          */
3120 OP(ed,2d) { illegal_2();										} /* DB   ED          */
3121 OP(ed,2e) { illegal_2();										} /* DB   ED          */
3122 OP(ed,2f) { illegal_2();										} /* DB   ED          */
3123 
3124 OP(ed,30) { illegal_2();										} /* DB   ED          */
3125 OP(ed,31) { illegal_2();										} /* DB   ED          */
3126 OP(ed,32) { illegal_2();										} /* DB   ED          */
3127 OP(ed,33) { illegal_2();										} /* DB   ED          */
3128 OP(ed,34) { illegal_2();										} /* DB   ED          */
3129 OP(ed,35) { illegal_2();										} /* DB   ED          */
3130 OP(ed,36) { illegal_2();										} /* DB   ED          */
3131 OP(ed,37) { illegal_2();										} /* DB   ED          */
3132 
3133 OP(ed,38) { illegal_2();										} /* DB   ED          */
3134 OP(ed,39) { illegal_2();										} /* DB   ED          */
3135 OP(ed,3a) { illegal_2();										} /* DB   ED          */
3136 OP(ed,3b) { illegal_2();										} /* DB   ED          */
3137 OP(ed,3c) { illegal_2();										} /* DB   ED          */
3138 OP(ed,3d) { illegal_2();										} /* DB   ED          */
3139 OP(ed,3e) { illegal_2();										} /* DB   ED          */
3140 OP(ed,3f) { illegal_2();										} /* DB   ED          */
3141 
3142 OP(ed,40) { B = IN(BC); F = (F & CF) | SZP[B];					} /* IN   B,(C)       */
3143 OP(ed,41) { OUT(BC, B);											} /* OUT  (C),B       */
3144 OP(ed,42) { SBC16( bc );										} /* SBC  HL,BC       */
3145 OP(ed,43) { EA = ARG16(); WM16( EA, &Z80.bc ); WZ = EA + 1;		} /* LD   (w),BC      */
3146 OP(ed,44) { NEG;												} /* NEG              */
3147 OP(ed,45) { RETN;												} /* RETN;            */
3148 OP(ed,46) { IM = 0;												} /* IM   0           */
3149 OP(ed,47) { LD_I_A;												} /* LD   I,A         */
3150 
3151 OP(ed,48) { C = IN(BC); F = (F & CF) | SZP[C];					} /* IN   C,(C)       */
3152 OP(ed,49) { OUT(BC, C);											} /* OUT  (C),C       */
3153 OP(ed,4a) { ADC16( bc );										} /* ADC  HL,BC       */
3154 OP(ed,4b) { EA = ARG16(); RM16( EA, &Z80.bc ); WZ = EA + 1;		} /* LD   BC,(w)      */
3155 OP(ed,4c) { NEG;												} /* NEG              */
3156 OP(ed,4d) { RETI;												} /* RETI             */
3157 OP(ed,4e) { IM = 0;												} /* IM   0           */
3158 OP(ed,4f) { LD_R_A;												} /* LD   R,A         */
3159 
3160 OP(ed,50) { D = IN(BC); F = (F & CF) | SZP[D];					} /* IN   D,(C)       */
3161 OP(ed,51) { OUT(BC, D);											} /* OUT  (C),D       */
3162 OP(ed,52) { SBC16( de );										} /* SBC  HL,DE       */
3163 OP(ed,53) { EA = ARG16(); WM16( EA, &Z80.de ); WZ = EA + 1;		} /* LD   (w),DE      */
3164 OP(ed,54) { NEG;												} /* NEG              */
3165 OP(ed,55) { RETN;												} /* RETN;            */
3166 OP(ed,56) { IM = 1;												} /* IM   1           */
3167 OP(ed,57) { LD_A_I;												} /* LD   A,I         */
3168 
3169 OP(ed,58) { E = IN(BC); F = (F & CF) | SZP[E];					} /* IN   E,(C)       */
3170 OP(ed,59) { OUT(BC, E);											} /* OUT  (C),E       */
3171 OP(ed,5a) { ADC16( de );										} /* ADC  HL,DE       */
3172 OP(ed,5b) { EA = ARG16(); RM16( EA, &Z80.de ); WZ = EA + 1;		} /* LD   DE,(w)      */
3173 OP(ed,5c) { NEG;												} /* NEG              */
3174 OP(ed,5d) { RETI;												} /* RETI             */
3175 OP(ed,5e) { IM = 2;												} /* IM   2           */
3176 OP(ed,5f) { LD_A_R;												} /* LD   A,R         */
3177 
3178 OP(ed,60) { H = IN(BC); F = (F & CF) | SZP[H];					} /* IN   H,(C)       */
3179 OP(ed,61) { OUT(BC, H);											} /* OUT  (C),H       */
3180 OP(ed,62) { SBC16( hl );										} /* SBC  HL,HL       */
3181 OP(ed,63) { EA = ARG16(); WM16( EA, &Z80.hl ); WZ = EA + 1;		} /* LD   (w),HL      */
3182 OP(ed,64) { NEG;												} /* NEG              */
3183 OP(ed,65) { RETN;												} /* RETN;            */
3184 OP(ed,66) { IM = 0;												} /* IM   0           */
3185 OP(ed,67) { RRD;												} /* RRD  (HL)        */
3186 
3187 OP(ed,68) { L = IN(BC); F = (F & CF) | SZP[L];					} /* IN   L,(C)       */
3188 OP(ed,69) { OUT(BC, L);											} /* OUT  (C),L       */
3189 OP(ed,6a) { ADC16( hl );										} /* ADC  HL,HL       */
3190 OP(ed,6b) { EA = ARG16(); RM16( EA, &Z80.hl ); WZ = EA + 1;		} /* LD   HL,(w)      */
3191 OP(ed,6c) { NEG;												} /* NEG              */
3192 OP(ed,6d) { RETI;												} /* RETI             */
3193 OP(ed,6e) { IM = 0;												} /* IM   0           */
3194 OP(ed,6f) { RLD;												} /* RLD  (HL)        */
3195 
3196 OP(ed,70) { UINT8 res = IN(BC); F = (F & CF) | SZP[res];		} /* IN   0,(C)       */
3197 OP(ed,71) { OUT(BC, 0);											} /* OUT  (C),0       */
3198 OP(ed,72) { SBC16( sp );										} /* SBC  HL,SP       */
3199 OP(ed,73) { EA = ARG16(); WM16( EA, &Z80.sp ); WZ = EA + 1;		} /* LD   (w),SP      */
3200 OP(ed,74) { NEG;												} /* NEG              */
3201 OP(ed,75) { RETN;												} /* RETN;            */
3202 OP(ed,76) { IM = 1;												} /* IM   1           */
3203 OP(ed,77) { illegal_2();										} /* DB   ED,77       */
3204 
3205 OP(ed,78) { A = IN(BC); F = (F & CF) | SZP[A]; WZ = BC + 1;		} /* IN   E,(C)       */
3206 OP(ed,79) { OUT(BC, A);WZ = BC + 1;								} /* OUT  (C),A       */
3207 OP(ed,7a) { ADC16( sp );										} /* ADC  HL,SP       */
3208 OP(ed,7b) { EA = ARG16(); RM16( EA, &Z80.sp ); WZ = EA + 1;		} /* LD   SP,(w)      */
3209 OP(ed,7c) { NEG;												} /* NEG              */
3210 OP(ed,7d) { RETI;												} /* RETI             */
3211 OP(ed,7e) { IM = 2;												} /* IM   2           */
3212 OP(ed,7f) { illegal_2();										} /* DB   ED,7F       */
3213 
3214 OP(ed,80) { illegal_2();										} /* DB   ED          */
3215 OP(ed,81) { illegal_2();										} /* DB   ED          */
3216 OP(ed,82) { illegal_2();										} /* DB   ED          */
3217 OP(ed,83) { illegal_2();										} /* DB   ED          */
3218 OP(ed,84) { illegal_2();										} /* DB   ED          */
3219 OP(ed,85) { illegal_2();										} /* DB   ED          */
3220 OP(ed,86) { illegal_2();										} /* DB   ED          */
3221 OP(ed,87) { illegal_2();										} /* DB   ED          */
3222 
3223 OP(ed,88) { illegal_2();										} /* DB   ED          */
3224 OP(ed,89) { illegal_2();										} /* DB   ED          */
3225 OP(ed,8a) { illegal_2();										} /* DB   ED          */
3226 OP(ed,8b) { illegal_2();										} /* DB   ED          */
3227 OP(ed,8c) { illegal_2();										} /* DB   ED          */
3228 OP(ed,8d) { illegal_2();										} /* DB   ED          */
3229 OP(ed,8e) { illegal_2();										} /* DB   ED          */
3230 OP(ed,8f) { illegal_2();										} /* DB   ED          */
3231 
3232 OP(ed,90) { illegal_2();										} /* DB   ED          */
3233 OP(ed,91) { illegal_2();										} /* DB   ED          */
3234 OP(ed,92) { illegal_2();										} /* DB   ED          */
3235 OP(ed,93) { illegal_2();										} /* DB   ED          */
3236 OP(ed,94) { illegal_2();										} /* DB   ED          */
3237 OP(ed,95) { illegal_2();										} /* DB   ED          */
3238 OP(ed,96) { illegal_2();										} /* DB   ED          */
3239 OP(ed,97) { illegal_2();										} /* DB   ED          */
3240 
3241 OP(ed,98) { illegal_2();										} /* DB   ED          */
3242 OP(ed,99) { illegal_2();										} /* DB   ED          */
3243 OP(ed,9a) { illegal_2();										} /* DB   ED          */
3244 OP(ed,9b) { illegal_2();										} /* DB   ED          */
3245 OP(ed,9c) { illegal_2();										} /* DB   ED          */
3246 OP(ed,9d) { illegal_2();										} /* DB   ED          */
3247 OP(ed,9e) { illegal_2();										} /* DB   ED          */
3248 OP(ed,9f) { illegal_2();										} /* DB   ED          */
3249 
OP(ed,a0)3250 OP(ed,a0) { LDI;												} /* LDI              */
OP(ed,a1)3251 OP(ed,a1) { CPI;												} /* CPI              */
OP(ed,a2)3252 OP(ed,a2) { INI;												} /* INI              */
OP(ed,a3)3253 OP(ed,a3) { OUTI;												} /* OUTI             */
OP(ed,a4)3254 OP(ed,a4) { illegal_2();										} /* DB   ED          */
OP(ed,a5)3255 OP(ed,a5) { illegal_2();										} /* DB   ED          */
OP(ed,a6)3256 OP(ed,a6) { illegal_2();										} /* DB   ED          */
OP(ed,a7)3257 OP(ed,a7) { illegal_2();										} /* DB   ED          */
3258 
OP(ed,a8)3259 OP(ed,a8) { LDD;												} /* LDD              */
OP(ed,a9)3260 OP(ed,a9) { CPD;												} /* CPD              */
OP(ed,aa)3261 OP(ed,aa) { IND;												} /* IND              */
OP(ed,ab)3262 OP(ed,ab) { OUTD;												} /* OUTD             */
OP(ed,ac)3263 OP(ed,ac) { illegal_2();										} /* DB   ED          */
OP(ed,ad)3264 OP(ed,ad) { illegal_2();										} /* DB   ED          */
OP(ed,ae)3265 OP(ed,ae) { illegal_2();										} /* DB   ED          */
OP(ed,af)3266 OP(ed,af) { illegal_2();										} /* DB   ED          */
3267 
OP(ed,b0)3268 OP(ed,b0) { LDIR;												} /* LDIR             */
OP(ed,b1)3269 OP(ed,b1) { CPIR;												} /* CPIR             */
OP(ed,b2)3270 OP(ed,b2) { INIR;												} /* INIR             */
OP(ed,b3)3271 OP(ed,b3) { OTIR;												} /* OTIR             */
OP(ed,b4)3272 OP(ed,b4) { illegal_2();										} /* DB   ED          */
OP(ed,b5)3273 OP(ed,b5) { illegal_2();										} /* DB   ED          */
OP(ed,b6)3274 OP(ed,b6) { illegal_2();										} /* DB   ED          */
OP(ed,b7)3275 OP(ed,b7) { illegal_2();										} /* DB   ED          */
3276 
OP(ed,b8)3277 OP(ed,b8) { LDDR;												} /* LDDR             */
OP(ed,b9)3278 OP(ed,b9) { CPDR;												} /* CPDR             */
OP(ed,ba)3279 OP(ed,ba) { INDR;												} /* INDR             */
OP(ed,bb)3280 OP(ed,bb) { OTDR;												} /* OTDR             */
OP(ed,bc)3281 OP(ed,bc) { illegal_2();										} /* DB   ED          */
OP(ed,bd)3282 OP(ed,bd) { illegal_2();										} /* DB   ED          */
OP(ed,be)3283 OP(ed,be) { illegal_2();										} /* DB   ED          */
OP(ed,bf)3284 OP(ed,bf) { illegal_2();										} /* DB   ED          */
3285 
OP(ed,c0)3286 OP(ed,c0) { illegal_2();										} /* DB   ED          */
OP(ed,c1)3287 OP(ed,c1) { illegal_2();										} /* DB   ED          */
OP(ed,c2)3288 OP(ed,c2) { illegal_2();										} /* DB   ED          */
OP(ed,c3)3289 OP(ed,c3) { illegal_2();										} /* DB   ED          */
OP(ed,c4)3290 OP(ed,c4) { illegal_2();										} /* DB   ED          */
OP(ed,c5)3291 OP(ed,c5) { illegal_2();										} /* DB   ED          */
OP(ed,c6)3292 OP(ed,c6) { illegal_2();										} /* DB   ED          */
OP(ed,c7)3293 OP(ed,c7) { illegal_2();										} /* DB   ED          */
3294 
OP(ed,c8)3295 OP(ed,c8) { illegal_2();										} /* DB   ED          */
OP(ed,c9)3296 OP(ed,c9) { illegal_2();										} /* DB   ED          */
OP(ed,ca)3297 OP(ed,ca) { illegal_2();										} /* DB   ED          */
OP(ed,cb)3298 OP(ed,cb) { illegal_2();										} /* DB   ED          */
OP(ed,cc)3299 OP(ed,cc) { illegal_2();										} /* DB   ED          */
OP(ed,cd)3300 OP(ed,cd) { illegal_2();										} /* DB   ED          */
OP(ed,ce)3301 OP(ed,ce) { illegal_2();										} /* DB   ED          */
OP(ed,cf)3302 OP(ed,cf) { illegal_2();										} /* DB   ED          */
3303 
OP(ed,d0)3304 OP(ed,d0) { illegal_2();										} /* DB   ED          */
OP(ed,d1)3305 OP(ed,d1) { illegal_2();										} /* DB   ED          */
OP(ed,d2)3306 OP(ed,d2) { illegal_2();										} /* DB   ED          */
OP(ed,d3)3307 OP(ed,d3) { illegal_2();										} /* DB   ED          */
OP(ed,d4)3308 OP(ed,d4) { illegal_2();										} /* DB   ED          */
OP(ed,d5)3309 OP(ed,d5) { illegal_2();										} /* DB   ED          */
OP(ed,d6)3310 OP(ed,d6) { illegal_2();										} /* DB   ED          */
OP(ed,d7)3311 OP(ed,d7) { illegal_2();										} /* DB   ED          */
3312 
OP(ed,d8)3313 OP(ed,d8) { illegal_2();										} /* DB   ED          */
OP(ed,d9)3314 OP(ed,d9) { illegal_2();										} /* DB   ED          */
OP(ed,da)3315 OP(ed,da) { illegal_2();										} /* DB   ED          */
OP(ed,db)3316 OP(ed,db) { illegal_2();										} /* DB   ED          */
OP(ed,dc)3317 OP(ed,dc) { illegal_2();										} /* DB   ED          */
OP(ed,dd)3318 OP(ed,dd) { illegal_2();										} /* DB   ED          */
OP(ed,de)3319 OP(ed,de) { illegal_2();										} /* DB   ED          */
OP(ed,df)3320 OP(ed,df) { illegal_2();										} /* DB   ED          */
3321 
OP(ed,e0)3322 OP(ed,e0) { illegal_2();										} /* DB   ED          */
OP(ed,e1)3323 OP(ed,e1) { illegal_2();										} /* DB   ED          */
OP(ed,e2)3324 OP(ed,e2) { illegal_2();										} /* DB   ED          */
OP(ed,e3)3325 OP(ed,e3) { illegal_2();										} /* DB   ED          */
OP(ed,e4)3326 OP(ed,e4) { illegal_2();										} /* DB   ED          */
OP(ed,e5)3327 OP(ed,e5) { illegal_2();										} /* DB   ED          */
OP(ed,e6)3328 OP(ed,e6) { illegal_2();										} /* DB   ED          */
OP(ed,e7)3329 OP(ed,e7) { illegal_2();										} /* DB   ED          */
3330 
OP(ed,e8)3331 OP(ed,e8) { illegal_2();										} /* DB   ED          */
OP(ed,e9)3332 OP(ed,e9) { illegal_2();										} /* DB   ED          */
OP(ed,ea)3333 OP(ed,ea) { illegal_2();										} /* DB   ED          */
OP(ed,eb)3334 OP(ed,eb) { illegal_2();										} /* DB   ED          */
OP(ed,ec)3335 OP(ed,ec) { illegal_2();										} /* DB   ED          */
OP(ed,ed)3336 OP(ed,ed) { illegal_2();										} /* DB   ED          */
OP(ed,ee)3337 OP(ed,ee) { illegal_2();										} /* DB   ED          */
OP(ed,ef)3338 OP(ed,ef) { illegal_2();										} /* DB   ED          */
3339 
OP(ed,f0)3340 OP(ed,f0) { illegal_2();										} /* DB   ED          */
OP(ed,f1)3341 OP(ed,f1) { illegal_2();										} /* DB   ED          */
OP(ed,f2)3342 OP(ed,f2) { illegal_2();										} /* DB   ED          */
OP(ed,f3)3343 OP(ed,f3) { illegal_2();										} /* DB   ED          */
OP(ed,f4)3344 OP(ed,f4) { illegal_2();										} /* DB   ED          */
OP(ed,f5)3345 OP(ed,f5) { illegal_2();										} /* DB   ED          */
OP(ed,f6)3346 OP(ed,f6) { illegal_2();										} /* DB   ED          */
OP(ed,f7)3347 OP(ed,f7) { illegal_2();										} /* DB   ED          */
3348 
OP(ed,f8)3349 OP(ed,f8) { illegal_2();										} /* DB   ED          */
OP(ed,f9)3350 OP(ed,f9) { illegal_2();										} /* DB   ED          */
OP(ed,fa)3351 OP(ed,fa) { illegal_2();										} /* DB   ED          */
OP(ed,fb)3352 OP(ed,fb) { illegal_2();										} /* DB   ED          */
OP(ed,fc)3353 OP(ed,fc) { illegal_2();										} /* DB   ED          */
OP(ed,fd)3354 OP(ed,fd) { illegal_2();										} /* DB   ED          */
OP(ed,fe)3355 OP(ed,fe) {
3356 	if (z80edfe_callback) {
3357 		(*z80edfe_callback)(&Z80);
3358 	} else {
3359 		illegal_2();
3360 	} } /* DB   ED          */
OP(ed,ff)3361 OP(ed,ff) { illegal_2();										} /* DB   ED          */
3362 
3363 
3364 /**********************************************************
3365  * main opcodes
3366  **********************************************************/
3367 OP(op,00) {														} /* NOP              */
3368 OP(op,01) { BC = ARG16();										} /* LD   BC,w        */
3369 OP(op,02) { WM( BC, A );WZ_L = (BC + 1) & 0xFF;  WZ_H = A;		} /* LD   (BC),A      */
3370 OP(op,03) { BC++;												} /* INC  BC          */
3371 OP(op,04) { B = INC(B);											} /* INC  B           */
3372 OP(op,05) { B = DEC(B);											} /* DEC  B           */
3373 OP(op,06) { B = ARG();											} /* LD   B,n         */
3374 OP(op,07) { RLCA;												} /* RLCA             */
3375 
3376 OP(op,08) { EX_AF;												} /* EX   AF,AF'      */
3377 OP(op,09) { ADD16(hl, bc);										} /* ADD  HL,BC       */
3378 OP(op,0a) { A = RM( BC );	WZ=BC+1; 							} /* LD   A,(BC)      */
3379 OP(op,0b) { BC--; 												} /* DEC  BC          */
3380 OP(op,0c) { C = INC(C);											} /* INC  C           */
3381 OP(op,0d) { C = DEC(C);											} /* DEC  C           */
3382 OP(op,0e) { C = ARG();											} /* LD   C,n         */
3383 OP(op,0f) { RRCA;												} /* RRCA             */
3384 
3385 OP(op,10) { B--; JR_COND( B, 0x10 );							} /* DJNZ o           */
3386 OP(op,11) { DE = ARG16();										} /* LD   DE,w        */
3387 OP(op,12) { WM( DE, A ); WZ_L = (DE + 1) & 0xFF;  WZ_H = A;		} /* LD   (DE),A      */
3388 OP(op,13) { DE++;												} /* INC  DE          */
3389 OP(op,14) { D = INC(D);											} /* INC  D           */
3390 OP(op,15) { D = DEC(D);											} /* DEC  D           */
3391 OP(op,16) { D = ARG();											} /* LD   D,n         */
3392 OP(op,17) { RLA;												} /* RLA              */
3393 
3394 OP(op,18) { JR();												} /* JR   o           */
3395 OP(op,19) { ADD16(hl, de);										} /* ADD  HL,DE       */
3396 OP(op,1a) { A = RM( DE );	WZ = DE + 1;  						} /* LD   A,(DE)      */
3397 OP(op,1b) { DE--; 												} /* DEC  DE          */
3398 OP(op,1c) { E = INC(E);											} /* INC  E           */
3399 OP(op,1d) { E = DEC(E);											} /* DEC  E           */
3400 OP(op,1e) { E = ARG();											} /* LD   E,n         */
3401 OP(op,1f) { RRA;												} /* RRA              */
3402 
3403 OP(op,20) { JR_COND( !(F & ZF), 0x20 );							} /* JR   NZ,o        */
3404 OP(op,21) { HL = ARG16();										} /* LD   HL,w        */
3405 OP(op,22) { EA = ARG16(); WM16( EA, &Z80.hl );	WZ = EA + 1; 	} /* LD   (w),HL      */
3406 OP(op,23) { HL++;												} /* INC  HL          */
3407 OP(op,24) { H = INC(H);											} /* INC  H           */
3408 OP(op,25) { H = DEC(H);											} /* DEC  H           */
3409 OP(op,26) { H = ARG();											} /* LD   H,n         */
3410 OP(op,27) { DAA;												} /* DAA              */
3411 
3412 OP(op,28) { JR_COND( F & ZF, 0x28 );							} /* JR   Z,o         */
3413 OP(op,29) { ADD16(hl, hl);										} /* ADD  HL,HL       */
3414 OP(op,2a) { EA = ARG16(); RM16( EA, &Z80.hl );WZ = EA + 1;		} /* LD   HL,(w)      */
3415 OP(op,2b) { HL--; 												} /* DEC  HL          */
3416 OP(op,2c) { L = INC(L);											} /* INC  L           */
3417 OP(op,2d) { L = DEC(L);											} /* DEC  L           */
3418 OP(op,2e) { L = ARG();											} /* LD   L,n         */
3419 OP(op,2f) { A ^= 0xff; F = (F&(SF|ZF|PF|CF))|HF|NF|(A&(YF|XF));	} /* CPL              */
3420 
3421 OP(op,30) { JR_COND( !(F & CF), 0x30 );							} /* JR   NC,o        */
3422 OP(op,31) { SP = ARG16();										} /* LD   SP,w        */
3423 OP(op,32) { EA = ARG16(); WM( EA, A );WZ_L = (EA + 1) & 0xFF; WZ_H = A; } /* LD   (w),A       */
3424 OP(op,33) { SP++;												} /* INC  SP          */
3425 OP(op,34) { WM( HL, INC(RM(HL)) );								} /* INC  (HL)        */
3426 OP(op,35) { WM( HL, DEC(RM(HL)) );								} /* DEC  (HL)        */
3427 OP(op,36) { WM( HL, ARG() );									} /* LD   (HL),n      */
3428 OP(op,37) { F = (F & (SF|ZF|YF|XF|PF)) | CF | (A & (YF|XF));			} /* SCF              */
3429 
3430 OP(op,38) { JR_COND( F & CF, 0x38 );							} /* JR   C,o         */
3431 OP(op,39) { ADD16(hl, sp);										} /* ADD  HL,SP       */
3432 OP(op,3a) { EA = ARG16(); A = RM( EA );WZ = EA + 1;			} /* LD   A,(w)       */
3433 OP(op,3b) { SP--;												} /* DEC  SP          */
3434 OP(op,3c) { A = INC(A);											} /* INC  A           */
3435 OP(op,3d) { A = DEC(A);											} /* DEC  A           */
3436 OP(op,3e) { A = ARG();											} /* LD   A,n         */
3437 OP(op,3f) { F = ((F&(SF|ZF|YF|XF|PF|CF))|((F&CF)<<4)|(A&(YF|XF)))^CF;	} /* CCF              */
3438 
3439 OP(op,40) {														} /* LD   B,B         */
3440 OP(op,41) { B = C;												} /* LD   B,C         */
3441 OP(op,42) { B = D;												} /* LD   B,D         */
3442 OP(op,43) { B = E;												} /* LD   B,E         */
3443 OP(op,44) { B = H;												} /* LD   B,H         */
3444 OP(op,45) { B = L;												} /* LD   B,L         */
3445 OP(op,46) { B = RM(HL);											} /* LD   B,(HL)      */
3446 OP(op,47) { B = A;												} /* LD   B,A         */
3447 
3448 OP(op,48) { C = B;												} /* LD   C,B         */
3449 OP(op,49) {														} /* LD   C,C         */
3450 OP(op,4a) { C = D;												} /* LD   C,D         */
3451 OP(op,4b) { C = E;												} /* LD   C,E         */
3452 OP(op,4c) { C = H;												} /* LD   C,H         */
3453 OP(op,4d) { C = L;												} /* LD   C,L         */
3454 OP(op,4e) { C = RM(HL);											} /* LD   C,(HL)      */
3455 OP(op,4f) { C = A;												} /* LD   C,A         */
3456 
3457 OP(op,50) { D = B;												} /* LD   D,B         */
3458 OP(op,51) { D = C;												} /* LD   D,C         */
3459 OP(op,52) {														} /* LD   D,D         */
3460 OP(op,53) { D = E;												} /* LD   D,E         */
3461 OP(op,54) { D = H;												} /* LD   D,H         */
3462 OP(op,55) { D = L;												} /* LD   D,L         */
3463 OP(op,56) { D = RM(HL);											} /* LD   D,(HL)      */
3464 OP(op,57) { D = A;												} /* LD   D,A         */
3465 
3466 OP(op,58) { E = B;												} /* LD   E,B         */
3467 OP(op,59) { E = C;												} /* LD   E,C         */
3468 OP(op,5a) { E = D;												} /* LD   E,D         */
3469 OP(op,5b) {														} /* LD   E,E         */
3470 OP(op,5c) { E = H;												} /* LD   E,H         */
3471 OP(op,5d) { E = L;												} /* LD   E,L         */
3472 OP(op,5e) { E = RM(HL);											} /* LD   E,(HL)      */
3473 OP(op,5f) { E = A;												} /* LD   E,A         */
3474 
3475 OP(op,60) { H = B;												} /* LD   H,B         */
3476 OP(op,61) { H = C;												} /* LD   H,C         */
3477 OP(op,62) { H = D;												} /* LD   H,D         */
3478 OP(op,63) { H = E;												} /* LD   H,E         */
3479 OP(op,64) {														} /* LD   H,H         */
3480 OP(op,65) { H = L;												} /* LD   H,L         */
3481 OP(op,66) { H = RM(HL);											} /* LD   H,(HL)      */
3482 OP(op,67) { H = A;												} /* LD   H,A         */
3483 
3484 OP(op,68) { L = B;												} /* LD   L,B         */
3485 OP(op,69) { L = C;												} /* LD   L,C         */
3486 OP(op,6a) { L = D;												} /* LD   L,D         */
3487 OP(op,6b) { L = E;												} /* LD   L,E         */
3488 OP(op,6c) { L = H;												} /* LD   L,H         */
3489 OP(op,6d) {														} /* LD   L,L         */
3490 OP(op,6e) { L = RM(HL);											} /* LD   L,(HL)      */
3491 OP(op,6f) { L = A;												} /* LD   L,A         */
3492 
3493 OP(op,70) { WM( HL, B );										} /* LD   (HL),B      */
3494 OP(op,71) { WM( HL, C );										} /* LD   (HL),C      */
3495 OP(op,72) { WM( HL, D );										} /* LD   (HL),D      */
3496 OP(op,73) { WM( HL, E );										} /* LD   (HL),E      */
3497 OP(op,74) { WM( HL, H );										} /* LD   (HL),H      */
3498 OP(op,75) { WM( HL, L );										} /* LD   (HL),L      */
3499 OP(op,76) { ENTER_HALT;											} /* HALT             */
3500 OP(op,77) { WM( HL, A );										} /* LD   (HL),A      */
3501 
3502 OP(op,78) { A = B;												} /* LD   A,B         */
3503 OP(op,79) { A = C;												} /* LD   A,C         */
3504 OP(op,7a) { A = D;												} /* LD   A,D         */
3505 OP(op,7b) { A = E;												} /* LD   A,E         */
3506 OP(op,7c) { A = H;												} /* LD   A,H         */
3507 OP(op,7d) { A = L;												} /* LD   A,L         */
3508 OP(op,7e) { A = RM(HL);											} /* LD   A,(HL)      */
3509 OP(op,7f) {														} /* LD   A,A         */
3510 
3511 OP(op,80) { ADD(B);												} /* ADD  A,B         */
3512 OP(op,81) { ADD(C);												} /* ADD  A,C         */
3513 OP(op,82) { ADD(D);												} /* ADD  A,D         */
3514 OP(op,83) { ADD(E);												} /* ADD  A,E         */
3515 OP(op,84) { ADD(H);												} /* ADD  A,H         */
3516 OP(op,85) { ADD(L);												} /* ADD  A,L         */
3517 OP(op,86) { ADD(RM(HL));										} /* ADD  A,(HL)      */
3518 OP(op,87) { ADD(A);												} /* ADD  A,A         */
3519 
3520 OP(op,88) { ADC(B);												} /* ADC  A,B         */
3521 OP(op,89) { ADC(C);												} /* ADC  A,C         */
3522 OP(op,8a) { ADC(D);												} /* ADC  A,D         */
3523 OP(op,8b) { ADC(E);												} /* ADC  A,E         */
3524 OP(op,8c) { ADC(H);												} /* ADC  A,H         */
3525 OP(op,8d) { ADC(L);												} /* ADC  A,L         */
3526 OP(op,8e) { ADC(RM(HL));										} /* ADC  A,(HL)      */
3527 OP(op,8f) { ADC(A);												} /* ADC  A,A         */
3528 
3529 OP(op,90) { SUB(B);												} /* SUB  B           */
3530 OP(op,91) { SUB(C);												} /* SUB  C           */
3531 OP(op,92) { SUB(D);												} /* SUB  D           */
3532 OP(op,93) { SUB(E);												} /* SUB  E           */
3533 OP(op,94) { SUB(H);												} /* SUB  H           */
3534 OP(op,95) { SUB(L);												} /* SUB  L           */
3535 OP(op,96) { SUB(RM(HL));										} /* SUB  (HL)        */
3536 OP(op,97) { SUB(A);												} /* SUB  A           */
3537 
3538 OP(op,98) { SBC(B);												} /* SBC  A,B         */
3539 OP(op,99) { SBC(C);												} /* SBC  A,C         */
3540 OP(op,9a) { SBC(D);												} /* SBC  A,D         */
3541 OP(op,9b) { SBC(E);												} /* SBC  A,E         */
3542 OP(op,9c) { SBC(H);												} /* SBC  A,H         */
3543 OP(op,9d) { SBC(L);												} /* SBC  A,L         */
3544 OP(op,9e) { SBC(RM(HL));										} /* SBC  A,(HL)      */
3545 OP(op,9f) { SBC(A);												} /* SBC  A,A         */
3546 
OP(op,a0)3547 OP(op,a0) { AND(B);												} /* AND  B           */
OP(op,a1)3548 OP(op,a1) { AND(C);												} /* AND  C           */
OP(op,a2)3549 OP(op,a2) { AND(D);												} /* AND  D           */
OP(op,a3)3550 OP(op,a3) { AND(E);												} /* AND  E           */
OP(op,a4)3551 OP(op,a4) { AND(H);												} /* AND  H           */
OP(op,a5)3552 OP(op,a5) { AND(L);												} /* AND  L           */
OP(op,a6)3553 OP(op,a6) { AND(RM(HL));										} /* AND  (HL)        */
OP(op,a7)3554 OP(op,a7) { AND(A);												} /* AND  A           */
3555 
OP(op,a8)3556 OP(op,a8) { XOR(B);												} /* XOR  B           */
OP(op,a9)3557 OP(op,a9) { XOR(C);												} /* XOR  C           */
OP(op,aa)3558 OP(op,aa) { XOR(D);												} /* XOR  D           */
OP(op,ab)3559 OP(op,ab) { XOR(E);												} /* XOR  E           */
OP(op,ac)3560 OP(op,ac) { XOR(H);												} /* XOR  H           */
OP(op,ad)3561 OP(op,ad) { XOR(L);												} /* XOR  L           */
OP(op,ae)3562 OP(op,ae) { XOR(RM(HL));										} /* XOR  (HL)        */
OP(op,af)3563 OP(op,af) { XOR(A);												} /* XOR  A           */
3564 
OP(op,b0)3565 OP(op,b0) { OR(B);												} /* OR   B           */
OP(op,b1)3566 OP(op,b1) { OR(C);												} /* OR   C           */
OP(op,b2)3567 OP(op,b2) { OR(D);												} /* OR   D           */
OP(op,b3)3568 OP(op,b3) { OR(E);												} /* OR   E           */
OP(op,b4)3569 OP(op,b4) { OR(H);												} /* OR   H           */
OP(op,b5)3570 OP(op,b5) { OR(L);												} /* OR   L           */
OP(op,b6)3571 OP(op,b6) { OR(RM(HL));											} /* OR   (HL)        */
OP(op,b7)3572 OP(op,b7) { OR(A);												} /* OR   A           */
3573 
OP(op,b8)3574 OP(op,b8) { CP(B);												} /* CP   B           */
OP(op,b9)3575 OP(op,b9) { CP(C);												} /* CP   C           */
OP(op,ba)3576 OP(op,ba) { CP(D);												} /* CP   D           */
OP(op,bb)3577 OP(op,bb) { CP(E);												} /* CP   E           */
OP(op,bc)3578 OP(op,bc) { CP(H);												} /* CP   H           */
OP(op,bd)3579 OP(op,bd) { CP(L);												} /* CP   L           */
OP(op,be)3580 OP(op,be) { CP(RM(HL));											} /* CP   (HL)        */
OP(op,bf)3581 OP(op,bf) { CP(A);												} /* CP   A           */
3582 
OP(op,c0)3583 OP(op,c0) { RET_COND_SPECTRUM( !(F & ZF), 0xc0 );				} /* RET  NZ          */
OP(op,c1)3584 OP(op,c1) { POP( bc );											} /* POP  BC          */
OP(op,c2)3585 OP(op,c2) { JP_COND( !(F & ZF) );								} /* JP   NZ,a        */
OP(op,c3)3586 OP(op,c3) { JP;													} /* JP   a           */
OP(op,c4)3587 OP(op,c4) { CALL_COND( !(F & ZF), 0xc4 );						} /* CALL NZ,a        */
OP(op,c5)3588 OP(op,c5) { PUSH( bc );											} /* PUSH BC          */
OP(op,c6)3589 OP(op,c6) { ADD(ARG());											} /* ADD  A,n         */
OP(op,c7)3590 OP(op,c7) { RST(0x00);											} /* RST  0           */
3591 
OP(op,c8)3592 OP(op,c8) { RET_COND( F & ZF, 0xc8 );							} /* RET  Z           */
OP(op,c9)3593 OP(op,c9) { POP( pc ); change_pc(PCD);WZ = PCD;  				} /* RET              */
OP(op,ca)3594 OP(op,ca) { JP_COND( F & ZF );									} /* JP   Z,a         */
OP(op,cb)3595 OP(op,cb) { R++; EXEC(cb,ROP());								} /* **** CB xx       */
OP(op,cc)3596 OP(op,cc) { CALL_COND( F & ZF, 0xcc );							} /* CALL Z,a         */
OP(op,cd)3597 OP(op,cd) { CALL();												} /* CALL a           */
OP(op,ce)3598 OP(op,ce) { ADC(ARG());											} /* ADC  A,n         */
OP(op,cf)3599 OP(op,cf) { RST(0x08);											} /* RST  1           */
3600 
OP(op,d0)3601 OP(op,d0) { RET_COND( !(F & CF), 0xd0 );						} /* RET  NC          */
OP(op,d1)3602 OP(op,d1) { POP( de );											} /* POP  DE          */
OP(op,d2)3603 OP(op,d2) { JP_COND( !(F & CF) );								} /* JP   NC,a        */
OP(op,d3)3604 OP(op,d3) { unsigned n = ARG() | (A << 8); OUT( n, A );WZ_L = ((n & 0xff) + 1) & 0xff;  WZ_H = A;  			} /* OUT  (n),A       */
OP(op,d4)3605 OP(op,d4) { CALL_COND( !(F & CF), 0xd4 );						} /* CALL NC,a        */
OP(op,d5)3606 OP(op,d5) { PUSH( de );											} /* PUSH DE          */
OP(op,d6)3607 OP(op,d6) { SUB(ARG());											} /* SUB  n           */
OP(op,d7)3608 OP(op,d7) { RST(0x10);											} /* RST  2           */
3609 
OP(op,d8)3610 OP(op,d8) { RET_COND( F & CF, 0xd8 );							} /* RET  C           */
OP(op,d9)3611 OP(op,d9) { EXX;												} /* EXX              */
OP(op,da)3612 OP(op,da) { JP_COND( F & CF );									} /* JP   C,a         */
OP(op,db)3613 OP(op,db) { unsigned n = ARG() | (A << 8); A = IN( n ); WZ = n + 1;			} /* IN   A,(n)       */
OP(op,dc)3614 OP(op,dc) { CALL_COND( F & CF, 0xdc );							} /* CALL C,a         */
OP(op,dd)3615 OP(op,dd) { R++; EXEC(dd,ROP());								} /* **** DD xx       */
OP(op,de)3616 OP(op,de) { SBC(ARG());											} /* SBC  A,n         */
OP(op,df)3617 OP(op,df) { RST(0x18);											} /* RST  3           */
3618 
OP(op,e0)3619 OP(op,e0) { RET_COND( !(F & PF), 0xe0 );						} /* RET  PO          */
OP(op,e1)3620 OP(op,e1) { POP( hl );											} /* POP  HL          */
OP(op,e2)3621 OP(op,e2) { JP_COND( !(F & PF) );								} /* JP   PO,a        */
OP(op,e3)3622 OP(op,e3) { EXSP( hl );											} /* EX   HL,(SP)     */
OP(op,e4)3623 OP(op,e4) { CALL_COND( !(F & PF), 0xe4 );						} /* CALL PO,a        */
OP(op,e5)3624 OP(op,e5) { PUSH( hl );											} /* PUSH HL          */
OP(op,e6)3625 OP(op,e6) { AND(ARG());											} /* AND  n           */
OP(op,e7)3626 OP(op,e7) { RST(0x20);											} /* RST  4           */
3627 
OP(op,e8)3628 OP(op,e8) { RET_COND( F & PF, 0xe8 );							} /* RET  PE          */
OP(op,e9)3629 OP(op,e9) { PC = HL; change_pc(PCD);							} /* JP   (HL)        */
OP(op,ea)3630 OP(op,ea) { JP_COND( F & PF );									} /* JP   PE,a        */
OP(op,eb)3631 OP(op,eb) { EX_DE_HL;											} /* EX   DE,HL       */
OP(op,ec)3632 OP(op,ec) { CALL_COND( F & PF, 0xec );							} /* CALL PE,a        */
OP(op,ed)3633 OP(op,ed) { R++; EXEC(ed,ROP());								} /* **** ED xx       */
OP(op,ee)3634 OP(op,ee) { XOR(ARG());											} /* XOR  n           */
OP(op,ef)3635 OP(op,ef) { RST(0x28);											} /* RST  5           */
3636 
OP(op,f0)3637 OP(op,f0) { RET_COND( !(F & SF), 0xf0 );						} /* RET  P           */
OP(op,f1)3638 OP(op,f1) { POP( af );											} /* POP  AF          */
OP(op,f2)3639 OP(op,f2) { JP_COND( !(F & SF) );								} /* JP   P,a         */
OP(op,f3)3640 OP(op,f3) { IFF1 = IFF2 = 0;									} /* DI               */
OP(op,f4)3641 OP(op,f4) { CALL_COND( !(F & SF), 0xf4 );						} /* CALL P,a         */
OP(op,f5)3642 OP(op,f5) { PUSH( af );											} /* PUSH AF          */
OP(op,f6)3643 OP(op,f6) { OR(ARG());											} /* OR   n           */
OP(op,f7)3644 OP(op,f7) { RST(0x30);											} /* RST  6           */
3645 
OP(op,f8)3646 OP(op,f8) { RET_COND( F & SF, 0xf8 );							} /* RET  M           */
OP(op,f9)3647 OP(op,f9) { SP = HL;											} /* LD   SP,HL       */
OP(op,fa)3648 OP(op,fa) { JP_COND(F & SF);									} /* JP   M,a         */
OP(op,fb)3649 OP(op,fb) { EI;													} /* EI               */
OP(op,fc)3650 OP(op,fc) { CALL_COND( F & SF, 0xfc );							} /* CALL M,a         */
OP(op,fd)3651 OP(op,fd) { R++; EXEC(fd,ROP());								} /* **** FD xx       */
OP(op,fe)3652 OP(op,fe) { CP(ARG());											} /* CP   n           */
OP(op,ff)3653 OP(op,ff) { RST(0x38);											} /* RST  7           */
3654 
3655 
take_interrupt(void)3656 static void take_interrupt(void)
3657 {
3658 	int irq_vector = Z80Vector;
3659 
3660 	if (m_ula_variant != ULA_VARIANT_NONE && m_tstate_counter >= 32)
3661 		return;
3662 
3663 	/* there isn't a valid previous program counter */
3664 	PRVPC = (UINT32)-1;
3665 
3666 	/* Check if processor was halted */
3667 	LEAVE_HALT;
3668 
3669 	/* Clear both interrupt flip flops */
3670 	IFF1 = IFF2 = 0;
3671 
3672 	/* Daisy chain mode? If so, call the requesting device */
3673 	if (Z80.daisy)
3674 		irq_vector = z80daisy_call_ack_device(Z80.daisy);
3675 
3676 	/* else call back the cpu interface to retrieve the vector */
3677 //	else
3678 //		irq_vector = (*Z80.irq_callback)(0);
3679 
3680 	/* "hold_irq" assures that an irq request (with CPU_IRQSTATUS_HOLD) gets
3681 	   acknowleged.  This is designed to get around the following 2 problems:
3682 
3683 	   1) Requests made with CPU_IRQSTATUS_AUTO might get skipped in
3684 	   circumstances where IRQs are disabled at the moment it was requested.
3685 
3686 	   2) Requests made with CPU_IRQSTATUS_ACK might cause more than 1 irq to
3687 	   get taken if is held in the _ACK state for too long(!) - dink jan.2016
3688 	*/
3689 	if (Z80.hold_irq) {
3690 		Z80.hold_irq = 0;
3691 		Z80.irq_state = 0;
3692 	}
3693 
3694 //	LOG(("Z80 #%d single int. irq_vector $%02x\n", cpu_getactivecpu(), irq_vector));
3695 
3696 	/* Interrupt mode 2. Call [Z80.i:databyte] */
3697 	if( IM == 2 )
3698 	{
3699 		irq_vector = (irq_vector & 0xff) | (I << 8);
3700 		PUSH( pc );
3701 		RM16( irq_vector, &Z80.pc );
3702 //		LOG(("Z80 #%d IM2 [$%04x] = $%04x\n",cpu_getactivecpu() , irq_vector, PCD));
3703 		/* CALL opcode timing */
3704 		eat_cycles(CYCLES_ISR, cc[Z80_TABLE_op][0xcd] + cc[Z80_TABLE_ex][0xff]);
3705 	}
3706 	else
3707 	/* Interrupt mode 1. RST 38h */
3708 	if( IM == 1 )
3709 	{
3710 //		LOG(("Z80 #%d IM1 $0038\n",cpu_getactivecpu() ));
3711 		PUSH( pc );
3712 		PCD = 0x0038;
3713 		/* RST $38 + 'interrupt latency' cycles */
3714 		eat_cycles(CYCLES_ISR, cc[Z80_TABLE_op][0xff] + cc[Z80_TABLE_ex][0xff]);
3715 	}
3716 	else
3717 	{
3718 		/* Interrupt mode 0. We check for CALL and JP instructions, */
3719 		/* if neither of these were found we assume a 1 byte opcode */
3720 		/* was placed on the databus                                */
3721 //		LOG(("Z80 #%d IM0 $%04x\n",cpu_getactivecpu() , irq_vector));
3722 		switch (irq_vector & 0xff0000)
3723 		{
3724 			case 0xcd0000:	/* call */
3725 				PUSH( pc );
3726 				PCD = irq_vector & 0xffff;
3727 				 /* CALL $xxxx + 'interrupt latency' cycles */
3728 				eat_cycles(CYCLES_ISR, cc[Z80_TABLE_op][0xcd]);
3729 				break;
3730 			case 0xc30000:	/* jump */
3731 				PCD = irq_vector & 0xffff;
3732 				/* JP $xxxx + 2 cycles */
3733 				eat_cycles(CYCLES_ISR, cc[Z80_TABLE_op][0xc3]);
3734 				break;
3735 			default:		/* rst (or other opcodes?) */
3736 				PUSH( pc );
3737 				PCD = irq_vector & 0x0038;
3738 				/* RST $xx + 2 cycles */
3739 				eat_cycles(CYCLES_ISR, cc[Z80_TABLE_op][PCD]);
3740 				break;
3741 		}
3742 		/* 'interrupt latency' cycles */
3743 		eat_cycles(CYCLES_ISR, cc[Z80_TABLE_ex][0xff]);
3744 	}
3745 	WZ=PCD;
3746 	change_pc(PCD);
3747 }
3748 
z80_set_cycle_tables_msx()3749 void z80_set_cycle_tables_msx()
3750 {
3751 	cc[Z80_TABLE_op] = cc_op_msx;
3752 	cc[Z80_TABLE_cb] = cc_cb_msx;
3753 	cc[Z80_TABLE_ed] = cc_ed_msx;
3754 	cc[Z80_TABLE_xy] = cc_xy_msx;
3755 	cc[Z80_TABLE_xycb] = cc_xycb_msx;
3756 	cc[Z80_TABLE_ex] = cc_ex_msx;
3757 }
3758 
Z80Init()3759 void Z80Init()
3760 {
3761 	int i, p;
3762 
3763 	/* setup cycle tables */
3764 	cc[Z80_TABLE_op] = cc_op;
3765 	cc[Z80_TABLE_cb] = cc_cb;
3766 	cc[Z80_TABLE_ed] = cc_ed;
3767 	cc[Z80_TABLE_xy] = cc_xy;
3768 	cc[Z80_TABLE_xycb] = cc_xycb;
3769 	cc[Z80_TABLE_ex] = cc_ex;
3770 
3771 #if BIG_FLAGS_ARRAY
3772 	if( !SZHVC_add || !SZHVC_sub )
3773 	{
3774 		int oldval, newval, val;
3775 		UINT8 *padd, *padc, *psub, *psbc;
3776 		/* allocate big flag arrays once */
3777 		SZHVC_add = (UINT8 *)malloc(2*256*256);
3778 		SZHVC_sub = (UINT8 *)malloc(2*256*256);
3779 		if( !SZHVC_add || !SZHVC_sub )
3780 		{
3781 //			fatalerror("Z80: failed to allocate 2 * 128K flags arrays!!!");
3782 		}
3783 		padd = &SZHVC_add[	0*256];
3784 		padc = &SZHVC_add[256*256];
3785 		psub = &SZHVC_sub[	0*256];
3786 		psbc = &SZHVC_sub[256*256];
3787 		for (oldval = 0; oldval < 256; oldval++)
3788 		{
3789 			for (newval = 0; newval < 256; newval++)
3790 			{
3791 				/* add or adc w/o carry set */
3792 				val = newval - oldval;
3793 				*padd = (newval) ? ((newval & 0x80) ? SF : 0) : ZF;
3794 				*padd |= (newval & (YF | XF));	/* undocumented flag bits 5+3 */
3795 				if( (newval & 0x0f) < (oldval & 0x0f) ) *padd |= HF;
3796 				if( newval < oldval ) *padd |= CF;
3797 				if( (val^oldval^0x80) & (val^newval) & 0x80 ) *padd |= VF;
3798 				padd++;
3799 
3800 				/* adc with carry set */
3801 				val = newval - oldval - 1;
3802 				*padc = (newval) ? ((newval & 0x80) ? SF : 0) : ZF;
3803 				*padc |= (newval & (YF | XF));	/* undocumented flag bits 5+3 */
3804 				if( (newval & 0x0f) <= (oldval & 0x0f) ) *padc |= HF;
3805 				if( newval <= oldval ) *padc |= CF;
3806 				if( (val^oldval^0x80) & (val^newval) & 0x80 ) *padc |= VF;
3807 				padc++;
3808 
3809 				/* cp, sub or sbc w/o carry set */
3810 				val = oldval - newval;
3811 				*psub = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF);
3812 				*psub |= (newval & (YF | XF));	/* undocumented flag bits 5+3 */
3813 				if( (newval & 0x0f) > (oldval & 0x0f) ) *psub |= HF;
3814 				if( newval > oldval ) *psub |= CF;
3815 				if( (val^oldval) & (oldval^newval) & 0x80 ) *psub |= VF;
3816 				psub++;
3817 
3818 				/* sbc with carry set */
3819 				val = oldval - newval - 1;
3820 				*psbc = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF);
3821 				*psbc |= (newval & (YF | XF));	/* undocumented flag bits 5+3 */
3822 				if( (newval & 0x0f) >= (oldval & 0x0f) ) *psbc |= HF;
3823 				if( newval >= oldval ) *psbc |= CF;
3824 				if( (val^oldval) & (oldval^newval) & 0x80 ) *psbc |= VF;
3825 				psbc++;
3826 			}
3827 		}
3828 	}
3829 #endif
3830 	for (i = 0; i < 256; i++)
3831 	{
3832 		p = 0;
3833 		if( i&0x01 ) ++p;
3834 		if( i&0x02 ) ++p;
3835 		if( i&0x04 ) ++p;
3836 		if( i&0x08 ) ++p;
3837 		if( i&0x10 ) ++p;
3838 		if( i&0x20 ) ++p;
3839 		if( i&0x40 ) ++p;
3840 		if( i&0x80 ) ++p;
3841 		SZ[i] = i ? i & SF : ZF;
3842 		SZ[i] |= (i & (YF | XF));		/* undocumented flag bits 5+3 */
3843 		SZ_BIT[i] = i ? i & SF : ZF | PF;
3844 		SZ_BIT[i] |= (i & (YF | XF));	/* undocumented flag bits 5+3 */
3845 		SZP[i] = SZ[i] | ((p & 1) ? 0 : PF);
3846 		SZHV_inc[i] = SZ[i];
3847 		if( i == 0x80 ) SZHV_inc[i] |= VF;
3848 		if( (i & 0x0f) == 0x00 ) SZHV_inc[i] |= HF;
3849 		SZHV_dec[i] = SZ[i] | NF;
3850 		if( i == 0x7f ) SZHV_dec[i] |= VF;
3851 		if( (i & 0x0f) == 0x0f ) SZHV_dec[i] |= HF;
3852 	}
3853 
3854 	/* Reset registers to their initial values */
3855 	memset(&Z80, 0, sizeof(Z80));
3856 	Z80.hold_irq = 0;
3857 	WZ = PCD;
3858 //	Z80.daisy = config;
3859 //	Z80.irq_callback = irqcallback;
3860 	IX = IY = 0xffff; /* IX and IY are FFFF after a reset! */
3861 	F = ZF;			/* Zero flag is set */
3862 	Z80InitContention(0, NULL);
3863 }
3864 
Z80Contention_set_bank(int bankno)3865 void Z80Contention_set_bank(int bankno)
3866 {
3867 	m_selected_bank = bankno;
3868 }
3869 
raster_dummy_callback(int)3870 static void raster_dummy_callback(int)
3871 {
3872 }
3873 
Z80InitContention(int is_on_type,void (* rastercallback)(int))3874 void Z80InitContention(int is_on_type, void (*rastercallback)(int))
3875 {
3876 	int i;
3877 	const char *default_pattern = "00000000";
3878 	const char *ula_pattern 	= "65432100";
3879 	const char *s128k_banks     = "1357";
3880 	m_raster_cb = (rastercallback) ? rastercallback : raster_dummy_callback;
3881 
3882 	memset(&m_scripts, 0, sizeof(m_scripts));
3883 	memset(&m_opcode_history, 0, sizeof(m_opcode_history));
3884 
3885 	switch (is_on_type) {
3886 		case 128:
3887 			m_ula_variant = ULA_VARIANT_SINCLAIR;
3888 			m_ula_delay_sequence = ula_pattern;
3889 			m_contended_banks = s128k_banks; // 128k
3890 			m_cycles_contention_start = 14361; //128k (48k is 14335)
3891 			m_cycles_per_line = 228;
3892 			m_cycles_per_frame = 70908; //228*311
3893 			break;
3894 		case 48:
3895 			m_ula_variant = ULA_VARIANT_SINCLAIR;
3896 			m_ula_delay_sequence = ula_pattern;
3897 			m_contended_banks = "";
3898 			m_cycles_contention_start = 14335;
3899 			m_cycles_per_line = 224;
3900 			m_cycles_per_frame = 69888; //224*312;
3901 			break;
3902 		case 0:
3903 			m_ula_variant = ULA_VARIANT_NONE;
3904 			m_ula_delay_sequence = default_pattern;
3905 			m_contended_banks = "";
3906 			m_cycles_contention_start = 0;
3907 			m_cycles_per_line = 0;
3908 			m_cycles_per_frame = 0;
3909 			break;
3910 	}
3911 
3912 	for(i=0; i<MAX_CM_SCRIPTS; i++)
3913 	{
3914 		//Create 'sinclair' variant breakdown tables by default.
3915 		m_scripts[i].id = i;
3916 		m_scripts[i].desc = cm_script_descriptions[i].sinclair;
3917 
3918 		if((m_ula_variant == ULA_VARIANT_AMSTRAD) && (cm_script_descriptions[i].amstrad != NULL))
3919 			m_scripts[i].desc = cm_script_descriptions[i].amstrad;
3920 
3921 		parse_script(m_scripts[i].desc, &(m_scripts[i].breakdown));
3922 	}
3923 
3924 	//Check the ula_delay_sequence.... (Set it to "00000000" if "" has been set)
3925 	if(m_ula_delay_sequence == NULL) m_ula_delay_sequence = default_pattern;
3926 	if(strlen(m_ula_delay_sequence) == 0) m_ula_delay_sequence = default_pattern;
3927 	if(strlen(m_ula_delay_sequence) != 8)
3928 	{
3929 		bprintf(0, _T("ULA delay sequence length must be 8 numeric digits in length (%S)\n"), m_ula_delay_sequence);
3930 	}
3931 	for(i=0; i<8; i++)
3932 	{
3933 		if((m_ula_delay_sequence[i] < '0') || (m_ula_delay_sequence[i] > '9'))
3934 		{
3935 			bprintf(0, _T("Bad character in ULA delay sequence"));
3936 		}
3937 	}
3938 
3939 	//Check contended banks...
3940 	if(m_contended_banks == NULL) m_contended_banks = "";
3941 	m_contended_banks_length = strlen(m_contended_banks);
3942 	for(i=0; i<m_contended_banks_length; i++)
3943 	{
3944 		if((m_contended_banks[i] < '0') || (m_contended_banks[i] > '9'))
3945 		{
3946 			bprintf(0, _T("Bad character in contended banks string"));
3947 		}
3948 	}
3949 
3950 	memset(&m_opcode_history, 0, sizeof(OPCODE_HISTORY));
3951 	m_opcode_history.capturing = false;
3952 	m_tstate_counter = 0;
3953 	m_selected_bank = 0;
3954 }
3955 
z80_set_spectrum_tape_callback(int (* tape_cb)())3956 void z80_set_spectrum_tape_callback(int (*tape_cb)())
3957 {
3958 	Z80.spectrum_mode = 1;
3959 	Z80.spectrum_tape_cb = tape_cb;
3960 }
3961 
Z80SetDaisy(void * dptr)3962 void Z80SetDaisy(void *dptr)
3963 {
3964 	Z80.daisy = (z80_irq_daisy_chain *)dptr;
3965 }
3966 
Z80Reset()3967 void Z80Reset()
3968 {
3969 	memset(&Z80, 0, STRUCT_SIZE_HELPER(Z80_Regs, hold_irq)); // don't clear the callback pointers
3970 	Z80.hold_irq = 0;
3971 
3972 	PC = 0x0000;
3973 	I = 0;
3974 	R = 0;
3975 	R2 = 0;
3976 	WZ = PCD;
3977 	Z80.nmi_state = Z80_CLEAR_LINE;
3978 	Z80.nmi_pending = FALSE;
3979 	Z80.irq_state = Z80_CLEAR_LINE;
3980 	Z80.after_ei = FALSE;
3981 	IX = IY = 0xffff; /* IX and IY are FFFF after a reset! */
3982 	IFF1 = 0;
3983 	IFF2 = 0;
3984 	WZ = PCD;
3985 	Z80Vector = 0xff;
3986 
3987 	if (Z80.daisy)
3988 		z80daisy_reset(Z80.daisy);
3989 
3990 	change_pc(PCD);
3991 
3992 	memset(&m_opcode_history, 0, sizeof(OPCODE_HISTORY));
3993 	m_opcode_history.capturing = false;
3994 	m_tstate_counter = 0;
3995 	m_selected_bank = 0;
3996 }
3997 
Z80Exit()3998 void Z80Exit()
3999 {
4000 	Z80.spectrum_tape_cb = NULL;
4001 	Z80.spectrum_mode = 0;
4002 
4003     if (Z80.daisy) {
4004         z80daisy_exit();
4005     }
4006 
4007 	if (SZHVC_add) free(SZHVC_add);
4008 	SZHVC_add = NULL;
4009 	if (SZHVC_sub) free(SZHVC_sub);
4010 	SZHVC_sub = NULL;
4011 	z80edfe_callback = NULL;
4012 }
4013 
Z80Execute(int cycles)4014 int Z80Execute(int cycles)
4015 {
4016 	Z80.ICount = cycles;
4017 	Z80.cycles_left = cycles;
4018 	Z80.end_run = 0;
4019 
4020 	/* check for NMIs on the way in; they can only be set externally */
4021 	/* via timers, and can't be dynamically enabled, so it is safe */
4022 	/* to just check here */
4023 	if (Z80.nmi_pending)
4024 	{
4025 //		LOG(("Z80 #%d take NMI\n", cpu_getactivecpu()));
4026 		PRVPC = (UINT32)-1;			/* there isn't a valid previous program counter */
4027 		LEAVE_HALT;			/* Check if processor was halted */
4028 
4029 		IFF1 = 0;
4030 		PUSH( pc );
4031 		PCD = 0x0066;
4032 		WZ=PCD;
4033 		change_pc(PCD);
4034 		eat_cycles(CYCLES_ISR, 11);
4035 		Z80.nmi_pending = FALSE;
4036 	}
4037 
4038 	do
4039 	{
4040 		/* check for IRQs before each instruction */
4041 		if (Z80.irq_state != Z80_CLEAR_LINE && IFF1 && !Z80.after_ei)
4042 			take_interrupt();
4043 		Z80.after_ei = FALSE;
4044 
4045 		PRVPC = PCD;
4046 //		CALL_DEBUGGER(PCD);
4047 		R++;
4048 		if (m_ula_variant == ULA_VARIANT_NONE)
4049 		{
4050 			EXEC_INLINE(op,ROP());
4051 		} else {
4052 			capture_opcode_history_start((UINT16)BC,(UINT16)(I << 8));
4053 			EXEC_INLINE(op,ROP());
4054 			capture_opcode_history_finish();
4055 
4056 			// Elimiates sprite flicker on various games (E.g. Marauder and
4057 			// Stormlord) and makes Firefly playable.
4058 			m_raster_cb(m_tstate_counter);
4059 		}
4060 	} while( Z80.ICount > 0 && !Z80.end_run );
4061 
4062 	cycles = cycles - Z80.ICount;
4063 
4064 	Z80.cycles_left = Z80.ICount = 0;
4065 
4066     if (Z80.daisy && z80daisy_has_ctc) {
4067         z80ctc_timer_update(cycles);
4068     }
4069 
4070 	return cycles;
4071 }
4072 
Z80StopExecute()4073 void Z80StopExecute()
4074 {
4075 	Z80.end_run = 1;
4076 }
4077 
z80TotalCycles()4078 INT32 z80TotalCycles()
4079 {
4080 	return Z80.cycles_left - Z80.ICount;
4081 }
4082 
4083 #if 0
4084 void Z80Burn(int cycles)
4085 {
4086 	if( cycles > 0 )
4087 	{
4088 		/* NOP takes 4 cycles per instruction */
4089 		int n = (cycles + 3) / 4;
4090 		R += n;
4091 		Z80.ICount -= 4 * n;
4092 	}
4093 }
4094 #endif
4095 
Z80SetIrqLine(int irqline,int state)4096 void Z80SetIrqLine(int irqline, int state)
4097 {
4098 	if (irqline == Z80_INPUT_LINE_NMI)
4099 	{
4100 		/* mark an NMI pending on the rising edge */
4101 		if (Z80.nmi_state == Z80_CLEAR_LINE && state != Z80_CLEAR_LINE)
4102 			Z80.nmi_pending = TRUE;
4103 		Z80.nmi_state = state;
4104 	}
4105 	else
4106 	{
4107 		/* update the IRQ state via the daisy chain */
4108 		Z80.irq_state = state;
4109 		if (Z80.daisy)
4110 			Z80.irq_state = z80daisy_update_irq_state(Z80.daisy);
4111 
4112 		/* the main execute loop will take the interrupt */
4113 	}
4114 }
4115 
Z80GetContext(void * dst)4116 void Z80GetContext (void *dst)
4117 {
4118 	if( dst )
4119 		*(Z80_Regs*)dst = Z80;
4120 }
4121 
Z80SetContext(void * src)4122 void Z80SetContext (void *src)
4123 {
4124 	if( src )
4125 		Z80 = *(Z80_Regs*)src;
4126 	change_pc(PCD);
4127 }
4128 
Z80Scan(int nAction)4129 int Z80Scan(int nAction)
4130 {
4131     if (Z80.daisy) {
4132         z80daisy_scan(nAction);
4133 	}
4134 
4135 	if (m_ula_variant != ULA_VARIANT_NONE) {
4136 		SCAN_VAR(m_tstate_counter);
4137 		SCAN_VAR(m_selected_bank);
4138 	}
4139 
4140 	return 0;
4141 }
4142 
Z80SetIOReadHandler(Z80ReadIoHandler handler)4143 void Z80SetIOReadHandler(Z80ReadIoHandler handler)
4144 {
4145 	Z80IORead = handler;
4146 }
4147 
Z80SetIOWriteHandler(Z80WriteIoHandler handler)4148 void Z80SetIOWriteHandler(Z80WriteIoHandler handler)
4149 {
4150 	Z80IOWrite = handler;
4151 }
4152 
Z80SetProgramReadHandler(Z80ReadProgHandler handler)4153 void Z80SetProgramReadHandler(Z80ReadProgHandler handler)
4154 {
4155 	Z80ProgramRead = handler;
4156 }
4157 
Z80SetProgramWriteHandler(Z80WriteProgHandler handler)4158 void Z80SetProgramWriteHandler(Z80WriteProgHandler handler)
4159 {
4160 	Z80ProgramWrite = handler;
4161 }
4162 
Z80SetCPUOpReadHandler(Z80ReadOpHandler handler)4163 void Z80SetCPUOpReadHandler(Z80ReadOpHandler handler)
4164 {
4165 	Z80CPUReadOp = handler;
4166 }
4167 
Z80SetCPUOpArgReadHandler(Z80ReadOpArgHandler handler)4168 void Z80SetCPUOpArgReadHandler(Z80ReadOpArgHandler handler)
4169 {
4170 	Z80CPUReadOpArg = handler;
4171 }
4172 
ActiveZ80EXAF()4173 void ActiveZ80EXAF()
4174 {
4175 	EX_AF;
4176 }
4177 
ActiveZ80GetPC()4178 int ActiveZ80GetPC()
4179 {
4180 	return Z80.pc.w.l;
4181 }
4182 
ActiveZ80GetPOP()4183 int ActiveZ80GetPOP()
4184 {
4185 	Z80_PAIR addr;
4186 	RM16( SPD, &addr );
4187 	SP += 2;
4188 	return addr.w.l;
4189 }
4190 
ActiveZ80SetPC(int pc)4191 void ActiveZ80SetPC(int pc)
4192 {
4193 	Z80.pc.w.l = pc;
4194 }
4195 
ActiveZ80SetCarry(int carry)4196 void ActiveZ80SetCarry(int carry)
4197 {
4198 	if (carry) {
4199 		F |= CF;
4200 	} else {
4201 		F &= ~CF;
4202 	}
4203 }
4204 
ActiveZ80GetCarry()4205 int ActiveZ80GetCarry()
4206 {
4207 	return F & CF;
4208 }
4209 
ActiveZ80GetA()4210 int ActiveZ80GetA()
4211 {
4212 	return A;
4213 }
4214 
ActiveZ80SetA(int a)4215 void ActiveZ80SetA(int a)
4216 {
4217 	A = a;
4218 }
4219 
ActiveZ80GetF()4220 int ActiveZ80GetF()
4221 {
4222 	return F;
4223 }
4224 
ActiveZ80SetF(int f)4225 void ActiveZ80SetF(int f)
4226 {
4227 	F = f;
4228 }
4229 
ActiveZ80GetIFF1()4230 int ActiveZ80GetIFF1()
4231 {
4232 	return IFF1;
4233 }
4234 
ActiveZ80GetIFF2()4235 int ActiveZ80GetIFF2()
4236 {
4237 	return IFF2;
4238 }
4239 
ActiveZ80GetCarry2()4240 int ActiveZ80GetCarry2()
4241 {
4242 	return Z80.af2.b.l & CF;
4243 }
4244 
ActiveZ80GetAF()4245 int ActiveZ80GetAF()
4246 {
4247 	return Z80.af.w.l;
4248 }
4249 
ActiveZ80GetAF2()4250 int ActiveZ80GetAF2()
4251 {
4252 	return Z80.af2.w.l;
4253 }
4254 
ActiveZ80SetAF2(int af2)4255 void ActiveZ80SetAF2(int af2)
4256 {
4257 	Z80.af2.w.l = af2;
4258 }
4259 
ActiveZ80GetBC()4260 int ActiveZ80GetBC()
4261 {
4262 	return Z80.bc.w.l;
4263 }
4264 
ActiveZ80GetDE()4265 int ActiveZ80GetDE()
4266 {
4267 	return Z80.de.w.l;
4268 }
4269 
ActiveZ80SetDE(int de)4270 void ActiveZ80SetDE(int de)
4271 {
4272 	Z80.de.w.l = de;
4273 }
4274 
ActiveZ80GetHL()4275 int ActiveZ80GetHL()
4276 {
4277 	return Z80.hl.w.l;
4278 }
4279 
ActiveZ80SetHL(int hl)4280 void ActiveZ80SetHL(int hl)
4281 {
4282 	Z80.hl.w.l = hl;
4283 }
4284 
ActiveZ80GetI()4285 int ActiveZ80GetI()
4286 {
4287 	return Z80.i;
4288 }
4289 
ActiveZ80GetIX()4290 int ActiveZ80GetIX()
4291 {
4292 	return IX;
4293 }
4294 
ActiveZ80SetIX(int ix)4295 void ActiveZ80SetIX(int ix)
4296 {
4297 	IX = ix;
4298 }
4299 
ActiveZ80GetIM()4300 int ActiveZ80GetIM()
4301 {
4302 	return Z80.im;
4303 }
4304 
ActiveZ80GetSP()4305 int ActiveZ80GetSP()
4306 {
4307 	return Z80.sp.w.l;
4308 }
4309 
ActiveZ80SetSP(int sp)4310 void ActiveZ80SetSP(int sp)
4311 {
4312 	Z80.sp.w.l = sp;
4313 }
4314 
ActiveZ80GetPrevPC()4315 int ActiveZ80GetPrevPC()
4316 {
4317 	return Z80.prvpc.w.l;
4318 }
4319 
ActiveZ80SetIRQHold()4320 void ActiveZ80SetIRQHold()
4321 {
4322 	Z80.hold_irq = 1;
4323 }
4324 
ActiveZ80SetVector(INT32 vector)4325 void ActiveZ80SetVector(INT32 vector)
4326 {
4327 	Z80Vector = vector;
4328 }
4329 
ActiveZ80GetVector()4330 int ActiveZ80GetVector()
4331 {
4332 	return Z80Vector;
4333 }
4334 
4335 /**************************************************************************
4336  * Contended Memory Functions                                 [geecab 2018]
4337  **************************************************************************/
capture_opcode_history_start(UINT16 reg_bc,UINT16 reg_ir)4338 void capture_opcode_history_start(UINT16 reg_bc, UINT16 reg_ir)
4339 {
4340 	m_opcode_history.rw_count = 0;
4341 	m_opcode_history.tstate_start = m_tstate_counter;
4342 	m_opcode_history.register_bc = reg_bc;
4343 	m_opcode_history.register_ir = reg_ir;
4344 	m_opcode_history.uncontended_cycles_predicted = 0;
4345 	m_opcode_history.uncontended_cycles_eaten = 0;
4346 
4347 	//We'll find out sometime during the opcode's execution whether to process the
4348 	//optional script elements or not.
4349 	m_opcode_history.do_optional = false; //Just process mandatory script elements (for now).
4350 
4351 	//Reset the script position
4352 	m_opcode_history.script = NULL;
4353 	m_opcode_history.breakdown = NULL;
4354 	m_opcode_history.element = 0;
4355 
4356 	//And we are good to go!
4357 	m_opcode_history.capturing = true;
4358 }
4359 
capture_opcode_history_finish()4360 void capture_opcode_history_finish()
4361 {
4362 	int i;
4363 	bool success = true;
4364 
4365 	//Stops us capturing rwinfo when we are processing interrupts
4366 	m_opcode_history.capturing = false;
4367 
4368 	if (m_opcode_history.uncontended_cycles_predicted != m_opcode_history.uncontended_cycles_eaten)
4369 	{
4370 		bprintf(0, _T("Wrong amount of uncontended cycles eaten (predicted=%d eaten=%d)\n"), m_opcode_history.uncontended_cycles_predicted, m_opcode_history.uncontended_cycles_eaten);
4371 		success = false;
4372 	}
4373 
4374 	//All the reads and writes we did for the last instruction should have been
4375 	//processed for contention.
4376 	for(i=0; i<m_opcode_history.rw_count; i++)
4377 	{
4378 		if(!(m_opcode_history.rw[i].flags & RWINFO_PROCESSED))
4379 		{
4380 			bprintf(0, _T("RWINFO %d not processed for contention\n"), i);
4381 			success = false;
4382 			break;
4383 		}
4384 	}
4385 
4386 	if(!success)
4387 	{
4388 		if(m_opcode_history.script == NULL)
4389 		{
4390 			bprintf(0, _T("Contended Memory Script Unknown\n"));
4391 		}
4392 		else
4393 		{
4394 			bprintf(0, _T("Contended Memory Script CM%02d breakdown=%S\n"), m_opcode_history.script->id, m_opcode_history.script->desc);
4395 		}
4396 
4397 		bprintf(0, _T("Last Opcode History:\n"));
4398 		for(i=0; i<m_opcode_history.rw_count; i++)
4399 		{
4400 #if 1
4401 			bprintf(0, _T(" [%d] addr=0x%04X val=0x%02X (%S, %S, Processed=%S dbg=%S)\n"),
4402 					i,
4403 					m_opcode_history.rw[i].addr,
4404 					m_opcode_history.rw[i].val,
4405 					m_opcode_history.rw[i].flags & RWINFO_READ     ? "Read" : "Write",
4406 					m_opcode_history.rw[i].flags & RWINFO_IO_PORT   ? "IO"  : "Addr",
4407 					m_opcode_history.rw[i].flags & RWINFO_PROCESSED ? "Y"   : "N",
4408 					 m_opcode_history.rw[i].dbg);
4409 #endif
4410 		}
4411 		//assert_always(false, "Failed to process opcode history");
4412 	}
4413 }
4414 
4415 
find_script()4416 bool find_script()
4417 {
4418 	if(m_opcode_history.script == NULL)
4419 	{
4420 		RWINFO *rw = m_opcode_history.rw;
4421 		int contended_type = -1;
4422 
4423 		if(m_opcode_history.rw_count <= 0) return false;
4424 		contended_type = cc_op_contended[rw[0].val];
4425 
4426 		if (contended_type == _CB_)
4427 		{
4428 			//CB** opcodes...
4429 			if(m_opcode_history.rw_count <= 1) return false;
4430 			contended_type = cc_cb_contended[rw[1].val];
4431 			m_opcode_history.script = &m_scripts[contended_type];
4432 			m_opcode_history.breakdown = &(m_opcode_history.script->breakdown);
4433 		}
4434 		else if(contended_type == _ED_)
4435 		{
4436 			//ED** opcodes...
4437 			if(m_opcode_history.rw_count <= 1) return false;
4438 			contended_type = cc_ed_contended[rw[1].val];
4439 			if(contended_type == ILL2) contended_type = CM01; //Illegal_2 ED** opcodes can be processed using the CM01 script
4440 			m_opcode_history.script = &m_scripts[contended_type];
4441 			m_opcode_history.breakdown = &(m_opcode_history.script->breakdown);
4442 		}
4443 		else if(contended_type == _XY_)
4444 		{
4445 			//DD** or FD** opcodes...
4446 			if(m_opcode_history.rw_count <= 1) return false;
4447 			contended_type = cc_xy_contended[rw[1].val];
4448 
4449 			if(contended_type == XYCB)
4450 			{
4451 				 //DDCB**** opcodes or FDCB**** opcodes
4452 				if(m_opcode_history.rw_count <= 3) return false;
4453 				contended_type = cc_xycb_contended[rw[3].val];
4454 				m_opcode_history.script = &m_scripts[contended_type];
4455 				m_opcode_history.breakdown = &(m_opcode_history.script->breakdown);
4456 			}
4457 			else if((contended_type == OPII) || (contended_type == ILL1))
4458 			{
4459 				//Run one of the bog standard opcodes, but with an IX/IY shift.
4460 				eat_cycles(CYCLES_CONTENDED, get_memory_access_delay(rw[0].addr));
4461 				eat_cycles(CYCLES_UNCONTENDED, 4);
4462 				rw[0] = rw[1];
4463 				m_opcode_history.rw_count--;
4464 				return find_script();
4465 			}
4466 			else
4467 			{
4468 				m_opcode_history.script = &(m_scripts[contended_type]);
4469 				m_opcode_history.breakdown = &(m_opcode_history.script->breakdown);
4470 			}
4471 		}
4472 		else
4473 		{
4474 			m_opcode_history.script = &(m_scripts[contended_type]);
4475 			m_opcode_history.breakdown = &(m_opcode_history.script->breakdown);
4476 			if((rw[0].val == 0xCD) || (rw[0].val == 0x18))
4477 			{
4478 				//0xCD ("call **", CM26) and 0x18 ("jz *", CM27) are non-optional
4479 				//but they all its optional elements need processing
4480 				m_opcode_history.do_optional = true;
4481 			}
4482 		}
4483 	}
4484 
4485 	return true; //Good to go!
4486 }
4487 
4488 
run_script()4489 void run_script()
4490 {
4491 	if(!m_opcode_history.capturing || m_ula_variant == ULA_VARIANT_NONE) return;
4492 
4493 	if(!find_script())
4494 	{
4495 		//Stop here. We don't know what script this opcode uses (yet).
4496 		return;
4497 	}
4498 
4499 	for(; m_opcode_history.element < m_opcode_history.breakdown->number_of_elements; m_opcode_history.element++)
4500 	{
4501 		CMSE *se = &(m_opcode_history.breakdown->elements[m_opcode_history.element]);
4502 		RWINFO *rw;
4503 		int mult;
4504 
4505 		if(se->rw_ix >= m_opcode_history.rw_count)
4506 		{
4507 			//Stop here. We don't have the rwinfo stored that will be required to process this script element (yet).
4508 			return;
4509 		}
4510 
4511 		//Check if this is an optional element.
4512 		if(se->is_optional && !m_opcode_history.do_optional)
4513 		{
4514 			//Stop here. This is an optional script element and we are not sure (yet)
4515 	                //if this opcode will need to go down the optional path.
4516 			return;
4517 		}
4518 
4519 
4520 		if(se->type == CMSE_TYPE_IO_PORT) //***Process PORT contention***
4521 		{
4522 			bool high_byte = false;
4523 			bool low_bit = false;
4524 
4525 			rw = &(m_opcode_history.rw[se->rw_ix]);
4526 			rw->flags |= RWINFO_PROCESSED;
4527 
4528 			if(m_ula_variant == ULA_VARIANT_AMSTRAD)
4529 			{
4530 				//For +2a/+3, just eat 4 uncontended cycles for IO operations.
4531 				//Note. According to https://faqwiki.zxnet.co.uk/wiki/Contended_I/O
4532 				//On the +2a/+3 Spectrum, the ULA applies contention only when the
4533 				//Z80's MREQ line is active, which it is not during an I/O operation.
4534 #ifdef DEBUG_CM
4535 				printf("  IO  TState=%d ULA=%d - Addr=%04X Val=%02X (C:0, N:4)\n",
4536 					m_tstate_counter,
4537 					get_ula_delay(),
4538 					m_opcode_history.rw[se->rw_ix].addr,
4539 					m_opcode_history.rw[se->rw_ix].val);
4540 #endif //DEBUG_CM
4541 				eat_cycles(CYCLES_UNCONTENDED, 4);
4542 			}
4543 			else //ULA_VARIANT_SINCLAIR
4544 			{
4545 				/*
4546 				High byte   |         |
4547 				in 40 - 7F? | Low bit | Contention pattern
4548 				------------+---------+-------------------
4549 				No          |  Reset  | N:1, C:3
4550 				No          |   Set   | N:4
4551 				Yes         |  Reset  | C:1, C:3
4552 				Yes         |   Set   | C:1, C:1, C:1, C:1
4553 				*/
4554 				if ((rw->addr >= 0x4000) && (rw->addr <= 0x7fff))
4555 				{
4556 					high_byte  = true;
4557 				}
4558 
4559 				if(rw->addr & 0x0001)
4560 				{
4561 					low_bit = true;
4562 				}
4563 
4564 #ifdef DEBUG_CM
4565 				printf("  IO  TState=%d ULA=%d - Addr=%04X (HiByte=%d LoBit=%d)\n",
4566 						m_tstate_counter,
4567 						get_ula_delay(),
4568 						rw->addr,
4569 						high_byte,
4570 						low_bit);
4571 #endif //DEBUG_CM
4572 
4573 				if((high_byte == false) && (low_bit == false))
4574 				{
4575 					//N:1, C:3
4576 					eat_cycles(CYCLES_UNCONTENDED, 1);
4577 					eat_cycles(CYCLES_CONTENDED, get_ula_delay());
4578 					eat_cycles(CYCLES_UNCONTENDED, 3);
4579 				}
4580 				else if((high_byte == false) && (low_bit == true))
4581 				{
4582 					//N:4
4583 					eat_cycles(CYCLES_UNCONTENDED, 4);
4584 				}
4585 				else if((high_byte == true) && (low_bit == false))
4586 				{
4587 					//C:1, C:3
4588 					eat_cycles(CYCLES_CONTENDED, get_ula_delay());
4589 					eat_cycles(CYCLES_UNCONTENDED, 1);
4590 					eat_cycles(CYCLES_CONTENDED, get_ula_delay());
4591 					eat_cycles(CYCLES_UNCONTENDED, 3);
4592 				}
4593 				else //((high_byte == true) && (low_bit == true))
4594 				{
4595 					//C:1, C:1, C:1, C:1
4596 					eat_cycles(CYCLES_CONTENDED, get_ula_delay());
4597 					eat_cycles(CYCLES_UNCONTENDED, 1);
4598 					eat_cycles(CYCLES_CONTENDED, get_ula_delay());
4599 					eat_cycles(CYCLES_UNCONTENDED, 1);
4600 					eat_cycles(CYCLES_CONTENDED, get_ula_delay());
4601 					eat_cycles(CYCLES_UNCONTENDED, 1);
4602 					eat_cycles(CYCLES_CONTENDED, get_ula_delay());
4603 					eat_cycles(CYCLES_UNCONTENDED, 1);
4604 				}
4605 			}
4606 		}
4607 		else if(se->type == CMSE_TYPE_MEMORY) //***Process Memory Address Contention***
4608 		{
4609 			rw = &(m_opcode_history.rw[se->rw_ix]);
4610 			rw->flags |= RWINFO_PROCESSED;
4611 
4612 			for(mult=0;mult<se->multiplier;mult++)
4613 			{
4614 #ifdef DEBUG_CM
4615 				printf("  MEM TState=%d ULA=%d - Addr=%04X Val=%02X (C:%d, N:%d)\n",
4616 					m_tstate_counter,
4617 					get_ula_delay(),
4618 					m_opcode_history.rw[se->rw_ix].addr,
4619 					m_opcode_history.rw[se->rw_ix].val,
4620 					get_memory_access_delay(m_opcode_history.rw[se->rw_ix].addr),
4621 					se->inst_cycles);
4622 #endif //DEBUG_CM
4623 
4624 				eat_cycles(CYCLES_CONTENDED, get_memory_access_delay(m_opcode_history.rw[se->rw_ix].addr));
4625 				eat_cycles(CYCLES_UNCONTENDED, se->inst_cycles);
4626 			}
4627 		}
4628 		else if(se->type == CMSE_TYPE_IR_REGISTER) //***Process IR Register Pair contention***
4629 		{
4630 			for(mult=0;mult<se->multiplier;mult++)
4631 			{
4632 #ifdef DEBUG_CM
4633 				printf("  IR  TState=%d ULA=%d - Addr=%04X        (C:%d, N:%d)\n",
4634 					m_tstate_counter,
4635 					get_ula_delay(),
4636 					m_opcode_history.register_ir,
4637 					get_memory_access_delay(m_opcode_history.register_ir),
4638 					se->inst_cycles);
4639 #endif //DEBUG_CM
4640 
4641 				eat_cycles(CYCLES_CONTENDED, get_memory_access_delay(m_opcode_history.register_ir));
4642 				eat_cycles(CYCLES_UNCONTENDED, se->inst_cycles);
4643 			}
4644 		}
4645 		else if(se->type == CMSE_TYPE_BC_REGISTER) //***Process BC Register Pair contention***
4646 		{
4647 			for(mult=0;mult<se->multiplier;mult++)
4648 			{
4649 #ifdef DEBUG_CM
4650 				printf("  BC  TState=%d ULA=%d - Addr=%04X        (C:%d, N:%d)\n",
4651 					m_tstate_counter,
4652 					get_ula_delay(),
4653 					m_opcode_history.register_bc,
4654 					get_memory_access_delay(m_opcode_history.register_bc),
4655 					se->inst_cycles);
4656 #endif //DEBUG_CM
4657 
4658 				eat_cycles(CYCLES_CONTENDED, get_memory_access_delay(m_opcode_history.register_bc));
4659 				eat_cycles(CYCLES_UNCONTENDED, se->inst_cycles);
4660 			}
4661 		}
4662 		else if(se->type == CMSE_TYPE_UNCONTENDED) //***Process uncontended cycles***
4663 		{
4664 			for(mult=0;mult<se->multiplier;mult++)
4665 			{
4666 #ifdef DEBUG_CM
4667 				printf("  N   TState=%d ULA=%d -                       (N:%d)\n",
4668 					m_tstate_counter,
4669 					get_ula_delay(),
4670 					se->inst_cycles);
4671 #endif //DEBUG_CM
4672 				eat_cycles(CYCLES_UNCONTENDED, se->inst_cycles);
4673 			}
4674 		}
4675 		else
4676 		{
4677 			bprintf(0, _T("Unknown CMSE type 0x%X\n"), se->type);
4678 			//assert_always(false, "Uknown element type in contented memory script");
4679 		}
4680 	}
4681 }
4682 
4683 
parse_script(const char * script,CM_SCRIPT_BREAKDOWN * breakdown)4684 void parse_script(const char *script, CM_SCRIPT_BREAKDOWN *breakdown)
4685 {
4686 	enum CMSE_STATE
4687 	{
4688 		CMSE_GET_INDEX,
4689 		CMSE_SAVED_INDEX,
4690 		CMSE_GET_CYCLES,
4691 		CMSE_SAVED_CYCLES,
4692 		CMSE_GET_MULTIPLIER,
4693 		CMSE_SAVED_MULTIPLIER
4694 	};
4695 	int state = CMSE_GET_INDEX;
4696 	bool finished = false;
4697 	bool is_optional = false;
4698 	int pos = 0;
4699 	int ch = '?';
4700 	int ch2= '?';
4701 	int *cycles_mandatory = &(breakdown->inst_cycles_mandatory);
4702 	int *cycles_optional = &(breakdown->inst_cycles_optional);
4703 	int  *count = &(breakdown->number_of_elements);
4704 	CMSE *element = &(breakdown->elements[0]);
4705 
4706 
4707 	memset(breakdown, 0, sizeof(CM_SCRIPT_BREAKDOWN));
4708 
4709 	while (!finished)
4710 	{
4711 		ch  = script[pos];
4712 		if(ch == '\0') ch2 = '\0';
4713 		else ch2 = script[pos+1];
4714 
4715 		if(ch == ' ')
4716 		{
4717 			//ignore
4718 		}
4719 		else if((ch == '\0') || (ch == ',') || (ch == ']'))
4720 		{
4721 			//Save the last entry and move onto the next
4722 			if((state == CMSE_SAVED_CYCLES) || (state == CMSE_SAVED_MULTIPLIER))
4723 			{
4724 				int total_cycles = element[*count].inst_cycles * element[*count].multiplier;
4725 
4726 				if(is_optional == false)
4727 				{
4728 					*cycles_mandatory += total_cycles;
4729 				}
4730 				else
4731 				{
4732 					*cycles_optional += total_cycles;
4733 				}
4734 
4735 				(*count)++; //Save the last entry
4736 				state = CMSE_GET_INDEX; //onto the next
4737 			}
4738 
4739 			if (ch == ']') is_optional = false;
4740 			else if (ch == '\0') finished = true;
4741 		}
4742 		else if(ch == '[')
4743 		{
4744 			is_optional = true;
4745 		}
4746 		else if(ch == ':')
4747 		{
4748 			state = CMSE_GET_CYCLES;
4749 		}
4750 		else if(ch == 'x')
4751 		{
4752 			state = CMSE_GET_MULTIPLIER;
4753 		}
4754 		else if((ch == 'I') && (ch2 == 'O'))
4755 		{
4756 			pos++;
4757 			if(state == CMSE_GET_CYCLES)
4758 			{
4759 				//It takes a minimum of 4 Tstates for the Z80 to read a value
4760 				//from an I/O port, or write a value to a port. As is the case with
4761 				//memory access, this can be lengthened by the ULA.
4762 				element[*count].inst_cycles = 4;
4763 				element[*count].type = CMSE_TYPE_IO_PORT;
4764 				state = CMSE_SAVED_CYCLES;
4765 			}
4766 			else break; //Failure!
4767 		}
4768 		else if((ch == 'i') && (ch2 == 'r'))
4769 		{
4770 			pos++;
4771 			if(state == CMSE_GET_INDEX)
4772 			{
4773 				if( *count >= MAX_CMSE)
4774 				{
4775 					//assert_always(false, "Too many script elements (Parsing 'ir')");
4776 				}
4777 
4778 				element[*count].rw_ix = -1;
4779 				element[*count].is_optional = is_optional;
4780 				element[*count].multiplier = 1;
4781 				element[*count].type = CMSE_TYPE_IR_REGISTER;
4782 				state = CMSE_SAVED_INDEX;
4783 			}
4784 			else break; //Failure!
4785 		}
4786 		else if((ch == 'b') && (ch2 == 'c'))
4787 		{
4788 			pos++;
4789 			if(state == CMSE_GET_INDEX)
4790 			{
4791 				if( *count >= MAX_CMSE)
4792 				{
4793 					//assert_always(false, "Too many script elements (Parsing 'bc')");
4794 				}
4795 
4796 				element[*count].rw_ix = -1;
4797 				element[*count].is_optional = is_optional;
4798 				element[*count].multiplier = 1;
4799 				element[*count].type = CMSE_TYPE_BC_REGISTER;
4800 				state = CMSE_SAVED_INDEX;
4801 			}
4802 			else break; //Failure!
4803 		}
4804 		else if(ch == 'N')
4805 		{
4806 			if(state == CMSE_GET_INDEX)
4807 			{
4808 				if( *count >= MAX_CMSE)
4809 				{
4810 					//assert_always(false, "Too many script elements (Parsing 'N')");
4811 				}
4812 
4813 				element[*count].rw_ix = -1;
4814 				element[*count].is_optional = is_optional;
4815 				element[*count].multiplier = 1;
4816 				element[*count].type = CMSE_TYPE_UNCONTENDED;
4817 				state = CMSE_SAVED_INDEX;
4818 			}
4819 			else break; //Failure!
4820 		}
4821 		else
4822 		{
4823 			if((ch >= '0') && (ch<='9'))
4824 			{
4825 				if(state == CMSE_GET_INDEX)
4826 				{
4827 					if( *count >= MAX_CMSE)
4828 					{
4829 						//assert_always(false, "Too many script elements (Parsing '0' to '9')");
4830 					}
4831 
4832 					element[*count].rw_ix = ch-'0';
4833 					element[*count].is_optional = is_optional;
4834 					element[*count].multiplier = 1;
4835 					element[*count].type = CMSE_TYPE_MEMORY;
4836 					state = CMSE_SAVED_INDEX;
4837 				}
4838 				else if(state == CMSE_GET_CYCLES)
4839 				{
4840 					element[*count].inst_cycles = ch-'0';
4841 
4842 					//Might be greater than 10 so lets have a cheeky peak forward.
4843 					ch = script[pos+1];
4844 					if((ch>=0x30) && (ch<=0x39))
4845 					{
4846 						//Yup, good job we had a peak!
4847 						pos++;
4848 						element[*count].inst_cycles *= 10;
4849 						element[*count].inst_cycles += ch-'0';
4850 					}
4851 					state = CMSE_SAVED_CYCLES;
4852 				}
4853 				else if(state == CMSE_GET_MULTIPLIER)
4854 				{
4855 					element[*count].multiplier = ch-'0';
4856 					state = CMSE_SAVED_MULTIPLIER;
4857 				}
4858 				else
4859 				{
4860 					break; //Failure!
4861 				}
4862 			}
4863 			else
4864 			{
4865 				break; //Failure!
4866 			}
4867 		}
4868 
4869 		pos++;
4870 	};
4871 
4872 	//If we broke out the loop before finishing, something went wrong
4873 	if(!finished)
4874 	{
4875 		bprintf(0, _T("Unexpected char '%c' (In script '%S')\n"), ch, script);
4876 		//assert_always(false, "Unexpected character in script");
4877 	}
4878 
4879 	breakdown->inst_cycles_total = *cycles_mandatory + *cycles_optional;
4880 }
4881 
4882 
get_ula_delay()4883 int get_ula_delay()
4884 {
4885 	if(m_tstate_counter >= m_cycles_contention_start)
4886 	{
4887 		int base = m_tstate_counter - m_cycles_contention_start;
4888 		int y_pos = base/m_cycles_per_line;
4889 		int x_pos = base%m_cycles_per_line;
4890 		if ((y_pos < 192) && (x_pos < 128))
4891 		{
4892 			return m_ula_delay_sequence[x_pos%8]-'0';
4893 		}
4894 	}
4895 
4896 	return 0;
4897 }
4898 
4899 
get_memory_access_delay(UINT16 pc_address)4900 int get_memory_access_delay(UINT16 pc_address)
4901 {
4902 	if((pc_address >= 0x4000) && (pc_address <=0x7fff))
4903 	{
4904 		return get_ula_delay();
4905 	}
4906 	else if((pc_address >= 0xc000) && (pc_address <=0xffff))
4907 	{
4908 		if(m_selected_bank > 0)
4909 		{
4910 			int i;
4911 			for(i=0; i<m_contended_banks_length; i++)
4912 			{
4913 				if(m_selected_bank == (m_contended_banks[i]-'0'))
4914 				{
4915 					return get_ula_delay();
4916 				}
4917 			}
4918 		}
4919 	}
4920 
4921 	return 0;
4922 }
4923 
eat_cycles(int type,int cycles)4924 void eat_cycles(int type, int cycles)
4925 {
4926 	// When this function is called and type CYCLES_CONTENDED or CYCLES_UNCONTENDED is set,
4927 	// it means the run_script function is processing the opcode history and that cycles are
4928 	// to be eaten immediately. Note. Only ever occurs when ULA_VARIANT_SINCLAIR or
4929 	// ULA_VARIANT_AMSTRAD is set.
4930 	//
4931 	// When this function is called and type is CYCLES_ISR, it means opcodes during an ISR
4932 	// have been processed. As memory contention processing is not required during ISRs, the
4933 	// predicted cycles are eaten immediately.
4934 	//
4935 	// When this function is called and type is CYCLES_EXEC, it means the EXEC() macro has
4936 	// been called. If ULA_VARIANT_NONE is set, as memory contention processing is not
4937 	// required, the predicted cycles are eaten immediately. If ULA_VARIANT_SINCLAIR or
4938 	// ULA_VARIANT_AMSTRAD is set, as memory contention processing IS required, then the
4939 	// predicted cycles are not eaten. Instead, it will be left to the run_script() function
4940 	// to eat cycles (CYCLES_CONTENDED or CYCLES_UNCONTENDED) based on the opcode's contended
4941 	// memory script. Note. Once all the history for an opcode has been captured, the total
4942 	// amount of CYCLES_UNCONTENDED should match up with the total amount of CYCLES_PREDICTED.
4943 	//
4944 	// Based on the above, this boils down to some simple logic to work out when to eat
4945 	// and when not to...
4946 	if((type == CYCLES_EXEC) && (m_ula_variant != ULA_VARIANT_NONE))
4947 	{
4948 		m_opcode_history.uncontended_cycles_predicted += cycles;
4949 		return;
4950 	}
4951 	else if(type == CYCLES_UNCONTENDED)
4952 	{
4953 		m_opcode_history.uncontended_cycles_eaten += cycles;
4954 	}
4955 
4956 	Z80.ICount -= cycles;
4957 	m_tstate_counter += cycles;
4958 	if(m_tstate_counter >= m_cycles_per_frame) {
4959 		//bprintf(0, _T("z80.cpp: spec frame eof %d\n"), m_tstate_counter);
4960 		m_tstate_counter -= m_cycles_per_frame;
4961 	}
4962 }
4963 
4964 
store_rwinfo(UINT16 addr,UINT8 val,UINT16 flags,const char * dbg)4965 void store_rwinfo(UINT16 addr, UINT8 val, UINT16 flags, const char *dbg)
4966 {
4967 	RWINFO *rw;
4968 
4969 	if(!m_opcode_history.capturing || m_ula_variant == ULA_VARIANT_NONE) return;
4970 
4971 	if(m_opcode_history.rw_count >= MAX_RWINFO)
4972 	{
4973 		bprintf(0, _T("RWINFO overflow. No room for addr=0x%04X val=0x%02X flags=0x%X (%S) tstate=%d\n"), addr, val, flags, dbg, m_tstate_counter);
4974 		//assert_always(false, "Opcode history list is full");
4975 	}
4976 
4977 	//Save the new rwinfo
4978 	rw = &(m_opcode_history.rw[m_opcode_history.rw_count]);
4979 	rw->addr = addr;
4980 	rw->val = val;
4981 	rw->flags = flags;
4982 	rw->dbg = dbg;
4983 	m_opcode_history.rw_count++;
4984 
4985 	run_script();
4986 
4987 	//Originally, the intention was to update the screen raster each time
4988 	//any tstates were eaten (I.e. call the raster_cb from inside the
4989 	//eat_cycles function) which worked well but wasn't efficient.
4990 	//So below is the opimisation, it is based on the fact that the screen
4991 	//raster only needs to be updated immediately *before* a border or screen colour
4992 	//attribute write occurs.
4993 	if(rw->flags & RWINFO_WRITE)
4994 	{
4995 		if(rw->flags & RWINFO_IO_PORT)
4996 		{
4997 			if((addr & 0xff) == 0xfe) //Border change
4998 			{
4999 				m_raster_cb(m_tstate_counter);
5000 			}
5001 		}
5002 		else if(rw->flags & RWINFO_MEMORY)
5003 		{
5004 			// Screen or attribute change (48K and 128K)
5005 			if((addr >= 0x4000) && (addr <= 0x5AFF))
5006 				m_raster_cb(m_tstate_counter);
5007 			// Screen or attribute change (128K models - bank 5)
5008 			else if( (m_selected_bank == 5) && ((addr >= 0xC000) && (addr <= 0xDAFF)) )
5009 				m_raster_cb(m_tstate_counter);
5010 		}
5011 	}
5012 }
5013