Update
[debian-dgen.git] / mz80 / makez80.c
blob994d02bcfad509890132094d47ca8e58e18517e4
1 /* Multi-Z80 32 Bit emulator */
3 /* Copyright 1996, 1997, 1998, 1999, 2000 Neil Bradley, All rights reserved
5 * License agreement:
7 * (MZ80 Refers to both the assembly and C code emitted by makeZ80.c and
8 * makeZ80.c itself)
10 * MZ80 May be distributed in unmodified form to any medium.
12 * MZ80 May not be sold, or sold as a part of a commercial package without
13 * the express written permission of Neil Bradley (neil@synthcom.com). This
14 * includes shareware.
16 * Modified versions of MZ80 may not be publicly redistributed without author
17 * approval (neil@synthcom.com). This includes distributing via a publicly
18 * accessible LAN. You may make your own source modifications and distribute
19 * MZ80 in source or object form, but if you make modifications to MZ80
20 * then it should be noted in the top as a comment in makeZ80.c.
22 * MZ80 Licensing for commercial applications is available. Please email
23 * neil@synthcom.com for details.
25 * Synthcom Systems, Inc, and Neil Bradley will not be held responsible for
26 * any damage done by the use of MZ80. It is purely "as-is".
28 * If you use MZ80 in a freeware application, credit in the following text:
30 * "Multi-Z80 CPU emulator by Neil Bradley (neil@synthcom.com)"
32 * must accompany the freeware application within the application itself or
33 * in the documentation.
35 * Legal stuff aside:
37 * If you find problems with MZ80, please email the author so they can get
38 * resolved. If you find a bug and fix it, please also email the author so
39 * that those bug fixes can be propogated to the installed base of MZ80
40 * users. If you find performance improvements or problems with MZ80, please
41 * email the author with your changes/suggestions and they will be rolled in
42 * with subsequent releases of MZ80.
44 * The whole idea of this emulator is to have the fastest available 32 bit
45 * Multi-Z80 emulator for the PC, giving maximum performance.
47 */
50 DGen/SDL modifications for compilation issues and bugfixes:
52 2011-08-28 - Rename VERSION to MZ80_VERSION.
53 - Some fprintf() calls had too many arguments.
54 - Use C99 uint*_t/int*_t for portability.
55 2011-09-11 - Replace assert(0) occurences with abort() as these checks
56 shouldn't go away when defining NDEBUG.
57 - Add default case to switch statement in IRHandler().
58 - Append -dgen to version number.
59 2011-10-08 - Fix segfault on reset in the C version.
60 2014-06-22 - Remove malloc() calls from mz80init() as they cannot be
61 checked nor freed.
64 #include <stdio.h>
65 #include <stdlib.h>
66 #include <string.h>
67 #include <assert.h>
68 #include <stdint.h>
69 #include <inttypes.h>
71 #define MZ80_VERSION "3.4-dgen"
73 #define TRUE 0xff
74 #define FALSE 0x0
75 #define INVALID 0xff
77 #define UINT32 uint32_t
78 #define UINT8 uint8_t
79 #define INT8 char
81 #define TIMING_REGULAR 0x00
82 #define TIMING_XXCB 0x01
83 #define TIMING_CB 0xcb
84 #define TIMING_DDFD 0xdd
85 #define TIMING_ED 0xed
86 #define TIMING_EXCEPT 0x02
88 FILE *fp = NULL;
89 char string[150];
90 char cpubasename[150];
91 static char mz80Index[50];
92 static char mz80IndexHalfHigh[50];
93 static char mz80IndexHalfLow[50];
94 char majorOp[50];
95 char procname[150];
96 UINT32 dwGlobalLabel = 0;
98 enum
100 MZ80_ASSEMBLY_X86,
101 MZ80_C,
102 MZ80_UNKNOWN
105 UINT8 bPlain = FALSE;
106 UINT8 bNoTiming = FALSE;
107 UINT8 bUseStack = 0;
108 UINT8 bCurrentMode = TIMING_REGULAR; // Current timing mode
109 UINT8 b16BitIo = FALSE;
110 UINT8 bThroughCallHandler = FALSE;
111 UINT8 bOS2 = FALSE;
112 UINT8 bWhat = MZ80_UNKNOWN;
114 void ProcBegin(UINT32 dwOpcode);
116 INT8 *pbLocalReg[8] =
118 "ch",
119 "cl",
120 "dh",
121 "dl",
122 "bh",
123 "bl",
124 "dl",
125 "al"
128 INT8 *pbLocalRegC[8] =
130 "cpu.z80B",
131 "cpu.z80C",
132 "cpu.z80D",
133 "cpu.z80E",
134 "cpu.z80H",
135 "cpu.z80L",
136 "barf",
137 "cpu.z80A"
140 INT8 *pbPushReg[8] =
142 "cl",
143 "ch",
144 "byte [_z80de]",
145 "byte [_z80de + 1]",
146 "bl",
147 "bh",
148 "ah",
149 "al"
152 INT8 *pbFlags[8] =
154 "nz",
155 "z",
156 "nc",
157 "c",
158 "po",
159 "pe",
160 "ns",
164 INT8 *pbRegPairC[] =
166 "cpu.z80BC",
167 "cpu.z80DE",
168 "cpu.z80HL",
169 "cpu.z80sp"
172 INT8 *pbFlagsC[8] =
174 "(!(cpu.z80F & Z80_FLAG_ZERO))",
175 "(cpu.z80F & Z80_FLAG_ZERO)",
176 "(!(cpu.z80F & Z80_FLAG_CARRY))",
177 "(cpu.z80F & Z80_FLAG_CARRY)",
178 "(!(cpu.z80F & Z80_FLAG_OVERFLOW_PARITY))",
179 "(cpu.z80F & Z80_FLAG_OVERFLOW_PARITY)",
180 "(!(cpu.z80F & Z80_FLAG_SIGN))",
181 "(cpu.z80F & Z80_FLAG_SIGN)"
184 INT8 *pbMathReg[8] =
186 "ch",
187 "cl",
188 "byte [_z80de + 1]",
189 "byte [_z80de]",
190 "bh",
191 "bl",
192 "INVALID",
193 "al"
196 INT8 *pbMathRegC[8] =
198 "cpu.z80B",
199 "cpu.z80C",
200 "cpu.z80D",
201 "cpu.z80E",
202 "cpu.z80H",
203 "cpu.z80L",
204 "bTemp",
205 "cpu.z80A"
208 INT8 *pbRegPairs[4] =
210 "cx", // BC
211 "word [_z80de]", // DE
212 "bx", // HL
213 "word [_z80sp]" // SP
216 INT8 *pbRegPairsC[4] =
218 "cpu.z80BC", // BC
219 "cpu.z80DE", // DE
220 "cpu.z80HL", // HL
221 "cpu.z80sp" // SP
224 INT8 *pbPopRegPairs[4] =
226 "cx", // BC
227 "word [_z80de]", // DE
228 "bx", // HL
229 "ax" // SP
232 INT8 *pbPopRegPairC[4] =
234 "cpu.z80BC",
235 "cpu.z80DE",
236 "cpu.z80HL",
237 "cpu.z80AF"
240 INT8 *pbIndexedRegPairs[4] =
242 "cx", // BC
243 "word [_z80de]", // DE
244 "di", // IX/IY
245 "word [_z80sp]" // SP
248 // Timing tables
250 UINT8 bTimingRegular[0x100] =
252 0x04, 0x0a, 0x07, 0x06, 0x04, 0x04, 0x07, 0x04, 0x04, 0x0b, 0x07, 0x06, 0x04, 0x04, 0x07, 0x04,
253 0x08, 0x0a, 0x07, 0x06, 0x04, 0x04, 0x07, 0x04, 0x0c, 0x0b, 0x07, 0x06, 0x04, 0x04, 0x07, 0x04,
254 0x07, 0x0a, 0x10, 0x06, 0x04, 0x04, 0x07, 0x04, 0x07, 0x0b, 0x10, 0x06, 0x04, 0x04, 0x07, 0x04,
255 0x07, 0x0a, 0x0d, 0x06, 0x0b, 0x0b, 0x0a, 0x04, 0x07, 0x0b, 0x0d, 0x06, 0x04, 0x04, 0x07, 0x04,
257 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
258 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
259 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
260 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
262 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
263 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
264 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
265 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
267 0x05, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x07, 0x0b, 0x05, 0x0a, 0x0a, 0x00, 0x0a, 0x11, 0x07, 0x0b,
268 0x05, 0x0a, 0x0a, 0x0b, 0x0a, 0x0b, 0x07, 0x0b, 0x05, 0x04, 0x0a, 0x0b, 0x0a, 0x00, 0x07, 0x0b,
269 0x05, 0x0a, 0x0a, 0x13, 0x0a, 0x0b, 0x07, 0x0b, 0x05, 0x04, 0x0a, 0x04, 0x0a, 0x00, 0x07, 0x0b,
270 0x05, 0x0a, 0x0a, 0x04, 0x0a, 0x0b, 0x07, 0x0b, 0x05, 0x06, 0x0a, 0x04, 0x0a, 0x00, 0x07, 0x0b
273 UINT8 bTimingCB[0x100] =
275 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
276 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
277 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
278 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
280 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08,
281 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08,
282 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08,
283 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08,
284 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
285 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
286 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
287 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
288 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
289 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
290 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
291 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08
294 UINT8 bTimingXXCB[0x100] =
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
300 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
301 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
302 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
303 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00
314 UINT8 bTimingDDFD[0x100] =
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x0e, 0x14, 0x0a, 0x09, 0x09, 0x09, 0x00, 0x00, 0x0f, 0x14, 0x0a, 0x09, 0x09, 0x09, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x13, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
324 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x13, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x13, 0x09,
325 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
326 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
328 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
329 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x0e, 0x00, 0x17, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
336 UINT8 bTimingED[0x100] =
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x0e, 0x08, 0x09, 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x0e, 0x08, 0x09,
344 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x09, 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x09,
345 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x12, 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x12,
346 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x00, 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
351 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
359 void EDHandler(UINT32 dwOpcode);
360 void DDHandler(UINT32 dwOpcode);
361 void FDHandler(UINT32 dwOpcode);
362 void CBHandler(UINT32 dwOpcode);
364 void PushPopOperations(UINT32 dwOpcode);
365 void AddRegpairOperations(UINT32 dwOpcode);
366 void CallHandler(UINT32 dwOpcode);
367 void MiscHandler(UINT32 dwOpcode);
368 void IMHandler(UINT32 dwOpcode);
369 void IRHandler(UINT32 dwOpcode);
370 void LdRegPairImmediate(UINT32 dwOpcode);
371 void LoadImmediate(UINT32 dwOpcode);
372 void LdRegpairPtrByte(UINT32 dwOpcode);
373 void MathOperation(UINT32 dwOpcode);
374 void RegIntoMemory(UINT32 dwOpcode);
375 void JpHandler(UINT32 dwOpcode);
376 void LdRegImmediate(UINT32 dwOpcode);
377 void IncRegister(UINT32 dwOpcode);
378 void DecRegister(UINT32 dwOpcode);
379 void IncDecRegpair(UINT32 dwOpcode);
380 void LdRegReg(UINT32 dwOpcode);
381 void MathOperationDirect(UINT32 dwOpcode);
382 void JrHandler(UINT32 dwOpcode);
383 void RetHandler(UINT32 dwOpcode);
384 void RestartHandler(UINT32 dwOpcode);
385 void ToRegFromHl(UINT32);
386 void RraRlaHandler(UINT32);
387 void LdByteRegpair(UINT32);
388 void IncDecHLPtr(UINT32 dwOpcode);
389 void InOutHandler(UINT32 dwOpcode);
390 void RLCRRCRLRRSLASRASRLHandler(UINT32 dwOpcode);
391 void BITHandler(UINT32 dwOpcode);
392 void RESSETHandler(UINT32 dwOpcode);
393 void PushPopOperationsIndexed(UINT32 dwOpcode);
394 void LDILDRLDIRLDDRHandler(UINT32);
395 void LdRegpair(UINT32 dwOpcode);
396 void ExtendedRegIntoMemory(UINT32 dwOpcode);
397 void NegHandler(UINT32 dwOpcode);
398 void ExtendedInHandler(UINT32 dwOpcode);
399 void ExtendedOutHandler(UINT32 dwOpcode);
400 void RetIRetNHandler(UINT32 dwOcode);
401 void AdcSbcRegpair(UINT32 dwOpcode);
402 void CPICPDCPIRCPDRHandler(UINT32 dwOpcode);
403 void RRDRLDHandler(UINT32 dwOpcode);
404 void UndocRegToIndex(UINT32 dwOpcode);
405 void UndocIndexToReg(UINT32 dwOpcode);
406 void MathOperationIndexed(UINT32 dwOpcode);
407 void IncDecIndexed(UINT32 dwOpcode);
408 void DDFDCBHandler(UINT32 dwOpcode);
409 void JPIXIYHandler(UINT32 dwOpcode);
410 void AddIndexHandler(UINT32 dwOpcode);
411 void SPToIndex(UINT32 dwOpcode);
412 void LdByteToIndex(UINT32 dwOpcode);
413 void LdRegIndexOffset(UINT32 dwOpcode);
414 void IncDecIndexReg(UINT32 dwOpcode);
415 void ExIndexed(UINT32 dwOpcode);
416 void UndocIncDecIndexReg(UINT32 dwOpcode);
417 void UndocLoadHalfIndexReg(UINT32 dwOpcode);
418 void UndocMathIndex(UINT32 dwOpcode);
419 void ddcbBitWise(UINT32 dwOpcode);
420 void LdIndexPtrReg(UINT32 dwOpcode);
421 void StoreIndexReg(UINT32 dwOpcode);
422 void LoadIndexReg(UINT32 dwOpcode);
423 void OTIROTDROUTIOUTDHandler(UINT32 dwOpcode);
424 void INIRINDRINIINDHandler(UINT32 dwOpcode);
426 struct sOp
428 UINT32 bOpCode;
429 void (*Emitter)(UINT32);
432 struct sOp StandardOps[] =
434 {0xd3, InOutHandler}, // V
435 {0xdb, InOutHandler}, // V
437 {0x0a, LdByteRegpair}, // V
438 {0x1a, LdByteRegpair}, // V
440 {0x17, RraRlaHandler}, // V
441 {0x1f, RraRlaHandler}, // V
443 {0x05, DecRegister}, // V
444 {0x0d, DecRegister}, // V
445 {0x15, DecRegister}, // V
446 {0x1d, DecRegister}, // V
447 {0x25, DecRegister}, // V
448 {0x2d, DecRegister}, // V
449 {0x3d, DecRegister}, // V
451 {0x04, IncRegister}, // V
452 {0x0c, IncRegister}, // V
453 {0x14, IncRegister}, // V
454 {0x1c, IncRegister}, // V
455 {0x24, IncRegister}, // V
456 {0x2c, IncRegister}, // V
457 {0x3c, IncRegister}, // V
459 {0x32, RegIntoMemory}, // V
460 {0x22, RegIntoMemory}, // V
462 {0xc3, JpHandler}, // V
463 {0xc2, JpHandler}, // V
464 {0xca, JpHandler}, // V
465 {0xd2, JpHandler}, // V
466 {0xda, JpHandler}, // V
467 {0xe2, JpHandler}, // V
468 {0xea, JpHandler}, // V
469 {0xf2, JpHandler}, // V
470 {0xfa, JpHandler}, // V
473 {0x06, LdRegImmediate}, // V
474 {0x0e, LdRegImmediate}, // V
475 {0x16, LdRegImmediate}, // V
476 {0x1e, LdRegImmediate}, // V
477 {0x26, LdRegImmediate}, // V
478 {0x2e, LdRegImmediate}, // V
479 {0x3e, LdRegImmediate}, // V
481 {0x0b, IncDecRegpair}, // V
482 {0x1b, IncDecRegpair}, // V
483 {0x2b, IncDecRegpair}, // V
484 {0x3b, IncDecRegpair}, // V
486 {0x03, IncDecRegpair}, // V
487 {0x13, IncDecRegpair}, // V
488 {0x23, IncDecRegpair}, // V
489 {0x33, IncDecRegpair}, // V
491 {0x34, IncDecHLPtr}, // V
492 {0x35, IncDecHLPtr}, // V
494 {0xcb, CBHandler},
495 {0xdd, DDHandler},
496 {0xed, EDHandler},
497 {0xfd, FDHandler},
499 {0x01, LdRegPairImmediate}, // V
500 {0x11, LdRegPairImmediate}, // V
501 {0x21, LdRegPairImmediate}, // V
502 {0x31, LdRegPairImmediate}, // V
504 {0xe3, MiscHandler}, // V
505 {0x2a, MiscHandler}, // V
506 {0xfb, MiscHandler}, // V
507 {0xf9, MiscHandler}, // V
508 {0xd9, MiscHandler}, // V
509 {0x76, MiscHandler}, // V
510 {0x3f, MiscHandler}, // V
511 {0x37, MiscHandler}, // V
512 {0x27, MiscHandler}, // V
513 {0x07, MiscHandler}, // V
514 {0x08, MiscHandler}, // V
515 {0x00, MiscHandler}, // V
516 {0xe9, MiscHandler}, // V
517 {0xeb, MiscHandler}, // V
518 {0xf3, MiscHandler}, // V
519 {0x3a, MiscHandler}, // V
520 {0x10, MiscHandler}, // V
521 {0x2f, MiscHandler}, // V
522 {0x0f, MiscHandler}, // V
524 {0x02, LdRegpairPtrByte}, // V
525 {0x12, LdRegpairPtrByte}, // V
527 {0x70, LdRegpairPtrByte}, // V
528 {0x71, LdRegpairPtrByte}, // V
529 {0x72, LdRegpairPtrByte}, // V
530 {0x73, LdRegpairPtrByte}, // V
531 {0x74, LdRegpairPtrByte}, // V
532 {0x75, LdRegpairPtrByte}, // V
533 {0x77, LdRegpairPtrByte}, // V
535 {0x36, LdRegpairPtrByte}, // V
537 {0x80, MathOperation}, // V
538 {0x81, MathOperation}, // V
539 {0x82, MathOperation}, // V
540 {0x83, MathOperation}, // V
541 {0x84, MathOperation}, // V
542 {0x85, MathOperation}, // V
543 {0x86, MathOperation}, // V
544 {0x87, MathOperation}, // V
545 {0x88, MathOperation}, // V
546 {0x89, MathOperation}, // V
547 {0x8a, MathOperation}, // V
548 {0x8b, MathOperation}, // V
549 {0x8c, MathOperation}, // V
550 {0x8d, MathOperation}, // V
551 {0x8e, MathOperation}, // V
552 {0x8f, MathOperation}, // V
553 {0x90, MathOperation}, // V
554 {0x91, MathOperation}, // V
555 {0x92, MathOperation}, // V
556 {0x93, MathOperation}, // V
557 {0x94, MathOperation}, // V
558 {0x95, MathOperation}, // V
559 {0x96, MathOperation}, // V
560 {0x97, MathOperation}, // V
561 {0x98, MathOperation}, // V
562 {0x99, MathOperation}, // V
563 {0x9a, MathOperation}, // V
564 {0x9b, MathOperation}, // V
565 {0x9c, MathOperation}, // V
566 {0x9d, MathOperation}, // V
567 {0x9e, MathOperation}, // V
568 {0x9f, MathOperation}, // V
569 {0xa0, MathOperation}, // V
570 {0xa1, MathOperation}, // V
571 {0xa2, MathOperation}, // V
572 {0xa3, MathOperation}, // V
573 {0xa4, MathOperation}, // V
574 {0xa5, MathOperation}, // V
575 {0xa6, MathOperation}, // V
576 {0xa7, MathOperation}, // V
577 {0xa8, MathOperation}, // V
578 {0xa9, MathOperation}, // V
579 {0xaa, MathOperation}, // V
580 {0xab, MathOperation}, // V
581 {0xac, MathOperation}, // V
582 {0xad, MathOperation}, // V
583 {0xae, MathOperation}, // V
584 {0xaf, MathOperation}, // V
585 {0xb0, MathOperation}, // V
586 {0xb1, MathOperation}, // V
587 {0xb2, MathOperation}, // V
588 {0xb3, MathOperation}, // V
589 {0xb4, MathOperation}, // V
590 {0xb5, MathOperation}, // V
591 {0xb6, MathOperation}, // V
592 {0xb7, MathOperation}, // V
593 {0xb8, MathOperation}, // V
594 {0xb9, MathOperation}, // V
595 {0xba, MathOperation}, // V
596 {0xbb, MathOperation}, // V
597 {0xbc, MathOperation}, // V
598 {0xbd, MathOperation}, // V
599 {0xbe, MathOperation}, // V
600 {0xbf, MathOperation}, // V
602 {0x40, LdRegReg}, // V
603 {0x41, LdRegReg}, // V
604 {0x42, LdRegReg}, // V
605 {0x43, LdRegReg}, // V
606 {0x44, LdRegReg}, // V
607 {0x45, LdRegReg}, // V
608 {0x47, LdRegReg}, // V
609 {0x48, LdRegReg}, // V
610 {0x49, LdRegReg}, // V
611 {0x4a, LdRegReg}, // V
612 {0x4b, LdRegReg}, // V
613 {0x4c, LdRegReg}, // V
614 {0x4d, LdRegReg}, // V
615 {0x4f, LdRegReg}, // V
616 {0x50, LdRegReg}, // V
617 {0x51, LdRegReg}, // V
618 {0x52, LdRegReg}, // V
619 {0x53, LdRegReg}, // V
620 {0x54, LdRegReg}, // V
621 {0x55, LdRegReg}, // V
622 {0x57, LdRegReg}, // V
623 {0x58, LdRegReg}, // V
624 {0x59, LdRegReg}, // V
625 {0x5a, LdRegReg}, // V
626 {0x5b, LdRegReg}, // V
627 {0x5c, LdRegReg}, // V
628 {0x5d, LdRegReg}, // V
629 {0x5f, LdRegReg}, // V
630 {0x60, LdRegReg}, // V
631 {0x61, LdRegReg}, // V
632 {0x62, LdRegReg}, // V
633 {0x63, LdRegReg}, // V
634 {0x64, LdRegReg}, // V
635 {0x65, LdRegReg}, // V
636 {0x67, LdRegReg}, // V
637 {0x68, LdRegReg}, // V
638 {0x69, LdRegReg}, // V
639 {0x6a, LdRegReg}, // V
640 {0x6b, LdRegReg}, // V
641 {0x6c, LdRegReg}, // V
642 {0x6d, LdRegReg}, // V
643 {0x6f, LdRegReg}, // V
644 {0x78, LdRegReg}, // V
645 {0x79, LdRegReg}, // V
646 {0x7a, LdRegReg}, // V
647 {0x7b, LdRegReg}, // V
648 {0x7c, LdRegReg}, // V
649 {0x7d, LdRegReg}, // V
650 {0x7f, LdRegReg}, // V
652 {0xc6, MathOperationDirect}, // V
653 {0xce, MathOperationDirect}, // V
654 {0xd6, MathOperationDirect}, // V
655 {0xde, MathOperationDirect}, // V
656 {0xe6, MathOperationDirect}, // V
657 {0xee, MathOperationDirect}, // V
658 {0xf6, MathOperationDirect}, // V
659 {0xfe, MathOperationDirect}, // V
661 {0x18, JrHandler}, // V
662 {0x20, JrHandler}, // V
663 {0x28, JrHandler}, // V
664 {0x30, JrHandler}, // V
665 {0x38, JrHandler},
667 {0xc4, CallHandler}, // V
668 {0xcc, CallHandler}, // V
669 {0xcd, CallHandler}, // V
670 {0xd4, CallHandler}, // V
671 {0xdc, CallHandler}, // V
672 {0xe4, CallHandler}, // V
673 {0xec, CallHandler}, // V
674 {0xf4, CallHandler}, // V
675 {0xfc, CallHandler}, // V
677 {0xc9, RetHandler}, // V
678 {0xc0, RetHandler}, // V
679 {0xc8, RetHandler}, // V
680 {0xd0, RetHandler}, // V
681 {0xd8, RetHandler}, // V
682 {0xe0, RetHandler}, // V
683 {0xe8, RetHandler}, // V
684 {0xf0, RetHandler}, // V
685 {0xf8, RetHandler}, // V
687 {0xc7, RestartHandler}, // V
688 {0xcf, RestartHandler}, // V
689 {0xd7, RestartHandler}, // V
690 {0xdf, RestartHandler}, // V
691 {0xe7, RestartHandler}, // V
692 {0xef, RestartHandler}, // V
693 {0xf7, RestartHandler}, // V
694 {0xff, RestartHandler}, // V
696 {0x46, ToRegFromHl}, // V
697 {0x4e, ToRegFromHl}, // V
698 {0x56, ToRegFromHl}, // V
699 {0x5e, ToRegFromHl}, // V
700 {0x66, ToRegFromHl}, // V
701 {0x6e, ToRegFromHl}, // V
702 {0x7e, ToRegFromHl},
704 {0x09, AddRegpairOperations}, // V
705 {0x19, AddRegpairOperations}, // V
706 {0x29, AddRegpairOperations}, // V
707 {0x39, AddRegpairOperations}, // V
709 {0xc5, PushPopOperations}, // V
710 {0xd5, PushPopOperations}, // V
711 {0xe5, PushPopOperations}, // V
712 {0xf5, PushPopOperations}, // V
713 {0xc1, PushPopOperations}, // V
714 {0xd1, PushPopOperations}, // V
715 {0xe1, PushPopOperations}, // V
716 {0xf1, PushPopOperations}, // V
718 // Terminator
720 {0xffffffff, NULL}
723 struct sOp CBOps[] =
725 {0x00, RLCRRCRLRRSLASRASRLHandler},
726 {0x01, RLCRRCRLRRSLASRASRLHandler},
727 {0x02, RLCRRCRLRRSLASRASRLHandler},
728 {0x03, RLCRRCRLRRSLASRASRLHandler},
729 {0x04, RLCRRCRLRRSLASRASRLHandler},
730 {0x05, RLCRRCRLRRSLASRASRLHandler},
731 {0x06, RLCRRCRLRRSLASRASRLHandler},
732 {0x07, RLCRRCRLRRSLASRASRLHandler},
733 {0x08, RLCRRCRLRRSLASRASRLHandler},
734 {0x09, RLCRRCRLRRSLASRASRLHandler},
735 {0x0a, RLCRRCRLRRSLASRASRLHandler},
736 {0x0b, RLCRRCRLRRSLASRASRLHandler},
737 {0x0c, RLCRRCRLRRSLASRASRLHandler},
738 {0x0d, RLCRRCRLRRSLASRASRLHandler},
739 {0x0e, RLCRRCRLRRSLASRASRLHandler},
740 {0x0f, RLCRRCRLRRSLASRASRLHandler},
742 {0x10, RLCRRCRLRRSLASRASRLHandler},
743 {0x11, RLCRRCRLRRSLASRASRLHandler},
744 {0x12, RLCRRCRLRRSLASRASRLHandler},
745 {0x13, RLCRRCRLRRSLASRASRLHandler},
746 {0x14, RLCRRCRLRRSLASRASRLHandler},
747 {0x15, RLCRRCRLRRSLASRASRLHandler},
748 {0x16, RLCRRCRLRRSLASRASRLHandler},
749 {0x17, RLCRRCRLRRSLASRASRLHandler},
750 {0x18, RLCRRCRLRRSLASRASRLHandler},
751 {0x19, RLCRRCRLRRSLASRASRLHandler},
752 {0x1a, RLCRRCRLRRSLASRASRLHandler},
753 {0x1b, RLCRRCRLRRSLASRASRLHandler},
754 {0x1c, RLCRRCRLRRSLASRASRLHandler},
755 {0x1d, RLCRRCRLRRSLASRASRLHandler},
756 {0x1e, RLCRRCRLRRSLASRASRLHandler},
757 {0x1f, RLCRRCRLRRSLASRASRLHandler},
759 {0x20, RLCRRCRLRRSLASRASRLHandler},
760 {0x21, RLCRRCRLRRSLASRASRLHandler},
761 {0x22, RLCRRCRLRRSLASRASRLHandler},
762 {0x23, RLCRRCRLRRSLASRASRLHandler},
763 {0x24, RLCRRCRLRRSLASRASRLHandler},
764 {0x25, RLCRRCRLRRSLASRASRLHandler},
765 {0x26, RLCRRCRLRRSLASRASRLHandler},
766 {0x27, RLCRRCRLRRSLASRASRLHandler},
767 {0x28, RLCRRCRLRRSLASRASRLHandler},
768 {0x29, RLCRRCRLRRSLASRASRLHandler},
769 {0x2a, RLCRRCRLRRSLASRASRLHandler},
770 {0x2b, RLCRRCRLRRSLASRASRLHandler},
771 {0x2c, RLCRRCRLRRSLASRASRLHandler},
772 {0x2d, RLCRRCRLRRSLASRASRLHandler},
773 {0x2e, RLCRRCRLRRSLASRASRLHandler},
774 {0x2f, RLCRRCRLRRSLASRASRLHandler},
776 {0x30, RLCRRCRLRRSLASRASRLHandler},
777 {0x31, RLCRRCRLRRSLASRASRLHandler},
778 {0x32, RLCRRCRLRRSLASRASRLHandler},
779 {0x33, RLCRRCRLRRSLASRASRLHandler},
780 {0x34, RLCRRCRLRRSLASRASRLHandler},
781 {0x35, RLCRRCRLRRSLASRASRLHandler},
782 {0x36, RLCRRCRLRRSLASRASRLHandler},
783 {0x37, RLCRRCRLRRSLASRASRLHandler},
785 {0x38, RLCRRCRLRRSLASRASRLHandler},
786 {0x39, RLCRRCRLRRSLASRASRLHandler},
787 {0x3a, RLCRRCRLRRSLASRASRLHandler},
788 {0x3b, RLCRRCRLRRSLASRASRLHandler},
789 {0x3c, RLCRRCRLRRSLASRASRLHandler},
790 {0x3d, RLCRRCRLRRSLASRASRLHandler},
791 {0x3e, RLCRRCRLRRSLASRASRLHandler},
792 {0x3f, RLCRRCRLRRSLASRASRLHandler},
794 {0x40, BITHandler},
795 {0x41, BITHandler},
796 {0x42, BITHandler},
797 {0x43, BITHandler},
798 {0x44, BITHandler},
799 {0x45, BITHandler},
800 {0x46, BITHandler},
801 {0x47, BITHandler},
802 {0x48, BITHandler},
803 {0x49, BITHandler},
804 {0x4a, BITHandler},
805 {0x4b, BITHandler},
806 {0x4c, BITHandler},
807 {0x4d, BITHandler},
808 {0x4e, BITHandler},
809 {0x4f, BITHandler},
811 {0x50, BITHandler},
812 {0x51, BITHandler},
813 {0x52, BITHandler},
814 {0x53, BITHandler},
815 {0x54, BITHandler},
816 {0x55, BITHandler},
817 {0x56, BITHandler},
818 {0x57, BITHandler},
819 {0x58, BITHandler},
820 {0x59, BITHandler},
821 {0x5a, BITHandler},
822 {0x5b, BITHandler},
823 {0x5c, BITHandler},
824 {0x5d, BITHandler},
825 {0x5e, BITHandler},
826 {0x5f, BITHandler},
828 {0x60, BITHandler},
829 {0x61, BITHandler},
830 {0x62, BITHandler},
831 {0x63, BITHandler},
832 {0x64, BITHandler},
833 {0x65, BITHandler},
834 {0x66, BITHandler},
835 {0x67, BITHandler},
836 {0x68, BITHandler},
837 {0x69, BITHandler},
838 {0x6a, BITHandler},
839 {0x6b, BITHandler},
840 {0x6c, BITHandler},
841 {0x6d, BITHandler},
842 {0x6e, BITHandler},
843 {0x6f, BITHandler},
845 {0x70, BITHandler},
846 {0x71, BITHandler},
847 {0x72, BITHandler},
848 {0x73, BITHandler},
849 {0x74, BITHandler},
850 {0x75, BITHandler},
851 {0x76, BITHandler},
852 {0x77, BITHandler},
853 {0x78, BITHandler},
854 {0x79, BITHandler},
855 {0x7a, BITHandler},
856 {0x7b, BITHandler},
857 {0x7c, BITHandler},
858 {0x7d, BITHandler},
859 {0x7e, BITHandler},
860 {0x7f, BITHandler},
862 // RES
864 {0x80, RESSETHandler},
865 {0x81, RESSETHandler},
866 {0x82, RESSETHandler},
867 {0x83, RESSETHandler},
868 {0x84, RESSETHandler},
869 {0x85, RESSETHandler},
870 {0x86, RESSETHandler},
871 {0x87, RESSETHandler},
872 {0x88, RESSETHandler},
873 {0x89, RESSETHandler},
874 {0x8a, RESSETHandler},
875 {0x8b, RESSETHandler},
876 {0x8c, RESSETHandler},
877 {0x8d, RESSETHandler},
878 {0x8e, RESSETHandler},
879 {0x8f, RESSETHandler},
881 {0x90, RESSETHandler},
882 {0x91, RESSETHandler},
883 {0x92, RESSETHandler},
884 {0x93, RESSETHandler},
885 {0x94, RESSETHandler},
886 {0x95, RESSETHandler},
887 {0x96, RESSETHandler},
888 {0x97, RESSETHandler},
889 {0x98, RESSETHandler},
890 {0x99, RESSETHandler},
891 {0x9a, RESSETHandler},
892 {0x9b, RESSETHandler},
893 {0x9c, RESSETHandler},
894 {0x9d, RESSETHandler},
895 {0x9e, RESSETHandler},
896 {0x9f, RESSETHandler},
898 {0xa0, RESSETHandler},
899 {0xa1, RESSETHandler},
900 {0xa2, RESSETHandler},
901 {0xa3, RESSETHandler},
902 {0xa4, RESSETHandler},
903 {0xa5, RESSETHandler},
904 {0xa6, RESSETHandler},
905 {0xa7, RESSETHandler},
906 {0xa8, RESSETHandler},
907 {0xa9, RESSETHandler},
908 {0xaa, RESSETHandler},
909 {0xab, RESSETHandler},
910 {0xac, RESSETHandler},
911 {0xad, RESSETHandler},
912 {0xae, RESSETHandler},
913 {0xaf, RESSETHandler},
915 {0xb0, RESSETHandler},
916 {0xb1, RESSETHandler},
917 {0xb2, RESSETHandler},
918 {0xb3, RESSETHandler},
919 {0xb4, RESSETHandler},
920 {0xb5, RESSETHandler},
921 {0xb6, RESSETHandler},
922 {0xb7, RESSETHandler},
923 {0xb8, RESSETHandler},
924 {0xb9, RESSETHandler},
925 {0xba, RESSETHandler},
926 {0xbb, RESSETHandler},
927 {0xbc, RESSETHandler},
928 {0xbd, RESSETHandler},
929 {0xbe, RESSETHandler},
930 {0xbf, RESSETHandler},
932 // SET
934 {0xc0, RESSETHandler},
935 {0xc1, RESSETHandler},
936 {0xc2, RESSETHandler},
937 {0xc3, RESSETHandler},
938 {0xc4, RESSETHandler},
939 {0xc5, RESSETHandler},
940 {0xc6, RESSETHandler},
941 {0xc7, RESSETHandler},
942 {0xc8, RESSETHandler},
943 {0xc9, RESSETHandler},
944 {0xca, RESSETHandler},
945 {0xcb, RESSETHandler},
946 {0xcc, RESSETHandler},
947 {0xcd, RESSETHandler},
948 {0xce, RESSETHandler},
949 {0xcf, RESSETHandler},
951 {0xd0, RESSETHandler},
952 {0xd1, RESSETHandler},
953 {0xd2, RESSETHandler},
954 {0xd3, RESSETHandler},
955 {0xd4, RESSETHandler},
956 {0xd5, RESSETHandler},
957 {0xd6, RESSETHandler},
958 {0xd7, RESSETHandler},
959 {0xd8, RESSETHandler},
960 {0xd9, RESSETHandler},
961 {0xda, RESSETHandler},
962 {0xdb, RESSETHandler},
963 {0xdc, RESSETHandler},
964 {0xdd, RESSETHandler},
965 {0xde, RESSETHandler},
966 {0xdf, RESSETHandler},
968 {0xe0, RESSETHandler},
969 {0xe1, RESSETHandler},
970 {0xe2, RESSETHandler},
971 {0xe3, RESSETHandler},
972 {0xe4, RESSETHandler},
973 {0xe5, RESSETHandler},
974 {0xe6, RESSETHandler},
975 {0xe7, RESSETHandler},
976 {0xe8, RESSETHandler},
977 {0xe9, RESSETHandler},
978 {0xea, RESSETHandler},
979 {0xeb, RESSETHandler},
980 {0xec, RESSETHandler},
981 {0xed, RESSETHandler},
982 {0xee, RESSETHandler},
983 {0xef, RESSETHandler},
985 {0xf0, RESSETHandler},
986 {0xf1, RESSETHandler},
987 {0xf2, RESSETHandler},
988 {0xf3, RESSETHandler},
989 {0xf4, RESSETHandler},
990 {0xf5, RESSETHandler},
991 {0xf6, RESSETHandler},
992 {0xf7, RESSETHandler},
993 {0xf8, RESSETHandler},
994 {0xf9, RESSETHandler},
995 {0xfa, RESSETHandler},
996 {0xfb, RESSETHandler},
997 {0xfc, RESSETHandler},
998 {0xfd, RESSETHandler},
999 {0xfe, RESSETHandler},
1000 {0xff, RESSETHandler},
1002 // Terminator
1004 {0xffffffff, NULL}
1007 struct sOp EDOps[] =
1009 {0x67, RRDRLDHandler},
1010 {0x6f, RRDRLDHandler},
1011 {0x42, AdcSbcRegpair},
1012 {0x4a, AdcSbcRegpair},
1013 {0x52, AdcSbcRegpair},
1014 {0x5a, AdcSbcRegpair},
1015 {0x62, AdcSbcRegpair},
1016 {0x6a, AdcSbcRegpair},
1017 {0x72, AdcSbcRegpair},
1018 {0x7a, AdcSbcRegpair},
1019 {0x45, RetIRetNHandler},
1020 {0x4d, RetIRetNHandler},
1021 {0x44, NegHandler},
1022 {0xa0, LDILDRLDIRLDDRHandler},
1023 {0xa8, LDILDRLDIRLDDRHandler},
1024 {0xb0, LDILDRLDIRLDDRHandler},
1025 {0xb8, LDILDRLDIRLDDRHandler},
1026 {0x57, IRHandler},
1027 {0x5F, IRHandler},
1028 {0x47, IRHandler},
1029 {0x4F, IRHandler},
1030 {0x46, IMHandler},
1031 {0x56, IMHandler},
1032 {0x5e, IMHandler},
1033 {0x4b, LdRegpair},
1034 {0x5b, LdRegpair},
1035 {0x7b, LdRegpair},
1036 {0x43, ExtendedRegIntoMemory},
1037 {0x53, ExtendedRegIntoMemory},
1038 {0x63, ExtendedRegIntoMemory},
1039 {0x73, ExtendedRegIntoMemory},
1040 {0x40, ExtendedInHandler},
1041 {0x48, ExtendedInHandler},
1042 {0x50, ExtendedInHandler},
1043 {0x58, ExtendedInHandler},
1044 {0x60, ExtendedInHandler},
1045 {0x68, ExtendedInHandler},
1046 {0x78, ExtendedInHandler},
1047 {0x41, ExtendedOutHandler},
1048 {0x49, ExtendedOutHandler},
1049 {0x51, ExtendedOutHandler},
1050 {0x59, ExtendedOutHandler},
1051 {0x61, ExtendedOutHandler},
1052 {0x69, ExtendedOutHandler},
1053 {0x79, ExtendedOutHandler},
1054 {0xa1, CPICPDCPIRCPDRHandler},
1055 {0xa9, CPICPDCPIRCPDRHandler},
1056 {0xb1, CPICPDCPIRCPDRHandler},
1057 {0xb9, CPICPDCPIRCPDRHandler},
1059 {0xbb, OTIROTDROUTIOUTDHandler}, // OTDR
1060 {0xb3, OTIROTDROUTIOUTDHandler}, // OTIR
1061 {0xab, OTIROTDROUTIOUTDHandler}, // OUTD
1062 {0xa3, OTIROTDROUTIOUTDHandler}, // OUTI
1064 {0xb2, INIRINDRINIINDHandler}, // INIR
1065 {0xba, INIRINDRINIINDHandler}, // INDR
1066 {0xa2, INIRINDRINIINDHandler}, // INI
1067 {0xaa, INIRINDRINIINDHandler}, // IND
1069 // Terminator
1071 {0xffffffff, NULL}
1074 struct sOp DDFDOps[] =
1076 {0x35, IncDecIndexed},
1077 {0x34, IncDecIndexed},
1078 {0xcb, DDFDCBHandler},
1079 {0x86, MathOperationIndexed},
1080 {0x8e, MathOperationIndexed},
1081 {0x96, MathOperationIndexed},
1082 {0x9e, MathOperationIndexed},
1083 {0xa6, MathOperationIndexed},
1084 {0xae, MathOperationIndexed},
1085 {0xb6, MathOperationIndexed},
1086 {0xbe, MathOperationIndexed},
1088 {0xe1, PushPopOperationsIndexed},
1089 {0xe5, PushPopOperationsIndexed},
1090 {0x21, LoadImmediate},
1091 {0xe9, JPIXIYHandler},
1092 {0x09, AddIndexHandler},
1093 {0x19, AddIndexHandler},
1094 {0x29, AddIndexHandler},
1095 {0x39, AddIndexHandler},
1096 {0xf9, SPToIndex},
1097 {0x36, LdByteToIndex},
1098 {0x46, LdRegIndexOffset},
1099 {0x4e, LdRegIndexOffset},
1100 {0x56, LdRegIndexOffset},
1101 {0x5e, LdRegIndexOffset},
1102 {0x66, LdRegIndexOffset},
1103 {0x6e, LdRegIndexOffset},
1104 {0x7e, LdRegIndexOffset},
1106 {0x70, LdIndexPtrReg},
1107 {0x71, LdIndexPtrReg},
1108 {0x72, LdIndexPtrReg},
1109 {0x73, LdIndexPtrReg},
1110 {0x74, LdIndexPtrReg},
1111 {0x75, LdIndexPtrReg},
1112 {0x77, LdIndexPtrReg},
1114 {0x23, IncDecIndexReg},
1115 {0x2b, IncDecIndexReg},
1117 {0x22, StoreIndexReg},
1118 {0x2a, LoadIndexReg},
1119 {0xe3, ExIndexed},
1121 {0x44, UndocRegToIndex},
1122 {0x45, UndocRegToIndex},
1123 {0x4c, UndocRegToIndex},
1124 {0x4d, UndocRegToIndex},
1125 {0x54, UndocRegToIndex},
1126 {0x55, UndocRegToIndex},
1127 {0x5c, UndocRegToIndex},
1128 {0x5d, UndocRegToIndex},
1129 {0x7c, UndocRegToIndex},
1130 {0x7d, UndocRegToIndex},
1132 {0x60, UndocIndexToReg},
1133 {0x61, UndocIndexToReg},
1134 {0x62, UndocIndexToReg},
1135 {0x63, UndocIndexToReg},
1136 {0x64, UndocIndexToReg},
1137 {0x65, UndocIndexToReg},
1138 {0x67, UndocIndexToReg},
1139 {0x68, UndocIndexToReg},
1140 {0x69, UndocIndexToReg},
1141 {0x6a, UndocIndexToReg},
1142 {0x6b, UndocIndexToReg},
1143 {0x6c, UndocIndexToReg},
1144 {0x6d, UndocIndexToReg},
1145 {0x6f, UndocIndexToReg},
1147 {0x24, UndocIncDecIndexReg},
1148 {0x25, UndocIncDecIndexReg},
1149 {0x2c, UndocIncDecIndexReg},
1150 {0x2d, UndocIncDecIndexReg},
1152 {0x26, UndocLoadHalfIndexReg},
1153 {0x2e, UndocLoadHalfIndexReg},
1155 {0x84, UndocMathIndex},
1156 {0x85, UndocMathIndex},
1157 {0x8c, UndocMathIndex},
1158 {0x8d, UndocMathIndex},
1160 {0x94, UndocMathIndex},
1161 {0x95, UndocMathIndex},
1162 {0x9c, UndocMathIndex},
1163 {0x9d, UndocMathIndex},
1165 {0xa4, UndocMathIndex},
1166 {0xa5, UndocMathIndex},
1167 {0xac, UndocMathIndex},
1168 {0xad, UndocMathIndex},
1170 {0xb4, UndocMathIndex},
1171 {0xb5, UndocMathIndex},
1172 {0xbc, UndocMathIndex},
1173 {0xbd, UndocMathIndex},
1175 // Terminator
1177 {0xffffffff, NULL}
1180 struct sOp DDFDCBOps[] =
1182 {0x06, ddcbBitWise},
1183 {0x0e, ddcbBitWise},
1184 {0x16, ddcbBitWise},
1185 {0x1e, ddcbBitWise},
1186 {0x26, ddcbBitWise},
1187 {0x2e, ddcbBitWise},
1188 {0x3e, ddcbBitWise},
1189 {0x46, ddcbBitWise},
1190 {0x4e, ddcbBitWise},
1191 {0x56, ddcbBitWise},
1192 {0x5e, ddcbBitWise},
1193 {0x66, ddcbBitWise},
1194 {0x6e, ddcbBitWise},
1195 {0x76, ddcbBitWise},
1196 {0x7e, ddcbBitWise},
1197 {0x86, ddcbBitWise},
1198 {0x8e, ddcbBitWise},
1199 {0x96, ddcbBitWise},
1200 {0x9e, ddcbBitWise},
1201 {0xa6, ddcbBitWise},
1202 {0xae, ddcbBitWise},
1203 {0xb6, ddcbBitWise},
1204 {0xbe, ddcbBitWise},
1205 {0xc6, ddcbBitWise},
1206 {0xce, ddcbBitWise},
1207 {0xd6, ddcbBitWise},
1208 {0xde, ddcbBitWise},
1209 {0xe6, ddcbBitWise},
1210 {0xee, ddcbBitWise},
1211 {0xf6, ddcbBitWise},
1212 {0xfe, ddcbBitWise},
1214 // Terminator
1216 {0xffffffff, NULL}
1219 void InvalidInstructionC(UINT32 dwCount)
1221 fprintf(fp, " InvalidInstruction(%" PRIu32 ");\n", dwCount);
1224 UINT32 Timing(UINT8 bWho, UINT32 dwOpcode)
1226 UINT32 dwTiming = 0;
1228 assert(dwOpcode < 0x100);
1230 if (TIMING_REGULAR == bWho) // Regular?
1231 dwTiming = bTimingRegular[dwOpcode];
1232 else
1233 if (TIMING_CB == bWho)
1234 dwTiming = bTimingCB[dwOpcode];
1235 else
1236 if (TIMING_DDFD == bWho)
1237 dwTiming = bTimingDDFD[dwOpcode];
1238 else
1239 if (TIMING_ED == bWho)
1240 dwTiming = bTimingED[dwOpcode];
1241 else
1242 if (TIMING_XXCB == bWho)
1243 dwTiming = bTimingXXCB[dwOpcode];
1244 else
1245 if (TIMING_EXCEPT == bWho)
1246 dwTiming = dwOpcode;
1247 else
1248 abort();
1250 if (0 == dwTiming)
1252 fprintf(stderr, "Opcode: %.2x:%.2x - Not zero!\n", bWho, dwOpcode);
1253 fclose(fp);
1254 exit(1);
1257 return(dwTiming);
1260 void IndexedOffset(INT8 *Localmz80Index)
1262 fprintf(fp, " mov dl, [esi] ; Fetch our offset\n");
1263 fprintf(fp, " inc esi ; Move past the offset\n");
1264 fprintf(fp, " or dl, dl ; Is this bad boy signed?\n");
1265 fprintf(fp, " jns notSigned%" PRIu32 " ; Nope!\n", dwGlobalLabel);
1266 fprintf(fp, " dec dh ; Make it FFable\n");
1267 fprintf(fp, "notSigned%" PRIu32 ":\n", dwGlobalLabel);
1268 fprintf(fp, " add dx, [_z80%s] ; Our offset!\n", Localmz80Index);
1269 ++dwGlobalLabel;
1272 void CBHandler(UINT32 dwOpcode)
1274 if (MZ80_ASSEMBLY_X86 == bWhat)
1276 fprintf(fp, ";\n");
1277 fprintf(fp, "; Handler for all CBxx instructions\n");
1278 fprintf(fp, ";\n");
1279 sprintf(string, "RegInst%.2x", dwOpcode);
1280 ProcBegin(0xffffffff);
1281 fprintf(fp, " mov dl, [esi]\n");
1282 fprintf(fp, " inc esi\n");
1283 fprintf(fp, " jmp dword [z80PrefixCB+edx*4]\n\n");
1284 fprintf(fp, "\n\n");
1286 else
1287 if (MZ80_C == bWhat)
1289 fprintf(fp, " CBHandler();\n");
1291 else
1293 abort();
1297 void EDHandler(UINT32 dwOpcode)
1299 if (MZ80_ASSEMBLY_X86 == bWhat)
1301 fprintf(fp, ";\n");
1302 fprintf(fp, "; Handler for all EDxx instructions\n");
1303 fprintf(fp, ";\n");
1304 sprintf(string, "RegInst%.2x", dwOpcode);
1305 ProcBegin(0xffffffff);
1306 fprintf(fp, " mov dl, [esi]\n");
1307 fprintf(fp, " inc esi\n");
1308 fprintf(fp, " jmp dword [z80PrefixED+edx*4]\n\n");
1309 fprintf(fp, "\n\n");
1311 else
1312 if (MZ80_C == bWhat)
1314 fprintf(fp, " EDHandler();\n");
1316 else
1318 abort();
1322 void DDHandler(UINT32 dwOpcode)
1324 if (MZ80_ASSEMBLY_X86 == bWhat)
1326 fprintf(fp, ";\n");
1327 fprintf(fp, "; Handler for all DDxx instructions\n");
1328 fprintf(fp, ";\n");
1329 sprintf(string, "RegInst%.2x", dwOpcode);
1330 ProcBegin(0xffffffff);
1331 fprintf(fp, " mov dl, [esi]\n");
1332 fprintf(fp, " inc esi\n");
1333 fprintf(fp, " jmp dword [z80PrefixDD+edx*4]\n\n");
1334 fprintf(fp, "\n\n");
1336 else
1337 if (MZ80_C == bWhat)
1339 fprintf(fp, " DDHandler();\n");
1341 else
1343 abort();
1347 void FDHandler(UINT32 dwOpcode)
1349 if (MZ80_ASSEMBLY_X86 == bWhat)
1351 fprintf(fp, ";\n");
1352 fprintf(fp, "; Handler for all FDxx instructions\n");
1353 fprintf(fp, ";\n");
1354 sprintf(string, "RegInst%.2x", dwOpcode);
1355 ProcBegin(0xffffffff);
1356 fprintf(fp, " mov dl, [esi]\n");
1357 fprintf(fp, " inc esi\n");
1358 fprintf(fp, " jmp dword [z80PrefixFD+edx*4]\n\n");
1359 fprintf(fp, "\n\n");
1361 else
1362 if (MZ80_C == bWhat)
1364 fprintf(fp, " FDHandler();\n");
1366 else
1368 abort();
1372 void StandardHeader(void)
1374 if (MZ80_ASSEMBLY_X86 == bWhat)
1376 fprintf(fp,"; For assembly by NASM only\n");
1377 fprintf(fp,"bits 32\n\n");
1379 fprintf(fp,"; Theory of operation\n\n");
1380 fprintf(fp,"; EDI=General purpose\n");
1381 fprintf(fp,"; ESI=Program counter + base address\n");
1382 fprintf(fp,"; EBP=z80Base\n");
1383 fprintf(fp,"; AX=AF\n");
1384 fprintf(fp,"; BX=HL\n");
1385 fprintf(fp,"; CX=BC\n");
1386 fprintf(fp,"; DX=General purpose\n\n");
1388 if (bUseStack)
1389 fprintf(fp, "; Using stack calling conventions\n");
1390 else
1391 fprintf(fp, "; Using register calling conventions\n");
1393 if (b16BitIo)
1394 fprintf(fp, "; Extended input/output instructions treat (BC) as I/O address\n");
1395 else
1396 fprintf(fp, "; Extended input/output instructions treat (C) as I/O address\n\n");
1398 fprintf(fp, "IFF1 equ 01h\n");
1399 fprintf(fp, "IFF2 equ 02h\n");
1401 fprintf(fp, "CPUREG_PC equ 00h\n");
1402 fprintf(fp, "CPUREG_SP equ 01h\n");
1403 fprintf(fp, "CPUREG_AF equ 02h\n");
1404 fprintf(fp, "CPUREG_BC equ 03h\n");
1405 fprintf(fp, "CPUREG_DE equ 04h\n");
1406 fprintf(fp, "CPUREG_HL equ 05h\n");
1407 fprintf(fp, "CPUREG_AFPRIME equ 06h\n");
1408 fprintf(fp, "CPUREG_BCPRIME equ 07h\n");
1409 fprintf(fp, "CPUREG_DEPRIME equ 08h\n");
1410 fprintf(fp, "CPUREG_HLPRIME equ 09h\n");
1411 fprintf(fp, "CPUREG_IX equ 0ah\n");
1412 fprintf(fp, "CPUREG_IY equ 0bh\n");
1413 fprintf(fp, "CPUREG_I equ 0ch\n");
1414 fprintf(fp, "CPUREG_A equ 0dh\n");
1415 fprintf(fp, "CPUREG_F equ 0eh\n");
1416 fprintf(fp, "CPUREG_B equ 0fh\n");
1417 fprintf(fp, "CPUREG_C equ 10h\n");
1418 fprintf(fp, "CPUREG_D equ 11h\n");
1419 fprintf(fp, "CPUREG_E equ 12h\n");
1420 fprintf(fp, "CPUREG_H equ 13h\n");
1421 fprintf(fp, "CPUREG_L equ 14h\n");
1422 fprintf(fp, "CPUREG_IFF1 equ 15h\n");
1423 fprintf(fp, "CPUREG_IFF2 equ 16h\n");
1424 fprintf(fp, "CPUREG_CARRY equ 17h\n");
1425 fprintf(fp, "CPUREG_NEGATIVE equ 18h\n");
1426 fprintf(fp, "CPUREG_PARITY equ 19h\n");
1427 fprintf(fp, "CPUREG_OVERFLOW equ 1ah\n");
1428 fprintf(fp, "CPUREG_HALFCARRY equ 1bh\n");
1429 fprintf(fp, "CPUREG_ZERO equ 1ch\n");
1430 fprintf(fp, "CPUREG_SIGN equ 1dh\n");
1431 fprintf(fp, "CPUREG_MAXINDEX equ 1eh\n\n");
1433 else
1434 if (MZ80_C == bWhat)
1436 fprintf(fp, "/* Multi-Z80 32 Bit emulator */\n");
1437 fprintf(fp, "\n");
1438 fprintf(fp, "/* Copyright 1996-2000 Neil Bradley, All rights reserved\n");
1439 fprintf(fp, " *\n");
1440 fprintf(fp, " * License agreement:\n");
1441 fprintf(fp, " *\n");
1442 fprintf(fp, " * (MZ80 Refers to both the assembly code emitted by makeZ80.c and makeZ80.c\n");
1443 fprintf(fp, " * itself)\n");
1444 fprintf(fp, " *\n");
1445 fprintf(fp, " * MZ80 May be distributed in unmodified form to any medium.\n");
1446 fprintf(fp, " *\n");
1447 fprintf(fp, " * MZ80 May not be sold, or sold as a part of a commercial package without\n");
1448 fprintf(fp, " * the express written permission of Neil Bradley (neil@synthcom.com). This\n");
1449 fprintf(fp, " * includes shareware.\n");
1450 fprintf(fp, " *\n");
1451 fprintf(fp, " * Modified versions of MZ80 may not be publicly redistributed without author\n");
1452 fprintf(fp, " * approval (neil@synthcom.com). This includes distributing via a publicly\n");
1453 fprintf(fp, " * accessible LAN. You may make your own source modifications and distribute\n");
1454 fprintf(fp, " * MZ80 in source or object form, but if you make modifications to MZ80\n");
1455 fprintf(fp, " * then it should be noted in the top as a comment in makeZ80.c.\n");
1456 fprintf(fp, " *\n");
1457 fprintf(fp, " * MZ80 Licensing for commercial applications is available. Please email\n");
1458 fprintf(fp, " * neil@synthcom.com for details.\n");
1459 fprintf(fp, " *\n");
1460 fprintf(fp, " * Synthcom Systems, Inc, and Neil Bradley will not be held responsible for\n");
1461 fprintf(fp, " * any damage done by the use of MZ80. It is purely \"as-is\".\n");
1462 fprintf(fp, " *\n");
1463 fprintf(fp, " * If you use MZ80 in a freeware application, credit in the following text:\n");
1464 fprintf(fp, " *\n");
1465 fprintf(fp, " * \"Multi-Z80 CPU emulator by Neil Bradley (neil@synthcom.com)\"\n");
1466 fprintf(fp, " *\n");
1467 fprintf(fp, " * must accompany the freeware application within the application itself or\n");
1468 fprintf(fp, " * in the documentation.\n");
1469 fprintf(fp, " *\n");
1470 fprintf(fp, " * Legal stuff aside:\n");
1471 fprintf(fp, " *\n");
1472 fprintf(fp, " * If you find problems with MZ80, please email the author so they can get\n");
1473 fprintf(fp, " * resolved. If you find a bug and fix it, please also email the author so\n");
1474 fprintf(fp, " * that those bug fixes can be propogated to the installed base of MZ80\n");
1475 fprintf(fp, " * users. If you find performance improvements or problems with MZ80, please\n");
1476 fprintf(fp, " * email the author with your changes/suggestions and they will be rolled in\n");
1477 fprintf(fp, " * with subsequent releases of MZ80.\n");
1478 fprintf(fp, " *\n");
1479 fprintf(fp, " * The whole idea of this emulator is to have the fastest available 32 bit\n");
1480 fprintf(fp, " * Multi-Z80 emulator for the PC, giving maximum performance. \n");
1481 fprintf(fp, " */\n\n");
1482 fprintf(fp, "#include <stdio.h>\n");
1483 fprintf(fp, "#include <stdlib.h>\n");
1484 fprintf(fp, "#include <string.h>\n");
1485 fprintf(fp,
1486 "#ifdef HAVE_MEMCPY_H\n"
1487 "#include \"memcpy.h\"\n"
1488 "#endif\n");
1489 fprintf(fp, "#include \"mz80.h\"\n");
1491 // HACK HACK
1493 fprintf(fp, "UINT32 z80intAddr;\n");
1494 fprintf(fp, "UINT32 z80pc;\n");
1496 else
1498 // Whoops. Unknown emission type.
1500 abort();
1503 fprintf(fp, "\n\n");
1506 void Alignment(void)
1508 fprintf(fp, "\ntimes ($$-$) & 3 nop ; pad with NOPs to 4-byte boundary\n\n");
1511 void ProcBegin(UINT32 dwOpcode)
1513 (void)dwOpcode;
1514 Alignment();
1515 fprintf(fp, "%s:\n", procname);
1518 void SetSubFlagsSZHVC(INT8 *pszLeft, INT8 *pszRight)
1520 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n");
1521 fprintf(fp, " Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n");
1522 fprintf(fp, " pbSubSbcTable[((UINT32) %s << 8) | %s];\n", pszLeft, pszRight);
1525 void SetSbcFlagsSZHVC(INT8 *pszLeft, INT8 *pszRight)
1527 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n");
1528 fprintf(fp, " Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n");
1529 fprintf(fp, " pbSubSbcTable[((UINT32) %s << 8) | %s | (((UINT32) cpu.z80F & Z80_FLAG_CARRY) << 16)];\n", pszLeft, pszRight);
1532 void SetAddFlagsSZHVC(INT8 *pszLeft, INT8 *pszRight)
1534 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n");
1535 fprintf(fp, " Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n");
1536 fprintf(fp, " pbAddAdcTable[((UINT32) %s << 8) | %s];\n", pszLeft, pszRight);
1539 void SetAdcFlagsSZHVC(INT8 *pszLeft, INT8 *pszRight)
1541 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n");
1542 fprintf(fp, " Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n");
1543 fprintf(fp, " pbAddAdcTable[((UINT32) %s << 8) | %s | (((UINT32) cpu.z80F & Z80_FLAG_CARRY) << 16)];\n", pszLeft, pszRight);
1546 UINT32 dwOverflowCount = 0;
1548 void SetOverflow(void)
1550 fprintf(fp, " seto dl\n");
1551 fprintf(fp, " and ah, 0fbh ; Knock out parity/overflow\n");
1552 fprintf(fp, " shl dl, 2\n");
1553 fprintf(fp, " or ah, dl\n");
1556 void FetchNextInstruction(UINT32 dwOpcode)
1558 if (0xffffffff != dwOpcode)
1560 fprintf(fp, " sub edi, byte %" PRIu32 "\n", Timing(bCurrentMode, dwOpcode));
1562 if (bCurrentMode == TIMING_REGULAR)
1563 fprintf(fp, " js near noMoreExec\n");
1564 else
1565 fprintf(fp, " js near noMoreExec\n");
1568 fprintf(fp, " mov dl, byte [esi] ; Get our next instruction\n");
1569 fprintf(fp, " inc esi ; Increment PC\n");
1570 fprintf(fp, " jmp dword [z80regular+edx*4]\n\n");
1573 void WriteValueToMemory(INT8 *pszAddress, INT8 *pszValue)
1575 if (MZ80_ASSEMBLY_X86 == bWhat)
1577 fprintf(fp, " mov [cyclesRemaining], edi\n");
1578 fprintf(fp, " mov [_z80af], ax ; Store AF\n");
1580 // First off, load our byte to write into al after we've saved AF
1582 if (strcmp(pszValue, "al") != 0)
1583 fprintf(fp, " mov al, %s ; And our data to write\n", pszValue);
1584 if (strcmp(pszValue, "[esi]") == 0) // Immediate value?
1585 fprintf(fp, " inc esi ; Increment our program counter\n");
1587 // Now get the address in DX - regardless of what it is
1589 if (strcmp(pszAddress, "[_z80de]") == 0 ||
1590 strcmp(pszAddress, "[_orgval]") == 0 ||
1591 strcmp(pszAddress, "[_z80ix]") == 0 ||
1592 strcmp(pszAddress, "[_z80iy]") == 0)
1593 fprintf(fp, " mov dx, %s\n", pszAddress);
1595 fprintf(fp, " mov edi, [_z80MemWrite] ; Point to the write array\n\n");
1596 fprintf(fp, "checkLoop%" PRIu32 ":\n", dwGlobalLabel);
1597 fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n");
1598 fprintf(fp, " je memoryWrite%" PRIu32 " ; Yes - go write it!\n", dwGlobalLabel);
1600 if (strcmp(pszAddress, "[_z80de]") == 0 ||
1601 strcmp(pszAddress, "[_orgval]") == 0 ||
1602 strcmp(pszAddress, "[_z80ix]") == 0 ||
1603 strcmp(pszAddress, "[_z80iy]") == 0)
1604 fprintf(fp, " cmp dx, [edi] ; Are we smaller?\n");
1605 else
1606 fprintf(fp, " cmp %s, [edi] ; Are we smaller?\n", pszAddress);
1608 fprintf(fp, " jb nextAddr%" PRIu32 " ; Yes... go to the next addr\n", dwGlobalLabel);
1610 if (strcmp(pszAddress, "[_z80de]") == 0 ||
1611 strcmp(pszAddress, "[_orgval]") == 0 ||
1612 strcmp(pszAddress, "[_z80ix]") == 0 ||
1613 strcmp(pszAddress, "[_z80iy]") == 0)
1614 fprintf(fp, " cmp dx, [edi+4] ; Are we smaller?\n");
1615 else
1616 fprintf(fp, " cmp %s, [edi+4] ; Are we smaller?\n", pszAddress);
1618 fprintf(fp, " jbe callRoutine%" PRIu32 " ; If not, go call it!\n\n", dwGlobalLabel);
1619 fprintf(fp, "nextAddr%" PRIu32 ":\n", dwGlobalLabel);
1620 fprintf(fp, " add edi, 10h ; Next structure, please\n");
1621 fprintf(fp, " jmp short checkLoop%" PRIu32 "\n\n", dwGlobalLabel);
1622 fprintf(fp, "callRoutine%" PRIu32 ":\n", dwGlobalLabel);
1624 // Save off our registers!
1626 if ((strcmp(pszAddress, "dx") != 0) && (strcmp(pszAddress, "[_z80de]") != 0) &&
1627 (strcmp(pszAddress, "[_z80ix]") != 0) &&
1628 (strcmp(pszAddress, "[_orgval]") != 0) &&
1629 (strcmp(pszAddress, "[_z80iy]") != 0))
1630 fprintf(fp, " mov dx, %s ; Get our address to target\n", pszAddress);
1632 fprintf(fp, " call WriteMemoryByte ; Go write the data!\n");
1633 fprintf(fp, " jmp short WriteMacroExit%" PRIu32 "\n", dwGlobalLabel);
1635 fprintf(fp, "memoryWrite%" PRIu32 ":\n", dwGlobalLabel);
1637 if (strcmp(pszValue, "[esi]") == 0)
1638 fprintf(fp, " mov [ebp + e%s], al ; Store our direct value\n", pszAddress);
1639 else
1641 if (pszValue[0] == 'b' && pszValue[1] == 'y' && pszValue[2] == 't')
1643 fprintf(fp, " mov edi, edx\n");
1644 assert(strcmp(pszValue, "dl") != 0);
1646 fprintf(fp, " mov dl, %s\n", pszValue);
1648 if (strcmp(pszAddress, "dx") == 0)
1649 fprintf(fp, " mov [ebp + edi], dl\n");
1650 else
1651 fprintf(fp, " mov [ebp + e%s], dl\n", pszAddress);
1653 fprintf(fp, " mov edx, edi\n");
1655 else
1657 if (strcmp(pszAddress, "[_z80de]") != 0 &&
1658 strcmp(pszAddress, "[_orgval]") != 0 &&
1659 strcmp(pszAddress, "[_z80ix]") != 0 &&
1660 strcmp(pszAddress, "[_z80iy]") != 0)
1661 fprintf(fp, " mov [ebp + e%s], %s\n", pszAddress, pszValue);
1662 else
1663 fprintf(fp, " mov [ebp + edx], al\n");
1667 fprintf(fp, " mov ax, [_z80af] ; Get our accumulator and flags\n");
1669 fprintf(fp, "WriteMacroExit%" PRIu32 ":\n", dwGlobalLabel);
1670 fprintf(fp, " mov edi, [cyclesRemaining]\n");
1672 ++dwGlobalLabel;
1674 else
1675 if (MZ80_C == bWhat)
1677 fprintf(fp, " psMemWrite = cpu.z80MemWrite; /* Beginning of our handler */\n");
1678 fprintf(fp, " while (psMemWrite->lowAddr != 0xffffffff)\n");
1679 fprintf(fp, " {\n");
1680 fprintf(fp, " if ((%s >= psMemWrite->lowAddr) && (%s <= psMemWrite->highAddr))\n", pszAddress, pszAddress);
1681 fprintf(fp, " {\n");
1682 fprintf(fp, " cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
1683 fprintf(fp, " if (psMemWrite->memoryCall)\n");
1684 fprintf(fp, " {\n");
1685 fprintf(fp, " psMemWrite->memoryCall(%s, %s, psMemWrite);\n", pszAddress, pszValue);
1686 fprintf(fp, " }\n");
1687 fprintf(fp, " else\n");
1688 fprintf(fp, " {\n");
1689 fprintf(fp, " *((UINT8 *) psMemWrite->pUserArea + (%s - psMemWrite->lowAddr)) = %s;\n", pszAddress, pszValue);
1690 fprintf(fp, " }\n");
1691 fprintf(fp, " psMemWrite = NULL;\n");
1692 fprintf(fp, " break;\n");
1693 fprintf(fp, " }\n");
1694 fprintf(fp, " ++psMemWrite;\n");
1695 fprintf(fp, " }\n\n");
1696 fprintf(fp, " if (psMemWrite)\n");
1697 fprintf(fp, " {\n");
1698 fprintf(fp, " cpu.z80Base[%s] = (UINT8) %s;\n", pszAddress, pszValue);
1699 fprintf(fp, " }\n\n");
1703 void WriteWordToMemory(INT8 *pszAddress, INT8 *pszTarget)
1705 if (MZ80_ASSEMBLY_X86 == bWhat)
1707 fprintf(fp, " mov [cyclesRemaining], edi\n");
1708 fprintf(fp, " mov edi, [_z80MemWrite] ; Point to the write array\n\n");
1709 fprintf(fp, "checkLoop%" PRIu32 ":\n", dwGlobalLabel);
1710 fprintf(fp, " cmp [edi], word 0ffffh ; End of the list?\n");
1711 fprintf(fp, " je memoryWrite%" PRIu32 "\n", dwGlobalLabel);
1712 fprintf(fp, " cmp %s, [edi] ; Are we smaller?\n", pszAddress);
1713 fprintf(fp, " jb nextAddr%" PRIu32 " ; Yes, go to the next address\n", dwGlobalLabel);
1714 fprintf(fp, " cmp %s, [edi+4] ; Are we bigger?\n", pszAddress);
1715 fprintf(fp, " jbe callRoutine%" PRIu32 "\n\n", dwGlobalLabel);
1716 fprintf(fp, "nextAddr%" PRIu32 ":\n", dwGlobalLabel);
1717 fprintf(fp, " add edi, 10h ; Next structure!\n");
1718 fprintf(fp, " jmp short checkLoop%" PRIu32 "\n\n", dwGlobalLabel);
1719 fprintf(fp, "callRoutine%" PRIu32 ":\n", dwGlobalLabel);
1721 fprintf(fp, " push ax ; Save this for later\n");
1723 // Write the LSB
1725 fprintf(fp, " push dx\n");
1727 if (strcmp(pszTarget, "ax") != 0)
1729 fprintf(fp, " mov ax, %s\n", pszTarget);
1731 else
1733 fprintf(fp, " xchg ah, al\n");
1736 fprintf(fp, " call WriteMemoryByte\n");
1737 fprintf(fp, " pop dx\n");
1738 fprintf(fp, " pop ax\n");
1739 fprintf(fp, " inc dx\n\n");
1741 fprintf(fp, " push ax\n");
1742 fprintf(fp, " push dx\n");
1744 if (strcmp(pszTarget, "ax") != 0)
1746 fprintf(fp, " mov ax, %s\n", pszTarget);
1747 fprintf(fp, " xchg ah, al\n");
1750 fprintf(fp, " call WriteMemoryByte\n");
1751 fprintf(fp, " pop dx\n");
1752 fprintf(fp, " pop ax ; Restore us!\n");
1754 fprintf(fp, " jmp writeExit%" PRIu32 "\n\n", dwGlobalLabel);
1756 fprintf(fp, "memoryWrite%" PRIu32 ":\n", dwGlobalLabel);
1758 if (strlen(pszTarget) != 2)
1760 fprintf(fp, " mov di, %s\n", pszTarget);
1761 fprintf(fp, " mov [ebp + e%s], di ; Store our word\n", pszAddress);
1763 else
1765 if (strcmp(pszTarget, "ax") != 0)
1767 fprintf(fp, " mov [ebp + e%s], %s ; Store our word\n", pszAddress, pszTarget);
1769 else
1771 fprintf(fp, " xchg ah, al ; Swap for later\n");
1772 fprintf(fp, " mov [ebp + e%s], %s ; Store our word\n", pszAddress, pszTarget);
1773 fprintf(fp, " xchg ah, al ; Restore\n");
1777 fprintf(fp, "writeExit%" PRIu32 ":\n", dwGlobalLabel);
1778 fprintf(fp, " mov edi, [cyclesRemaining]\n");
1780 dwGlobalLabel++;
1782 else
1783 if (MZ80_C == bWhat)
1785 fprintf(fp, " psMemWrite = cpu.z80MemWrite; /* Beginning of our handler */\n");
1786 fprintf(fp, " while (psMemWrite->lowAddr != 0xffffffff)\n");
1787 fprintf(fp, " {\n");
1788 fprintf(fp, " if ((%s >= psMemWrite->lowAddr) && (%s <= psMemWrite->highAddr))\n", pszAddress, pszAddress);
1789 fprintf(fp, " {\n");
1790 fprintf(fp, " cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
1792 fprintf(fp, " if (psMemWrite->memoryCall)\n");
1793 fprintf(fp, " {\n");
1794 fprintf(fp, " psMemWrite->memoryCall(%s, (%s & 0xff), psMemWrite);\n", pszAddress, pszTarget);
1795 fprintf(fp, " psMemWrite->memoryCall(%s + 1, (%s >> 8), psMemWrite);\n", pszAddress, pszTarget);
1796 fprintf(fp, " }\n");
1797 fprintf(fp, " else\n");
1798 fprintf(fp, " {\n");
1799 fprintf(fp, " *((UINT8 *) psMemWrite->pUserArea + (%s - psMemWrite->lowAddr)) = %s;\n", pszAddress, pszTarget);
1800 fprintf(fp, " *((UINT8 *) psMemWrite->pUserArea + (%s - psMemWrite->lowAddr) + 1) = %s >> 8;\n", pszAddress, pszTarget);
1801 fprintf(fp, " }\n");
1803 fprintf(fp, " psMemWrite = NULL;\n");
1804 fprintf(fp, " break;\n");
1805 fprintf(fp, " }\n");
1806 fprintf(fp, " ++psMemWrite;\n");
1807 fprintf(fp, " }\n\n");
1808 fprintf(fp, " if (psMemWrite)\n");
1809 fprintf(fp, " {\n");
1810 fprintf(fp, " cpu.z80Base[%s] = (UINT8) %s;\n", pszAddress, pszTarget);
1811 fprintf(fp, " cpu.z80Base[%s + 1] = (UINT8) ((UINT32) %s >> 8);\n", pszAddress, pszTarget);
1812 fprintf(fp, " }\n\n");
1814 else
1816 abort();
1820 void WriteValueToIo(INT8 *pszIoAddress, INT8 *pszValue)
1822 if (MZ80_ASSEMBLY_X86 == bWhat)
1824 fprintf(fp, " mov [cyclesRemaining], edi\n");
1825 fprintf(fp, " mov [_z80af], ax ; Store AF\n");
1827 if (strcmp(pszValue, "al") != 0)
1828 fprintf(fp, " mov al, %s ; And our data to write\n", pszValue);
1829 if (strcmp(pszValue, "[esi]") == 0) // Immediate value?
1830 fprintf(fp, " inc esi ; Increment our program counter\n");
1832 fprintf(fp, " mov edi, [_z80IoWrite] ; Point to the I/O write array\n\n");
1833 fprintf(fp, "checkLoop%" PRIu32 ":\n", dwGlobalLabel);
1834 fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n");
1835 fprintf(fp, " je WriteMacroExit%" PRIu32 " ; Yes - ignore it!\n", dwGlobalLabel);
1836 fprintf(fp, " cmp %s, [edi] ; Are we smaller?\n", pszIoAddress);
1837 fprintf(fp, " jb nextAddr%" PRIu32 " ; Yes... go to the next addr\n", dwGlobalLabel);
1838 fprintf(fp, " cmp %s, [edi+2] ; Are we bigger?\n", pszIoAddress);
1839 fprintf(fp, " jbe callRoutine%" PRIu32 " ; If not, go call it!\n\n", dwGlobalLabel);
1840 fprintf(fp, "nextAddr%" PRIu32 ":\n", dwGlobalLabel);
1841 fprintf(fp, " add edi, 0ch ; Next structure, please\n");
1842 fprintf(fp, " jmp short checkLoop%" PRIu32 "\n\n", dwGlobalLabel);
1843 fprintf(fp, "callRoutine%" PRIu32 ":\n", dwGlobalLabel);
1845 // Save off our registers!
1847 if (strcmp(pszIoAddress, "dx") != 0)
1848 fprintf(fp, " mov dx, %s ; Get our address to target\n", pszIoAddress);
1850 fprintf(fp, " call WriteIOByte ; Go write the data!\n");
1852 fprintf(fp, "WriteMacroExit%" PRIu32 ":\n", dwGlobalLabel);
1853 fprintf(fp, " mov edi, [cyclesRemaining]\n");
1855 else
1856 if (MZ80_C == bWhat)
1858 fprintf(fp, " psIoWrite = cpu.z80IoWrite; /* Beginning of our handler */\n");
1859 fprintf(fp, " while (psIoWrite->lowIoAddr != 0xffff)\n");
1860 fprintf(fp, " {\n");
1861 fprintf(fp, " if ((%s >= psIoWrite->lowIoAddr) && (%s <= psIoWrite->highIoAddr))\n", pszIoAddress, pszIoAddress);
1862 fprintf(fp, " {\n");
1863 fprintf(fp, " cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
1864 fprintf(fp, " psIoWrite->IOCall(%s, %s, psIoWrite);\n", pszIoAddress, pszValue);
1865 fprintf(fp, " psIoWrite = NULL;\n");
1866 fprintf(fp, " break;\n");
1867 fprintf(fp, " }\n");
1868 fprintf(fp, " ++psIoWrite;\n");
1869 fprintf(fp, " }\n\n");
1871 else
1873 abort();
1876 ++dwGlobalLabel;
1879 void ReadValueFromMemory(INT8 *pszAddress, INT8 *pszTarget)
1881 if (MZ80_ASSEMBLY_X86 == bWhat)
1883 fprintf(fp, " mov [cyclesRemaining], edi\n");
1884 fprintf(fp, " mov edi, [_z80MemRead] ; Point to the read array\n\n");
1885 fprintf(fp, "checkLoop%" PRIu32 ":\n", dwGlobalLabel);
1886 fprintf(fp, " cmp [edi], word 0ffffh ; End of the list?\n");
1887 fprintf(fp, " je memoryRead%" PRIu32 "\n", dwGlobalLabel);
1888 fprintf(fp, " cmp e%s, [edi] ; Are we smaller?\n", pszAddress);
1889 fprintf(fp, " jb nextAddr%" PRIu32 " ; Yes, go to the next address\n", dwGlobalLabel);
1890 fprintf(fp, " cmp e%s, [edi+4] ; Are we bigger?\n", pszAddress);
1891 fprintf(fp, " jbe callRoutine%" PRIu32 "\n\n", dwGlobalLabel);
1892 fprintf(fp, "nextAddr%" PRIu32 ":\n", dwGlobalLabel);
1893 fprintf(fp, " add edi, 10h ; Next structure!\n");
1894 fprintf(fp, " jmp short checkLoop%" PRIu32 "\n\n", dwGlobalLabel);
1895 fprintf(fp, "callRoutine%" PRIu32 ":\n", dwGlobalLabel);
1897 if (strcmp(pszAddress, "dx") != 0)
1898 fprintf(fp, " mov dx, %s ; Get our address\n", pszAddress);
1900 fprintf(fp, " call ReadMemoryByte ; Standard read routine\n");
1902 // Yes, these are intentionally reversed!
1904 if (strcmp(pszTarget, "al") == 0)
1905 fprintf(fp, " mov [_z80af], al ; Save our new accumulator\n");
1906 else
1907 if (strcmp(pszTarget, "ah") == 0)
1908 fprintf(fp, " mov [_z80af + 1], al ; Save our new flags\n");
1909 else
1910 fprintf(fp, " mov %s, al ; Put our returned value here\n", pszTarget);
1912 // And are properly restored HERE:
1914 fprintf(fp, " mov ax, [_z80af] ; Get our AF back\n");
1916 // Restore registers here...
1918 fprintf(fp, " jmp short readExit%" PRIu32 "\n\n", dwGlobalLabel);
1919 fprintf(fp, "memoryRead%" PRIu32 ":\n", dwGlobalLabel);
1921 if (pszTarget[0] == 'b' && pszTarget[1] == 'y' && pszTarget[2] == 't')
1923 fprintf(fp, " mov di, dx\n");
1924 fprintf(fp, " mov dl, [ebp + e%s]\n", pszAddress);
1925 fprintf(fp, " mov %s, dl\n", pszTarget);
1926 fprintf(fp, " mov dx, di\n");
1928 else
1929 fprintf(fp, " mov %s, [ebp + e%s] ; Get our data\n\n", pszTarget, pszAddress);
1931 fprintf(fp, "readExit%" PRIu32 ":\n", dwGlobalLabel);
1932 fprintf(fp, " mov edi, [cyclesRemaining]\n");
1934 dwGlobalLabel++;
1936 else
1937 if (MZ80_C == bWhat)
1939 fprintf(fp, " psMemRead = cpu.z80MemRead; /* Beginning of our handler */\n");
1940 fprintf(fp, " while (psMemRead->lowAddr != 0xffffffff)\n");
1941 fprintf(fp, " {\n");
1942 fprintf(fp, " if ((%s >= psMemRead->lowAddr) && (%s <= psMemRead->highAddr))\n", pszAddress, pszAddress);
1943 fprintf(fp, " {\n");
1944 fprintf(fp, " cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
1945 fprintf(fp, " if (psMemRead->memoryCall)\n");
1946 fprintf(fp, " {\n");
1947 fprintf(fp, " %s = psMemRead->memoryCall(%s, psMemRead);\n", pszTarget, pszAddress);
1948 fprintf(fp, " }\n");
1949 fprintf(fp, " else\n");
1950 fprintf(fp, " {\n");
1951 fprintf(fp, " %s = *((UINT8 *) psMemRead->pUserArea + (%s - psMemRead->lowAddr));\n", pszTarget, pszAddress);
1952 fprintf(fp, " }\n");
1953 fprintf(fp, " psMemRead = NULL;\n");
1954 fprintf(fp, " break;\n");
1955 fprintf(fp, " }\n");
1956 fprintf(fp, " ++psMemRead;\n");
1957 fprintf(fp, " }\n\n");
1958 fprintf(fp, " if (psMemRead)\n");
1959 fprintf(fp, " {\n");
1960 fprintf(fp, " %s = cpu.z80Base[%s];\n", pszTarget, pszAddress);
1961 fprintf(fp, " }\n\n");
1963 else
1965 abort();
1970 void ReadWordFromMemory(INT8 *pszAddress, INT8 *pszTarget)
1972 if (MZ80_ASSEMBLY_X86 == bWhat)
1974 fprintf(fp, " mov [cyclesRemaining], edi\n");
1975 fprintf(fp, " mov edi, [_z80MemRead] ; Point to the read array\n\n");
1976 fprintf(fp, "checkLoop%" PRIu32 ":\n", dwGlobalLabel);
1977 fprintf(fp, " cmp [edi], word 0ffffh ; End of the list?\n");
1978 fprintf(fp, " je memoryRead%" PRIu32 "\n", dwGlobalLabel);
1979 fprintf(fp, " cmp %s, [edi] ; Are we smaller?\n", pszAddress);
1980 fprintf(fp, " jb nextAddr%" PRIu32 " ; Yes, go to the next address\n", dwGlobalLabel);
1981 fprintf(fp, " cmp %s, [edi+4] ; Are we bigger?\n", pszAddress);
1982 fprintf(fp, " jbe callRoutine%" PRIu32 "\n\n", dwGlobalLabel);
1983 fprintf(fp, "nextAddr%" PRIu32 ":\n", dwGlobalLabel);
1984 fprintf(fp, " add edi, 10h ; Next structure!\n");
1985 fprintf(fp, " jmp short checkLoop%" PRIu32 "\n\n", dwGlobalLabel);
1986 fprintf(fp, "callRoutine%" PRIu32 ":\n", dwGlobalLabel);
1988 if (strcmp(pszAddress, "dx") != 0)
1989 fprintf(fp, " mov dx, %s ; Get our address\n", pszAddress);
1991 if (strcmp(pszTarget, "ax") != 0)
1992 fprintf(fp, " push ax ; Save this for later\n");
1994 fprintf(fp, " push dx ; Save address\n");
1995 fprintf(fp, " call ReadMemoryByte ; Standard read routine\n");
1996 fprintf(fp, " pop dx ; Restore our address\n");
1998 fprintf(fp, " inc dx ; Next byte, please\n");
2000 fprintf(fp, " push ax ; Save returned byte\n");
2001 fprintf(fp, " call ReadMemoryByte ; Standard read routine\n");
2002 fprintf(fp, " xchg ah, al ; Swap for endian's sake\n");
2003 fprintf(fp, " pop dx ; Restore LSB\n");
2005 fprintf(fp, " mov dh, ah ; Our word is now in DX\n");
2007 // DX Now has our data and our address is toast
2009 if (strcmp(pszTarget, "ax") != 0)
2011 fprintf(fp, " pop ax ; Restore this\n");
2013 if (strcmp(pszTarget, "dx") != 0)
2015 fprintf(fp, " mov %s, dx ; Store our word\n", pszTarget);
2018 else
2019 fprintf(fp, " mov ax, dx\n");
2021 if (strcmp(pszTarget, "ax") == 0)
2023 fprintf(fp, " xchg ah, al\n");
2026 fprintf(fp, " jmp readExit%" PRIu32 "\n\n", dwGlobalLabel);
2028 fprintf(fp, "memoryRead%" PRIu32 ":\n", dwGlobalLabel);
2030 if (strlen(pszTarget) == 2)
2032 fprintf(fp, " mov %s, [ebp + e%s]\n", pszTarget, pszAddress);
2033 if (strcmp(pszTarget, "ax") == 0)
2035 fprintf(fp, " xchg ah, al\n");
2038 else
2040 fprintf(fp, " mov dx, [ebp + e%s]\n", pszAddress);
2041 fprintf(fp, " mov %s, dx\n", pszTarget);
2044 fprintf(fp, "readExit%" PRIu32 ":\n", dwGlobalLabel);
2045 fprintf(fp, " mov edi, [cyclesRemaining]\n");
2047 else
2048 if (MZ80_C == bWhat)
2050 fprintf(fp, " psMemRead = cpu.z80MemRead; /* Beginning of our handler */\n");
2051 fprintf(fp, " while (psMemRead->lowAddr != 0xffffffff)\n");
2052 fprintf(fp, " {\n");
2053 fprintf(fp, " if ((%s >= psMemRead->lowAddr) && (%s <= psMemRead->highAddr))\n", pszAddress, pszAddress);
2054 fprintf(fp, " {\n");
2055 fprintf(fp, " cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
2056 fprintf(fp, " if (psMemRead->memoryCall)\n");
2057 fprintf(fp, " {\n");
2058 fprintf(fp, " %s = psMemRead->memoryCall(%s, psMemRead);\n", pszTarget, pszAddress);
2059 fprintf(fp, " %s |= (UINT32) ((UINT32) psMemRead->memoryCall(%s + 1, psMemRead) << 8);\n", pszTarget, pszAddress);
2060 fprintf(fp, " }\n");
2061 fprintf(fp, " else\n");
2062 fprintf(fp, " {\n");
2063 fprintf(fp, " %s = *((UINT8 *) psMemRead->pUserArea + (%s - psMemRead->lowAddr));\n", pszTarget, pszAddress);
2064 fprintf(fp, " %s |= (UINT32) ((UINT32) *((UINT8 *) psMemRead->pUserArea + (%s - psMemRead->lowAddr + 1)) << 8);\n", pszTarget, pszAddress);
2065 fprintf(fp, " }\n");
2066 fprintf(fp, " psMemRead = NULL;\n");
2067 fprintf(fp, " break;\n");
2068 fprintf(fp, " }\n");
2069 fprintf(fp, " ++psMemRead;\n");
2070 fprintf(fp, " }\n\n");
2071 fprintf(fp, " if (psMemRead)\n");
2072 fprintf(fp, " {\n");
2073 fprintf(fp, " %s = cpu.z80Base[%s];\n", pszTarget, pszAddress);
2074 fprintf(fp, " %s |= (UINT32) ((UINT32) cpu.z80Base[%s + 1] << 8);\n", pszTarget, pszAddress);
2075 fprintf(fp, " }\n\n");
2077 else
2079 abort();
2082 dwGlobalLabel++;
2086 void ReadValueFromIo(INT8 *pszIoAddress, INT8 *pszTarget)
2088 if (MZ80_ASSEMBLY_X86 == bWhat)
2090 fprintf(fp, " mov [cyclesRemaining], edi\n");
2091 fprintf(fp, " mov edi, [_z80IoRead] ; Point to the read array\n\n");
2092 fprintf(fp, "checkLoop%" PRIu32 ":\n", dwGlobalLabel);
2093 fprintf(fp, " cmp [edi], word 0ffffh ; End of the list?\n");
2094 fprintf(fp, " je ioRead%" PRIu32 "\n", dwGlobalLabel);
2095 fprintf(fp, " cmp %s, [edi] ; Are we smaller?\n", pszIoAddress);
2096 fprintf(fp, " jb nextAddr%" PRIu32 " ; Yes, go to the next address\n", dwGlobalLabel);
2097 fprintf(fp, " cmp %s, [edi+2] ; Are we bigger?\n", pszIoAddress);
2098 fprintf(fp, " jbe callRoutine%" PRIu32 "\n\n", dwGlobalLabel);
2099 fprintf(fp, "nextAddr%" PRIu32 ":\n", dwGlobalLabel);
2100 fprintf(fp, " add edi, 0ch ; Next structure!\n");
2101 fprintf(fp, " jmp short checkLoop%" PRIu32 "\n\n", dwGlobalLabel);
2102 fprintf(fp, "callRoutine%" PRIu32 ":\n", dwGlobalLabel);
2104 if (strcmp(pszIoAddress, "dx") != 0)
2105 fprintf(fp, " mov dx, %s ; Get our address\n", pszIoAddress);
2107 fprintf(fp, " call ReadIOByte ; Standard read routine\n");
2109 // Yes, these are intentionally reversed!
2111 if (strcmp(pszTarget, "al") == 0)
2112 fprintf(fp, " mov [_z80af], al ; Save our new accumulator\n");
2113 else
2114 if (strcmp(pszTarget, "ah") == 0)
2115 fprintf(fp, " mov [_z80af + 1], ah ; Save our new flags\n");
2116 else
2117 if (strcmp(pszTarget, "dl") == 0)
2118 fprintf(fp, " mov [_z80de], al ; Put it in E\n");
2119 else
2120 if (strcmp(pszTarget, "dh") == 0)
2121 fprintf(fp, " mov [_z80de + 1], al ; Put it in D\n");
2122 else
2123 if (strcmp(pszTarget, "*dl") == 0)
2124 fprintf(fp, " mov dl, al ; Put it in DL for later consumption\n");
2125 else
2126 fprintf(fp, " mov %s, al ; Put our returned value here\n", pszTarget);
2128 // And are properly restored HERE:
2130 fprintf(fp, " mov ax, [_z80af] ; Get our AF back\n");
2132 // Restore registers here...
2134 fprintf(fp, " jmp short readExit%" PRIu32 "\n\n", dwGlobalLabel);
2135 fprintf(fp, "ioRead%" PRIu32 ":\n", dwGlobalLabel);
2137 if (strcmp(pszTarget, "*dl") == 0)
2138 fprintf(fp, " mov dl, 0ffh ; An unreferenced read\n");
2139 else
2140 fprintf(fp, " mov %s, 0ffh ; An unreferenced read\n", pszTarget);
2141 fprintf(fp, "readExit%" PRIu32 ":\n", dwGlobalLabel);
2142 fprintf(fp, " mov edi, [cyclesRemaining]\n");
2144 else
2145 if (MZ80_C == bWhat)
2147 fprintf(fp, " psIoRead = cpu.z80IoRead; /* Beginning of our handler */\n");
2148 fprintf(fp, " while (psIoRead->lowIoAddr != 0xffff)\n");
2149 fprintf(fp, " {\n");
2150 fprintf(fp, " if ((%s >= psIoRead->lowIoAddr) && (%s <= psIoRead->highIoAddr))\n", pszIoAddress, pszIoAddress);
2151 fprintf(fp, " {\n");
2152 fprintf(fp, " cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
2153 fprintf(fp, " %s = psIoRead->IOCall(%s, psIoRead);\n", pszTarget, pszIoAddress);
2154 fprintf(fp, " psIoRead = NULL;\n");
2155 fprintf(fp, " break;\n");
2156 fprintf(fp, " }\n");
2157 fprintf(fp, " ++psIoRead;\n");
2158 fprintf(fp, " }\n\n");
2159 fprintf(fp, " if (psIoRead)\n");
2160 fprintf(fp, " {\n");
2161 fprintf(fp, " %s = 0xff; /* Unclaimed I/O read */\n", pszTarget);
2162 fprintf(fp, " }\n\n");
2164 else
2166 abort();
2169 dwGlobalLabel++;
2172 // Basic instruction set area
2174 void MiscHandler(UINT32 dwOpcode)
2176 if (MZ80_ASSEMBLY_X86 == bWhat)
2178 ProcBegin(dwOpcode);
2180 if (dwOpcode == 0xe3)
2182 if (bThroughCallHandler)
2184 fprintf(fp, " call PopWord\n");
2185 fprintf(fp, " xchg bx, [_wordval]\n");
2186 fprintf(fp, " call PushWord\n");
2188 else
2190 fprintf(fp, " mov dx, word [_z80sp]\n");
2191 fprintf(fp, " xchg bx, [ebp+edx]\n");
2192 fprintf(fp, " xor edx, edx\n");
2196 if (dwOpcode == 0x2a)
2198 fprintf(fp, " mov dx, [esi] ; Get address to load\n");
2199 fprintf(fp, " add esi, 2 ; Skip over it so we don't execute it\n");
2201 ReadWordFromMemory("dx", "bx");
2202 fprintf(fp, " xor edx, edx\n");
2205 if (dwOpcode == 0xfb)
2207 fprintf(fp, " or dword [_z80iff], IFF1 ; Indicate interrupts are enabled now\n");
2208 fprintf(fp, " sub edi, 4 ; Takes 4 cycles!\n");
2209 fprintf(fp, " mov [dwEITiming], edi ; Snapshot our current timing\n");
2210 fprintf(fp, " mov [bEIExit], byte 1 ; Indicate we're exiting because of an EI\n");
2211 fprintf(fp, " xor edi, edi ; Force next instruction to exit\n");
2212 fprintf(fp, " mov dl, byte [esi] ; Get our next instruction\n");
2213 fprintf(fp, " inc esi ; Next PC\n");
2214 fprintf(fp, " jmp dword [z80regular+edx*4]\n\n");
2217 if (dwOpcode == 0xf9)
2218 fprintf(fp, " mov word [_z80sp], bx\n");
2220 if (dwOpcode == 0xd9)
2222 fprintf(fp, " mov [cyclesRemaining], edi\n");
2223 fprintf(fp, " mov di, [_z80de]\n");
2224 fprintf(fp, " xchg cx, [_z80bcprime]\n");
2225 fprintf(fp, " xchg di, [_z80deprime]\n");
2226 fprintf(fp, " xchg bx, [_z80hlprime]\n");
2227 fprintf(fp, " mov [_z80de], di\n");
2228 fprintf(fp, " mov edi, [cyclesRemaining]\n");
2231 if (dwOpcode == 0x76)
2233 fprintf(fp, " mov dword [_z80halted], 1 ; We've halted the chip!\n");
2235 if (FALSE == bNoTiming)
2237 fprintf(fp, " xor edi, edi\n");
2238 fprintf(fp, " mov [cyclesRemaining], edi\n");
2241 fprintf(fp, " jmp noMoreExec\n");
2242 return;
2245 if (dwOpcode == 0x3f)
2247 fprintf(fp, " mov dl, ah\n");
2248 fprintf(fp, " and dl, 01h\n");
2249 fprintf(fp, " shl dl, 4\n");
2250 fprintf(fp, " xor ah, 01h\n");
2251 fprintf(fp, " and ah, 0edh\n");
2252 fprintf(fp, " or ah, dl\n");
2255 if (dwOpcode == 0x37)
2257 fprintf(fp, " or ah, 1\n");
2258 fprintf(fp, " and ah,0edh\n");
2261 if (dwOpcode == 0x27)
2263 fprintf(fp, " mov dh, ah\n");
2264 fprintf(fp, " and dh, 02ah\n");
2265 fprintf(fp, " test ah, 02h ; Were we doing a subtraction?\n");
2266 fprintf(fp, " jnz handleNeg ; Nope!\n");
2267 fprintf(fp, " sahf\n");
2268 fprintf(fp, " daa\n");
2269 fprintf(fp, " lahf\n");
2270 fprintf(fp, " jmp short endDaa\n");
2271 fprintf(fp, "handleNeg:\n");
2272 fprintf(fp, " sahf\n");
2273 fprintf(fp, " das\n");
2274 fprintf(fp, " lahf\n");
2275 fprintf(fp, "endDaa:\n");
2276 fprintf(fp, " and ah, 0d5h\n");
2277 fprintf(fp, " or ah, dh\n");
2278 fprintf(fp, " xor edx, edx\n");
2281 if (dwOpcode == 0x08)
2283 fprintf(fp, " xchg ah, al\n");
2284 fprintf(fp, " xchg ax, [_z80afprime]\n");
2285 fprintf(fp, " xchg ah, al\n");
2288 if (dwOpcode == 0x07)
2290 fprintf(fp, " sahf\n");
2291 fprintf(fp, " rol al, 1\n");
2292 fprintf(fp, " lahf\n");
2293 fprintf(fp, " and ah, 0edh\n");
2296 if (dwOpcode == 0x0f)
2298 fprintf(fp, " sahf\n");
2299 fprintf(fp, " ror al, 1\n");
2300 fprintf(fp, " lahf\n");
2301 fprintf(fp, " and ah, 0edh\n");
2304 if (dwOpcode == 0xe9)
2306 fprintf(fp, " mov si, bx\n");
2307 fprintf(fp, " and esi, 0ffffh\n");
2308 fprintf(fp, " add esi, ebp\n");
2311 if (dwOpcode == 0xeb)
2312 fprintf(fp, " xchg [_z80de], bx ; Exchange DE & HL\n");
2314 if (dwOpcode == 0x2f)
2316 fprintf(fp, " not al\n");
2317 fprintf(fp, " or ah, 012h ; N And H are now on!\n");
2320 if (dwOpcode == 0x10) // DJNZ
2322 fprintf(fp, " mov dl, [esi] ; Get our relative offset\n");
2323 fprintf(fp, " inc esi ; Next instruction, please!\n");
2324 fprintf(fp, " dec ch ; Decrement B\n");
2325 fprintf(fp, " jz noJump ; Don't take the jump if it's done!\n");
2326 fprintf(fp, "; Otherwise, take the jump\n");
2328 fprintf(fp, " sub edi, 5\n");
2330 fprintf(fp, " xchg eax, edx\n");
2331 fprintf(fp, " cbw\n");
2332 fprintf(fp, " xchg eax, edx\n");
2333 fprintf(fp, " sub esi, ebp\n");
2334 fprintf(fp, " add si, dx\n");
2335 fprintf(fp, " add esi, ebp\n");
2336 fprintf(fp, "noJump:\n");
2337 fprintf(fp, " xor edx, edx\n");
2340 if (dwOpcode == 0x3a) // LD A,(xxxx)
2342 fprintf(fp, " mov dx, [esi] ; Get our address\n");
2343 fprintf(fp, " add esi, 2 ; Skip past the address\n");
2344 ReadValueFromMemory("dx", "al");
2345 fprintf(fp, " xor edx, edx ; Make sure we don't hose things\n");
2348 if (dwOpcode == 0xf3) // DI
2350 fprintf(fp, " and dword [_z80iff], (~IFF1) ; Not in an interrupt\n");
2353 FetchNextInstruction(dwOpcode);
2355 else
2356 if (MZ80_C == bWhat)
2358 if (dwOpcode == 0x76) // HALT!
2360 fprintf(fp, " cpu.z80halted = 1;\n");
2361 fprintf(fp, " dwElapsedTicks += sdwCyclesRemaining;\n");
2363 fprintf(fp, " sdwCyclesRemaining = 0;\n");
2365 else
2366 if (dwOpcode == 0x2f) // CPL
2368 fprintf(fp, " cpu.z80A ^= 0xff;\n");
2369 fprintf(fp, " cpu.z80F |= (Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");
2371 else
2372 if (dwOpcode == 0xd9) // EXX
2374 fprintf(fp, " dwTemp = cpu.z80DE;\n");
2375 fprintf(fp, " cpu.z80DE = cpu.z80deprime;\n");
2376 fprintf(fp, " cpu.z80deprime = dwTemp;\n");
2378 fprintf(fp, " dwTemp = cpu.z80BC;\n");
2379 fprintf(fp, " cpu.z80BC = cpu.z80bcprime;\n");
2380 fprintf(fp, " cpu.z80bcprime = dwTemp;\n");
2382 fprintf(fp, " dwTemp = cpu.z80HL;\n");
2383 fprintf(fp, " cpu.z80HL = cpu.z80hlprime;\n");
2384 fprintf(fp, " cpu.z80hlprime = dwTemp;\n");
2386 else
2387 if (dwOpcode == 0xf9) // LD SP, HL
2389 fprintf(fp, " cpu.z80sp = cpu.z80HL;\n");
2391 else
2392 if (dwOpcode == 0x27) // DAA
2394 fprintf(fp, " dwAddr = (((cpu.z80F & Z80_FLAG_CARRY) | \n");
2395 fprintf(fp, " ((cpu.z80F & Z80_FLAG_HALF_CARRY) >> 3) | \n");
2396 fprintf(fp, " ((cpu.z80F & Z80_FLAG_NEGATIVE) << 1)) << 8) | cpu.z80A;\n");
2397 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
2398 fprintf(fp, " cpu.z80F |= (wDAATable[dwAddr] >> 8);\n");
2399 fprintf(fp, " cpu.z80A = wDAATable[dwAddr] & 0xff;\n");
2401 else
2402 if (dwOpcode == 0x2a)
2404 fprintf(fp, " dwAddr = *pbPC++;\n");
2405 fprintf(fp, " dwAddr |= ((UINT32) *pbPC++ << 8);\n");
2406 ReadWordFromMemory("dwAddr", "cpu.z80HL");
2408 else
2409 if (dwOpcode == 0xe3) // EX (SP), HL
2411 ReadWordFromMemory("cpu.z80sp", "dwAddr");
2412 WriteWordToMemory("cpu.z80sp", "cpu.z80HL");
2413 fprintf(fp, " cpu.z80HL = dwAddr;\n");
2415 else
2416 if (dwOpcode == 0xe9) // JP (HL)
2418 fprintf(fp, " pbPC = cpu.z80Base + cpu.z80HL;\n");
2420 else
2421 if (0x08 == dwOpcode) // EX AF, AF'
2423 fprintf(fp, " dwAddr = (UINT32) cpu.z80AF;\n");
2424 fprintf(fp, " cpu.z80AF = cpu.z80afprime;\n");
2425 fprintf(fp, " cpu.z80afprime = dwAddr;\n");
2427 else
2428 if (0xeb == dwOpcode) // EX DE, HL
2430 fprintf(fp, " dwAddr = cpu.z80DE;\n");
2431 fprintf(fp, " cpu.z80DE = cpu.z80HL;\n");
2432 fprintf(fp, " cpu.z80HL = dwAddr;\n");
2434 else
2435 if (0x10 == dwOpcode) // DJNZ
2437 fprintf(fp, " sdwAddr = (INT8) *pbPC++; /* Get LSB first */\n");
2438 fprintf(fp, " if (--cpu.z80B)\n");
2439 fprintf(fp, " {\n");
2440 fprintf(fp, " dwElapsedTicks += 5; /* 5 More for jump taken */\n");
2441 fprintf(fp, " cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
2442 fprintf(fp, " sdwAddr = (sdwAddr + (INT32) cpu.z80pc) & 0xffff;\n");
2443 fprintf(fp, " pbPC = cpu.z80Base + sdwAddr; /* Normalize the address */\n");
2444 fprintf(fp, " }\n");
2446 else
2447 if (0x37 == dwOpcode) // SCF
2449 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_NEGATIVE);\n");
2450 fprintf(fp, " cpu.z80F |= Z80_FLAG_CARRY;\n");
2452 else
2453 if (0x3f == dwOpcode) // CCF
2455 fprintf(fp, " bTemp = (cpu.z80F & Z80_FLAG_CARRY) << 4;\n");
2456 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_NEGATIVE);\n");
2457 fprintf(fp, " cpu.z80F ^= Z80_FLAG_CARRY;\n");
2459 else
2460 if (0x07 == dwOpcode) // RLCA
2462 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");
2463 fprintf(fp, " cpu.z80F |= (cpu.z80A >> 7);\n");
2464 fprintf(fp, " cpu.z80A = (cpu.z80A << 1) | (cpu.z80A >> 7);\n");
2466 else
2467 if (0x0f == dwOpcode) // RRCA
2469 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");
2470 fprintf(fp, " cpu.z80F |= (cpu.z80A & Z80_FLAG_CARRY);\n");
2471 fprintf(fp, " cpu.z80A = (cpu.z80A >> 1) | (cpu.z80A << 7);\n");
2473 else
2474 if (0x3a == dwOpcode) // LD A, (xxxxh)
2476 fprintf(fp, " dwTemp = *pbPC++;\n");
2477 fprintf(fp, " dwTemp |= (((UINT32) *pbPC++) << 8);\n");
2478 ReadValueFromMemory("dwTemp", "cpu.z80A");
2480 else
2481 if (0xf3 == dwOpcode) // DI
2483 fprintf(fp, " cpu.z80iff &= (~IFF1);\n");
2485 else
2486 if (0xfb == dwOpcode) // EI
2488 fprintf(fp, " cpu.z80iff |= IFF1;\n");
2490 else
2491 if (0x00 == dwOpcode) // NOP
2493 fprintf(fp, " /* Intentionally not doing anything - NOP! */\n");
2495 else
2497 InvalidInstructionC(1);
2500 else
2502 abort();
2507 void LdRegPairImmediate(UINT32 dwOpcode)
2509 UINT8 bOp = 0;
2511 bOp = (dwOpcode >> 4) & 0x3;
2513 if (MZ80_ASSEMBLY_X86 == bWhat)
2515 ProcBegin(dwOpcode);
2517 if (bOp == 0)
2518 fprintf(fp, " mov cx, [esi] ; Get our immediate value of BC\n");
2519 else
2520 if (bOp == 2)
2521 fprintf(fp, " mov bx, [esi] ; Get our immediate value of HL\n");
2522 else
2523 if (bOp == 1)
2525 fprintf(fp, " mov dx, [esi] ; Get our immediate value of DE\n");
2526 fprintf(fp, " mov word [_z80de], dx ; Store DE\n");
2527 fprintf(fp, " xor edx, edx\n");
2529 else
2530 if (bOp == 3)
2532 fprintf(fp, " mov dx, [esi] ; Get our immediate value of SP\n");
2533 fprintf(fp, " mov word [_z80sp], dx ; Store it!\n");
2534 fprintf(fp, " xor edx, edx\n");
2537 fprintf(fp, " add esi, 2\n");
2538 FetchNextInstruction(dwOpcode);
2540 else
2541 if (MZ80_C == bWhat)
2543 fprintf(fp, " %s = *pbPC++; /* LSB First */\n", pbRegPairC[bOp]);
2544 fprintf(fp, " %s |= (((UINT32) *pbPC++ << 8)); /* Now the MSB */\n", pbRegPairC[bOp]);
2546 else
2548 abort();
2552 void LdRegpairPtrByte(UINT32 dwOpcode)
2554 if (MZ80_ASSEMBLY_X86 == bWhat)
2556 ProcBegin(dwOpcode);
2558 if (dwOpcode == 0x36) // Immediate into (HL)
2559 WriteValueToMemory("bx", "[esi]");
2561 if (dwOpcode == 0x12)
2562 WriteValueToMemory("[_z80de]", "al"); // (DE), A
2564 if (dwOpcode == 0x2) // (BC), A
2565 WriteValueToMemory("cx", "al");
2567 if (dwOpcode >= 0x70 && dwOpcode < 0x78)
2568 WriteValueToMemory("bx", pbMathReg[dwOpcode & 0x07]);
2570 fprintf(fp, " xor edx, edx\n");
2571 FetchNextInstruction(dwOpcode);
2573 else
2574 if (MZ80_C == bWhat)
2576 if (dwOpcode == 0x36)
2577 WriteValueToMemory("cpu.z80HL", "*pbPC++");
2579 if (dwOpcode == 0x12)
2580 WriteValueToMemory("cpu.z80DE", "cpu.z80A");
2582 if (dwOpcode == 0x02)
2583 WriteValueToMemory("cpu.z80BC", "cpu.z80A");
2585 if (dwOpcode >= 0x70 && dwOpcode < 0x78)
2586 WriteValueToMemory("cpu.z80HL", pbMathRegC[dwOpcode & 0x07]);
2588 else
2590 abort();
2594 void MathOperation(UINT32 dwOrgOpcode)
2596 UINT8 bRegister;
2597 UINT32 dwOpcode;
2598 INT8 tempstr[150];
2600 if (MZ80_ASSEMBLY_X86 == bWhat)
2602 ProcBegin(dwOrgOpcode);
2604 dwOpcode = dwOrgOpcode;
2605 bRegister = dwOpcode & 0x07;
2606 dwOpcode &= 0xf8;
2608 if (dwOpcode == 0x80)
2609 strcpy(tempstr, "add");
2610 if (dwOpcode == 0x88)
2611 strcpy(tempstr, "adc");
2612 if (dwOpcode == 0x90)
2613 strcpy(tempstr, "sub");
2614 if (dwOpcode == 0x98)
2615 strcpy(tempstr, "sbb");
2616 if (dwOpcode == 0xa0)
2617 strcpy(tempstr, "and");
2618 if (dwOpcode == 0xa8)
2619 strcpy(tempstr, "xor");
2620 if (dwOpcode == 0xb0)
2621 strcpy(tempstr, "or");
2622 if (dwOpcode == 0xb8)
2623 strcpy(tempstr, "cmp");
2625 // Let's see if we have to deal with (HL) or #xxh
2627 if (bRegister == 0x6)
2629 // We have to deal with (HL)
2631 ReadValueFromMemory("bx", "dl");
2634 if (bRegister != 0x06 && bRegister < 0xff)
2636 fprintf(fp, " sahf\n");
2637 fprintf(fp, " %s al, %s\n", tempstr, pbMathReg[bRegister]);
2638 fprintf(fp, " lahf\n");
2640 else // If it's (HL)....
2642 fprintf(fp, " sahf\n");
2643 fprintf(fp, " %s al, dl\n", tempstr);
2644 fprintf(fp, " lahf\n");
2647 if (dwOpcode != 0xa8 && dwOpcode != 0xa0 && dwOpcode != 0xb0)
2648 SetOverflow();
2650 if (dwOpcode == 0xa8)
2651 fprintf(fp, " and ah, 0ech ; Only these flags matter!\n");
2653 if (dwOpcode == 0xa0)
2655 fprintf(fp, " and ah, 0ech ; Only these flags matter!\n");
2656 fprintf(fp, " or ah, 010h ; Half carry gets set\n");
2659 if (dwOpcode == 0xb0)
2660 fprintf(fp, " and ah, 0ech ; No H, N, or C\n");
2662 if (dwOpcode == 0xb8)
2663 fprintf(fp, " or ah, 02h ; Set N for compare!\n");
2665 if (dwOpcode == 0x80 || dwOpcode == 0x88)
2666 fprintf(fp, " and ah, 0fdh ; No N!\n");
2668 if (dwOpcode == 0x90 || dwOpcode == 0x98)
2669 fprintf(fp, " or ah, 02h ; N Gets set!\n");
2671 if (bRegister == 0x6)
2672 fprintf(fp, " xor edx, edx ; Zero this...\n");
2674 FetchNextInstruction(dwOrgOpcode);
2676 else
2677 if (MZ80_C == bWhat)
2679 dwOpcode = dwOrgOpcode;
2680 bRegister = dwOpcode & 0x07;
2681 dwOpcode &= 0xf8;
2683 if (6 == bRegister) // Deal with (HL)
2685 ReadValueFromMemory("cpu.z80HL", "bTemp");
2688 if (dwOpcode == 0xa0)
2690 fprintf(fp, " cpu.z80A &= %s;\n", pbMathRegC[bRegister]);
2692 else
2693 if (dwOpcode == 0xa8)
2695 fprintf(fp, " cpu.z80A ^= %s;\n", pbMathRegC[bRegister]);
2697 else
2698 if (dwOpcode == 0xb0)
2700 fprintf(fp, " cpu.z80A |= %s;\n", pbMathRegC[bRegister]);
2702 else
2703 if (dwOpcode == 0xb8)
2705 // Don't do anything. We just do flags!
2707 else
2708 if (dwOpcode == 0x88) // ADC
2710 fprintf(fp, " bTemp2 = cpu.z80A + %s + (cpu.z80F & Z80_FLAG_CARRY);\n", pbMathRegC[bRegister]);
2712 else
2713 if (dwOpcode == 0x90) // SUB
2715 fprintf(fp, " bTemp2 = cpu.z80A - %s;\n", pbMathRegC[bRegister]);
2717 else
2718 if (dwOpcode == 0x80) // ADD
2720 fprintf(fp, " bTemp2 = cpu.z80A + %s;\n", pbMathRegC[bRegister]);
2722 else
2723 if (dwOpcode == 0x98) // SBC
2725 fprintf(fp, " bTemp2 = cpu.z80A - %s - (cpu.z80F & Z80_FLAG_CARRY);\n", pbMathRegC[bRegister]);
2727 else
2729 InvalidInstructionC(1);
2732 // Now do flag fixup
2734 if (0xb0 == dwOpcode || 0xa8 == dwOpcode)
2736 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
2737 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
2740 if (0xa0 == dwOpcode)
2742 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
2743 fprintf(fp, " cpu.z80F |= bPostANDFlags[cpu.z80A];\n\n");
2746 if (0xb8 == dwOpcode || 0x90 == dwOpcode)
2748 SetSubFlagsSZHVC("cpu.z80A", pbMathRegC[bRegister]);
2750 if (0x90 == dwOpcode)
2752 fprintf(fp, " cpu.z80A = bTemp2;\n");
2756 if (0x80 == dwOpcode) // Add fixup
2758 SetAddFlagsSZHVC("cpu.z80A", pbMathRegC[bRegister]);
2759 fprintf(fp, " cpu.z80A = bTemp2;\n");
2762 if (0x88 == dwOpcode) // Adc fixup
2764 SetAdcFlagsSZHVC("cpu.z80A", pbMathRegC[bRegister]);
2765 fprintf(fp, " cpu.z80A = bTemp2;\n");
2768 if (0x98 == dwOpcode) // Sbc fixup
2770 SetSbcFlagsSZHVC("cpu.z80A", pbMathRegC[bRegister]);
2771 fprintf(fp, " cpu.z80A = bTemp2;\n");
2774 else
2776 abort();
2780 void RegIntoMemory(UINT32 dwOpcode)
2782 if (MZ80_ASSEMBLY_X86 == bWhat)
2784 ProcBegin(dwOpcode);
2786 fprintf(fp, " mov dx, [esi] ; Get our address to write to\n");
2787 fprintf(fp, " add esi, 2 ; Next address, please...\n");
2789 if (0x32 == dwOpcode) // LD (xxxx), A
2790 WriteValueToMemory("dx", "al");
2791 if (0x22 == dwOpcode) // LD (xxxx), HL
2793 WriteWordToMemory("dx", "bx");
2796 fprintf(fp, " xor edx, edx ; Zero our upper byte\n");
2798 FetchNextInstruction(dwOpcode);
2800 else
2801 if (MZ80_C == bWhat)
2803 fprintf(fp, " dwTemp = *pbPC++;\n");
2804 fprintf(fp, " dwTemp |= ((UINT32) *pbPC++ << 8);\n");
2806 if (0x32 == dwOpcode)
2807 WriteValueToMemory("dwTemp", "cpu.z80A");
2808 if (0x22 == dwOpcode)
2809 WriteWordToMemory("dwTemp", "cpu.z80HL");
2811 return;
2813 else
2815 abort();
2819 void JpHandler(UINT32 dwOpcode)
2821 if (MZ80_ASSEMBLY_X86 == bWhat)
2823 ProcBegin(dwOpcode);
2825 if (0xc3 == dwOpcode) // If it's a straight jump...
2827 fprintf(fp, " mov si, [esi] ; Get our new address\n");
2828 fprintf(fp, " and esi, 0ffffh ; Only the lower 16 bits\n");
2829 fprintf(fp, " add esi, ebp ; Our new address!\n");
2831 else // It's a conditional handler...
2833 fprintf(fp, " sahf ; Restore our flags\n");
2834 fprintf(fp, " j%s takeJump%" PRIu32 " ; We're going to take a jump\n", pbFlags[(dwOpcode >> 3) & 0x07], dwGlobalLabel);
2835 fprintf(fp, " add esi, 2 ; Skip past the address\n");
2836 fprintf(fp, " jmp short nextInst%" PRIu32 " ; Go execute the next instruction\n", dwGlobalLabel);
2837 fprintf(fp, "takeJump%" PRIu32 ":\n", dwGlobalLabel);
2839 fprintf(fp, " mov si, [esi] ; Get our new offset\n");
2840 fprintf(fp, " and esi, 0ffffh ; Only the lower WORD is valid\n");
2841 fprintf(fp, " add esi, ebp ; Our new address!\n");
2842 fprintf(fp, "nextInst%" PRIu32 ":\n", dwGlobalLabel);
2843 ++dwGlobalLabel;
2846 FetchNextInstruction(dwOpcode);
2848 else
2849 if (MZ80_C == bWhat)
2851 fprintf(fp, " dwAddr = *pbPC++; /* Get LSB first */\n");
2852 fprintf(fp, " dwAddr |= ((UINT32) *pbPC++ << 8); /* Get MSB last */\n");
2854 if (0xc3 != dwOpcode)
2856 fprintf(fp, " if %s\n", pbFlagsC[(dwOpcode >> 3) & 0x07]);
2857 fprintf(fp, " {\n");
2858 fprintf(fp, " pbPC = cpu.z80Base + dwAddr; /* Normalize the address */\n");
2859 fprintf(fp, " }\n");
2861 else // Regular jump here
2863 fprintf(fp, " pbPC = cpu.z80Base + dwAddr; /* Normalize the address */\n");
2866 else
2868 abort();
2872 void LdRegImmediate(UINT32 dwOpcode)
2874 UINT8 bOp;
2876 bOp = (dwOpcode >> 3) & 0x7;
2878 if (MZ80_ASSEMBLY_X86 == bWhat)
2880 ProcBegin(dwOpcode);
2883 if (bOp != 2 && bOp != 3)
2884 fprintf(fp, " mov %s, [esi] ; Get our immediate value\n", pbMathReg[bOp]);
2885 else
2887 fprintf(fp, " mov dl, [esi] ; Get our immediate value\n");
2888 fprintf(fp, " mov %s, dl ; Store our new value\n", pbMathReg[bOp]);
2891 fprintf(fp, " inc esi\n");
2893 FetchNextInstruction(dwOpcode);
2895 else
2896 if (MZ80_C == bWhat)
2898 fprintf(fp, " %s = *pbPC++; /* Get immediate byte into register */\n", pbMathRegC[bOp]);
2900 else
2902 abort();
2906 void IncRegister(UINT32 dwOpcode)
2908 UINT32 dwOpcode1 = 0;
2910 dwOpcode1 = (dwOpcode >> 3) & 0x07;
2912 if (MZ80_ASSEMBLY_X86 == bWhat)
2914 ProcBegin(dwOpcode);
2916 fprintf(fp, " sahf\n");
2917 fprintf(fp, " inc %s\n", pbMathReg[dwOpcode1]);
2918 fprintf(fp, " lahf\n");
2919 SetOverflow();
2920 fprintf(fp, " and ah, 0fdh ; Knock out N!\n");
2922 FetchNextInstruction(dwOpcode);
2924 else
2925 if (MZ80_C == bWhat)
2927 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
2928 fprintf(fp ," cpu.z80F |= bPostIncFlags[%s++];\n", pbMathRegC[dwOpcode1]);
2930 else
2932 abort();
2936 void DecRegister(UINT32 dwOpcode)
2938 UINT32 dwOpcode1 = 0;
2940 dwOpcode1 = (dwOpcode >> 3) & 0x07;
2942 if (MZ80_ASSEMBLY_X86 == bWhat)
2944 ProcBegin(dwOpcode);
2946 fprintf(fp, " sahf\n");
2947 fprintf(fp, " dec %s\n", pbMathReg[dwOpcode1]);
2948 fprintf(fp, " lahf\n");
2949 SetOverflow();
2950 fprintf(fp, " or ah, 02h ; Set negative!\n");
2952 FetchNextInstruction(dwOpcode);
2954 else
2955 if (MZ80_C == bWhat)
2957 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY);\n");
2958 fprintf(fp ," cpu.z80F |= bPostDecFlags[%s--];\n", pbMathRegC[dwOpcode1]);
2960 else
2962 abort();
2966 void IncDecRegpair(UINT32 dwOpcode)
2968 if (MZ80_ASSEMBLY_X86 == bWhat)
2970 ProcBegin(dwOpcode);
2972 if ((dwOpcode & 0x0f) == 3) // Increment?
2973 fprintf(fp, " inc %s\n", pbRegPairs[(dwOpcode >> 4) & 0x03]);
2974 else
2975 fprintf(fp, " dec %s\n", pbRegPairs[(dwOpcode >> 4) & 0x03]);
2977 FetchNextInstruction(dwOpcode);
2979 else
2980 if (MZ80_C == bWhat)
2982 if ((dwOpcode & 0x0f) == 3) // Increment
2983 fprintf(fp, " %s++;\n", pbRegPairC[(dwOpcode >> 4) & 0x03]);
2984 else
2985 fprintf(fp, " %s--;\n", pbRegPairC[(dwOpcode >> 4) & 0x03]);
2986 fprintf(fp, " %s &= 0xffff;\n", pbRegPairC[(dwOpcode >> 4) & 0x03]);
2988 else
2990 abort();
2994 void LdRegReg(UINT32 dwOpcode)
2996 UINT8 bDestination;
2997 UINT8 bSource;
2999 bDestination = (dwOpcode >> 3) & 0x07;
3000 bSource = (dwOpcode) & 0x07;
3002 if (MZ80_ASSEMBLY_X86 == bWhat)
3005 ProcBegin(dwOpcode);
3007 if (bSource != bDestination)
3009 if (bSource == 2 && bDestination == 3)
3011 fprintf(fp, " mov dl, byte [_z80de + 1]\n");
3012 fprintf(fp, " mov [_z80de], dl\n");
3014 else
3015 if (bSource == 3 && bDestination == 2)
3017 fprintf(fp, " mov dl, byte [_z80de]\n");
3018 fprintf(fp, " mov [_z80de + 1], dl\n");
3020 else
3021 fprintf(fp, " mov %s, %s\n", pbMathReg[bDestination], pbMathReg[bSource]);
3024 FetchNextInstruction(dwOpcode);
3026 else
3027 if (MZ80_C == bWhat)
3029 if (bDestination != bSource)
3031 fprintf(fp, " %s = %s;\n",
3032 pbMathRegC[bDestination],
3033 pbMathRegC[bSource]);
3036 else
3038 abort();
3042 void MathOperationDirect(UINT32 dwOpcode)
3044 INT8 tempstr[4];
3046 if (MZ80_ASSEMBLY_X86 == bWhat)
3048 if (dwOpcode == 0xc6)
3049 strcpy(tempstr, "add");
3050 if (dwOpcode == 0xce)
3051 strcpy(tempstr, "adc");
3052 if (dwOpcode == 0xd6)
3053 strcpy(tempstr, "sub");
3054 if (dwOpcode == 0xde)
3055 strcpy(tempstr, "sbb");
3056 if (dwOpcode == 0xe6)
3057 strcpy(tempstr, "and");
3058 if (dwOpcode == 0xee)
3059 strcpy(tempstr, "xor");
3060 if (dwOpcode == 0xf6)
3061 strcpy(tempstr, "or");
3062 if (dwOpcode == 0xfe)
3063 strcpy(tempstr, "cmp");
3065 ProcBegin(dwOpcode);
3067 // Let's see if we have to deal with (HL) or #xxh
3069 fprintf(fp, " sahf\n");
3070 fprintf(fp, " %s al, [esi]\n", tempstr);
3071 fprintf(fp, " lahf\n");
3073 if (dwOpcode != 0xee && dwOpcode != 0xe6 && dwOpcode != 0xf6)
3075 SetOverflow();
3078 if (dwOpcode == 0xe6)
3080 fprintf(fp, " and ah, 0ech ; Only parity, half carry, sign, zero\n");
3081 fprintf(fp, " or ah, 10h ; Half carry\n");
3084 if (dwOpcode == 0xc6 || dwOpcode == 0xce)
3085 fprintf(fp, " and ah, 0fdh ; Knock out N!\n");
3087 if (dwOpcode == 0xd6 || dwOpcode == 0xde || dwOpcode == 0xfe)
3088 fprintf(fp, " or ah, 02h ; Set negative!\n");
3090 if (dwOpcode == 0xf6 || dwOpcode == 0xee)
3091 fprintf(fp, " and ah, 0ech ; No H, N, or C\n");
3093 fprintf(fp, " inc esi\n");
3095 FetchNextInstruction(dwOpcode);
3097 else
3098 if (MZ80_C == bWhat)
3100 if (0xfe == dwOpcode) // Cp
3102 SetSubFlagsSZHVC("cpu.z80A", "*pbPC++");
3104 else
3105 if (0xe6 == dwOpcode) // And
3107 fprintf(fp, " cpu.z80A &= *pbPC++;\n");
3108 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
3109 fprintf(fp, " cpu.z80F |= bPostANDFlags[cpu.z80A];\n\n");
3111 else
3112 if (0xf6 == dwOpcode) // Or
3114 fprintf(fp, " cpu.z80A |= *pbPC++;\n");
3115 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
3116 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
3118 else
3119 if (0xc6 == dwOpcode) // Add
3121 fprintf(fp, " bTemp = *pbPC++;\n");
3122 SetAddFlagsSZHVC("cpu.z80A", "bTemp");
3123 fprintf(fp, " cpu.z80A += bTemp;\n");
3125 else
3126 if (0xce == dwOpcode) // Adc
3128 fprintf(fp, " bTemp = *pbPC++ + (cpu.z80F & Z80_FLAG_CARRY);\n");
3129 SetAdcFlagsSZHVC("cpu.z80A", "bTemp");
3130 fprintf(fp, " cpu.z80A += bTemp;\n");
3132 else
3133 if (0xd6 == dwOpcode) // Sub
3135 fprintf(fp, " bTemp = *pbPC++;\n");
3136 SetSubFlagsSZHVC("cpu.z80A", "bTemp");
3137 fprintf(fp, " cpu.z80A -= bTemp;\n");
3139 else
3140 if (0xde == dwOpcode) // Sbc
3142 fprintf(fp, " bTemp = *pbPC++ + (cpu.z80F & Z80_FLAG_CARRY);\n");
3143 SetSbcFlagsSZHVC("cpu.z80A", "bTemp");
3144 fprintf(fp, " cpu.z80A = cpu.z80A - bTemp;\n");
3146 else
3147 if (0xee == dwOpcode) // Xor
3149 fprintf(fp, " cpu.z80A ^= *pbPC++;\n");
3150 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
3151 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
3153 else
3154 InvalidInstructionC(1);
3156 else
3158 abort();
3162 // JR cc, addr
3164 void JrHandler(UINT32 dwOpcode)
3166 if (MZ80_ASSEMBLY_X86 == bWhat)
3168 ProcBegin(dwOpcode);
3170 fprintf(fp, " sub esi, ebp\n");
3171 fprintf(fp, " and esi, 0ffffh\n");
3172 fprintf(fp, " add esi, ebp\n");
3174 fprintf(fp, " mov dl, [esi] ; Get our relative offset\n");
3175 fprintf(fp, " inc esi ; Next instruction, please!\n");
3177 if (dwOpcode != 0x18)
3179 fprintf(fp, " sahf\n");
3180 fprintf(fp, " j%s takeJump%" PRIu32 "\n", pbFlags[(dwOpcode >> 3) & 0x3], dwGlobalLabel);
3181 fprintf(fp, " jmp short noJumpMan%" PRIu32 "\n", dwGlobalLabel);
3182 fprintf(fp, "takeJump%" PRIu32 ":\n", dwGlobalLabel);
3184 if (FALSE == bNoTiming)
3186 fprintf(fp, " sub edi, 5\n");
3189 else // It's a JR
3191 fprintf(fp, " cmp dl, 0feh ; Jump to self?\n");
3192 fprintf(fp, " je yesJrMan ; Yup! Bail out!\n");
3195 fprintf(fp, " xchg eax, edx\n");
3196 fprintf(fp, " cbw\n");
3197 fprintf(fp, " xchg eax, edx\n");
3198 fprintf(fp, " sub esi, ebp\n");
3199 fprintf(fp, " add si, dx\n");
3200 fprintf(fp, " and esi, 0ffffh ; Only the lower 16 bits\n");
3201 fprintf(fp, " add esi, ebp\n");
3202 fprintf(fp, " xor dh, dh\n");
3203 fprintf(fp, "noJumpMan%" PRIu32 ":\n", dwGlobalLabel++);
3205 FetchNextInstruction(dwOpcode);
3207 if (0x18 == dwOpcode)
3209 fprintf(fp,"yesJrMan:\n");
3211 fprintf(fp, " xor edx, edx ; Zero me for later\n");
3212 fprintf(fp, " mov edi, edx\n");
3213 fprintf(fp, " mov [cyclesRemaining], edx\n");
3214 fprintf(fp, " sub esi, 2 ; Back to the instruction again\n");
3215 fprintf(fp, " jmp noMoreExec\n\n");
3218 else
3219 if (MZ80_C == bWhat)
3221 fprintf(fp, " sdwAddr = (INT8) *pbPC++; /* Get LSB first */\n");
3222 fprintf(fp, " cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
3223 fprintf(fp, " sdwAddr = (sdwAddr + (INT32) cpu.z80pc) & 0xffff;\n");
3225 if (0x18 != dwOpcode)
3227 fprintf(fp, " if %s\n", pbFlagsC[(dwOpcode >> 3) & 0x03]);
3230 fprintf(fp, " {\n");
3232 fprintf(fp, " sdwCyclesRemaining -= 5;\n");
3234 fprintf(fp, " pbPC = cpu.z80Base + sdwAddr; /* Normalize the address */\n");
3235 fprintf(fp, " }\n");
3238 else
3240 abort();
3244 void CallHandler(UINT32 dwOpcode)
3246 if (MZ80_ASSEMBLY_X86 == bWhat)
3248 ProcBegin(dwOpcode);
3250 if (dwOpcode != 0xcd)
3252 fprintf(fp, " sahf ; Restore our flags\n");
3253 fprintf(fp, " j%s takeJump%" PRIu32 " ; We're going call in this case\n", pbFlags[(dwOpcode >> 3) & 0x07], dwGlobalLabel);
3254 fprintf(fp, " add esi, 2 ; Skip past the address\n");
3255 fprintf(fp, " jmp short noCallTaken%" PRIu32 " ; Go execute the next instruction\n", dwGlobalLabel);
3256 fprintf(fp, "takeJump%" PRIu32 ":\n", dwGlobalLabel);
3258 fprintf(fp, " sub edi, 7\n");
3262 if (bThroughCallHandler)
3264 fprintf(fp, " mov dx, [esi] ; Get our call to address\n");
3265 fprintf(fp, " mov [_z80pc], dx ; Store our new program counter\n");
3266 fprintf(fp, " add esi, 2 ; Skip to our new address to be pushed\n");
3267 fprintf(fp, " sub esi, ebp ; Value to push onto the \"stack\"\n");
3268 fprintf(fp, " mov [_wordval], si ; Store our return address on the stack\n");
3269 fprintf(fp, " mov si, dx ; Our new address\n");
3270 fprintf(fp, " add esi, ebp ; And our base address\n");
3271 fprintf(fp, " call PushWord ; Go push our orgval to the stack\n");
3273 else
3275 fprintf(fp, " mov dx, [esi] ; Get our call to address\n");
3276 fprintf(fp, " mov [_z80pc], dx ; Store our new program counter\n");
3277 fprintf(fp, " add esi, 2 ; Skip to our new address to be pushed\n");
3278 fprintf(fp, " sub esi, ebp ; Value to push onto the \"stack\"\n");
3279 fprintf(fp, " mov dx, word [_z80sp] ; Get the current stack pointer\n");
3280 fprintf(fp, " sub dx, 2 ; Back up two bytes\n");
3281 fprintf(fp, " mov [ebp+edx], si ; PUSH It!\n");
3282 fprintf(fp, " mov word [_z80sp], dx ; Store our new stack pointer\n");
3283 fprintf(fp, " mov si, [_z80pc] ; Get our new program counter\n");
3284 fprintf(fp, " add esi, ebp ; Naturalize it!\n");
3287 if (dwOpcode != 0xcd)
3288 fprintf(fp, "noCallTaken%" PRIu32 ":\n", dwGlobalLabel++);
3290 fprintf(fp, " xor edx, edx\n");
3291 FetchNextInstruction(dwOpcode);
3293 else
3294 if (MZ80_C == bWhat)
3296 fprintf(fp, " dwAddr = *pbPC++; /* Get LSB first */\n");
3297 fprintf(fp, " dwAddr |= ((UINT32) *pbPC++ << 8); /* Get MSB last */\n");
3299 if (0xcd != dwOpcode)
3301 fprintf(fp, " if %s\n", pbFlagsC[(dwOpcode >> 3) & 0x07]);
3302 fprintf(fp, " {\n");
3303 fprintf(fp, " cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
3304 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp - 1); /* Normalize the stack pointer */\n");
3305 fprintf(fp, " *pbSP-- = cpu.z80pc >> 8; /* MSB */\n");
3306 fprintf(fp, " *pbSP = (UINT8) cpu.z80pc; /* LSB */\n");
3307 fprintf(fp, " cpu.z80sp -= 2; /* Back our stack up */\n");
3308 fprintf(fp, " pbPC = cpu.z80Base + dwAddr; /* Normalize the address */\n");
3309 fprintf(fp, " }\n");
3311 else // Just a regular call
3313 fprintf(fp, " cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
3314 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp - 1); /* Normalize the stack pointer */\n");
3315 fprintf(fp, " *pbSP-- = cpu.z80pc >> 8; /* LSB */\n");
3316 fprintf(fp, " *pbSP = (UINT8) cpu.z80pc; /* MSB */\n");
3317 fprintf(fp, " cpu.z80sp -= 2; /* Back our stack up */\n");
3318 fprintf(fp, " pbPC = cpu.z80Base + dwAddr; /* Normalize the address */\n");
3321 else
3323 abort();
3327 void RetHandler(UINT32 dwOpcode)
3329 if (MZ80_ASSEMBLY_X86 == bWhat)
3331 ProcBegin(dwOpcode);
3333 if (dwOpcode != 0xc9)
3335 fprintf(fp, " sahf\n");
3336 fprintf(fp, " j%s takeReturn%" PRIu32 "\n", pbFlags[(dwOpcode >> 3) & 0x07], dwGlobalLabel);
3337 fprintf(fp, " jmp short retNotTaken%" PRIu32 "\n", dwGlobalLabel);
3338 fprintf(fp, "takeReturn%" PRIu32 ":\n", dwGlobalLabel);
3340 if (FALSE == bNoTiming)
3342 fprintf(fp, " sub edi, byte 6\n");
3347 if (bThroughCallHandler)
3349 fprintf(fp, " call PopWord\n");
3350 fprintf(fp, " xor esi, esi\n");
3351 fprintf(fp, " mov si, dx\n");
3352 fprintf(fp, " add esi, ebp\n");
3353 fprintf(fp, " xor edx, edx\n");
3355 else
3357 fprintf(fp, " mov dx, word [_z80sp] ; Get our current stack pointer\n");
3358 fprintf(fp, " mov si, [edx+ebp] ; Get our return address\n");
3359 fprintf(fp, " and esi, 0ffffh ; Only within 64K!\n");
3360 fprintf(fp, " add esi, ebp ; Add in our base address\n");
3361 fprintf(fp, " add word [_z80sp], 02h ; Remove our two bytes from the stack\n");
3362 fprintf(fp, " xor edx, edx\n");
3365 if (dwOpcode != 0xc9)
3366 fprintf(fp, "retNotTaken%" PRIu32 ":\n", dwGlobalLabel++);
3368 FetchNextInstruction(dwOpcode);
3370 else
3371 if (MZ80_C == bWhat)
3373 if (dwOpcode != 0xc9)
3375 fprintf(fp, " if %s\n", pbFlagsC[(dwOpcode >> 3) & 0x07]);
3376 fprintf(fp, " {\n");
3377 fprintf(fp, " dwElapsedTicks += 6;\n");
3380 fprintf(fp, " pbSP = cpu.z80Base + cpu.z80sp; /* Normalize our stack PTR */\n");
3381 fprintf(fp, " dwAddr = *pbSP++; /* Pop LSB */\n");
3382 fprintf(fp, " dwAddr |= ((UINT32) *pbSP << 8); /* Pop MSB */\n");
3383 fprintf(fp, " cpu.z80sp += 2; /* Pop the word off */\n");
3384 fprintf(fp, " pbPC = (cpu.z80Base + dwAddr); /* Point PC to our return address */\n");
3386 if (dwOpcode != 0xc9)
3388 fprintf(fp, " }\n");
3391 else
3393 abort();
3397 void RestartHandler(UINT32 dwOpcode)
3399 UINT32 dwOpcode1 = 0;
3401 dwOpcode1 = dwOpcode & 0x38;
3403 if (MZ80_ASSEMBLY_X86 == bWhat)
3405 ProcBegin(dwOpcode);
3407 if (bThroughCallHandler)
3409 fprintf(fp, " sub esi, ebp\n");
3410 fprintf(fp, " mov [_wordval], si ; Store our return address\n");
3411 fprintf(fp, " call PushWord\n");
3412 fprintf(fp, " xor esi, esi\n");
3413 fprintf(fp, " mov si, %.4" PRIx32 "h\n", dwOpcode1);
3414 fprintf(fp, " add esi, ebp\n");
3416 else
3418 fprintf(fp, " mov dx, word [_z80sp] ; Get our stack pointer\n");
3419 fprintf(fp, " sub dx, 2 ; Make room for the new value!\n");
3420 fprintf(fp, " mov word [_z80sp], dx ; Store our new stack pointer\n");
3421 fprintf(fp, " sub esi, ebp ; Get our real PC\n");
3422 fprintf(fp, " mov [ebp+edx], si ; Our return address\n");
3423 fprintf(fp, " mov si, 0%.2xh ; Our new call address\n", dwOpcode1);
3424 fprintf(fp, " add esi, ebp ; Back to the base!\n");
3427 fprintf(fp, " xor edx, edx\n");
3428 FetchNextInstruction(dwOpcode);
3430 else
3431 if (MZ80_C == bWhat)
3433 fprintf(fp, " cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
3434 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp - 1); /* Normalize the stack pointer */\n");
3435 fprintf(fp, " *pbSP-- = cpu.z80pc >> 8; /* LSB */\n");
3436 fprintf(fp, " *pbSP = (UINT8) cpu.z80pc; /* MSB */\n");
3437 fprintf(fp, " cpu.z80sp -= 2; /* Back our stack up */\n");
3438 fprintf(fp, " pbPC = cpu.z80Base + 0x%.2x; /* Normalize the address */\n", dwOpcode1);
3440 else
3442 abort();
3446 void ToRegFromHl(UINT32 dwOpcode)
3448 UINT8 bReg;
3450 bReg = (dwOpcode >> 3) & 0x07;
3452 if (MZ80_ASSEMBLY_X86 == bWhat)
3454 ProcBegin(dwOpcode);
3456 if (bReg != 2 && bReg != 3)
3457 ReadValueFromMemory("bx", pbMathReg[bReg]);
3458 else
3460 ReadValueFromMemory("bx", pbLocalReg[bReg]);
3461 fprintf(fp, " mov %s, %s\n", pbMathReg[bReg], pbLocalReg[bReg]);
3464 fprintf(fp, " xor edx, edx\n");
3465 FetchNextInstruction(dwOpcode);
3467 else
3468 if (MZ80_C == bWhat)
3470 ReadValueFromMemory("cpu.z80HL", pbLocalRegC[bReg]);
3472 else
3474 abort();
3478 void AddRegpairOperations(UINT32 dwOpcode)
3480 UINT8 bRegpair;
3482 bRegpair = (dwOpcode >> 4) & 0x3;
3484 if (MZ80_ASSEMBLY_X86 == bWhat)
3486 ProcBegin(dwOpcode);
3488 fprintf(fp, " mov dh, ah ; Get our flags\n");
3489 fprintf(fp, " and dh, 0ech ; Preserve the top three and bits 2 & 3\n");
3491 fprintf(fp, " mov [_orgval], bx ; Store our original value\n");
3492 fprintf(fp, " add bx, %s\n", pbRegPairs[bRegpair]);
3493 fprintf(fp, " lahf\n");
3495 fprintf(fp, " mov [cyclesRemaining], edi\n");
3496 fprintf(fp, " mov di, [_orgval] ; Get original\n");
3497 fprintf(fp, " xor di, bx ; XOR It with our computed value\n");
3498 fprintf(fp, " xor di, %s\n", pbRegPairs[bRegpair]);
3499 fprintf(fp, " and di, 1000h ; Just our half carry\n");
3500 fprintf(fp, " or dx, di ; Or in our flags\n");
3501 fprintf(fp, " and ah, 01h ; Just carry\n");
3502 fprintf(fp, " or ah, dh\n");
3503 fprintf(fp, " mov edi, [cyclesRemaining]\n");
3504 fprintf(fp, " xor edx, edx\n");
3506 FetchNextInstruction(dwOpcode);
3508 else
3509 if (MZ80_C == bWhat)
3511 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");
3512 fprintf(fp, " dwTemp = cpu.z80HL + %s;\n", pbRegPairsC[bRegpair]);
3513 fprintf(fp, " cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY) | (((cpu.z80HL ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", pbRegPairsC[bRegpair]);
3514 fprintf(fp, " cpu.z80HL = dwTemp & 0xffff;\n");
3516 return;
3518 else
3520 abort();
3524 void PushPopOperations(UINT32 dwOpcode)
3526 UINT8 bRegPair;
3528 bRegPair = ((dwOpcode >> 4) & 0x3) << 1;
3530 if (MZ80_ASSEMBLY_X86 == bWhat)
3532 ProcBegin(dwOpcode);
3534 if ((dwOpcode & 0xcf) == 0xc5) // Push
3536 fprintf(fp, " sub word [_z80sp], 2\n");
3537 fprintf(fp, " mov dx, [_z80sp]\n");
3538 WriteWordToMemory("dx", pbPopRegPairs[bRegPair >> 1]);
3540 else // Pop
3542 fprintf(fp, " mov dx, [_z80sp]\n");
3543 ReadWordFromMemory("dx", pbPopRegPairs[bRegPair >> 1]);
3544 fprintf(fp, " add word [_z80sp], 2\n");
3547 fprintf(fp, " xor edx, edx\n");
3548 FetchNextInstruction(dwOpcode);
3550 else
3551 if (MZ80_C == bWhat)
3553 if ((dwOpcode & 0xcf) == 0xc5) // Push?
3555 fprintf(fp, " cpu.z80sp -= 2;\n");
3556 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp); /* Normalize the stack pointer */\n");
3558 WriteWordToMemory("cpu.z80sp", pbPopRegPairC[bRegPair >> 1]);
3559 return;
3561 else
3563 ReadWordFromMemory("cpu.z80sp", pbPopRegPairC[bRegPair >> 1]);
3565 fprintf(fp, " cpu.z80sp += 2;\n");
3566 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp); /* Normalize the stack pointer */\n");
3567 return;
3570 InvalidInstructionC(1);
3572 else
3574 abort();
3578 void RraRlaHandler(UINT32 dwOpcode)
3580 if (MZ80_ASSEMBLY_X86 == bWhat)
3582 ProcBegin(dwOpcode);
3584 fprintf(fp, " sahf\n");
3585 if (dwOpcode == 0x1f)
3586 fprintf(fp, " rcr al, 1\n");
3587 else
3588 fprintf(fp, " rcl al, 1\n");
3590 fprintf(fp, " lahf\n");
3591 fprintf(fp, " and ah, 0edh\n");
3593 FetchNextInstruction(dwOpcode);
3595 else
3596 if (MZ80_C == bWhat)
3598 if (0x1f == dwOpcode) // RRA
3600 fprintf(fp, " bTemp = (cpu.z80F & Z80_FLAG_CARRY) << 7;\n");
3601 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY)) | (cpu.z80A & Z80_FLAG_CARRY);\n");
3602 fprintf(fp, " cpu.z80A = ((cpu.z80A >> 1) | bTemp);\n");
3604 else // RLA
3606 fprintf(fp, " bTemp = cpu.z80A >> 7;\n");
3607 fprintf(fp, " cpu.z80A = (cpu.z80A << 1) | (cpu.z80F & Z80_FLAG_CARRY);\n");
3608 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY)) | bTemp;\n");
3611 else
3613 abort();
3617 void LdByteRegpair(UINT32 dwOpcode)
3619 if (MZ80_ASSEMBLY_X86 == bWhat)
3621 ProcBegin(dwOpcode);
3623 if (dwOpcode == 0x0a)
3624 ReadValueFromMemory("cx", "al");
3625 if (dwOpcode == 0x1a)
3627 fprintf(fp, " mov dx, [_z80de]\n");
3628 ReadValueFromMemory("dx", "al");
3631 fprintf(fp, " xor edx, edx\n");
3632 FetchNextInstruction(dwOpcode);
3634 else
3635 if (MZ80_C == bWhat)
3637 if (dwOpcode == 0x0a)
3638 ReadValueFromMemory("cpu.z80BC", "cpu.z80A");
3639 if (dwOpcode == 0x1a)
3640 ReadValueFromMemory("cpu.z80DE", "cpu.z80A");
3642 else
3644 abort();
3648 void IncDecHLPtr(UINT32 dwOpcode)
3650 if (MZ80_ASSEMBLY_X86 == bWhat)
3652 ProcBegin(dwOpcode);
3654 ReadValueFromMemory("bx", "dl");
3656 fprintf(fp, " sahf\n");
3658 if (dwOpcode == 0x34)
3659 fprintf(fp, " inc dl\n");
3660 else
3661 fprintf(fp, " dec dl\n");
3662 fprintf(fp, " lahf\n");
3664 fprintf(fp, " o16 pushf\n");
3665 fprintf(fp, " shl edx, 16\n");
3666 fprintf(fp, " and ah, 0fbh ; Knock out parity/overflow\n");
3667 fprintf(fp, " pop dx\n");
3668 fprintf(fp, " and dh, 08h ; Just the overflow\n");
3669 fprintf(fp, " shr dh, 1 ; Shift it into position\n");
3670 fprintf(fp, " or ah, dh ; OR It in with the real flags\n");
3672 fprintf(fp, " shr edx, 16\n");
3674 if (dwOpcode == 0x34)
3675 fprintf(fp, " and ah, 0fdh ; Knock out N!\n");
3676 else
3677 fprintf(fp, " or ah, 02h ; Make it N!\n");
3679 WriteValueToMemory("bx", "dl");
3680 fprintf(fp, " xor edx, edx\n");
3682 FetchNextInstruction(dwOpcode);
3684 else
3685 if (MZ80_C == bWhat)
3687 ReadValueFromMemory("cpu.z80HL", "bTemp");
3689 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
3691 if (0x34 == dwOpcode)
3692 fprintf(fp ," cpu.z80F |= bPostIncFlags[bTemp];\n");
3693 else
3694 fprintf(fp ," cpu.z80F |= bPostDecFlags[bTemp];\n");
3696 if (0x34 == dwOpcode)
3697 fprintf(fp, " bTemp++;\n");
3698 else
3699 fprintf(fp, " bTemp--;\n");
3701 WriteValueToMemory("cpu.z80HL", "bTemp");
3702 return;
3704 else
3706 abort();
3710 void InOutHandler(UINT32 dwOpcode)
3712 if (MZ80_ASSEMBLY_X86 == bWhat)
3714 ProcBegin(dwOpcode);
3716 fprintf(fp, " mov dl, [esi] ; Get our address to 'out' to\n");
3717 fprintf(fp, " inc esi ; Next address\n");
3719 if (b16BitIo)
3721 fprintf(fp, " mov dh, al ; Upper 8 bits are the A register for 16 bit addressing\n");
3724 if (0xd3 == dwOpcode)
3725 WriteValueToIo("dx", "al");
3726 else
3727 ReadValueFromIo("dx", "al");
3729 fprintf(fp, " xor edx, edx\n");
3730 FetchNextInstruction(dwOpcode);
3732 else
3733 if (MZ80_C == bWhat)
3735 fprintf(fp ," dwTemp = *pbPC++;\n");
3737 if (0xd3 == dwOpcode)
3738 WriteValueToIo("dwTemp", "cpu.z80A");
3739 else
3740 ReadValueFromIo("dwTemp", "cpu.z80A");
3742 // Not supposed to set flags for immediate instruction!
3744 return;
3746 else
3748 abort();
3752 // CB Area
3754 void RESSETHandler(UINT32 dwOpcode)
3756 UINT8 op = 0;
3758 op = dwOpcode & 0x07;
3760 if (MZ80_ASSEMBLY_X86 == bWhat)
3762 ProcBegin(dwOpcode);
3764 if ((2 == op) || (3 == op))
3765 fprintf(fp, " mov dx, [_z80de] ; Move DE into something half usable\n");
3767 if ((dwOpcode & 0x07) == 6) // (HL)?
3768 ReadValueFromMemory("bx", "dl");
3770 if ((dwOpcode & 0xc0) == 0x80)
3771 fprintf(fp, " and %s, 0%.2xh ; Reset a bit\n",
3772 pbLocalReg[op],
3773 0xff - (1 << ((dwOpcode >> 3) & 0x7)));
3775 if ((dwOpcode & 0xc0) == 0xc0)
3776 fprintf(fp, " or %s, 0%.2xh ; Set a bit\n",
3777 pbLocalReg[op],
3778 (1 << ((dwOpcode >> 3) & 0x7)));
3780 if ((2 == op) || (3 == op))
3782 fprintf(fp, " mov [_z80de], dx ; Once modified, put it back\n");
3783 fprintf(fp, " xor edx, edx\n");
3786 if ((dwOpcode & 0x07) == 6) // (HL)?
3788 WriteValueToMemory("bx", "dl");
3789 fprintf(fp, " xor edx, edx\n");
3792 FetchNextInstruction(dwOpcode);
3794 else
3795 if (MZ80_C == bWhat)
3797 if (6 == op) // (HL)?
3798 ReadValueFromMemory("cpu.z80HL", "bTemp");
3800 if ((dwOpcode & 0xc0) == 0x80) // RES
3801 fprintf(fp, " %s &= 0x%.2x;\n", pbMathRegC[op], (UINT8) ~((UINT8) 1 << ((dwOpcode >> 3) & 0x07)));
3802 else // SET
3803 fprintf(fp, " %s |= 0x%.2x;\n", pbMathRegC[op], 1 << ((dwOpcode >> 3) & 0x07));
3805 if (6 == op) // (HL)?
3806 WriteValueToMemory("cpu.z80HL", "bTemp");
3808 else
3809 abort();
3812 void BITHandler(UINT32 dwOpcode)
3814 UINT8 op = 0;
3815 UINT8 bBitVal = 0;
3817 op = dwOpcode & 0x07;
3818 bBitVal = 1 << ((dwOpcode >> 3) & 0x07);
3820 if (MZ80_ASSEMBLY_X86 == bWhat)
3822 ProcBegin(dwOpcode);
3824 if ((dwOpcode & 0x07) == 6) // (HL)?
3825 ReadValueFromMemory("bx", "dl");
3827 fprintf(fp, " mov byte [_z80af], ah ; Store F\n");
3828 fprintf(fp, " sahf\n");
3830 if ((dwOpcode & 0x07) == 6)
3831 fprintf(fp, " test dl, 0%.2xh ; Do a bitwise check\n", 1 << ((dwOpcode >> 3) & 0x7));
3832 else
3833 fprintf(fp, " test %s, 0%.2xh ; Do a bitwise check\n", pbMathReg[op], 1 << ((dwOpcode >> 3) & 0x7));
3835 fprintf(fp, " lahf\n");
3836 fprintf(fp, " and ah, 0c0h ; Only care about Z and S\n");
3837 fprintf(fp, " or ah, 10h ; Set half carry to 1\n");
3839 fprintf(fp, " and byte [_z80af], 029h ; Only zero/non-zero!\n");
3840 fprintf(fp, " or ah, byte [_z80af] ; Put it in with the real flags\n");
3842 if (6 == (dwOpcode & 0x07)) // (HL)?
3843 fprintf(fp, " xor edx, edx\n");
3845 FetchNextInstruction(dwOpcode);
3847 else
3848 if (MZ80_C == bWhat)
3850 if (6 == op) // (HL)?
3851 ReadValueFromMemory("cpu.z80HL", "bTemp");
3853 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_ZERO);\n");
3854 fprintf(fp, " cpu.z80F |= (Z80_FLAG_HALF_CARRY);\n");
3855 fprintf(fp, " if (!(%s & 0x%.2" PRIx32 "))\n", pbMathRegC[op], bBitVal);
3856 fprintf(fp, " {\n");
3857 fprintf(fp, " cpu.z80F |= Z80_FLAG_ZERO;\n");
3858 fprintf(fp, " }\n");
3860 else
3861 abort();
3864 void RLCRRCRLRRSLASRASRLHandler(UINT32 dwOpcode)
3866 UINT8 op = 0;
3868 op = dwOpcode & 0x07;
3870 if (MZ80_ASSEMBLY_X86 == bWhat)
3872 ProcBegin(dwOpcode);
3874 if ((2 == op) || (3 == op))
3875 fprintf(fp, " mov dx, [_z80de] ; Move DE into something half usable\n");
3877 if ((dwOpcode & 0x07) == 6) // (HL)?
3878 ReadValueFromMemory("bx", "dl");
3880 fprintf(fp, " sahf\n");
3882 if ((dwOpcode & 0xf8) == 0)
3883 fprintf(fp, " rol %s, 1\n", pbLocalReg[op]);
3884 else
3885 if ((dwOpcode & 0xf8) == 0x08)
3886 fprintf(fp, " ror %s, 1\n", pbLocalReg[op]);
3887 else
3888 if ((dwOpcode & 0xf8) == 0x10)
3889 fprintf(fp, " rcl %s, 1\n", pbLocalReg[op]);
3890 else
3891 if ((dwOpcode & 0xf8) == 0x18)
3892 fprintf(fp, " rcr %s, 1\n", pbLocalReg[op]);
3893 else
3894 if ((dwOpcode & 0xf8) == 0x20 || (dwOpcode & 0xf8) == 0x30)
3895 fprintf(fp, " shl %s, 1\n", pbLocalReg[op]);
3896 else
3897 if ((dwOpcode & 0xf8) == 0x28)
3898 fprintf(fp, " sar %s, 1\n", pbLocalReg[op]);
3899 else
3900 if ((dwOpcode & 0xf8) == 0x38)
3901 fprintf(fp, " shr %s, 1\n", pbLocalReg[op]);
3902 else
3903 abort();
3905 fprintf(fp, " lahf\n");
3907 if ((dwOpcode & 0xf8) >= 0x20)
3909 if ((dwOpcode & 0xf8) == 0x30)
3910 fprintf(fp, " or %s, 1 ; Slide in a 1 bit (SLIA)\n", pbLocalReg[op]);
3911 fprintf(fp, " and ah, 0edh ; Clear H and N\n");
3913 else
3915 fprintf(fp, " and ah, 029h ; Clear H and N\n");
3916 fprintf(fp, " mov byte [_z80af], ah\n");
3918 fprintf(fp, " or %s, %s\n", pbLocalReg[op], pbLocalReg[op]);
3920 fprintf(fp, " lahf\n");
3921 fprintf(fp, " and ah, 0c4h ; Sign, zero, and parity\n");
3922 fprintf(fp, " or ah, byte [_z80af]\n");
3925 if ((2 == op) || (3 == op))
3927 fprintf(fp, " mov [_z80de], dx ; Once modified, put it back\n");
3928 fprintf(fp, " xor edx, edx\n");
3931 if ((dwOpcode & 0x07) == 6) // (HL)?
3933 WriteValueToMemory("bx", "dl");
3934 fprintf(fp, " xor edx, edx\n");
3937 FetchNextInstruction(dwOpcode);
3939 else
3940 if (MZ80_C == bWhat)
3942 if (6 == op) // (HL)?
3943 ReadValueFromMemory("cpu.z80HL", "bTemp");
3945 dwOpcode &= 0xf8; // Just the instruction
3947 if (0 == dwOpcode) // RLC
3949 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
3950 fprintf(fp, " bTemp2 = (%s >> 7);\n", pbMathRegC[op]);
3951 fprintf(fp, " %s = (%s << 1) | bTemp2;\n", pbMathRegC[op], pbMathRegC[op]);
3952 fprintf(fp, " cpu.z80F |= bTemp2 | bPostORFlags[%s];\n", pbMathRegC[op]);
3954 else
3955 if (0x08 == dwOpcode) // RRC
3957 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
3958 fprintf(fp, " cpu.z80F |= (%s & Z80_FLAG_CARRY);\n", pbMathRegC[op]);
3959 fprintf(fp, " %s = (%s >> 1) | (%s << 7);\n", pbMathRegC[op], pbMathRegC[op], pbMathRegC[op]);
3960 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);
3962 else
3963 if (0x10 == dwOpcode) // RL
3965 fprintf(fp, " bTemp2 = cpu.z80F & Z80_FLAG_CARRY;\n");
3966 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
3967 fprintf(fp, " cpu.z80F |= (%s >> 7);\n", pbMathRegC[op]);
3968 fprintf(fp, " %s = (%s << 1) | bTemp2;\n", pbMathRegC[op], pbMathRegC[op]);
3969 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);
3971 else
3972 if (0x18 == dwOpcode) // RR
3974 fprintf(fp, " bTemp2 = (cpu.z80F & Z80_FLAG_CARRY) << 7;\n");
3975 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
3976 fprintf(fp, " cpu.z80F |= (%s & Z80_FLAG_CARRY);\n", pbMathRegC[op]);
3977 fprintf(fp, " %s = (%s >> 1) | bTemp2;\n", pbMathRegC[op], pbMathRegC[op]);
3978 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);
3980 else
3981 if ((0x20 == dwOpcode) || (0x30 == dwOpcode)) // SLA/SRL
3983 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
3984 fprintf(fp, " cpu.z80F |= (%s >> 7);\n", pbMathRegC[op]);
3985 fprintf(fp, " %s = (%s << 1);\n", pbMathRegC[op], pbMathRegC[op]);
3986 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);
3988 else
3989 if (0x28 == dwOpcode) // SRA
3991 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
3992 fprintf(fp, " cpu.z80F |= (%s & Z80_FLAG_CARRY);\n", pbMathRegC[op]);
3993 fprintf(fp, " %s = (%s >> 1) | (%s & 0x80);\n", pbMathRegC[op], pbMathRegC[op], pbMathRegC[op]);
3994 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);
3996 else
3997 if (0x38 == dwOpcode) // SRL
3999 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
4000 fprintf(fp, " cpu.z80F |= (%s & Z80_FLAG_CARRY);\n", pbMathRegC[op]);
4001 fprintf(fp, " %s = (%s >> 1);\n", pbMathRegC[op], pbMathRegC[op]);
4002 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);
4004 else
4006 InvalidInstructionC(2);
4009 if (6 == op) // (HL)?
4010 WriteValueToMemory("cpu.z80HL", "bTemp");
4012 else
4013 abort();
4016 // ED Area
4018 void RRDRLDHandler(UINT32 dwOpcode)
4020 if (MZ80_ASSEMBLY_X86 == bWhat)
4022 ProcBegin(dwOpcode);
4024 ReadValueFromMemory("bx", "dl"); // Get (HL)
4025 fprintf(fp, " mov dh, dl ; Put a copy in DH\n");
4027 if (0x6f == dwOpcode) // RLD
4029 fprintf(fp, " shr dh, 4 ; Get our upper nibble in position\n");
4030 fprintf(fp, " shl dl, 4 ; Get our lower nibble into the higher position\n");
4031 fprintf(fp, " shl ecx, 16 ; Save this for later\n");
4032 fprintf(fp, " mov cl, al\n");
4033 fprintf(fp, " and cl, 0fh\n ; Only the lower nibble\n");
4034 fprintf(fp, " or dl, cl ; OR In A->(HL) transfer\n");
4035 fprintf(fp, " and al, 0f0h ; Only the upper 4 bits remain\n");
4036 fprintf(fp, " or al, dh ; OR It in to our accumulator\n");
4037 fprintf(fp, " shr ecx, 16 ; Restore this\n");
4039 else // RRD
4040 if (0x67 == dwOpcode)
4042 fprintf(fp, " shr dl, 4 ; Upper nibble to lower nibble\n");
4043 fprintf(fp, " shl ecx, 16 ; Save this\n");
4044 fprintf(fp, " mov cl, al\n");
4045 fprintf(fp, " shl cl, 4\n");
4046 fprintf(fp, " or dl, cl ; OR In what was in A\n");
4047 fprintf(fp, " and al, 0f0h ; Knock out lower part\n");
4048 fprintf(fp, " and dh, 0fh ; Only the lower nibble\n");
4049 fprintf(fp, " or al, dh ; OR In our nibble\n");
4050 fprintf(fp, " shr ecx, 16 ; Restore this\n");
4052 else // Whoops!
4053 abort();
4055 // This routine assumes that the new value to be placed at (HL) is in DL
4057 fprintf(fp, " and ah, 29h ; Retain carry & two undefined bits\n");
4058 fprintf(fp, " mov dh, ah ; Store our flags away for later\n");
4060 fprintf(fp, " or al, al ; Get our flags\n");
4061 fprintf(fp, " lahf\n");
4062 fprintf(fp, " and ah,0c4h ; Only partiy, zero, and sign\n");
4063 fprintf(fp, " or ah, dh ; OR In our old flags\n");
4065 // Now go write the value back
4067 WriteValueToMemory("bx", "dl");
4068 fprintf(fp, " xor edx, edx ; Zero out this for later\n");
4070 FetchNextInstruction(dwOpcode);
4072 else
4073 if (MZ80_C == bWhat)
4075 if (0x67 == dwOpcode) // RRD
4077 ReadValueFromMemory("cpu.z80HL", "bTemp");
4078 fprintf(fp, " bTemp2 = (cpu.z80A & 0x0f) << 4;\n");
4079 fprintf(fp, " cpu.z80A = (cpu.z80A & 0xf0) | (bTemp & 0x0f);\n");
4080 fprintf(fp, " bTemp = (bTemp >> 4) | bTemp2;\n");
4082 WriteValueToMemory("cpu.z80HL", "bTemp");
4083 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
4084 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n");
4086 else
4087 if (0x6f == dwOpcode) // RLD
4089 ReadValueFromMemory("cpu.z80HL", "bTemp");
4091 fprintf(fp, " bTemp2 = (cpu.z80A & 0x0f);\n");
4092 fprintf(fp, " cpu.z80A = (cpu.z80A & 0xf0) | (bTemp >> 4);\n");
4093 fprintf(fp, " bTemp = (bTemp << 4) | bTemp2;\n");
4095 WriteValueToMemory("cpu.z80HL", "bTemp");
4096 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
4097 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n");
4099 else
4100 InvalidInstructionC(2);
4102 else
4103 abort();
4106 void CPICPDCPIRCPDRHandler(UINT32 dwOpcode)
4108 UINT32 dwRepeatOb = 0;
4110 if (MZ80_ASSEMBLY_X86 == bWhat)
4112 ProcBegin(dwOpcode);
4114 if (dwOpcode == 0xb1 || dwOpcode == 0xb9)
4116 fprintf(fp, "cpRepeat%" PRIu32 ":\n", dwGlobalLabel);
4117 dwRepeatOb = dwGlobalLabel;
4118 ++dwGlobalLabel;
4121 // Now go get the data from the source
4123 ReadValueFromMemory("bx", "dl");
4125 // Target data is in DL
4127 fprintf(fp, " mov byte [_z80af], ah\n");
4128 fprintf(fp, " sahf\n");
4129 fprintf(fp, " cmp al, dl ; Do our comparison\n");
4130 fprintf(fp, " lahf\n");
4131 fprintf(fp, " and ah, 0fah ; No P/V or carry!\n");
4132 fprintf(fp, " dec cx ; Dec BC\n");
4133 fprintf(fp, " jz notBcZero%" PRIu32 "\n", dwGlobalLabel);
4134 fprintf(fp, " or ah, 04h ; P/V set when BC not zero\n");
4135 fprintf(fp, "notBcZero%" PRIu32 ":\n", dwGlobalLabel);
4136 fprintf(fp, " or ah, 02h ; N Gets set when we do compares\n");
4137 fprintf(fp, " mov dl, byte [_z80af]\n");
4138 fprintf(fp, " and dl, 01h\n");
4139 fprintf(fp, " or ah, dl ; Preserve carry!\n");
4141 if (dwOpcode == 0xa1 || dwOpcode == 0xb1)
4142 fprintf(fp, " inc bx ; Increment!\n");
4143 if (dwOpcode == 0xa9 || dwOpcode == 0xb9)
4144 fprintf(fp, " dec bx ; Decrement!\n");
4146 // Let's see if we repeat...
4148 if (dwOpcode == 0xb1 || dwOpcode == 0xb9)
4150 fprintf(fp, " sahf\n");
4151 fprintf(fp, " jz BCDone%" PRIu32 "\n", dwRepeatOb);
4152 fprintf(fp, " jnp BCDone%" PRIu32 "\n", dwRepeatOb);
4154 if (FALSE == bNoTiming)
4156 fprintf(fp, " sub edi, dword 21\n");
4157 fprintf(fp, " js BCDoneExit%" PRIu32 "\n", dwRepeatOb);
4160 fprintf(fp, " jmp cpRepeat%" PRIu32 "\n", dwRepeatOb);
4162 fprintf(fp, "BCDoneExit%" PRIu32 ":\n", dwRepeatOb);
4163 fprintf(fp, " sub esi, 2 ; Back up to the instruction again\n");
4164 fprintf(fp, " jmp noMoreExec\n\n");
4165 fprintf(fp, "BCDone%" PRIu32 ":\n", dwRepeatOb);
4168 fprintf(fp, " xor edx, edx\n");
4170 FetchNextInstruction(dwOpcode);
4172 else
4173 if (MZ80_C == bWhat)
4175 if (0xb1 == dwOpcode || 0xb9 == dwOpcode) // Repeat instruction?
4177 fprintf(fp, " while ((sdwCyclesRemaining >= 0) && (cpu.z80BC))\n");
4180 fprintf(fp, " {\n");
4182 ReadValueFromMemory("cpu.z80HL", "bTemp");
4184 if (0xb1 == dwOpcode || 0xa1 == dwOpcode)
4186 fprintf(fp, " cpu.z80HL++;\n");
4187 fprintf(fp, " cpu.z80HL &= 0xffff;\n");
4189 else
4191 fprintf(fp, " cpu.z80HL--;\n");
4192 fprintf(fp, " cpu.z80HL &= 0xffff;\n");
4195 fprintf(fp, " cpu.z80BC--;\n");
4196 fprintf(fp, " cpu.z80BC &= 0xffff;\n");
4198 if (0xb1 == dwOpcode || 0xb9 == dwOpcode) // Repeat?
4200 fprintf(fp, " sdwCyclesRemaining -= 16;\n");
4201 fprintf(fp, " if (cpu.z80A == bTemp)\n");
4202 fprintf(fp, " {\n");
4203 fprintf(fp, " break;\n");
4204 fprintf(fp, " }\n");
4207 fprintf(fp, " }\n");
4209 // Now figure out what's going on
4211 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
4212 fprintf(fp, " cpu.z80F |= (pbSubSbcTable[((UINT32) cpu.z80A << 8) | bTemp] & (Z80_FLAG_SIGN | Z80_FLAG_NEGATIVE | Z80_FLAG_ZERO));\n");
4213 fprintf(fp, " if (cpu.z80BC)\n");
4214 fprintf(fp, " {\n");
4215 fprintf(fp, " cpu.z80F |= Z80_FLAG_OVERFLOW_PARITY;\n");
4217 fprintf(fp, " }\n");
4219 else
4220 abort();
4223 void INIRINDRINIINDHandler(UINT32 dwOpcode)
4225 UINT32 dwTempLabel = 0;
4227 if (MZ80_ASSEMBLY_X86 == bWhat)
4229 ProcBegin(dwOpcode);
4231 dwTempLabel = dwGlobalLabel;
4232 dwGlobalLabel++;
4234 if (0xba == dwOpcode || 0xb2 == dwOpcode)
4235 fprintf(fp, "loopIt%" PRIu32 ":\n", dwTempLabel);
4237 // Fetch what's at (C) and put it in (HL)
4239 fprintf(fp, " push cx ; Save BC\n");
4241 if (b16BitIo == FALSE)
4242 fprintf(fp, " xor ch, ch ; We want 8 bit ports\n");
4244 ReadValueFromIo("cx", "*dl"); // Put our value in DL
4245 fprintf(fp, " pop cx ; Restore BC\n");
4247 WriteValueToMemory("bx", "dl");
4249 if (0xa2 == dwOpcode || 0xb2 == dwOpcode)
4250 fprintf(fp, " inc bx ; Increment HL\n");
4251 else
4252 if (0xaa == dwOpcode || 0xba == dwOpcode)
4253 fprintf(fp, " dec bx ; Decrement HL\n");
4255 // Now we decrement B
4257 fprintf(fp, " dec ch ; Decrement B (of C)\n");
4259 // Emit this instruction if we repeat
4261 if (0xba == dwOpcode || 0xb2 == dwOpcode)
4263 fprintf(fp, " jz near finalExit%" PRIu32 "\n", dwTempLabel);
4265 // Otherwise, we need to loop again
4267 if (FALSE == bNoTiming)
4269 fprintf(fp, " sub edi, dword 21\n");
4270 fprintf(fp, " js loopExit%" PRIu32 "\n", dwTempLabel);
4273 fprintf(fp, " jmp loopIt%" PRIu32 "\n\n", dwTempLabel);
4274 fprintf(fp, "loopExit%" PRIu32 ":\n", dwTempLabel);
4275 fprintf(fp, " sub esi, 2\n");
4276 fprintf(fp, " jmp noMoreExec\n\n");
4279 // Now let's fix up the flags
4281 fprintf(fp, "finalExit%" PRIu32 ":\n", dwTempLabel);
4282 fprintf(fp, " jnz clearFlag%" PRIu32 "\n", dwTempLabel);
4283 fprintf(fp, " or ah, 040h ; Set the Zero flag!\n");
4284 fprintf(fp, " jmp short continue%" PRIu32 "\n", dwTempLabel);
4285 fprintf(fp, "clearFlag%" PRIu32 ":\n", dwTempLabel);
4286 fprintf(fp, " and ah, 0bfh ; Clear the zero flag\n");
4287 fprintf(fp, "continue%" PRIu32 ":\n", dwTempLabel);
4288 fprintf(fp, " or ah, 02h ; Set negative!\n");
4289 fprintf(fp, " xor edx, edx\n");
4290 FetchNextInstruction(dwOpcode);
4292 else
4293 if (MZ80_C == bWhat)
4295 if (0xb2 == dwOpcode || 0xba == dwOpcode) // Repeat instruction?
4297 fprintf(fp, " while ((sdwCyclesRemaining > 0) && (cpu.z80B))\n");
4300 fprintf(fp, " {\n");
4302 ReadValueFromIo("cpu.z80B", "bTemp");
4303 WriteValueToMemory("cpu.z80HL", "bTemp");
4305 if (0xb2 == dwOpcode || 0xa2 == dwOpcode)
4307 fprintf(fp, " cpu.z80HL++;\n");
4308 fprintf(fp, " cpu.z80HL &= 0xffff;\n");
4310 else
4312 fprintf(fp, " cpu.z80HL--;\n");
4313 fprintf(fp, " cpu.z80HL &= 0xffff;\n");
4316 fprintf(fp, " sdwCyclesRemaining -= 16;\n");
4318 fprintf(fp, " cpu.z80B--;\n");
4319 fprintf(fp, " }\n");
4321 // Now figure out what's going on
4323 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
4324 fprintf(fp, " cpu.z80F |= (bPostORFlags[bTemp] & (Z80_FLAG_SIGN | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY));\n");
4325 fprintf(fp, " if (cpu.z80B)\n");
4326 fprintf(fp, " {\n");
4327 fprintf(fp, " cpu.z80F |= Z80_FLAG_OVERFLOW_PARITY;\n");
4329 fprintf(fp, " pbPC -= 2;\n");
4331 fprintf(fp, " }\n");
4333 else
4334 abort();
4337 void OTIROTDROUTIOUTDHandler(UINT32 dwOpcode)
4339 UINT32 dwTempLabel = 0;
4341 if (MZ80_ASSEMBLY_X86 == bWhat)
4343 ProcBegin(dwOpcode);
4345 dwTempLabel = dwGlobalLabel;
4346 dwGlobalLabel++;
4348 if (0xbb == dwOpcode || 0xb3 == dwOpcode)
4349 fprintf(fp, "loopIt%" PRIu32 ":\n", dwTempLabel);
4351 // Fetch what's at (HL) and put it in DL
4353 ReadValueFromMemory("bx", "dl");
4355 fprintf(fp, " push cx ; Save BC\n");
4356 if (b16BitIo == FALSE)
4357 fprintf(fp, " xor ch, ch ; No 16 bit for this instruction!\n");
4358 WriteValueToIo("cx", "dl");
4359 fprintf(fp, " pop cx ; Restore BC now that it has been \"OUT\"ed\n");
4361 if (0xa3 == dwOpcode || 0xb3 == dwOpcode)
4362 fprintf(fp, " inc bx ; Increment HL\n");
4363 else
4364 if (0xab == dwOpcode || 0xbb == dwOpcode)
4365 fprintf(fp, " dec bx ; Decrement HL\n");
4367 // Now we decrement B
4369 fprintf(fp, " dec ch ; Decrement B (of C)\n");
4371 // Emit this instruction if we repeat
4373 if (0xbb == dwOpcode || 0xb3 == dwOpcode)
4375 fprintf(fp, " jz near finalExit%" PRIu32 "\n", dwTempLabel);
4377 // Otherwise, we need to loop again
4379 if (FALSE == bNoTiming)
4381 fprintf(fp, " sub edi, dword 21\n");
4382 fprintf(fp, " js loopExit%" PRIu32 "\n", dwTempLabel);
4385 fprintf(fp, " jmp loopIt%" PRIu32 "\n\n", dwTempLabel);
4386 fprintf(fp, "loopExit%" PRIu32 ":\n", dwTempLabel);
4387 fprintf(fp, " sub esi, 2\n");
4388 fprintf(fp, " jmp noMoreExec\n\n");
4391 // Now let's fix up the flags
4393 fprintf(fp, "finalExit%" PRIu32 ":\n", dwTempLabel);
4394 fprintf(fp, " jnz clearFlag%" PRIu32 "\n", dwTempLabel);
4395 fprintf(fp, " or ah, 040h ; Set the Zero flag!\n");
4396 fprintf(fp, " jmp short continue%" PRIu32 "\n", dwTempLabel);
4397 fprintf(fp, "clearFlag%" PRIu32 ":\n", dwTempLabel);
4398 fprintf(fp, " and ah, 0bfh ; Clear the zero flag\n");
4399 fprintf(fp, "continue%" PRIu32 ":\n", dwTempLabel);
4400 fprintf(fp, " or ah, 02h ; Set negative!\n");
4401 fprintf(fp, " xor edx, edx\n");
4402 FetchNextInstruction(dwOpcode);
4404 else
4405 if (MZ80_C == bWhat)
4407 if (0xb3 == dwOpcode || 0xbb == dwOpcode) // Repeat instruction?
4409 fprintf(fp, " while ((sdwCyclesRemaining > 0) && (cpu.z80B))\n");
4412 fprintf(fp, " {\n");
4414 ReadValueFromMemory("cpu.z80HL", "bTemp");
4415 WriteValueToIo("cpu.z80BC", "bTemp");
4417 if (0xb3 == dwOpcode || 0xa3 == dwOpcode)
4419 fprintf(fp, " cpu.z80HL++;\n");
4420 fprintf(fp, " cpu.z80HL &= 0xffff;\n");
4422 else
4424 fprintf(fp, " cpu.z80HL--;\n");
4425 fprintf(fp, " cpu.z80HL &= 0xffff;\n");
4428 fprintf(fp, " sdwCyclesRemaining -= 16;\n");
4430 fprintf(fp, " cpu.z80B--;\n");
4431 fprintf(fp, " }\n");
4433 // Now figure out what's going on
4435 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
4436 fprintf(fp, " cpu.z80F |= (bPostORFlags[bTemp] & (Z80_FLAG_SIGN | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY));\n");
4437 fprintf(fp, " if (cpu.z80B)\n");
4438 fprintf(fp, " {\n");
4439 fprintf(fp, " cpu.z80F |= Z80_FLAG_OVERFLOW_PARITY;\n");
4441 fprintf(fp, " }\n");
4443 else
4444 abort();
4447 void AdcSbcRegpair(UINT32 dwOpcode)
4449 UINT8 bOp = 0;
4451 bOp = (dwOpcode >> 4) & 0x03;
4453 if (MZ80_ASSEMBLY_X86 == bWhat)
4455 ProcBegin(dwOpcode);
4457 fprintf(fp, " mov dx, %s ; Get our original register\n", pbRegPairs[bOp]);
4458 fprintf(fp, " mov [_orgval], dx ; Store this for later half carry computation\n");
4459 fprintf(fp, " mov [_orgval2], bx ; Store this, too\n");
4460 fprintf(fp, " sahf ; Restore our flags\n");
4462 if ((dwOpcode & 0xcf) == 0x4a)
4463 fprintf(fp, " adc bx, dx ; Do the operation!\n");
4464 else
4465 fprintf(fp, " sbb bx, dx ; Do the operation!\n");
4467 fprintf(fp, " lahf ; Get our new flags\n");
4469 if ((dwOpcode & 0xcf) != 0x4a)
4471 SetOverflow();
4472 fprintf(fp, " and ah, 0edh ; Knock out negative & half carry flags\n");
4473 fprintf(fp, " or ah, 02h ; Negative!\n");
4474 fprintf(fp, " mov [_z80hl], bx\n");
4475 fprintf(fp, " xor bx, [_orgval]\n");
4476 fprintf(fp, " xor bx, [_orgval2]\n");
4477 fprintf(fp, " and bh, 10h ; Half carry?\n");
4478 fprintf(fp, " or ah, bh ; OR It in if so\n");
4479 fprintf(fp, " mov bx, [_z80hl]\n");
4481 else
4483 SetOverflow();
4484 fprintf(fp, " and ah, 0edh ; Knock out negative & half carry flags\n");
4485 fprintf(fp, " mov [_z80hl], bx\n");
4486 fprintf(fp, " xor bx, [_orgval]\n");
4487 fprintf(fp, " xor bx, [_orgval2]\n");
4488 fprintf(fp, " and bh, 10h ; Half carry?\n");
4489 fprintf(fp, " or ah, bh ; OR It in if so\n");
4490 fprintf(fp, " mov bx, [_z80hl]\n");
4493 fprintf(fp, " xor edx, edx ; Make sure we don't hose things\n");
4494 FetchNextInstruction(dwOpcode);
4496 else
4497 if (MZ80_C == bWhat)
4499 if ((dwOpcode & 0xcf) == 0x4a) // ADC
4501 fprintf(fp, " dwTemp = cpu.z80HL + %s + (cpu.z80F & Z80_FLAG_CARRY);\n", pbRegPairsC[bOp]);
4502 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
4503 fprintf(fp, " cpu.z80F |= ((dwTemp >> 8) & Z80_FLAG_SIGN);\n");
4504 fprintf(fp, " if (0 == (dwTemp & 0xffff))\n");
4505 fprintf(fp, " {\n");
4506 fprintf(fp, " cpu.z80F |= Z80_FLAG_ZERO;\n");
4507 fprintf(fp, " }\n");
4508 fprintf(fp, " cpu.z80F |= (((cpu.z80HL ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", pbRegPairsC[bOp]);
4509 fprintf(fp, " cpu.z80F |= ((((%s ^ cpu.z80HL ^ 0x8000) & (%s ^ dwTemp)) >> 13) & Z80_FLAG_OVERFLOW_PARITY);\n", pbRegPairsC[bOp], pbRegPairsC[bOp]);
4510 fprintf(fp, " cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY);\n");
4511 fprintf(fp, " cpu.z80HL = dwTemp & 0xffff;\n");
4512 return;
4514 else // SBC
4516 fprintf(fp, " dwTemp = cpu.z80HL - %s - (cpu.z80F & Z80_FLAG_CARRY);\n", pbRegPairsC[bOp]);
4517 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
4518 fprintf(fp, " cpu.z80F |= ((dwTemp >> 8) & Z80_FLAG_SIGN);\n");
4519 fprintf(fp, " if (0 == (dwTemp & 0xffff))\n");
4520 fprintf(fp, " {\n");
4521 fprintf(fp, " cpu.z80F |= Z80_FLAG_ZERO;\n");
4522 fprintf(fp, " }\n");
4523 fprintf(fp, " cpu.z80F |= (((cpu.z80HL ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", pbRegPairsC[bOp]);
4524 fprintf(fp, " cpu.z80F |= ((((%s ^ cpu.z80HL) & (%s ^ dwTemp)) >> 13) & Z80_FLAG_OVERFLOW_PARITY);\n", pbRegPairsC[bOp], pbRegPairsC[bOp]);
4525 fprintf(fp, " cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY);\n");
4526 fprintf(fp, " cpu.z80HL = dwTemp & 0xffff;\n");
4527 return;
4530 else
4531 abort();
4534 void RetIRetNHandler(UINT32 dwOpcode)
4536 if (MZ80_ASSEMBLY_X86 == bWhat)
4538 ProcBegin(dwOpcode);
4540 if (bThroughCallHandler)
4542 fprintf(fp, " call PopWord\n");
4543 fprintf(fp, " xor esi, esi\n");
4544 fprintf(fp, " mov si, dx\n");
4545 fprintf(fp, " add esi, ebp\n");
4547 else
4549 fprintf(fp, " mov dx, word [_z80sp] ; Get our current stack pointer\n");
4550 fprintf(fp, " mov si, [edx+ebp] ; Get our return address\n");
4551 fprintf(fp, " and esi, 0ffffh ; Only within 64K!\n");
4552 fprintf(fp, " add esi, ebp ; Add in our base address\n");
4553 fprintf(fp, " add word [_z80sp], 02h ; Remove our two bytes from the stack\n");
4556 if (dwOpcode == 0x45)
4558 fprintf(fp, " xor edx, edx\n");
4559 fprintf(fp, " mov dl, [_z80iff] ; Get interrupt flags\n");
4560 fprintf(fp, " shr dl, 1 ; Move IFF2->IFF1\n");
4561 fprintf(fp, " and [_z80iff], dword (~IFF1) ; Get rid of IFF 1\n");
4562 fprintf(fp, " and dl, IFF1 ; Just want the IFF 1 value now\n");
4563 fprintf(fp, " or dword [_z80iff], edx\n");
4566 fprintf(fp, " xor edx, edx ; Make sure we don't hose things\n");
4567 FetchNextInstruction(dwOpcode);
4569 else
4570 if (MZ80_C == bWhat)
4572 if (0x4d == dwOpcode) // RETI
4574 fprintf(fp, " pbSP = cpu.z80Base + cpu.z80sp; /* Normalize our stack PTR */\n");
4575 fprintf(fp, " dwAddr = *pbSP++; /* Pop LSB */\n");
4576 fprintf(fp, " dwAddr |= ((UINT32) *pbSP << 8); /* Pop MSB */\n");
4577 fprintf(fp, " cpu.z80sp += 2; /* Pop the word off */\n");
4578 fprintf(fp, " pbPC = (cpu.z80Base + dwAddr); /* Point PC to our return address */\n");
4580 else
4581 if (0x45 == dwOpcode) // RETN
4583 fprintf(fp, " pbSP = cpu.z80Base + cpu.z80sp; /* Normalize our stack PTR */\n");
4584 fprintf(fp, " dwAddr = *pbSP++; /* Pop LSB */\n");
4585 fprintf(fp, " dwAddr |= ((UINT32) *pbSP << 8); /* Pop MSB */\n");
4586 fprintf(fp, " cpu.z80sp += 2; /* Pop the word off */\n");
4587 fprintf(fp, " pbPC = (cpu.z80Base + dwAddr); /* Point PC to our return address */\n");
4588 fprintf(fp, " cpu.z80iff &= ~(IFF1); /* Keep IFF2 around */\n");
4589 fprintf(fp, " cpu.z80iff |= ((cpu.z80iff >> 1) & IFF1); /* IFF2->IFF1 */\n");
4591 else
4593 InvalidInstructionC(2);
4596 else
4597 abort();
4600 void ExtendedOutHandler(UINT32 dwOpcode)
4602 if (MZ80_ASSEMBLY_X86 == bWhat)
4604 ProcBegin(dwOpcode);
4606 if (b16BitIo == FALSE)
4607 fprintf(fp, " mov dl, cl ; Address in DX... (C)\n");
4608 else
4609 fprintf(fp, " mov dx, cx ; Address in DX... (BC)\n");
4611 WriteValueToIo("dx", pbMathReg[(dwOpcode >> 3) & 0x07]);
4613 fprintf(fp, " xor edx, edx\n");
4614 FetchNextInstruction(dwOpcode);
4616 else
4617 if (MZ80_C == bWhat)
4619 if (b16BitIo == FALSE)
4620 fprintf(fp, " dwAddr = cpu.z80C;\n");
4621 else
4622 fprintf(fp, " dwAddr = cpu.z80BC;\n");
4624 WriteValueToIo("dwAddr", pbMathRegC[(dwOpcode >> 3) & 0x07]);
4626 else
4627 abort();
4630 void ExtendedInHandler(UINT32 dwOpcode)
4632 if (MZ80_ASSEMBLY_X86 == bWhat)
4634 ProcBegin(dwOpcode);
4636 if (b16BitIo == FALSE)
4637 fprintf(fp, " mov dl, cl ; Address in DX... (C)\n");
4638 else
4639 fprintf(fp, " mov dx, cx ; Address in DX... (BC)\n");
4641 ReadValueFromIo("dx", pbMathReg[(dwOpcode >> 3) & 0x07]);
4643 fprintf(fp, ";\n; Remember, this variant of the IN instruction modifies the flags\n;\n\n");
4644 fprintf(fp, " sahf ; Restore our flags\n");
4645 fprintf(fp, " mov dh, ah ; Save flags for later\n");
4647 if (0x50 == dwOpcode || 0x58 == dwOpcode)
4649 fprintf(fp, " mov dl, %s\n", pbMathReg[(dwOpcode >> 3) & 0x07]);
4650 fprintf(fp, " or dl, dl\n");
4652 else
4653 fprintf(fp, " or %s, %s;\n", pbMathReg[(dwOpcode >> 3) & 0x07], pbMathReg[(dwOpcode >> 3) & 0x07]);
4655 fprintf(fp, " lahf\n");
4656 fprintf(fp, " and dh, 029h ; Only keep carry and two unused flags\n");
4657 fprintf(fp, " and ah, 0d4h\n");
4658 fprintf(fp, " or ah, dh\n");
4660 fprintf(fp, " xor edx, edx\n");
4662 FetchNextInstruction(dwOpcode);
4664 else
4665 if (MZ80_C == bWhat)
4667 if (b16BitIo == FALSE)
4668 fprintf(fp, " dwAddr = cpu.z80C;\n");
4669 else
4670 fprintf(fp, " dwAddr = cpu.z80BC;\n");
4672 ReadValueFromIo("dwAddr", pbMathRegC[(dwOpcode >> 3) & 0x07]);
4674 // Set flags!
4676 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
4677 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[(dwOpcode >> 3) & 0x07]);
4679 else
4680 abort();
4683 void NegHandler(UINT32 dwOpcode)
4685 if (MZ80_ASSEMBLY_X86 == bWhat)
4687 ProcBegin(dwOpcode);
4689 fprintf(fp, " sahf\n");
4690 fprintf(fp, " sub dh, al\n");
4691 fprintf(fp, " lahf\n");
4692 fprintf(fp, " mov al, dh\n");
4694 SetOverflow();
4695 fprintf(fp, " or ah, 02h\n");
4696 fprintf(fp, " xor edx, edx\n");
4698 FetchNextInstruction(dwOpcode);
4700 else
4701 if (MZ80_C == bWhat)
4703 SetSubFlagsSZHVC("0", "cpu.z80A");
4704 fprintf(fp, " cpu.z80A = 0 - cpu.z80A;\n");
4706 else
4707 abort();
4710 void ExtendedRegIntoMemory(UINT32 dwOpcode)
4712 if (MZ80_ASSEMBLY_X86 == bWhat)
4714 ProcBegin(dwOpcode);
4716 fprintf(fp, " mov dx, [esi] ; Get our address to write to\n");
4717 fprintf(fp, " add esi, 2 ; Next address, please...\n");
4719 if (dwOpcode == 0x43)
4720 WriteValueToMemory("dx", "cl");
4721 if (dwOpcode == 0x53)
4722 WriteValueToMemory("dx", "byte [_z80de]");
4723 if (dwOpcode == 0x63)
4724 WriteValueToMemory("dx", "bl");
4725 if (dwOpcode == 0x73)
4726 WriteValueToMemory("dx", "byte [_z80sp]");
4728 fprintf(fp, " inc dx\n");
4730 if (dwOpcode == 0x43)
4731 WriteValueToMemory("dx", "ch");
4732 if (dwOpcode == 0x53)
4733 WriteValueToMemory("dx", "byte [_z80de + 1]");
4734 if (dwOpcode == 0x63)
4735 WriteValueToMemory("dx", "bh");
4736 if (dwOpcode == 0x73)
4737 WriteValueToMemory("dx", "byte [_z80sp + 1]");
4739 fprintf(fp, " xor edx, edx ; Zero our upper word\n");
4741 FetchNextInstruction(dwOpcode);
4743 else
4744 if (MZ80_C == bWhat)
4746 fprintf(fp, " dwTemp = *pbPC++;\n");
4747 fprintf(fp, " dwTemp |= ((UINT32) *pbPC++ << 8);\n");
4749 if (0x43 == dwOpcode) // LD (xxxxh), BC
4750 WriteWordToMemory("dwTemp", "cpu.z80BC");
4751 if (0x53 == dwOpcode) // LD (xxxxh), DE
4752 WriteWordToMemory("dwTemp", "cpu.z80DE");
4753 if (0x63 == dwOpcode) // LD (xxxxh), HL
4754 WriteWordToMemory("dwTemp", "cpu.z80HL");
4755 if (0x73 == dwOpcode) // LD (xxxxh), SP
4756 WriteWordToMemory("dwTemp", "cpu.z80sp");
4758 else
4759 abort();
4762 void LdRegpair(UINT32 dwOpcode)
4764 if (MZ80_ASSEMBLY_X86 == bWhat)
4766 ProcBegin(dwOpcode);
4768 fprintf(fp, " mov dx, [esi] ; Get address to load\n");
4769 fprintf(fp, " add esi, 2 ; Skip over it so we don't execute it\n");
4771 if (dwOpcode == 0x4b)
4772 ReadValueFromMemory("dx", "cl");
4773 if (dwOpcode == 0x5b)
4774 ReadValueFromMemory("dx", "byte [_z80de]");
4775 if (dwOpcode == 0x7b)
4776 ReadValueFromMemory("dx", "byte [_z80sp]");
4778 fprintf(fp, " inc dx\n");
4780 if (dwOpcode == 0x4b)
4781 ReadValueFromMemory("dx", "ch");
4782 if (dwOpcode == 0x5b)
4783 ReadValueFromMemory("dx", "byte [_z80de + 1]");
4784 if (dwOpcode == 0x7b)
4785 ReadValueFromMemory("dx", "byte [_z80sp + 1]");
4787 fprintf(fp, " xor edx, edx\n");
4789 FetchNextInstruction(dwOpcode);
4791 else
4792 if (MZ80_C == bWhat)
4794 fprintf(fp, " dwTemp = *pbPC++;\n");
4795 fprintf(fp, " dwTemp |= ((UINT32) *pbPC++ << 8);\n");
4797 if (0x4b == dwOpcode)
4798 ReadWordFromMemory("dwTemp", "cpu.z80BC");
4799 if (0x5b == dwOpcode)
4800 ReadWordFromMemory("dwTemp", "cpu.z80DE");
4801 if (0x7b == dwOpcode)
4802 ReadWordFromMemory("dwTemp", "cpu.z80sp");
4804 else
4805 abort();
4808 void LDILDRLDIRLDDRHandler(UINT32 dwOpcode)
4810 UINT32 dwOrgGlobal = 0;
4812 if (MZ80_ASSEMBLY_X86 == bWhat)
4814 ProcBegin(dwOpcode);
4816 if (dwOpcode == 0xb0 || dwOpcode == 0xb8)
4818 dwOrgGlobal = dwGlobalLabel;
4819 fprintf(fp, "ldRepeat%" PRIu32 ":\n", dwGlobalLabel);
4822 ReadValueFromMemory("bx", "dl");
4824 // Here we write the byte back to the target
4826 WriteValueToMemory("[_z80de]", "dl");
4828 // Now we decide what to do
4830 if ((dwOpcode & 0x0f) == 0)
4832 fprintf(fp, " inc bx ; Increment HL\n");
4833 fprintf(fp, " inc word [_z80de] ; Increment DE\n");
4835 else
4837 fprintf(fp, " dec bx ; Decrement HL\n");
4838 fprintf(fp, " dec word [_z80de] ; Decrement DE\n");
4841 fprintf(fp, " dec cx ; Decrement BC\n");
4843 if (dwOpcode == 0xb0 || dwOpcode == 0xb8)
4845 if (FALSE == bNoTiming)
4847 fprintf(fp, " jz noMore%" PRIu32 "\n", dwGlobalLabel);
4848 fprintf(fp, " sub edi, dword 16 ; 16 T-States per iteration\n");
4849 fprintf(fp, " js noMore%" PRIu32 "\n", dwGlobalLabel);
4851 else
4853 fprintf(fp, " jz noMore%" PRIu32 "\n", dwGlobalLabel);
4856 fprintf(fp, " jmp ldRepeat%" PRIu32 " ; Loop until we're done!\n", dwOrgGlobal);
4857 fprintf(fp, "noMore%" PRIu32 ":\n", dwGlobalLabel);
4860 fprintf(fp, " and ah, 0e9h ; Knock out H & N and P/V\n");
4861 fprintf(fp, " or cx, cx ; Flag BC\n");
4862 fprintf(fp, " jz atZero%" PRIu32 " ; We're done!\n", dwGlobalLabel);
4864 if (dwOpcode == 0xb0 || dwOpcode == 0xb8)
4866 // It's a repeat, so let's readjust ESI, shall we?
4868 fprintf(fp, " or ah, 04h ; Non-zero - we're still going!\n");
4869 fprintf(fp, " sub esi, 2 ; Adjust back to the beginning of the instruction\n");
4870 fprintf(fp, " jmp noMoreExec\n\n");
4872 else
4873 if (dwOpcode == 0xa0 || dwOpcode == 0xa8)
4875 fprintf(fp, " or ah, 04h ; Non-zero - we're still going!\n");
4878 fprintf(fp, "atZero%" PRIu32 ":\n", dwGlobalLabel);
4879 ++dwGlobalLabel;
4881 fprintf(fp, " xor edx, edx ; Make sure we don't hose things\n");
4882 FetchNextInstruction(dwOpcode);
4884 else
4885 if (MZ80_C == bWhat)
4887 // This is the actual move
4889 if (0xb0 == dwOpcode || 0xb8 == dwOpcode) // Repeat instruction?
4891 fprintf(fp, " while ((sdwCyclesRemaining > 0) && (cpu.z80BC))\n");
4893 fprintf(fp, " {\n");
4896 ReadValueFromMemory("cpu.z80HL", "bTemp");
4897 WriteValueToMemory("cpu.z80DE", "bTemp");
4899 if ((dwOpcode & 0x0f) == 0)
4901 fprintf(fp, " ++cpu.z80HL;\n");
4902 fprintf(fp, " ++cpu.z80DE;\n");
4904 else
4906 fprintf(fp, " --cpu.z80HL;\n");
4907 fprintf(fp, " --cpu.z80DE;\n");
4910 fprintf(fp, " --cpu.z80BC;\n");
4911 fprintf(fp, " cpu.z80HL &= 0xffff;\n");
4912 fprintf(fp, " cpu.z80DE &= 0xffff;\n");
4913 fprintf(fp, " cpu.z80BC &= 0xffff;\n");
4915 if (0xb0 == dwOpcode || 0xb8 == dwOpcode) // Repeat instruction?
4917 fprintf(fp, " sdwCyclesRemaining -= 21;\n");
4919 fprintf(fp, " }\n");
4922 // Time for a flag fixup!
4924 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY);\n");
4925 fprintf(fp, " if (cpu.z80BC)\n");
4926 fprintf(fp, " {\n");
4928 if (0xb0 == dwOpcode || 0xb8 == dwOpcode)
4930 fprintf(fp, " pbPC -= 2; /* Back up so we hit this instruction again */\n");
4933 fprintf(fp, " cpu.z80F |= Z80_FLAG_OVERFLOW_PARITY;\n");
4934 fprintf(fp, " }\n");
4936 if (0xb0 == dwOpcode || 0xb8 == dwOpcode) // Repeat instruction?
4938 fprintf(fp, " sdwCyclesRemaining -= 16;\n");
4941 else
4942 abort();
4945 void IMHandler(UINT32 dwOpcode)
4947 if (MZ80_ASSEMBLY_X86 == bWhat)
4949 ProcBegin(dwOpcode);
4951 if (dwOpcode == 0x46)
4952 fprintf(fp, " mov dword [_z80interruptMode], 0 ; IM 0\n");
4954 if (dwOpcode == 0x56)
4956 fprintf(fp, " mov dword [_z80interruptMode], 1 ; Interrupt mode 1\n");
4957 fprintf(fp, " mov word [_z80intAddr], 038h ; Interrupt mode 1 cmd!\n");
4960 if (dwOpcode == 0x5e)
4961 fprintf(fp, " mov dword [_z80interruptMode], 2 ; IM 2\n");
4963 FetchNextInstruction(dwOpcode);
4965 else
4966 if (MZ80_C == bWhat)
4968 if (0x46 == dwOpcode) // IM 0
4969 fprintf(fp, " cpu.z80interruptMode = 0;\n");
4971 if (0x56 == dwOpcode) // IM 1
4973 fprintf(fp, " cpu.z80interruptMode = 1;\n");
4974 fprintf(fp, " cpu.z80intAddr = 0x38;\n");
4977 if (0x5e == dwOpcode) // IM 2
4978 fprintf(fp, " cpu.z80interruptMode = 2;\n");
4980 else
4981 abort();
4985 void IRHandler(UINT32 dwOpcode)
4987 char *src, *dst;
4989 if (MZ80_ASSEMBLY_X86 == bWhat)
4991 switch(dwOpcode)
4993 case 0x57:
4994 dst = "al"; src="[_z80i]"; break;
4995 case 0x5F:
4996 dst = "al"; src="[_z80r]"; break;
4997 case 0x47:
4998 dst = "[_z80i]"; src="al"; break;
4999 case 0x4F:
5000 dst = "[_z80r]"; src="al"; break;
5001 default:
5002 abort();
5005 ProcBegin(dwOpcode);
5007 fprintf(fp, " mov %s, %s\n",dst,src);
5009 if (dwOpcode == 0x5f)
5011 fprintf(fp, " and ah, 029h ; No N, H, Z, or S!\n");
5012 fprintf(fp, " or al,al ; Get appropriate flags\n");
5013 fprintf(fp, " o16 pushf\n");
5014 fprintf(fp, " pop dx\n");
5015 fprintf(fp, " and dl, 0c0h\n");
5016 fprintf(fp, " or ah, dl ; OR In our S & Z flags\n");
5018 fprintf(fp, " mov dl, [_z80iff]\n");
5019 fprintf(fp, " and dl, IFF2\n");
5020 fprintf(fp, " shl dl, 1\n");
5021 fprintf(fp, " or ah, dl\n");
5023 // Randomize R
5025 fprintf(fp, " mov edx, [dwLastRSample]\n");
5026 fprintf(fp, " sub edx, edi\n");
5027 fprintf(fp, " add edx, [_z80rCounter]\n");
5028 fprintf(fp, " shr edx, 2\n");
5029 fprintf(fp, " and edx, 07fh\n");
5030 fprintf(fp, " and byte [_z80r], 80h\n");
5031 fprintf(fp, " or byte [_z80r], dl\n");
5033 fprintf(fp, " xor edx, edx\n");
5034 fprintf(fp, " mov [dwLastRSample], edi\n");
5037 FetchNextInstruction(dwOpcode);
5039 else
5040 if (MZ80_C == bWhat)
5042 if (0x5f == dwOpcode) // LD A, R
5044 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
5045 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80r];\n");
5046 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_OVERFLOW_PARITY)) | ((cpu.z80iff & IFF2) << 1);\n");
5047 fprintf(fp, " cpu.z80A = cpu.z80r;\n");
5049 // Now randomize a little
5051 fprintf(fp, " bTemp = (cpu.z80r + (cpu.z80B + sdwCyclesRemaining + 1 + cpu.z80H)) ^ cpu.z80A;\n");
5052 fprintf(fp, " cpu.z80r = (cpu.z80r & 0x80) | (bTemp & 0x7f);\n");
5054 else
5055 if (0x47 == dwOpcode) // LD I, A
5057 fprintf(fp, " cpu.z80i = cpu.z80A;\n");
5059 else
5060 if (0x57 == dwOpcode) // LD A, I
5062 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
5063 fprintf(fp, " cpu.z80F |= ((cpu.z80iff & IFF2) << 1);\n");
5064 fprintf(fp, " cpu.z80A = cpu.z80i;\n");
5065 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n");
5067 else
5068 if (0x4f == dwOpcode) // LD R, A
5070 fprintf(fp, " cpu.z80r = cpu.z80A;\n");
5072 else
5074 InvalidInstructionC(2);
5077 else
5078 abort();
5081 // DD/FD Area
5083 void DDFDCBHandler(UINT32 dwOpcode)
5085 UINT32 dwData = 0;
5087 if (MZ80_ASSEMBLY_X86 == bWhat)
5089 fprintf(fp, "%sInst%.2x:\n", majorOp, dwOpcode);
5090 fprintf(fp, " mov dx, [esi] ; Get our instruction (and offset)\n");
5091 fprintf(fp, " add esi, 2 ; Increment our PC\n");
5093 fprintf(fp, " mov byte [_orgval], dl ; Store our value\n");
5094 fprintf(fp, " or dl, dl\n");
5095 fprintf(fp, " js notNeg%" PRIu32 "\n", dwGlobalLabel);
5096 fprintf(fp, " mov byte [_orgval + 1], 00h;\n");
5098 fprintf(fp, " jmp short jumpHandler%" PRIu32 "\n", dwGlobalLabel);
5099 fprintf(fp, "notNeg%" PRIu32 ":\n", dwGlobalLabel);
5100 fprintf(fp, " mov byte [_orgval + 1], 0ffh; It's negative\n");
5101 fprintf(fp, "jumpHandler%" PRIu32 ":\n", dwGlobalLabel++);
5102 fprintf(fp, " shl ebx, 16 ; Save BX away\n");
5103 fprintf(fp, " mov bx, [_z80%s]\n", mz80Index);
5104 fprintf(fp, " add [_orgval], bx\n");
5105 fprintf(fp, " shr ebx, 16 ; Restore BX\n");
5106 fprintf(fp, " mov dl, dh ; Get our instruction\n");
5107 fprintf(fp, " xor dh, dh ; Zero this\n");
5108 fprintf(fp, " jmp dword [z80ddfdcbInstructions+edx*4]\n\n");
5110 else
5111 if (MZ80_C == bWhat)
5113 if (strcmp("cpu.z80IX", mz80Index) == 0)
5114 dwData = 0;
5115 else
5116 dwData = 1;
5118 fprintf(fp, " DDFDCBHandler(%d);\n", dwData);
5120 else
5121 abort();
5124 void LoadIndexReg(UINT32 dwOpcode)
5126 INT8 string[150];
5128 if (MZ80_ASSEMBLY_X86 == bWhat)
5130 ProcBegin(dwOpcode);
5132 sprintf(string, "[_z80%s]", mz80Index);
5134 fprintf(fp, " mov dx, [esi] ; Get our address to store\n");
5135 fprintf(fp, " add esi, 2\n");
5137 ReadWordFromMemory("dx", string);
5138 fprintf(fp, " xor edx, edx\n");
5139 FetchNextInstruction(dwOpcode);
5141 else
5142 if (MZ80_C == bWhat)
5144 fprintf(fp, " dwAddr = *pbPC++;\n");
5145 fprintf(fp, " dwAddr |= ((UINT32) *pbPC++ << 8);\n");
5146 ReadWordFromMemory("dwAddr", mz80Index);
5148 else
5149 abort();
5152 void StoreIndexReg(UINT32 dwOpcode)
5154 if (MZ80_ASSEMBLY_X86 == bWhat)
5156 ProcBegin(dwOpcode);
5158 fprintf(fp, " mov dx, [esi] ; Get our address to store\n");
5159 fprintf(fp, " add esi, 2\n");
5160 fprintf(fp, " mov [_orgval], dx\n");
5162 fprintf(fp, " mov dl, [_z80%s]\n", mz80Index);
5163 WriteValueToMemory("[_orgval]", "dl");
5165 fprintf(fp, " inc word [_orgval]\n");
5167 fprintf(fp, " mov dl, [_z80%s + 1]\n", mz80Index);
5168 WriteValueToMemory("[_orgval]", "dl");
5169 fprintf(fp, " xor edx, edx\n");
5171 FetchNextInstruction(dwOpcode);
5173 else
5174 if (MZ80_C == bWhat)
5176 fprintf(fp, " dwAddr = *pbPC++;\n");
5177 fprintf(fp, " dwAddr |= ((UINT32) *pbPC++ << 8);\n");
5178 WriteWordToMemory("dwAddr", mz80Index);
5180 else
5181 abort();
5184 void LdIndexPtrReg(UINT32 dwOpcode)
5186 if (MZ80_ASSEMBLY_X86 == bWhat)
5188 ProcBegin(dwOpcode);
5190 IndexedOffset(mz80Index);
5192 // DX Contains the address
5194 WriteValueToMemory("dx", pbMathReg[dwOpcode & 0x07]);
5195 fprintf(fp, " xor edx, edx\n");
5197 FetchNextInstruction(dwOpcode);
5199 else
5200 if (MZ80_C == bWhat)
5202 fprintf(fp, " sdwAddr = (INT8) *pbPC++; // Get the offset\n");
5203 fprintf(fp, " sdwAddr = ((INT32) %s + sdwAddr) & 0xffff;\n", mz80Index);
5205 WriteValueToMemory("sdwAddr", pbMathRegC[dwOpcode & 0x07]);
5207 else
5208 abort();
5211 void UndocMathIndex(UINT32 dwOpcode)
5213 UINT32 dwOpcode1 = 0;
5214 INT8 *pbIndexReg = NULL;
5216 if (MZ80_ASSEMBLY_X86 == bWhat)
5218 ProcBegin(dwOpcode);
5220 if (dwOpcode & 1)
5221 fprintf(fp, " mov dl, byte [_z80%s]\n", mz80Index);
5222 else
5223 fprintf(fp, " mov dl, byte [_z80%s + 1]\n", mz80Index);
5225 // Info is in DL - let's do the math operation
5227 fprintf(fp, " sahf ; Store our flags in x86 flag reg\n");
5229 dwOpcode1 = (dwOpcode & 0xf8); // Only the operation
5231 if (dwOpcode1 == 0x80)
5232 fprintf(fp, " add al, dl\n");
5233 else
5234 if (dwOpcode1 == 0x88)
5235 fprintf(fp, " adc al, dl\n");
5236 else
5237 if (dwOpcode1 == 0x90)
5238 fprintf(fp, " sub al, dl\n");
5239 else
5240 if (dwOpcode1 == 0x98)
5241 fprintf(fp, " sbb al, dl\n");
5242 else
5243 if (dwOpcode1 == 0xa0)
5244 fprintf(fp, " and al, dl\n");
5245 else
5246 if (dwOpcode1 == 0xa8)
5247 fprintf(fp, " xor al, dl\n");
5248 else
5249 if (dwOpcode1 == 0xb0)
5250 fprintf(fp, " or al, dl\n");
5251 else
5252 if (dwOpcode1 == 0xb8)
5253 fprintf(fp, " cmp al, dl\n");
5254 else
5255 abort();
5257 fprintf(fp, " lahf ; Get flags back into AH\n");
5259 if (dwOpcode1 != 0xa8 && dwOpcode1 != 0xa0 && dwOpcode1 != 0xb0)
5261 SetOverflow();
5264 if (dwOpcode1 == 0xa8)
5265 fprintf(fp, " and ah, 0ech ; Only these flags matter!\n");
5267 if (dwOpcode1 == 0xa0)
5269 fprintf(fp, " and ah, 0ech ; Only these flags matter!\n");
5270 fprintf(fp, " or ah, 010h ; Half carry gets set\n");
5273 if (dwOpcode1 == 0xb0)
5274 fprintf(fp, " and ah, 0ech ; No H, N, or C\n");
5276 if (dwOpcode1 == 0xb8)
5277 fprintf(fp, " or ah, 02h ; Negative gets set on a compare\n");
5279 if (dwOpcode1 == 0x80 || dwOpcode1 == 0x88)
5280 fprintf(fp, " and ah, 0fdh ; No N!\n");
5282 if (dwOpcode1 == 0x90 || dwOpcode1 == 0x98)
5283 fprintf(fp, " or ah, 02h ; N Gets set!\n");
5285 if (dwOpcode1 == 0xb0)
5286 fprintf(fp, " and ah, 0ech ; No H, N, or C\n");
5288 FetchNextInstruction(dwOpcode);
5290 else
5291 if (MZ80_C == bWhat)
5293 if (dwOpcode & 1)
5294 pbIndexReg = mz80IndexHalfLow;
5295 else
5296 pbIndexReg = mz80IndexHalfHigh;
5298 dwOpcode1 = (dwOpcode & 0xf8); // Only the operation
5300 if (0x80 == dwOpcode1) // ADD
5302 fprintf(fp, " bTemp2 = cpu.z80A + %s;\n", pbIndexReg);
5303 SetAddFlagsSZHVC("cpu.z80A", pbIndexReg);
5305 else
5306 if (0x88 == dwOpcode1) // ADC
5308 fprintf(fp, " bTemp2 = cpu.z80A + %s + (cpu.z80F & Z80_FLAG_CARRY);\n", pbIndexReg);
5309 SetAdcFlagsSZHVC("cpu.z80A", pbIndexReg);
5311 else
5312 if (0x90 == dwOpcode1) // SUB
5314 fprintf(fp, " bTemp2 = cpu.z80A - %s;\n", pbIndexReg);
5315 SetSubFlagsSZHVC("cpu.z80A", pbIndexReg);
5317 else
5318 if (0x98 == dwOpcode1) // SBC
5320 fprintf(fp, " bTemp2 = cpu.z80A - %s - (cpu.z80F & Z80_FLAG_CARRY);\n", pbIndexReg);
5321 SetSbcFlagsSZHVC("cpu.z80A", pbIndexReg);
5323 else
5324 if (0xa0 == dwOpcode1) // AND
5326 fprintf(fp, " cpu.z80A &= %s;\n", pbIndexReg);
5327 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
5328 fprintf(fp, " cpu.z80F |= bPostANDFlags[cpu.z80A];\n\n");
5330 else
5331 if (0xa8 == dwOpcode1) // XOR
5333 fprintf(fp, " cpu.z80A ^= %s;\n", pbIndexReg);
5334 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
5335 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
5337 else
5338 if (0xb0 == dwOpcode1) // OR
5340 fprintf(fp, " cpu.z80A |= %s;\n", pbIndexReg);
5341 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
5342 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
5344 else
5345 if (0xb8 == dwOpcode1) // CP - Don't do anything! Just flags!
5347 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
5348 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
5350 else
5352 abort();
5355 InvalidInstructionC(2);
5357 else
5358 abort();
5361 void UndocLoadHalfIndexReg(UINT32 dwOpcode)
5363 if (MZ80_ASSEMBLY_X86 == bWhat)
5365 ProcBegin(dwOpcode);
5367 fprintf(fp, " mov dl, [esi] ; Get immediate byte to load\n");
5368 fprintf(fp, " inc esi ; Next byte\n");
5370 if (dwOpcode == 0x26)
5371 fprintf(fp, " mov byte [_z80%s + 1], dl\n", mz80Index);
5372 if (dwOpcode == 0x2e)
5373 fprintf(fp, " mov byte [_z80%s], dl\n", mz80Index);
5375 FetchNextInstruction(dwOpcode);
5377 else
5378 if (MZ80_C == bWhat)
5380 if (dwOpcode & 0x08)
5381 fprintf(fp, " %s = *pbPC++;\n", mz80IndexHalfLow);
5382 else
5383 fprintf(fp, " %s = *pbPC++;\n", mz80IndexHalfHigh);
5385 else
5386 abort();
5389 void UndocIncDecIndexReg(UINT32 dwOpcode)
5391 if (MZ80_ASSEMBLY_X86 == bWhat)
5393 ProcBegin(dwOpcode);
5395 fprintf(fp, " sahf\n");
5397 if (dwOpcode == 0x24)
5398 fprintf(fp, " inc byte [_z80%s + 1]\n", mz80Index);
5399 if (dwOpcode == 0x25)
5400 fprintf(fp, " dec byte [_z80%s + 1]\n", mz80Index);
5402 if (dwOpcode == 0x2c)
5403 fprintf(fp, " inc byte [_z80%s]\n", mz80Index);
5404 if (dwOpcode == 0x2d)
5405 fprintf(fp, " dec byte [_z80%s]\n", mz80Index);
5407 fprintf(fp, " lahf\n");
5408 SetOverflow();
5410 if ((0x24 == dwOpcode) || (0x2c == dwOpcode))
5411 fprintf(fp, " and ah, 0fdh ; Knock out N!\n");
5412 else
5413 fprintf(fp, " or ah, 02h ; Set negative!\n");
5415 FetchNextInstruction(dwOpcode);
5417 else
5418 if (MZ80_C == bWhat)
5420 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
5422 if (0x24 == dwOpcode || 0x2c == dwOpcode)
5424 if (dwOpcode & 0x08)
5425 fprintf(fp, " cpu.z80F |= bPostIncFlags[%s++];\n", mz80IndexHalfLow);
5426 else
5427 fprintf(fp, " cpu.z80F |= bPostIncFlags[%s++];\n", mz80IndexHalfHigh);
5429 else
5431 if (dwOpcode & 0x08)
5432 fprintf(fp, " cpu.z80F |= bPostDecFlags[%s--];\n", mz80IndexHalfLow);
5433 else
5434 fprintf(fp, " cpu.z80F |= bPostDecFlags[%s--];\n", mz80IndexHalfHigh);
5437 else
5438 abort();
5441 void ExIndexed(UINT32 dwOpcode)
5443 if (MZ80_ASSEMBLY_X86 == bWhat)
5445 ProcBegin(dwOpcode);
5447 if( bThroughCallHandler )
5449 fprintf(fp, " mov dx, word [_z80%s]\n", mz80Index);
5450 fprintf(fp, " push dx\n");
5451 fprintf(fp, " call PopWord\n");
5452 fprintf(fp, " mov [_z80%s], dx\n", mz80Index);
5453 fprintf(fp, " pop dx\n");
5454 fprintf(fp, " mov [_wordval], dx\n" );
5455 fprintf(fp, " call PushWord\n" );
5457 else
5459 fprintf(fp, " mov [cyclesRemaining], edi\n");
5460 fprintf(fp, " mov dx, word [_z80sp]\n");
5461 fprintf(fp, " xor edi, edi\n");
5462 fprintf(fp, " mov di, [_z80%s]\n", mz80Index);
5463 fprintf(fp, " xchg di, [ebp+edx]\n");
5464 fprintf(fp, " mov [_z80%s], di\n", mz80Index);
5465 fprintf(fp, " xor edx, edx\n");
5466 fprintf(fp, " mov edi, [cyclesRemaining]\n");
5469 FetchNextInstruction(dwOpcode);
5471 else
5472 if (MZ80_C == bWhat)
5474 ReadWordFromMemory("cpu.z80sp", "dwAddr");
5475 WriteWordToMemory("cpu.z80sp", mz80Index);
5476 fprintf(fp, " %s = dwAddr;\n", mz80Index);
5478 else
5479 abort();
5482 void IncDecIndexReg(UINT32 dwOpcode)
5484 if (MZ80_ASSEMBLY_X86 == bWhat)
5486 ProcBegin(dwOpcode);
5488 if (dwOpcode == 0x23)
5489 fprintf(fp, " inc word [_z80%s] ; Increment our mz80Index register\n", mz80Index);
5490 else
5491 fprintf(fp, " dec word [_z80%s] ; Increment our mz80Index register\n", mz80Index);
5493 FetchNextInstruction(dwOpcode);
5495 else
5496 if (MZ80_C == bWhat)
5498 if (0x23 == dwOpcode)
5500 fprintf(fp, " %s++;\n", mz80Index);
5502 else
5504 fprintf(fp, " %s--;\n", mz80Index);
5507 fprintf(fp, " %s &= 0xffff;\n", mz80Index);
5509 else
5510 abort();
5513 void LdRegIndexOffset(UINT32 dwOpcode)
5515 UINT32 dwOpcode1 = 0;
5517 dwOpcode1 = (dwOpcode & 0x38) >> 3;
5519 if (MZ80_ASSEMBLY_X86 == bWhat)
5521 ProcBegin(dwOpcode);
5523 IndexedOffset(mz80Index);
5525 ReadValueFromMemory("dx", pbMathReg[dwOpcode1]);
5527 fprintf(fp, " xor edx, edx ; Make sure we don't hose things\n");
5528 dwGlobalLabel++;
5529 FetchNextInstruction(dwOpcode);
5531 else
5532 if (MZ80_C == bWhat)
5534 fprintf(fp, " sdwAddr = (INT8) *pbPC++; // Get the offset\n");
5535 fprintf(fp, " sdwAddr = ((INT32) %s + sdwAddr) & 0xffff;\n", mz80Index);
5537 ReadValueFromMemory("sdwAddr", pbMathRegC[dwOpcode1]);
5539 else
5540 abort();
5543 void LdByteToIndex(UINT32 dwOpcode)
5545 if (MZ80_ASSEMBLY_X86 == bWhat)
5547 ProcBegin(dwOpcode);
5549 fprintf(fp, " mov dx, [esi] ; Get our address\n");
5550 fprintf(fp, " add esi, 2 ; Skip over our storage bytes\n");
5551 fprintf(fp, " mov [cyclesRemaining], edi\n");
5552 fprintf(fp, " mov di, dx ; Store it here for later\n");
5553 fprintf(fp, " xor dh, dh\n");
5554 fprintf(fp, " or dl, dl\n");
5555 fprintf(fp, " jns noNegate%" PRIu32 "\n", dwGlobalLabel);
5556 fprintf(fp, " dec dh\n");
5557 fprintf(fp, "noNegate%" PRIu32 ":\n", dwGlobalLabel);
5558 fprintf(fp, " add dx, [_z80%s] ; Add in our index\n", mz80Index);
5559 fprintf(fp, " mov [_orgval], dx ; Store our address to write to\n");
5560 fprintf(fp, " mov dx, di\n");
5561 fprintf(fp, " xchg dh, dl\n");
5562 fprintf(fp, " mov edi, [cyclesRemaining]\n");
5564 WriteValueToMemory("[_orgval]", "dl");
5566 fprintf(fp, " xor edx, edx\n");
5567 ++dwGlobalLabel;
5568 FetchNextInstruction(dwOpcode);
5570 else
5571 if (MZ80_C == bWhat)
5573 fprintf(fp, " sdwAddr = (INT8) *pbPC++; // Get the offset\n");
5574 fprintf(fp, " sdwAddr = ((INT32) %s + sdwAddr) & 0xffff;\n", mz80Index);
5576 WriteValueToMemory("sdwAddr", "*pbPC++");
5578 else
5579 abort();
5583 void SPToIndex(UINT32 dwOpcode)
5585 if (MZ80_ASSEMBLY_X86 == bWhat)
5587 ProcBegin(dwOpcode);
5589 fprintf(fp, " mov dx, [_z80%s] ; Get our source register\n", mz80Index);
5590 fprintf(fp, " mov word [_z80sp], dx ; Store our new SP\n");
5591 fprintf(fp, " xor edx, edx\n");
5593 FetchNextInstruction(dwOpcode);
5595 else
5596 if (MZ80_C == bWhat)
5598 fprintf(fp, " cpu.z80sp = %s;\n", mz80Index);
5600 else
5601 abort();
5604 void AddIndexHandler(UINT32 dwOpcode)
5606 UINT8 bRegPair;
5608 bRegPair = dwOpcode >> 4;
5610 if (MZ80_ASSEMBLY_X86 == bWhat)
5612 ProcBegin(dwOpcode);
5614 fprintf(fp, " mov dh, ah ; Get our flags\n");
5615 fprintf(fp, " and dh, 0ech ; Preserve the top three and bits 2 & 3\n");
5617 fprintf(fp, " mov [cyclesRemaining], edi\n");
5618 fprintf(fp, " mov di, [_z80%s] ; Get our value\n", mz80Index);
5619 fprintf(fp, " mov [_orgval], di ; Store our original value\n");
5620 fprintf(fp, " add di, %s\n", pbIndexedRegPairs[(dwOpcode & 0x30) >> 4]);
5621 fprintf(fp, " lahf\n");
5622 fprintf(fp, " mov [_z80%s], di ; Store our register back\n", mz80Index);
5624 fprintf(fp, " mov di, [_orgval] ; Get original\n");
5625 fprintf(fp, " xor di, word [_z80%s] ; XOR It with our computed value\n", mz80Index);
5626 fprintf(fp, " xor di, %s\n", pbIndexedRegPairs[(dwOpcode & 0x30) >> 4]);
5627 fprintf(fp, " and di, 1000h ; Just our half carry\n");
5628 fprintf(fp, " or dx, di ; Or in our flags\n");
5629 fprintf(fp, " and ah, 01h ; Just carry\n");
5630 fprintf(fp, " or ah, dh\n");
5631 fprintf(fp, " mov edi, [cyclesRemaining]\n");
5632 fprintf(fp, " xor edx, edx\n");
5633 FetchNextInstruction(dwOpcode);
5635 else
5636 if (MZ80_C == bWhat)
5638 if (bRegPair != 2)
5640 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");
5641 fprintf(fp, " dwTemp = %s + %s;\n", mz80Index, pbRegPairsC[bRegPair]);
5642 fprintf(fp, " cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY) | (((%s ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", mz80Index, pbRegPairsC[bRegPair]);
5643 fprintf(fp, " %s = dwTemp & 0xffff;\n", mz80Index);
5645 else
5647 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");
5648 fprintf(fp, " dwTemp = %s + %s;\n", mz80Index, mz80Index);
5649 fprintf(fp, " cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY) | (((%s ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", mz80Index, pbRegPairsC[bRegPair]);
5650 fprintf(fp, " %s = dwTemp & 0xffff;\n", mz80Index);
5653 else
5654 abort();
5657 void JPIXIYHandler(UINT32 dwOpcode)
5659 if (MZ80_ASSEMBLY_X86 == bWhat)
5661 ProcBegin(dwOpcode);
5663 fprintf(fp, " mov dx, [_z80%s] ; Get our value\n", mz80Index);
5664 fprintf(fp, " mov esi, edx ; New PC!\n");
5665 fprintf(fp, " add esi, ebp ; Add in our base\n");
5666 fprintf(fp, " xor edx, edx\n");
5667 FetchNextInstruction(dwOpcode);
5669 else
5670 if (MZ80_C == bWhat)
5672 fprintf(fp, " pbPC = cpu.z80Base + %s;\n", mz80Index);
5674 else
5675 abort();
5678 void IncDecIndexed(UINT32 dwOpcode)
5680 if (MZ80_ASSEMBLY_X86 == bWhat)
5682 ProcBegin(dwOpcode);
5684 IndexedOffset(mz80Index);
5686 fprintf(fp, " mov [_orgval], dx\n");
5688 ReadValueFromMemory("dx", "dl");
5690 fprintf(fp, " sahf\n");
5692 if (dwOpcode == 0x34)
5693 fprintf(fp, " inc dl\n");
5694 else
5695 fprintf(fp, " dec dl\n");
5696 fprintf(fp, " lahf\n");
5698 fprintf(fp, " o16 pushf\n");
5699 fprintf(fp, " shl edx, 16\n");
5700 fprintf(fp, " and ah, 0fbh ; Knock out parity/overflow\n");
5701 fprintf(fp, " pop dx\n");
5702 fprintf(fp, " and dh, 08h ; Just the overflow\n");
5703 fprintf(fp, " shr dh, 1 ; Shift it into position\n");
5704 fprintf(fp, " or ah, dh ; OR It in with the real flags\n");
5706 fprintf(fp, " shr edx, 16\n");
5708 if (dwOpcode == 0x34)
5709 fprintf(fp, " and ah, 0fdh ; Knock out N!\n");
5710 else
5711 fprintf(fp, " or ah, 02h ; Make it N!\n");
5713 WriteValueToMemory("[_orgval]", "dl");
5715 fprintf(fp, " xor edx, edx\n");
5717 FetchNextInstruction(dwOpcode);
5719 else
5720 if (MZ80_C == bWhat)
5722 fprintf(fp, " sdwAddr = (INT8) *pbPC++; /* Get LSB first */\n");
5723 fprintf(fp, " dwAddr = (sdwAddr + (INT32) %s) & 0xffff;\n", mz80Index);
5725 ReadValueFromMemory("dwAddr", "bTemp");
5727 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
5729 if (0x34 == dwOpcode)
5731 fprintf(fp ," cpu.z80F |= bPostIncFlags[bTemp++];\n");
5733 else
5735 fprintf(fp ," cpu.z80F |= bPostDecFlags[bTemp--];\n");
5738 WriteValueToMemory("dwAddr", "bTemp");
5740 else
5741 abort();
5744 void MathOperationIndexed(UINT32 dwOpcode)
5746 if (MZ80_ASSEMBLY_X86 == bWhat)
5748 ProcBegin(dwOpcode);
5750 IndexedOffset(mz80Index);
5751 ReadValueFromMemory("dx", "dl");
5753 fprintf(fp, " sahf\n");
5755 if (dwOpcode == 0x86) // Add
5756 fprintf(fp, " add al, dl\n");
5757 if (dwOpcode == 0x8e) // Adc
5758 fprintf(fp, " adc al, dl\n");
5759 if (dwOpcode == 0x96) // Sub
5760 fprintf(fp, " sub al, dl\n");
5761 if (dwOpcode == 0x9e) // Sbc
5762 fprintf(fp, " sbb al, dl\n");
5763 if (dwOpcode == 0xa6) // And
5764 fprintf(fp, " and al, dl\n");
5765 if (dwOpcode == 0xae) // Xor
5766 fprintf(fp, " xor al, dl\n");
5767 if (dwOpcode == 0xb6) // Or
5768 fprintf(fp, " or al, dl\n");
5769 if (dwOpcode == 0xbe) // Cp
5770 fprintf(fp, " cmp al, dl\n");
5772 fprintf(fp, " lahf\n");
5774 if (dwOpcode == 0x86 || dwOpcode == 0x8e)
5776 SetOverflow();
5777 fprintf(fp, " and ah, 0fdh ; Knock out negative\n");
5780 if (dwOpcode == 0x96 || dwOpcode == 0x9e || dwOpcode == 0xbe)
5782 SetOverflow();
5783 fprintf(fp, " or ah, 02h ; Set negative\n");
5786 if (dwOpcode == 0xae || dwOpcode == 0xb6)
5787 fprintf(fp, " and ah, 0ech ; Knock out H, N, and C\n");
5789 if (dwOpcode == 0xa6)
5791 fprintf(fp, " and ah,0fch ; Knock out N & C\n");
5792 fprintf(fp, " or ah, 10h ; Set half carry\n");
5795 fprintf(fp, " xor edx, edx\n");
5796 FetchNextInstruction(dwOpcode);
5798 else
5799 if (MZ80_C == bWhat)
5801 fprintf(fp, " sdwAddr = (INT8) *pbPC++; /* Get LSB first */\n");
5802 fprintf(fp, " dwAddr = (sdwAddr + (INT32) %s) & 0xffff;\n", mz80Index);
5804 ReadValueFromMemory("dwAddr", "bTemp");
5806 if (0x86 == dwOpcode) // ADD A, (IX/IY+nn)
5808 SetAddFlagsSZHVC("cpu.z80A", "bTemp");
5809 fprintf(fp, " cpu.z80A += bTemp;\n");
5811 else
5812 if (0x8e == dwOpcode) // ADC A, (IX/IY+nn)
5814 fprintf(fp, " bTemp2 = (cpu.z80F & Z80_FLAG_CARRY);\n");
5815 SetAdcFlagsSZHVC("cpu.z80A", "bTemp");
5816 fprintf(fp, " cpu.z80A += bTemp + bTemp2;\n");
5818 else
5819 if (0x96 == dwOpcode) // SUB A, (IX/IY+nn)
5821 SetSubFlagsSZHVC("cpu.z80A", "bTemp");
5822 fprintf(fp, " cpu.z80A -= bTemp;\n");
5824 else
5825 if (0x9e == dwOpcode) // SBC A, (IX/IY+nn)
5827 fprintf(fp, " bTemp2 = cpu.z80A;\n");
5828 fprintf(fp, " cpu.z80A = cpu.z80A - bTemp - (cpu.z80F & Z80_FLAG_CARRY);\n");
5829 SetSbcFlagsSZHVC("bTemp2", "bTemp");
5831 else
5832 if (0xa6 == dwOpcode) // AND A, (IX/IY+nn)
5834 fprintf(fp, " cpu.z80A &= bTemp;\n");
5835 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
5836 fprintf(fp, " cpu.z80F |= bPostANDFlags[cpu.z80A];\n\n");
5838 else
5839 if (0xae == dwOpcode) // XOR A, (IX/IY+nn)
5841 fprintf(fp, " cpu.z80A ^= bTemp;\n");
5842 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
5843 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
5845 else
5846 if (0xb6 == dwOpcode) // OR A, (IX/IY+nn)
5848 fprintf(fp, " cpu.z80A |= bTemp;\n");
5849 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
5850 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
5852 else
5853 if (0xbe == dwOpcode) // CP A, (IX/IY+nn)
5855 SetSubFlagsSZHVC("cpu.z80A", "bTemp");
5857 else
5858 InvalidInstructionC(2);
5860 else
5861 abort();
5864 void UndocIndexToReg(UINT32 dwOpcode)
5866 if (MZ80_ASSEMBLY_X86 == bWhat)
5868 ProcBegin(dwOpcode);
5870 if ((dwOpcode & 0x07) == 2 || (dwOpcode & 0x07) == 3)
5871 fprintf(fp, " mov dx, [_z80de] ; Get DE\n");
5873 if ((dwOpcode & 0x07) == 4)
5874 fprintf(fp, " mov dh, byte [_z80%s + 1]\n", mz80Index);
5875 if ((dwOpcode & 0x07) == 5)
5876 fprintf(fp, " mov dl, byte [_z80%s]\n", mz80Index);
5878 fprintf(fp, " mov byte [_z80%s + %" PRIu32 "], %s\n", mz80Index, 1 - ((dwOpcode & 0x08) >> 3), pbLocalReg[dwOpcode & 0x07]);
5879 fprintf(fp, " xor edx, edx\n");
5880 FetchNextInstruction(dwOpcode);
5882 else
5883 if (MZ80_C == bWhat)
5885 if (dwOpcode != 0x64 && dwOpcode != 0x65 && dwOpcode != 0x6c && dwOpcode != 0x6d)
5887 if (dwOpcode & 0x08)
5888 fprintf(fp, " %s = %s;\n", mz80IndexHalfLow, pbLocalRegC[dwOpcode & 0x07]);
5889 else
5890 fprintf(fp, " %s = %s;\n", mz80IndexHalfHigh, pbLocalRegC[dwOpcode & 0x07]);
5892 else // IX/IY High/low weirdness afoot...
5894 // We don't generate any code for ld indexH, indexH and ld indexL, indexL
5896 if (0x65 == dwOpcode) // LD indexH, indexL
5898 fprintf(fp, " %s = %s;\n", mz80IndexHalfHigh, mz80IndexHalfLow);
5900 else
5901 if (0x6c == dwOpcode) // LD indexH, indexL
5903 fprintf(fp, " %s = %s;\n", mz80IndexHalfLow, mz80IndexHalfHigh);
5907 else
5908 abort();
5911 void UndocRegToIndex(UINT32 dwOpcode)
5913 if (MZ80_ASSEMBLY_X86 == bWhat)
5915 ProcBegin(dwOpcode);
5917 if ((dwOpcode & 0x38) == 0x10 || (dwOpcode & 0x38) == 0x18)
5918 fprintf(fp, " mov dx, [_z80de] ; Get a usable copy of DE here\n");
5920 fprintf(fp, " mov %s, byte [_z80%s + %" PRIu32 "]\n", pbLocalReg[(dwOpcode >> 3) & 0x07], mz80Index, 1 - (dwOpcode & 1));
5922 if ((dwOpcode & 0x38) == 0x10 || (dwOpcode & 0x38) == 0x18)
5923 fprintf(fp, " mov [_z80de], dx ; Put it back!\n");
5925 fprintf(fp, " xor edx, edx\n");
5926 FetchNextInstruction(dwOpcode);
5928 else
5929 if (MZ80_C == bWhat)
5931 if (dwOpcode & 1)
5932 fprintf(fp, " %s = %s;\n", pbLocalRegC[(dwOpcode >> 3) & 0x07], mz80IndexHalfLow);
5933 else
5934 fprintf(fp, " %s = %s;\n", pbLocalRegC[(dwOpcode >> 3) & 0x07], mz80IndexHalfHigh);
5936 else
5937 abort();
5940 void LoadImmediate(UINT32 dwOpcode)
5942 if (MZ80_ASSEMBLY_X86 == bWhat)
5944 ProcBegin(dwOpcode);
5946 fprintf(fp, " mov dx, [esi] ; Get our word to load\n");
5947 fprintf(fp, " add esi, 2 ; Advance past the word\n");
5948 fprintf(fp, " mov [_z80%s], dx ; Store our new value\n", mz80Index);
5949 fprintf(fp, " xor edx, edx\n");
5951 FetchNextInstruction(dwOpcode);
5953 else
5954 if (MZ80_C == bWhat)
5956 fprintf(fp, " %s = *pbPC++;\n", mz80Index);
5957 fprintf(fp, " %s |= ((UINT32) *pbPC++ << 8);\n", mz80Index);
5959 else
5960 abort();
5963 void PushPopOperationsIndexed(UINT32 dwOpcode)
5965 INT8 bRegBaseLsb[25];
5966 INT8 bRegBaseMsb[25];
5967 INT8 string[150];
5969 if (MZ80_ASSEMBLY_X86 == bWhat)
5971 sprintf(bRegBaseLsb, "byte [_z80%s]", mz80Index);
5972 sprintf(bRegBaseMsb, "byte [_z80%s + 1]", mz80Index);
5974 sprintf(string, "[_z80%s]", mz80Index);
5976 ProcBegin(dwOpcode);
5978 if (dwOpcode == 0xe5) // Push IX/IY
5980 fprintf(fp, " sub word [_z80sp], 2\n");
5981 fprintf(fp, " mov dx, [_z80sp]\n");
5983 WriteWordToMemory("dx", string);
5985 else // Pop
5987 fprintf(fp, " mov dx, [_z80sp]\n");
5988 ReadWordFromMemory("dx", string);
5989 fprintf(fp, " add word [_z80sp], 2\n");
5992 fprintf(fp, " xor edx, edx\n");
5993 FetchNextInstruction(dwOpcode);
5995 else
5996 if (MZ80_C == bWhat)
5998 if (0xe5 == dwOpcode) // Push IX/IY
6000 fprintf(fp, " cpu.z80sp -= 2;\n");
6001 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp); /* Normalize the stack pointer */\n");
6003 WriteWordToMemory("cpu.z80sp", mz80Index);
6005 else
6006 if (0xe1 == dwOpcode) // Pop IX/IY
6008 ReadWordFromMemory("cpu.z80sp", mz80Index);
6010 fprintf(fp, " cpu.z80sp += 2;\n");
6011 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp); /* Normalize the stack pointer */\n");
6012 return;
6015 else
6016 abort();
6019 // DDFD XXCB Instructions
6021 void ddcbBitWise(UINT32 dwOpcode)
6023 if (MZ80_ASSEMBLY_X86 == bWhat)
6025 ProcBegin(dwOpcode);
6027 // NOTE: _orgval contains the address to get from. It includes the offset
6028 // already computed plus the mz80Index register.
6030 // Read our byte
6032 fprintf(fp, " mov dx, [_orgval] ; Get our target address\n");
6033 ReadValueFromMemory("dx", "dl");
6035 // Do the operation
6037 if (dwOpcode != 0x06 && dwOpcode != 0x0e &&
6038 dwOpcode != 0x16 && dwOpcode != 0x1e &&
6039 dwOpcode != 0x26 && dwOpcode != 0x2e &&
6040 dwOpcode != 0x3e && (dwOpcode & 0xc7) != 0x86 &&
6041 (dwOpcode & 0xc7) != 0xc6)
6043 fprintf(fp, " mov dh, ah ; Store our original flags\n");
6044 fprintf(fp, " and dh, 29h ; Keep our old flags\n");
6047 if ((dwOpcode & 0xc7) != 0x86 && (dwOpcode & 0xc7) != 0xc6)
6048 fprintf(fp, " sahf ; Restore our flags\n");
6050 if (dwOpcode == 0x06)
6051 fprintf(fp, " rol dl, 1\n");
6052 if (dwOpcode == 0x0e)
6053 fprintf(fp, " ror dl, 1\n");
6054 if (dwOpcode == 0x16)
6055 fprintf(fp, " rcl dl, 1\n");
6056 if (dwOpcode == 0x1e)
6057 fprintf(fp, " rcr dl, 1\n");
6058 if (dwOpcode == 0x26)
6059 fprintf(fp, " shl dl, 1\n");
6060 if (dwOpcode == 0x2e)
6061 fprintf(fp, " sar dl, 1\n");
6062 if (dwOpcode == 0x3e)
6063 fprintf(fp, " shr dl, 1\n");
6065 // BIT, AND, and OR
6067 if ((dwOpcode & 0xc7) == 0x46)
6068 fprintf(fp, " test dl, 0%.2xh ; Is it set?\n", (1 << ((dwOpcode >> 3) & 0x07)));
6069 else
6070 if ((dwOpcode & 0xc7) == 0x86)
6071 fprintf(fp, " and dl, 0%.2xh ; Reset the bit\n",
6072 0xff - (1 << ((dwOpcode >> 3) & 0x07)));
6073 else
6074 if ((dwOpcode & 0xc7) == 0xc6)
6075 fprintf(fp, " or dl, 0%.2xh ; Set the bit\n",
6076 (1 << ((dwOpcode >> 3) & 0x07)));
6078 if ((dwOpcode & 0xc7) != 0x86 && (dwOpcode & 0xc7) != 0xc6)
6079 fprintf(fp, " lahf ; Get our flags back\n");
6081 // Do the flag fixup (if any)
6083 if (dwOpcode == 0x26 || dwOpcode == 0x2e || ((dwOpcode & 0xc7) == 0x46))
6084 fprintf(fp, " and ah, 0edh ; No Half carry or negative!\n");
6086 if (dwOpcode == 0x06 || dwOpcode == 0x0e ||
6087 dwOpcode == 0x16 || dwOpcode == 0x1e ||
6088 dwOpcode == 0x3e)
6089 fprintf(fp, " and ah, 0edh ; Knock out H & N\n");
6091 // BIT!
6093 if ((dwOpcode & 0xc7) == 0x46)
6095 fprintf(fp, " or ah, 10h ; OR In our half carry\n");
6096 fprintf(fp, " and ah, 0d0h ; New flags\n");
6097 fprintf(fp, " or ah, dh ; OR In our old flags\n");
6100 // Now write our data back if it's not a BIT instruction
6102 if ((dwOpcode & 0xc7) != 0x46) // If it's not a BIT, write it back
6103 WriteValueToMemory("[_orgval]", "dl");
6105 fprintf(fp, " xor edx, edx\n");
6106 FetchNextInstruction(dwOpcode);
6108 else
6109 if (MZ80_C == bWhat)
6111 if (0x06 == dwOpcode) // RLC
6113 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
6114 fprintf(fp, " bTemp2 = (bTemp >> 7);\n");
6115 fprintf(fp, " bTemp = (bTemp << 1) | bTemp2;\n");
6116 fprintf(fp, " cpu.z80F |= bTemp2 | bPostORFlags[bTemp];\n");
6117 WriteValueToMemory("dwAddr", "bTemp");
6119 else
6120 if (0x0e == dwOpcode) // RRC
6122 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
6123 fprintf(fp, " cpu.z80F |= (bTemp & Z80_FLAG_CARRY);\n");
6124 fprintf(fp, " bTemp = (bTemp >> 1) | (bTemp << 7);\n");
6125 fprintf(fp, " cpu.z80F |= bPostORFlags[bTemp];\n");
6126 WriteValueToMemory("dwAddr", "bTemp");
6128 else
6129 if (0x16 == dwOpcode) // RL
6131 fprintf(fp, " bTemp2 = cpu.z80F & Z80_FLAG_CARRY;\n");
6132 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
6133 fprintf(fp, " cpu.z80F |= (bTemp >> 7);\n");
6134 fprintf(fp, " bTemp = (bTemp << 1) | bTemp2;\n");
6135 fprintf(fp, " cpu.z80F |= bPostORFlags[bTemp];\n");
6136 WriteValueToMemory("dwAddr", "bTemp");
6138 else
6139 if (0x1e == dwOpcode) // RR
6141 fprintf(fp, " bTemp2 = (cpu.z80F & Z80_FLAG_CARRY) << 7;\n");
6142 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
6143 fprintf(fp, " cpu.z80F |= (bTemp & Z80_FLAG_CARRY);\n");
6144 fprintf(fp, " bTemp = (bTemp >> 1) | bTemp2;\n");
6145 fprintf(fp, " cpu.z80F |= bPostORFlags[bTemp];\n");
6146 WriteValueToMemory("dwAddr", "bTemp");
6148 else
6149 if (0x26 == dwOpcode) // SLA
6151 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
6152 fprintf(fp, " cpu.z80F |= (bTemp >> 7);\n");
6153 fprintf(fp, " bTemp = (bTemp << 1);\n");
6154 fprintf(fp, " cpu.z80F |= bPostORFlags[bTemp];\n");
6155 WriteValueToMemory("dwAddr", "bTemp");
6157 else
6158 if (0x2e == dwOpcode) // SRA
6160 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
6161 fprintf(fp, " cpu.z80F |= (bTemp & Z80_FLAG_CARRY);\n");
6162 fprintf(fp, " bTemp = (bTemp >> 1) | (bTemp & 0x80);\n");
6163 fprintf(fp, " cpu.z80F |= bPostORFlags[bTemp];\n");
6164 WriteValueToMemory("dwAddr", "bTemp");
6166 else
6167 if (0x3e == dwOpcode) // SRL
6169 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
6170 fprintf(fp, " cpu.z80F |= (bTemp & Z80_FLAG_CARRY);\n");
6171 fprintf(fp, " bTemp = (bTemp >> 1);\n");
6172 fprintf(fp, " cpu.z80F |= bPostORFlags[bTemp];\n");
6173 WriteValueToMemory("dwAddr", "bTemp");
6175 else
6176 if ((dwOpcode & 0xc0) == 0x40) // BIT
6178 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_ZERO | Z80_FLAG_NEGATIVE)) | Z80_FLAG_HALF_CARRY;\n");
6179 fprintf(fp, " if (!(bTemp & 0x%.2x))\n", 1 << ((dwOpcode >> 3) & 0x07));
6180 fprintf(fp, " {\n");
6181 fprintf(fp, " cpu.z80F |= Z80_FLAG_ZERO;\n");
6182 fprintf(fp, " }\n");
6184 else
6185 if ((dwOpcode & 0xc0) == 0x80) // RES
6187 fprintf(fp, " bTemp &= 0x%.2x;\n", ~(1 << ((dwOpcode >> 3) & 0x07)) & 0xff);
6188 WriteValueToMemory("dwAddr", "bTemp");
6190 else
6191 if ((dwOpcode & 0xc0) == 0xC0) // SET
6193 fprintf(fp, " bTemp |= 0x%.2x;\n", 1 << ((dwOpcode >> 3) & 0x07));
6194 WriteValueToMemory("dwAddr", "bTemp");
6196 else
6197 InvalidInstructionC(4);
6199 else
6200 abort();
6203 void GetTicksCode(void)
6205 if (MZ80_ASSEMBLY_X86 == bWhat)
6207 fprintf(fp, " global _%sGetElapsedTicks\n", cpubasename);
6208 fprintf(fp, " global %sGetElapsedTicks_\n", cpubasename);
6209 fprintf(fp, " global %sGetElapsedTicks\n", cpubasename);
6211 Alignment();
6212 sprintf(procname, "%sGetElapsedTicks_", cpubasename);
6213 ProcBegin(0xffffffff);
6214 fprintf(fp, "_%sGetElapsedTicks:\n", cpubasename);
6215 fprintf(fp, "%sGetElapsedTicks:\n", cpubasename);
6217 if (bUseStack)
6218 fprintf(fp, " mov eax, [esp+4] ; Get our context address\n");
6220 fprintf(fp, " or eax, eax ; Should we clear it?\n");
6221 fprintf(fp, " jz getTicks\n");
6222 fprintf(fp, " xor eax, eax\n");
6223 fprintf(fp, " xchg eax, [dwElapsedTicks]\n");
6224 fprintf(fp, " ret\n");
6225 fprintf(fp, "getTicks:\n");
6226 fprintf(fp, " mov eax, [dwElapsedTicks]\n");
6227 fprintf(fp, " ret\n");
6229 else
6230 if (MZ80_C == bWhat)
6232 fprintf(fp, "/* This will return the elapsed ticks */\n\n");
6233 fprintf(fp, "UINT32 %sGetElapsedTicks(UINT32 dwClear)\n", cpubasename);
6234 fprintf(fp, "{\n");
6235 fprintf(fp, " UINT32 dwTemp = dwElapsedTicks;\n\n");
6236 fprintf(fp, " if (dwClear)\n");
6237 fprintf(fp, " {\n");
6238 fprintf(fp, " dwElapsedTicks = 0;\n");
6239 fprintf(fp, " }\n\n");
6240 fprintf(fp, " return(dwTemp);\n");
6241 fprintf(fp, "}\n\n");
6243 else
6245 abort();
6249 void ReleaseTimesliceCode(void)
6251 if (MZ80_ASSEMBLY_X86 == bWhat)
6253 fprintf(fp, " global _%sReleaseTimeslice\n", cpubasename);
6254 fprintf(fp, " global %sReleaseTimeslice_\n", cpubasename);
6255 fprintf(fp, " global %sReleaseTimeslice\n", cpubasename);
6257 Alignment();
6258 sprintf(procname, "%sReleaseTimeslice_", cpubasename);
6259 ProcBegin(0xffffffff);
6260 fprintf(fp, "_%sReleaseTimeslice:\n", cpubasename);
6261 fprintf(fp, "%sReleaseTimeslice:\n", cpubasename);
6263 fprintf(fp, " mov eax, [cyclesRemaining]\n");
6264 fprintf(fp, " sub [dwOriginalExec], eax\n");
6265 fprintf(fp, " mov [cyclesRemaining], dword 0\n");
6267 fprintf(fp, " ret\n\n");
6269 else
6270 if (MZ80_C == bWhat)
6272 fprintf(fp, "/* Releases mz80 from its current timeslice */\n\n");
6273 fprintf(fp, "void %sReleaseTimeslice(void)\n", cpubasename);
6274 fprintf(fp, "{\n");
6275 fprintf(fp, " dwOriginalCycles -= sdwCyclesRemaining;\n");
6276 fprintf(fp, " sdwCyclesRemaining = 0;\n");
6277 fprintf(fp, "}\n\n");
6279 else
6281 abort();
6285 void DataSegment(void)
6287 UINT32 dwLoop = 0;
6288 UINT8 bUsed[256];
6290 if (MZ80_ASSEMBLY_X86 == bWhat)
6292 if (bOS2)
6293 fprintf(fp, " section .DATA32 use32 flat class=data\n");
6294 else
6295 fprintf(fp, " section .data use32 flat class=data\n");
6297 Alignment();
6298 fprintf(fp, " global _%scontextBegin\n", cpubasename);
6299 fprintf(fp, "_%scontextBegin:\n", cpubasename);
6301 fprintf(fp, " global _z80pc\n");
6302 fprintf(fp, " global z80pc_\n");
6304 if (bPlain)
6305 fprintf(fp, " global z80pc\n");
6307 fprintf(fp, " global _z80nmiAddr\n");
6308 fprintf(fp, " global _z80intAddr\n");
6309 fprintf(fp, " global z80intAddr\n");
6311 fprintf(fp, "\n");
6312 fprintf(fp, "; DO NOT CHANGE THE ORDER OF AF, BC, DE, HL and THE PRIME REGISTERS!\n");
6313 fprintf(fp, "\n");
6314 fprintf(fp, "_z80Base dd 0 ; Base address for Z80 stuff\n");
6315 fprintf(fp, "_z80MemRead dd 0 ; Offset of memory read structure array\n");
6316 fprintf(fp, "_z80MemWrite dd 0 ; Offset of memory write structure array\n");
6317 fprintf(fp, "_z80IoRead dd 0 ; Base address for I/O reads list\n");
6318 fprintf(fp, "_z80IoWrite dd 0 ; Base address for I/O write list\n");
6319 fprintf(fp, "_z80clockticks dd 0 ; # Of clock tips that have elapsed\n");
6320 fprintf(fp, "_z80iff dd 0 ; Non-zero if we're in an interrupt\n");
6321 fprintf(fp, "_z80interruptMode dd 0 ; Interrupt mode\n");
6322 fprintf(fp, "_z80halted dd 0 ; 0=Not halted, 1=Halted\n");
6323 #ifdef MZ80_TRAP
6324 fprintf(fp, "_z80trapList dd 0 ; pointer to trap list\n");
6325 fprintf(fp, "_z80trapAddr dw 0 ; PC where trap occurred\n");
6326 #endif
6327 fprintf(fp, "_z80af dd 0 ; A Flag & Flags\n");
6328 fprintf(fp, "_z80bc dd 0 ; BC\n");
6329 fprintf(fp, "_z80de dd 0 ; DE\n");
6330 fprintf(fp, "_z80hl dd 0 ; HL\n");
6331 fprintf(fp, "_z80afprime dd 0 ; A Flag & Flags prime\n");
6332 fprintf(fp, "_z80bcprime dd 0 ; BC prime\n");
6333 fprintf(fp, "_z80deprime dd 0 ; DE prime\n");
6334 fprintf(fp, "_z80hlprime dd 0 ; HL prime\n");
6335 fprintf(fp, "\n");
6336 fprintf(fp, "; The order of the following registers can be changed without adverse\n");
6337 fprintf(fp, "; effect. Keep the WORD and DWORDs on boundaries of two for faster access\n");
6338 fprintf(fp, "\n");
6339 fprintf(fp, "_z80ix dd 0 ; IX\n");
6340 fprintf(fp, "_z80iy dd 0 ; IY\n");
6341 fprintf(fp, "_z80sp dd 0 ; Stack pointer\n");
6343 if (bPlain)
6344 fprintf(fp,"z80pc:\n");
6346 fprintf(fp, "z80pc_:\n");
6347 fprintf(fp, "_z80pc dd 0 ; PC\n");
6348 fprintf(fp, "_z80nmiAddr dd 0 ; Address to jump to for NMI\n");
6349 fprintf(fp, "z80intAddr:\n");
6350 fprintf(fp, "_z80intAddr dd 0 ; Address to jump to for INT\n");
6351 fprintf(fp, "_z80rCounter dd 0 ; R Register counter\n");
6352 fprintf(fp, "_z80i db 0 ; I register\n");
6353 fprintf(fp, "_z80r db 0 ; R register\n");
6354 fprintf(fp, "_z80intPending db 0 ; Non-zero if an interrupt is pending\n");
6355 fprintf(fp, "\n");
6356 fprintf(fp, "_%scontextEnd:\n", cpubasename);
6357 Alignment();
6358 fprintf(fp, "dwElapsedTicks dd 0 ; # Of ticks elapsed\n");
6359 fprintf(fp, "cyclesRemaining dd 0 ; # Of cycles remaining\n");
6360 fprintf(fp, "dwOriginalExec dd 0 ; # Of cycles originally executing\n");
6361 fprintf(fp, "dwLastRSample dd 0 ; Last sample for R computation\n");
6362 fprintf(fp, "dwEITiming dd 0 ; Used when we cause an interrupt\n");
6363 fprintf(fp, "_orgval dw 0 ; Scratch area\n");
6364 fprintf(fp, "_orgval2 dw 0 ; Scratch area\n");
6365 fprintf(fp, "_wordval dw 0 ; Scratch area\n");
6366 fprintf(fp, "_intData db 0 ; Interrupt data when an interrupt is pending\n");
6367 fprintf(fp, "bEIExit db 0 ; Are we exiting because of an EI instruction?\n");
6368 fprintf(fp, "\n");
6370 // Debugger junk
6372 fprintf(fp, "RegTextPC db 'PC',0\n");
6373 fprintf(fp, "RegTextAF db 'AF',0\n");
6374 fprintf(fp, "RegTextBC db 'BC',0\n");
6375 fprintf(fp, "RegTextDE db 'DE',0\n");
6376 fprintf(fp, "RegTextHL db 'HL',0\n");
6377 fprintf(fp, "RegTextAFP db 'AF',27h,0\n");
6378 fprintf(fp, "RegTextBCP db 'BC',27h,0\n");
6379 fprintf(fp, "RegTextDEP db 'DE',27h,0\n");
6380 fprintf(fp, "RegTextHLP db 'HL',27h,0\n");
6381 fprintf(fp, "RegTextIX db 'IX',0\n");
6382 fprintf(fp, "RegTextIY db 'IY',0\n");
6383 fprintf(fp, "RegTextSP db 'SP',0\n");
6384 fprintf(fp, "RegTextI db 'I',0\n");
6385 fprintf(fp, "RegTextR db 'R',0\n");
6387 // 8 Byte textual info
6389 fprintf(fp, "RegTextA db 'A',0\n");
6390 fprintf(fp, "RegTextB db 'B',0\n");
6391 fprintf(fp, "RegTextC db 'C',0\n");
6392 fprintf(fp, "RegTextD db 'D',0\n");
6393 fprintf(fp, "RegTextE db 'E',0\n");
6394 fprintf(fp, "RegTextH db 'H',0\n");
6395 fprintf(fp, "RegTextL db 'L',0\n");
6396 fprintf(fp, "RegTextF db 'F',0\n");
6398 // Individual flags
6400 fprintf(fp, "RegTextCarry db 'Carry',0\n");
6401 fprintf(fp, "RegTextNegative db 'Negative',0\n");
6402 fprintf(fp, "RegTextParity db 'Parity',0\n");
6403 fprintf(fp, "RegTextOverflow db 'Overflow',0\n");
6404 fprintf(fp, "RegTextHalfCarry db 'HalfCarry',0\n");
6405 fprintf(fp, "RegTextZero db 'Zero',0\n");
6406 fprintf(fp, "RegTextSign db 'Sign',0\n");
6407 fprintf(fp, "RegTextIFF1 db 'IFF1',0\n");
6408 fprintf(fp, "RegTextIFF2 db 'IFF2',0\n\n");
6410 // Timing for interrupt modes
6412 fprintf(fp, "intModeTStates:\n");
6413 fprintf(fp, " db 13 ; IM 0 - 13 T-States\n");
6414 fprintf(fp, " db 11 ; IM 1 - 11 T-States\n");
6415 fprintf(fp, " db 11 ; IM 2 - 11 T-States\n\n");
6417 // Now the master reg/flag table
6419 fprintf(fp, "\n;\n");
6420 fprintf(fp, "; Info is in: pointer to text, address, shift value, mask value, size of data chunk\n");
6421 fprintf(fp, ";\n\n");
6422 fprintf(fp, "RegTable:\n");
6424 // Pointer to text, address, shift value, mask, size
6426 fprintf(fp, " dd RegTextPC, _z80pc - _%scontextBegin, 0, 0ffffh\n", cpubasename);
6427 fprintf(fp, " dd RegTextSP, _z80sp - _%scontextBegin, 0, 0ffffh\n", cpubasename);
6428 fprintf(fp, " dd RegTextAF, _z80af - _%scontextBegin, 0, 0ffffh\n", cpubasename);
6429 fprintf(fp, " dd RegTextBC, _z80bc - _%scontextBegin, 0, 0ffffh\n", cpubasename);
6430 fprintf(fp, " dd RegTextDE, _z80de - _%scontextBegin, 0, 0ffffh\n", cpubasename);
6431 fprintf(fp, " dd RegTextHL, _z80hl - _%scontextBegin, 0, 0ffffh\n", cpubasename);
6432 fprintf(fp, " dd RegTextAFP, _z80af - _%scontextBegin, 0, 0ffffh\n", cpubasename);
6433 fprintf(fp, " dd RegTextBCP, _z80bc - _%scontextBegin, 0, 0ffffh\n", cpubasename);
6434 fprintf(fp, " dd RegTextDEP, _z80de - _%scontextBegin, 0, 0ffffh\n", cpubasename);
6435 fprintf(fp, " dd RegTextHLP, _z80hl - _%scontextBegin, 0, 0ffffh\n", cpubasename);
6436 fprintf(fp, " dd RegTextIX, _z80ix - _%scontextBegin, 0, 0ffffh\n", cpubasename);
6437 fprintf(fp, " dd RegTextIY, _z80iy - _%scontextBegin, 0, 0ffffh\n", cpubasename);
6438 fprintf(fp, " dd RegTextI, _z80i - _%scontextBegin, 0, 0ffh\n", cpubasename);
6439 fprintf(fp, " dd RegTextR, _z80r - _%scontextBegin, 0, 0ffh\n", cpubasename);
6441 // Individual regs
6443 fprintf(fp, " dd RegTextA, (_z80af + 1) - _%scontextBegin, 0, 0ffh\n", cpubasename);
6444 fprintf(fp, " dd RegTextF, _z80af - _%scontextBegin, 0, 0ffh\n", cpubasename);
6445 fprintf(fp, " dd RegTextB, (_z80bc + 1) - _%scontextBegin, 0, 0ffh\n", cpubasename);
6446 fprintf(fp, " dd RegTextC, _z80bc - _%scontextBegin, 0, 0ffh\n", cpubasename);
6447 fprintf(fp, " dd RegTextD, (_z80de + 1) - _%scontextBegin, 0, 0ffh\n", cpubasename);
6448 fprintf(fp, " dd RegTextE, _z80de - _%scontextBegin, 0, 0ffh\n", cpubasename);
6449 fprintf(fp, " dd RegTextH, (_z80hl + 1) - _%scontextBegin, 0, 0ffh\n", cpubasename);
6450 fprintf(fp, " dd RegTextL, _z80hl - _%scontextBegin, 0, 0ffh\n", cpubasename);
6452 // IFF register
6454 fprintf(fp, " dd RegTextIFF1, _z80iff - _%scontextBegin, 0, 01h\n", cpubasename);
6455 fprintf(fp, " dd RegTextIFF2, _z80iff - _%scontextBegin, 1, 01h\n", cpubasename);
6457 // Individual flags
6459 fprintf(fp, " dd RegTextCarry, _z80af - _%scontextBegin, 0, 01h\n", cpubasename);
6460 fprintf(fp, " dd RegTextNegative, _z80af - _%scontextBegin, 1, 01h\n", cpubasename);
6461 fprintf(fp, " dd RegTextParity, _z80af - _%scontextBegin, 2, 01h\n", cpubasename);
6462 fprintf(fp, " dd RegTextOverflow, _z80af - _%scontextBegin, 2, 01h\n", cpubasename);
6463 fprintf(fp, " dd RegTextHalfCarry, _z80af - _%scontextBegin, 4, 01h\n", cpubasename);
6464 fprintf(fp, " dd RegTextZero, _z80af - _%scontextBegin, 6, 01h\n", cpubasename);
6465 fprintf(fp, " dd RegTextSign, _z80af - _%scontextBegin, 7, 01h\n", cpubasename);
6467 // Now we write out our tables
6469 Alignment();
6471 for (dwLoop = 0; dwLoop < 256; dwLoop++)
6472 bUsed[dwLoop] = 0;
6474 // Now rip through and find out what is and isn't used
6476 dwLoop = 0;
6478 while (StandardOps[dwLoop].Emitter)
6480 assert(StandardOps[dwLoop].bOpCode < 0x100);
6481 if (bUsed[StandardOps[dwLoop].bOpCode])
6483 fprintf(stderr, "Oops! %.2x\n", dwLoop);
6484 fclose(fp);
6485 exit(1);
6487 bUsed[StandardOps[dwLoop].bOpCode] = 1;
6488 dwLoop++;
6491 // Now that that's taken care of, emit the table
6493 fprintf(fp, "z80regular:\n");
6495 dwLoop = 0;
6497 while (dwLoop < 0x100)
6499 fprintf(fp, " dd ");
6500 if (bUsed[dwLoop])
6501 fprintf(fp, "RegInst%.2x", dwLoop);
6502 else
6503 fprintf(fp, "invalidInsByte");
6504 fprintf(fp, "\n");
6505 dwLoop++;
6507 fprintf(fp, "\n");
6509 // Now rip through and find out what is and isn't used (CB Ops)
6511 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
6512 bUsed[dwLoop] = 0;
6514 dwLoop = 0;
6516 while (CBOps[dwLoop].Emitter)
6518 assert(CBOps[dwLoop].bOpCode < 0x100);
6519 if (bUsed[CBOps[dwLoop].bOpCode])
6521 fprintf(stderr, "Oops CB! %.2x\n", dwLoop);
6522 fclose(fp);
6523 exit(1);
6525 bUsed[CBOps[dwLoop].bOpCode] = 1;
6526 dwLoop++;
6529 dwLoop = 0;
6531 // Let's emit the CB prefixes
6533 fprintf(fp, "z80PrefixCB:\n");
6535 while (dwLoop < 0x100)
6537 fprintf(fp, " dd ");
6538 if (bUsed[dwLoop])
6539 fprintf(fp, "CBInst%.2x", dwLoop);
6540 else
6541 fprintf(fp, "invalidInsWord");
6542 fprintf(fp, "\n");
6543 dwLoop++;
6545 fprintf(fp, "\n");
6547 // Now rip through and find out what is and isn't used (ED Ops)
6549 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
6550 bUsed[dwLoop] = 0;
6552 dwLoop = 0;
6554 while (EDOps[dwLoop].Emitter)
6556 assert(EDOps[dwLoop].bOpCode < 0x100);
6557 if (bUsed[EDOps[dwLoop].bOpCode])
6559 fprintf(stderr, "Oops ED! %.2x\n", dwLoop);
6560 fclose(fp);
6561 exit(1);
6563 bUsed[EDOps[dwLoop].bOpCode] = 1;
6564 dwLoop++;
6567 dwLoop = 0;
6569 // Let's emit the ED prefixes
6571 fprintf(fp, "z80PrefixED:\n");
6573 while (dwLoop < 0x100)
6575 fprintf(fp, " dd ");
6576 if (bUsed[dwLoop])
6577 fprintf(fp, "EDInst%.2x", dwLoop);
6578 else
6579 fprintf(fp, "invalidInsWord");
6580 fprintf(fp, "\n");
6581 dwLoop++;
6583 fprintf(fp, "\n");
6585 // Now rip through and find out what is and isn't used (DD Ops)
6587 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
6588 bUsed[dwLoop] = 0;
6590 dwLoop = 0;
6592 while (DDFDOps[dwLoop].Emitter)
6594 assert(DDFDOps[dwLoop].bOpCode < 0x100);
6595 if (bUsed[DDFDOps[dwLoop].bOpCode])
6597 fprintf(stderr, "Oops DD! %.2x\n", bUsed[DDFDOps[dwLoop].bOpCode]);
6598 fclose(fp);
6599 exit(1);
6601 bUsed[DDFDOps[dwLoop].bOpCode] = 1;
6602 dwLoop++;
6605 dwLoop = 0;
6607 // Let's emit the DD prefixes
6609 fprintf(fp, "z80PrefixDD:\n");
6611 while (dwLoop < 0x100)
6613 fprintf(fp, " dd ");
6614 if (bUsed[dwLoop])
6615 fprintf(fp, "DDInst%.2x", dwLoop);
6616 else
6617 fprintf(fp, "invalidInsWord");
6618 fprintf(fp, "\n");
6619 dwLoop++;
6621 fprintf(fp, "\n");
6623 // Now rip through and find out what is and isn't used (FD Ops)
6625 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
6626 bUsed[dwLoop] = 0;
6628 dwLoop = 0;
6630 while (DDFDOps[dwLoop].Emitter)
6632 assert(DDFDOps[dwLoop].bOpCode < 0x100);
6633 if (bUsed[DDFDOps[dwLoop].bOpCode])
6635 fprintf(stderr, "Oops FD! %.2x\n", dwLoop);
6636 fclose(fp);
6637 exit(1);
6639 bUsed[DDFDOps[dwLoop].bOpCode] = 1;
6640 dwLoop++;
6643 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
6644 bUsed[dwLoop] = 0;
6646 // Let's emit the DDFD prefixes
6648 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
6649 bUsed[dwLoop] = 0;
6651 dwLoop = 0;
6653 while (DDFDOps[dwLoop].Emitter)
6655 assert(DDFDOps[dwLoop].bOpCode < 0x100);
6656 if (bUsed[DDFDOps[dwLoop].bOpCode])
6658 fprintf(stderr, "Oops FD! %.2x\n", dwLoop);
6659 exit(1);
6661 bUsed[DDFDOps[dwLoop].bOpCode] = 1;
6662 dwLoop++;
6665 dwLoop = 0;
6667 // Let's emit the DDFD prefixes
6669 fprintf(fp, "z80PrefixFD:\n");
6671 while (dwLoop < 0x100)
6673 fprintf(fp, " dd ");
6674 if (bUsed[dwLoop])
6675 fprintf(fp, "FDInst%.2x", dwLoop);
6676 else
6677 fprintf(fp, "invalidInsWord");
6678 fprintf(fp, "\n");
6679 dwLoop++;
6682 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
6683 bUsed[dwLoop] = 0;
6685 dwLoop = 0;
6687 while (DDFDCBOps[dwLoop].Emitter)
6689 assert(DDFDCBOps[dwLoop].bOpCode < 0x100);
6690 if (bUsed[DDFDCBOps[dwLoop].bOpCode])
6692 fprintf(stderr, "Oops CBFDDD! %.2x\n", bUsed[DDFDCBOps[dwLoop].bOpCode]);
6693 fclose(fp);
6694 exit(1);
6696 bUsed[DDFDCBOps[dwLoop].bOpCode] = 1;
6697 dwLoop++;
6700 // Let's emit the DDFD prefixes
6702 dwLoop = 0;
6704 fprintf(fp, "z80ddfdcbInstructions:\n");
6706 while (dwLoop < 0x100)
6708 fprintf(fp, " dd ");
6709 if (bUsed[dwLoop])
6710 fprintf(fp, "DDFDCBInst%.2x", dwLoop);
6711 else
6712 fprintf(fp, "invalidInsWord");
6713 fprintf(fp, "\n");
6714 dwLoop++;
6716 fprintf(fp, "\n");
6718 else
6719 if (MZ80_C == bWhat)
6721 fprintf(fp, "/* Modular global variables go here*/\n\n");
6722 fprintf(fp, "static CONTEXTMZ80 cpu; /* CPU Context */\n");
6723 fprintf(fp, "static UINT8 *pbPC; /* Program counter normalized */\n");
6724 fprintf(fp, "static UINT8 *pbSP; /* Stack pointer normalized */\n");
6725 fprintf(fp, "static struct MemoryReadByte *psMemRead; /* Read memory structure */\n");
6726 fprintf(fp, "static struct MemoryWriteByte *psMemWrite; /* Write memory structure */\n");
6727 fprintf(fp, "static struct z80PortRead *psIoRead; /* Read I/O structure */\n");
6728 fprintf(fp, "static struct z80PortWrite *psIoWrite; /* Write memory structure */\n");
6729 fprintf(fp, "static INT32 sdwCyclesRemaining; /* Used as a countdown */\n");
6730 fprintf(fp, "static UINT32 dwReturnCode; /* Return code from exec() */\n");
6731 fprintf(fp, "static UINT32 dwOriginalCycles; /* How many cycles did we start with? */\n");
6732 fprintf(fp, "static UINT32 dwElapsedTicks; /* How many ticks did we elapse? */\n");
6733 fprintf(fp, "static UINT32 sdwAddr; /* Temporary address storage */\n");
6734 fprintf(fp, "static UINT32 dwAddr; /* Temporary stack address */\n");
6735 fprintf(fp, "static UINT8 *pbAddAdcTable; /* Pointer to add/adc flag table */\n");
6736 fprintf(fp, "static UINT8 *pbSubSbcTable; /* Pointer to sub/sbc flag table */\n");
6737 fprintf(fp, "static UINT32 dwTemp; /* Temporary value */\n\n");
6738 fprintf(fp, "static UINT8 bTemp; /* Temporary value */\n\n");
6739 fprintf(fp, "static UINT8 bTemp2; /* Temporary value */\n\n");
6741 fprintf(fp, "/* Precomputed flag tables */\n\n");
6743 fprintf(fp, "static UINT8 bPostIncFlags[0x100] = \n");
6744 fprintf(fp, "{\n");
6745 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
6746 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
6747 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
6748 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
6749 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
6750 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
6751 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
6752 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,\n");
6753 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
6754 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
6755 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
6756 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
6757 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
6758 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
6759 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
6760 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x50\n");
6761 fprintf(fp, "};\n\n");
6763 fprintf(fp, "static UINT8 bPostDecFlags[0x100] = \n");
6764 fprintf(fp, "{\n");
6765 fprintf(fp, " 0x92,0x42,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
6766 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
6767 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
6768 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
6769 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
6770 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
6771 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
6772 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
6773 fprintf(fp, " 0x16,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
6774 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
6775 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
6776 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
6777 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
6778 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
6779 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
6780 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82\n");
6781 fprintf(fp, "};\n\n");
6783 fprintf(fp, "static UINT8 bPostORFlags[0x100] = \n");
6784 fprintf(fp, "{\n");
6785 fprintf(fp, " 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,\n");
6786 fprintf(fp, " 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,\n");
6787 fprintf(fp, " 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,\n");
6788 fprintf(fp, " 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,\n");
6789 fprintf(fp, " 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,\n");
6790 fprintf(fp, " 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,\n");
6791 fprintf(fp, " 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,\n");
6792 fprintf(fp, " 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,\n");
6793 fprintf(fp, " 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,\n");
6794 fprintf(fp, " 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,\n");
6795 fprintf(fp, " 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,\n");
6796 fprintf(fp, " 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,\n");
6797 fprintf(fp, " 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,\n");
6798 fprintf(fp, " 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,\n");
6799 fprintf(fp, " 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,\n");
6800 fprintf(fp, " 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84\n");
6801 fprintf(fp, "};\n\n");
6803 fprintf(fp, "static UINT8 bPostANDFlags[0x100] = \n");
6804 fprintf(fp, "{\n");
6805 fprintf(fp, " 0x54,0x10,0x10,0x14,0x10,0x14,0x14,0x10,0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,\n");
6806 fprintf(fp, " 0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,\n");
6807 fprintf(fp, " 0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,\n");
6808 fprintf(fp, " 0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,\n");
6809 fprintf(fp, " 0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,\n");
6810 fprintf(fp, " 0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,\n");
6811 fprintf(fp, " 0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,\n");
6812 fprintf(fp, " 0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,\n");
6813 fprintf(fp, " 0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,\n");
6814 fprintf(fp, " 0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,\n");
6815 fprintf(fp, " 0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,\n");
6816 fprintf(fp, " 0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,\n");
6817 fprintf(fp, " 0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,\n");
6818 fprintf(fp, " 0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,\n");
6819 fprintf(fp, " 0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,\n");
6820 fprintf(fp, " 0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94\n");
6821 fprintf(fp, "};\n\n");
6823 fprintf(fp, "static UINT16 wDAATable[0x800] = \n");
6824 fprintf(fp, "{\n");
6825 fprintf(fp, " 0x5400,0x1001,0x1002,0x1403,0x1004,0x1405,0x1406,0x1007,\n");
6826 fprintf(fp, " 0x1008,0x1409,0x1010,0x1411,0x1412,0x1013,0x1414,0x1015,\n");
6827 fprintf(fp, " 0x1010,0x1411,0x1412,0x1013,0x1414,0x1015,0x1016,0x1417,\n");
6828 fprintf(fp, " 0x1418,0x1019,0x1020,0x1421,0x1422,0x1023,0x1424,0x1025,\n");
6829 fprintf(fp, " 0x1020,0x1421,0x1422,0x1023,0x1424,0x1025,0x1026,0x1427,\n");
6830 fprintf(fp, " 0x1428,0x1029,0x1430,0x1031,0x1032,0x1433,0x1034,0x1435,\n");
6831 fprintf(fp, " 0x1430,0x1031,0x1032,0x1433,0x1034,0x1435,0x1436,0x1037,\n");
6832 fprintf(fp, " 0x1038,0x1439,0x1040,0x1441,0x1442,0x1043,0x1444,0x1045,\n");
6833 fprintf(fp, " 0x1040,0x1441,0x1442,0x1043,0x1444,0x1045,0x1046,0x1447,\n");
6834 fprintf(fp, " 0x1448,0x1049,0x1450,0x1051,0x1052,0x1453,0x1054,0x1455,\n");
6835 fprintf(fp, " 0x1450,0x1051,0x1052,0x1453,0x1054,0x1455,0x1456,0x1057,\n");
6836 fprintf(fp, " 0x1058,0x1459,0x1460,0x1061,0x1062,0x1463,0x1064,0x1465,\n");
6837 fprintf(fp, " 0x1460,0x1061,0x1062,0x1463,0x1064,0x1465,0x1466,0x1067,\n");
6838 fprintf(fp, " 0x1068,0x1469,0x1070,0x1471,0x1472,0x1073,0x1474,0x1075,\n");
6839 fprintf(fp, " 0x1070,0x1471,0x1472,0x1073,0x1474,0x1075,0x1076,0x1477,\n");
6840 fprintf(fp, " 0x1478,0x1079,0x9080,0x9481,0x9482,0x9083,0x9484,0x9085,\n");
6841 fprintf(fp, " 0x9080,0x9481,0x9482,0x9083,0x9484,0x9085,0x9086,0x9487,\n");
6842 fprintf(fp, " 0x9488,0x9089,0x9490,0x9091,0x9092,0x9493,0x9094,0x9495,\n");
6843 fprintf(fp, " 0x9490,0x9091,0x9092,0x9493,0x9094,0x9495,0x9496,0x9097,\n");
6844 fprintf(fp, " 0x9098,0x9499,0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,\n");
6845 fprintf(fp, " 0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,0x1506,0x1107,\n");
6846 fprintf(fp, " 0x1108,0x1509,0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,\n");
6847 fprintf(fp, " 0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,0x1116,0x1517,\n");
6848 fprintf(fp, " 0x1518,0x1119,0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,\n");
6849 fprintf(fp, " 0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,0x1126,0x1527,\n");
6850 fprintf(fp, " 0x1528,0x1129,0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,\n");
6851 fprintf(fp, " 0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,0x1536,0x1137,\n");
6852 fprintf(fp, " 0x1138,0x1539,0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,\n");
6853 fprintf(fp, " 0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,0x1146,0x1547,\n");
6854 fprintf(fp, " 0x1548,0x1149,0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,\n");
6855 fprintf(fp, " 0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,0x1556,0x1157,\n");
6856 fprintf(fp, " 0x1158,0x1559,0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,\n");
6857 fprintf(fp, " 0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,0x1566,0x1167,\n");
6858 fprintf(fp, " 0x1168,0x1569,0x1170,0x1571,0x1572,0x1173,0x1574,0x1175,\n");
6859 fprintf(fp, " 0x1170,0x1571,0x1572,0x1173,0x1574,0x1175,0x1176,0x1577,\n");
6860 fprintf(fp, " 0x1578,0x1179,0x9180,0x9581,0x9582,0x9183,0x9584,0x9185,\n");
6861 fprintf(fp, " 0x9180,0x9581,0x9582,0x9183,0x9584,0x9185,0x9186,0x9587,\n");
6862 fprintf(fp, " 0x9588,0x9189,0x9590,0x9191,0x9192,0x9593,0x9194,0x9595,\n");
6863 fprintf(fp, " 0x9590,0x9191,0x9192,0x9593,0x9194,0x9595,0x9596,0x9197,\n");
6864 fprintf(fp, " 0x9198,0x9599,0x95a0,0x91a1,0x91a2,0x95a3,0x91a4,0x95a5,\n");
6865 fprintf(fp, " 0x95a0,0x91a1,0x91a2,0x95a3,0x91a4,0x95a5,0x95a6,0x91a7,\n");
6866 fprintf(fp, " 0x91a8,0x95a9,0x91b0,0x95b1,0x95b2,0x91b3,0x95b4,0x91b5,\n");
6867 fprintf(fp, " 0x91b0,0x95b1,0x95b2,0x91b3,0x95b4,0x91b5,0x91b6,0x95b7,\n");
6868 fprintf(fp, " 0x95b8,0x91b9,0x95c0,0x91c1,0x91c2,0x95c3,0x91c4,0x95c5,\n");
6869 fprintf(fp, " 0x95c0,0x91c1,0x91c2,0x95c3,0x91c4,0x95c5,0x95c6,0x91c7,\n");
6870 fprintf(fp, " 0x91c8,0x95c9,0x91d0,0x95d1,0x95d2,0x91d3,0x95d4,0x91d5,\n");
6871 fprintf(fp, " 0x91d0,0x95d1,0x95d2,0x91d3,0x95d4,0x91d5,0x91d6,0x95d7,\n");
6872 fprintf(fp, " 0x95d8,0x91d9,0x91e0,0x95e1,0x95e2,0x91e3,0x95e4,0x91e5,\n");
6873 fprintf(fp, " 0x91e0,0x95e1,0x95e2,0x91e3,0x95e4,0x91e5,0x91e6,0x95e7,\n");
6874 fprintf(fp, " 0x95e8,0x91e9,0x95f0,0x91f1,0x91f2,0x95f3,0x91f4,0x95f5,\n");
6875 fprintf(fp, " 0x95f0,0x91f1,0x91f2,0x95f3,0x91f4,0x95f5,0x95f6,0x91f7,\n");
6876 fprintf(fp, " 0x91f8,0x95f9,0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,\n");
6877 fprintf(fp, " 0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,0x1506,0x1107,\n");
6878 fprintf(fp, " 0x1108,0x1509,0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,\n");
6879 fprintf(fp, " 0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,0x1116,0x1517,\n");
6880 fprintf(fp, " 0x1518,0x1119,0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,\n");
6881 fprintf(fp, " 0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,0x1126,0x1527,\n");
6882 fprintf(fp, " 0x1528,0x1129,0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,\n");
6883 fprintf(fp, " 0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,0x1536,0x1137,\n");
6884 fprintf(fp, " 0x1138,0x1539,0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,\n");
6885 fprintf(fp, " 0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,0x1146,0x1547,\n");
6886 fprintf(fp, " 0x1548,0x1149,0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,\n");
6887 fprintf(fp, " 0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,0x1556,0x1157,\n");
6888 fprintf(fp, " 0x1158,0x1559,0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,\n");
6889 fprintf(fp, " 0x1406,0x1007,0x1008,0x1409,0x140a,0x100b,0x140c,0x100d,\n");
6890 fprintf(fp, " 0x100e,0x140f,0x1010,0x1411,0x1412,0x1013,0x1414,0x1015,\n");
6891 fprintf(fp, " 0x1016,0x1417,0x1418,0x1019,0x101a,0x141b,0x101c,0x141d,\n");
6892 fprintf(fp, " 0x141e,0x101f,0x1020,0x1421,0x1422,0x1023,0x1424,0x1025,\n");
6893 fprintf(fp, " 0x1026,0x1427,0x1428,0x1029,0x102a,0x142b,0x102c,0x142d,\n");
6894 fprintf(fp, " 0x142e,0x102f,0x1430,0x1031,0x1032,0x1433,0x1034,0x1435,\n");
6895 fprintf(fp, " 0x1436,0x1037,0x1038,0x1439,0x143a,0x103b,0x143c,0x103d,\n");
6896 fprintf(fp, " 0x103e,0x143f,0x1040,0x1441,0x1442,0x1043,0x1444,0x1045,\n");
6897 fprintf(fp, " 0x1046,0x1447,0x1448,0x1049,0x104a,0x144b,0x104c,0x144d,\n");
6898 fprintf(fp, " 0x144e,0x104f,0x1450,0x1051,0x1052,0x1453,0x1054,0x1455,\n");
6899 fprintf(fp, " 0x1456,0x1057,0x1058,0x1459,0x145a,0x105b,0x145c,0x105d,\n");
6900 fprintf(fp, " 0x105e,0x145f,0x1460,0x1061,0x1062,0x1463,0x1064,0x1465,\n");
6901 fprintf(fp, " 0x1466,0x1067,0x1068,0x1469,0x146a,0x106b,0x146c,0x106d,\n");
6902 fprintf(fp, " 0x106e,0x146f,0x1070,0x1471,0x1472,0x1073,0x1474,0x1075,\n");
6903 fprintf(fp, " 0x1076,0x1477,0x1478,0x1079,0x107a,0x147b,0x107c,0x147d,\n");
6904 fprintf(fp, " 0x147e,0x107f,0x9080,0x9481,0x9482,0x9083,0x9484,0x9085,\n");
6905 fprintf(fp, " 0x9086,0x9487,0x9488,0x9089,0x908a,0x948b,0x908c,0x948d,\n");
6906 fprintf(fp, " 0x948e,0x908f,0x9490,0x9091,0x9092,0x9493,0x9094,0x9495,\n");
6907 fprintf(fp, " 0x9496,0x9097,0x9098,0x9499,0x949a,0x909b,0x949c,0x909d,\n");
6908 fprintf(fp, " 0x909e,0x949f,0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,\n");
6909 fprintf(fp, " 0x1506,0x1107,0x1108,0x1509,0x150a,0x110b,0x150c,0x110d,\n");
6910 fprintf(fp, " 0x110e,0x150f,0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,\n");
6911 fprintf(fp, " 0x1116,0x1517,0x1518,0x1119,0x111a,0x151b,0x111c,0x151d,\n");
6912 fprintf(fp, " 0x151e,0x111f,0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,\n");
6913 fprintf(fp, " 0x1126,0x1527,0x1528,0x1129,0x112a,0x152b,0x112c,0x152d,\n");
6914 fprintf(fp, " 0x152e,0x112f,0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,\n");
6915 fprintf(fp, " 0x1536,0x1137,0x1138,0x1539,0x153a,0x113b,0x153c,0x113d,\n");
6916 fprintf(fp, " 0x113e,0x153f,0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,\n");
6917 fprintf(fp, " 0x1146,0x1547,0x1548,0x1149,0x114a,0x154b,0x114c,0x154d,\n");
6918 fprintf(fp, " 0x154e,0x114f,0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,\n");
6919 fprintf(fp, " 0x1556,0x1157,0x1158,0x1559,0x155a,0x115b,0x155c,0x115d,\n");
6920 fprintf(fp, " 0x115e,0x155f,0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,\n");
6921 fprintf(fp, " 0x1566,0x1167,0x1168,0x1569,0x156a,0x116b,0x156c,0x116d,\n");
6922 fprintf(fp, " 0x116e,0x156f,0x1170,0x1571,0x1572,0x1173,0x1574,0x1175,\n");
6923 fprintf(fp, " 0x1176,0x1577,0x1578,0x1179,0x117a,0x157b,0x117c,0x157d,\n");
6924 fprintf(fp, " 0x157e,0x117f,0x9180,0x9581,0x9582,0x9183,0x9584,0x9185,\n");
6925 fprintf(fp, " 0x9186,0x9587,0x9588,0x9189,0x918a,0x958b,0x918c,0x958d,\n");
6926 fprintf(fp, " 0x958e,0x918f,0x9590,0x9191,0x9192,0x9593,0x9194,0x9595,\n");
6927 fprintf(fp, " 0x9596,0x9197,0x9198,0x9599,0x959a,0x919b,0x959c,0x919d,\n");
6928 fprintf(fp, " 0x919e,0x959f,0x95a0,0x91a1,0x91a2,0x95a3,0x91a4,0x95a5,\n");
6929 fprintf(fp, " 0x95a6,0x91a7,0x91a8,0x95a9,0x95aa,0x91ab,0x95ac,0x91ad,\n");
6930 fprintf(fp, " 0x91ae,0x95af,0x91b0,0x95b1,0x95b2,0x91b3,0x95b4,0x91b5,\n");
6931 fprintf(fp, " 0x91b6,0x95b7,0x95b8,0x91b9,0x91ba,0x95bb,0x91bc,0x95bd,\n");
6932 fprintf(fp, " 0x95be,0x91bf,0x95c0,0x91c1,0x91c2,0x95c3,0x91c4,0x95c5,\n");
6933 fprintf(fp, " 0x95c6,0x91c7,0x91c8,0x95c9,0x95ca,0x91cb,0x95cc,0x91cd,\n");
6934 fprintf(fp, " 0x91ce,0x95cf,0x91d0,0x95d1,0x95d2,0x91d3,0x95d4,0x91d5,\n");
6935 fprintf(fp, " 0x91d6,0x95d7,0x95d8,0x91d9,0x91da,0x95db,0x91dc,0x95dd,\n");
6936 fprintf(fp, " 0x95de,0x91df,0x91e0,0x95e1,0x95e2,0x91e3,0x95e4,0x91e5,\n");
6937 fprintf(fp, " 0x91e6,0x95e7,0x95e8,0x91e9,0x91ea,0x95eb,0x91ec,0x95ed,\n");
6938 fprintf(fp, " 0x95ee,0x91ef,0x95f0,0x91f1,0x91f2,0x95f3,0x91f4,0x95f5,\n");
6939 fprintf(fp, " 0x95f6,0x91f7,0x91f8,0x95f9,0x95fa,0x91fb,0x95fc,0x91fd,\n");
6940 fprintf(fp, " 0x91fe,0x95ff,0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,\n");
6941 fprintf(fp, " 0x1506,0x1107,0x1108,0x1509,0x150a,0x110b,0x150c,0x110d,\n");
6942 fprintf(fp, " 0x110e,0x150f,0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,\n");
6943 fprintf(fp, " 0x1116,0x1517,0x1518,0x1119,0x111a,0x151b,0x111c,0x151d,\n");
6944 fprintf(fp, " 0x151e,0x111f,0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,\n");
6945 fprintf(fp, " 0x1126,0x1527,0x1528,0x1129,0x112a,0x152b,0x112c,0x152d,\n");
6946 fprintf(fp, " 0x152e,0x112f,0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,\n");
6947 fprintf(fp, " 0x1536,0x1137,0x1138,0x1539,0x153a,0x113b,0x153c,0x113d,\n");
6948 fprintf(fp, " 0x113e,0x153f,0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,\n");
6949 fprintf(fp, " 0x1146,0x1547,0x1548,0x1149,0x114a,0x154b,0x114c,0x154d,\n");
6950 fprintf(fp, " 0x154e,0x114f,0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,\n");
6951 fprintf(fp, " 0x1556,0x1157,0x1158,0x1559,0x155a,0x115b,0x155c,0x115d,\n");
6952 fprintf(fp, " 0x115e,0x155f,0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,\n");
6953 fprintf(fp, " 0x5600,0x1201,0x1202,0x1603,0x1204,0x1605,0x1606,0x1207,\n");
6954 fprintf(fp, " 0x1208,0x1609,0x1204,0x1605,0x1606,0x1207,0x1208,0x1609,\n");
6955 fprintf(fp, " 0x1210,0x1611,0x1612,0x1213,0x1614,0x1215,0x1216,0x1617,\n");
6956 fprintf(fp, " 0x1618,0x1219,0x1614,0x1215,0x1216,0x1617,0x1618,0x1219,\n");
6957 fprintf(fp, " 0x1220,0x1621,0x1622,0x1223,0x1624,0x1225,0x1226,0x1627,\n");
6958 fprintf(fp, " 0x1628,0x1229,0x1624,0x1225,0x1226,0x1627,0x1628,0x1229,\n");
6959 fprintf(fp, " 0x1630,0x1231,0x1232,0x1633,0x1234,0x1635,0x1636,0x1237,\n");
6960 fprintf(fp, " 0x1238,0x1639,0x1234,0x1635,0x1636,0x1237,0x1238,0x1639,\n");
6961 fprintf(fp, " 0x1240,0x1641,0x1642,0x1243,0x1644,0x1245,0x1246,0x1647,\n");
6962 fprintf(fp, " 0x1648,0x1249,0x1644,0x1245,0x1246,0x1647,0x1648,0x1249,\n");
6963 fprintf(fp, " 0x1650,0x1251,0x1252,0x1653,0x1254,0x1655,0x1656,0x1257,\n");
6964 fprintf(fp, " 0x1258,0x1659,0x1254,0x1655,0x1656,0x1257,0x1258,0x1659,\n");
6965 fprintf(fp, " 0x1660,0x1261,0x1262,0x1663,0x1264,0x1665,0x1666,0x1267,\n");
6966 fprintf(fp, " 0x1268,0x1669,0x1264,0x1665,0x1666,0x1267,0x1268,0x1669,\n");
6967 fprintf(fp, " 0x1270,0x1671,0x1672,0x1273,0x1674,0x1275,0x1276,0x1677,\n");
6968 fprintf(fp, " 0x1678,0x1279,0x1674,0x1275,0x1276,0x1677,0x1678,0x1279,\n");
6969 fprintf(fp, " 0x9280,0x9681,0x9682,0x9283,0x9684,0x9285,0x9286,0x9687,\n");
6970 fprintf(fp, " 0x9688,0x9289,0x9684,0x9285,0x9286,0x9687,0x9688,0x9289,\n");
6971 fprintf(fp, " 0x9690,0x9291,0x9292,0x9693,0x9294,0x9695,0x9696,0x9297,\n");
6972 fprintf(fp, " 0x9298,0x9699,0x1334,0x1735,0x1736,0x1337,0x1338,0x1739,\n");
6973 fprintf(fp, " 0x1340,0x1741,0x1742,0x1343,0x1744,0x1345,0x1346,0x1747,\n");
6974 fprintf(fp, " 0x1748,0x1349,0x1744,0x1345,0x1346,0x1747,0x1748,0x1349,\n");
6975 fprintf(fp, " 0x1750,0x1351,0x1352,0x1753,0x1354,0x1755,0x1756,0x1357,\n");
6976 fprintf(fp, " 0x1358,0x1759,0x1354,0x1755,0x1756,0x1357,0x1358,0x1759,\n");
6977 fprintf(fp, " 0x1760,0x1361,0x1362,0x1763,0x1364,0x1765,0x1766,0x1367,\n");
6978 fprintf(fp, " 0x1368,0x1769,0x1364,0x1765,0x1766,0x1367,0x1368,0x1769,\n");
6979 fprintf(fp, " 0x1370,0x1771,0x1772,0x1373,0x1774,0x1375,0x1376,0x1777,\n");
6980 fprintf(fp, " 0x1778,0x1379,0x1774,0x1375,0x1376,0x1777,0x1778,0x1379,\n");
6981 fprintf(fp, " 0x9380,0x9781,0x9782,0x9383,0x9784,0x9385,0x9386,0x9787,\n");
6982 fprintf(fp, " 0x9788,0x9389,0x9784,0x9385,0x9386,0x9787,0x9788,0x9389,\n");
6983 fprintf(fp, " 0x9790,0x9391,0x9392,0x9793,0x9394,0x9795,0x9796,0x9397,\n");
6984 fprintf(fp, " 0x9398,0x9799,0x9394,0x9795,0x9796,0x9397,0x9398,0x9799,\n");
6985 fprintf(fp, " 0x97a0,0x93a1,0x93a2,0x97a3,0x93a4,0x97a5,0x97a6,0x93a7,\n");
6986 fprintf(fp, " 0x93a8,0x97a9,0x93a4,0x97a5,0x97a6,0x93a7,0x93a8,0x97a9,\n");
6987 fprintf(fp, " 0x93b0,0x97b1,0x97b2,0x93b3,0x97b4,0x93b5,0x93b6,0x97b7,\n");
6988 fprintf(fp, " 0x97b8,0x93b9,0x97b4,0x93b5,0x93b6,0x97b7,0x97b8,0x93b9,\n");
6989 fprintf(fp, " 0x97c0,0x93c1,0x93c2,0x97c3,0x93c4,0x97c5,0x97c6,0x93c7,\n");
6990 fprintf(fp, " 0x93c8,0x97c9,0x93c4,0x97c5,0x97c6,0x93c7,0x93c8,0x97c9,\n");
6991 fprintf(fp, " 0x93d0,0x97d1,0x97d2,0x93d3,0x97d4,0x93d5,0x93d6,0x97d7,\n");
6992 fprintf(fp, " 0x97d8,0x93d9,0x97d4,0x93d5,0x93d6,0x97d7,0x97d8,0x93d9,\n");
6993 fprintf(fp, " 0x93e0,0x97e1,0x97e2,0x93e3,0x97e4,0x93e5,0x93e6,0x97e7,\n");
6994 fprintf(fp, " 0x97e8,0x93e9,0x97e4,0x93e5,0x93e6,0x97e7,0x97e8,0x93e9,\n");
6995 fprintf(fp, " 0x97f0,0x93f1,0x93f2,0x97f3,0x93f4,0x97f5,0x97f6,0x93f7,\n");
6996 fprintf(fp, " 0x93f8,0x97f9,0x93f4,0x97f5,0x97f6,0x93f7,0x93f8,0x97f9,\n");
6997 fprintf(fp, " 0x5700,0x1301,0x1302,0x1703,0x1304,0x1705,0x1706,0x1307,\n");
6998 fprintf(fp, " 0x1308,0x1709,0x1304,0x1705,0x1706,0x1307,0x1308,0x1709,\n");
6999 fprintf(fp, " 0x1310,0x1711,0x1712,0x1313,0x1714,0x1315,0x1316,0x1717,\n");
7000 fprintf(fp, " 0x1718,0x1319,0x1714,0x1315,0x1316,0x1717,0x1718,0x1319,\n");
7001 fprintf(fp, " 0x1320,0x1721,0x1722,0x1323,0x1724,0x1325,0x1326,0x1727,\n");
7002 fprintf(fp, " 0x1728,0x1329,0x1724,0x1325,0x1326,0x1727,0x1728,0x1329,\n");
7003 fprintf(fp, " 0x1730,0x1331,0x1332,0x1733,0x1334,0x1735,0x1736,0x1337,\n");
7004 fprintf(fp, " 0x1338,0x1739,0x1334,0x1735,0x1736,0x1337,0x1338,0x1739,\n");
7005 fprintf(fp, " 0x1340,0x1741,0x1742,0x1343,0x1744,0x1345,0x1346,0x1747,\n");
7006 fprintf(fp, " 0x1748,0x1349,0x1744,0x1345,0x1346,0x1747,0x1748,0x1349,\n");
7007 fprintf(fp, " 0x1750,0x1351,0x1352,0x1753,0x1354,0x1755,0x1756,0x1357,\n");
7008 fprintf(fp, " 0x1358,0x1759,0x1354,0x1755,0x1756,0x1357,0x1358,0x1759,\n");
7009 fprintf(fp, " 0x1760,0x1361,0x1362,0x1763,0x1364,0x1765,0x1766,0x1367,\n");
7010 fprintf(fp, " 0x1368,0x1769,0x1364,0x1765,0x1766,0x1367,0x1368,0x1769,\n");
7011 fprintf(fp, " 0x1370,0x1771,0x1772,0x1373,0x1774,0x1375,0x1376,0x1777,\n");
7012 fprintf(fp, " 0x1778,0x1379,0x1774,0x1375,0x1376,0x1777,0x1778,0x1379,\n");
7013 fprintf(fp, " 0x9380,0x9781,0x9782,0x9383,0x9784,0x9385,0x9386,0x9787,\n");
7014 fprintf(fp, " 0x9788,0x9389,0x9784,0x9385,0x9386,0x9787,0x9788,0x9389,\n");
7015 fprintf(fp, " 0x9790,0x9391,0x9392,0x9793,0x9394,0x9795,0x9796,0x9397,\n");
7016 fprintf(fp, " 0x9398,0x9799,0x9394,0x9795,0x9796,0x9397,0x9398,0x9799,\n");
7017 fprintf(fp, " 0x97fa,0x93fb,0x97fc,0x93fd,0x93fe,0x97ff,0x5600,0x1201,\n");
7018 fprintf(fp, " 0x1202,0x1603,0x1204,0x1605,0x1606,0x1207,0x1208,0x1609,\n");
7019 fprintf(fp, " 0x160a,0x120b,0x160c,0x120d,0x120e,0x160f,0x1210,0x1611,\n");
7020 fprintf(fp, " 0x1612,0x1213,0x1614,0x1215,0x1216,0x1617,0x1618,0x1219,\n");
7021 fprintf(fp, " 0x121a,0x161b,0x121c,0x161d,0x161e,0x121f,0x1220,0x1621,\n");
7022 fprintf(fp, " 0x1622,0x1223,0x1624,0x1225,0x1226,0x1627,0x1628,0x1229,\n");
7023 fprintf(fp, " 0x122a,0x162b,0x122c,0x162d,0x162e,0x122f,0x1630,0x1231,\n");
7024 fprintf(fp, " 0x1232,0x1633,0x1234,0x1635,0x1636,0x1237,0x1238,0x1639,\n");
7025 fprintf(fp, " 0x163a,0x123b,0x163c,0x123d,0x123e,0x163f,0x1240,0x1641,\n");
7026 fprintf(fp, " 0x1642,0x1243,0x1644,0x1245,0x1246,0x1647,0x1648,0x1249,\n");
7027 fprintf(fp, " 0x124a,0x164b,0x124c,0x164d,0x164e,0x124f,0x1650,0x1251,\n");
7028 fprintf(fp, " 0x1252,0x1653,0x1254,0x1655,0x1656,0x1257,0x1258,0x1659,\n");
7029 fprintf(fp, " 0x165a,0x125b,0x165c,0x125d,0x125e,0x165f,0x1660,0x1261,\n");
7030 fprintf(fp, " 0x1262,0x1663,0x1264,0x1665,0x1666,0x1267,0x1268,0x1669,\n");
7031 fprintf(fp, " 0x166a,0x126b,0x166c,0x126d,0x126e,0x166f,0x1270,0x1671,\n");
7032 fprintf(fp, " 0x1672,0x1273,0x1674,0x1275,0x1276,0x1677,0x1678,0x1279,\n");
7033 fprintf(fp, " 0x127a,0x167b,0x127c,0x167d,0x167e,0x127f,0x9280,0x9681,\n");
7034 fprintf(fp, " 0x9682,0x9283,0x9684,0x9285,0x9286,0x9687,0x9688,0x9289,\n");
7035 fprintf(fp, " 0x928a,0x968b,0x928c,0x968d,0x968e,0x928f,0x9690,0x9291,\n");
7036 fprintf(fp, " 0x9292,0x9693,0x1334,0x1735,0x1736,0x1337,0x1338,0x1739,\n");
7037 fprintf(fp, " 0x173a,0x133b,0x173c,0x133d,0x133e,0x173f,0x1340,0x1741,\n");
7038 fprintf(fp, " 0x1742,0x1343,0x1744,0x1345,0x1346,0x1747,0x1748,0x1349,\n");
7039 fprintf(fp, " 0x134a,0x174b,0x134c,0x174d,0x174e,0x134f,0x1750,0x1351,\n");
7040 fprintf(fp, " 0x1352,0x1753,0x1354,0x1755,0x1756,0x1357,0x1358,0x1759,\n");
7041 fprintf(fp, " 0x175a,0x135b,0x175c,0x135d,0x135e,0x175f,0x1760,0x1361,\n");
7042 fprintf(fp, " 0x1362,0x1763,0x1364,0x1765,0x1766,0x1367,0x1368,0x1769,\n");
7043 fprintf(fp, " 0x176a,0x136b,0x176c,0x136d,0x136e,0x176f,0x1370,0x1771,\n");
7044 fprintf(fp, " 0x1772,0x1373,0x1774,0x1375,0x1376,0x1777,0x1778,0x1379,\n");
7045 fprintf(fp, " 0x137a,0x177b,0x137c,0x177d,0x177e,0x137f,0x9380,0x9781,\n");
7046 fprintf(fp, " 0x9782,0x9383,0x9784,0x9385,0x9386,0x9787,0x9788,0x9389,\n");
7047 fprintf(fp, " 0x938a,0x978b,0x938c,0x978d,0x978e,0x938f,0x9790,0x9391,\n");
7048 fprintf(fp, " 0x9392,0x9793,0x9394,0x9795,0x9796,0x9397,0x9398,0x9799,\n");
7049 fprintf(fp, " 0x979a,0x939b,0x979c,0x939d,0x939e,0x979f,0x97a0,0x93a1,\n");
7050 fprintf(fp, " 0x93a2,0x97a3,0x93a4,0x97a5,0x97a6,0x93a7,0x93a8,0x97a9,\n");
7051 fprintf(fp, " 0x97aa,0x93ab,0x97ac,0x93ad,0x93ae,0x97af,0x93b0,0x97b1,\n");
7052 fprintf(fp, " 0x97b2,0x93b3,0x97b4,0x93b5,0x93b6,0x97b7,0x97b8,0x93b9,\n");
7053 fprintf(fp, " 0x93ba,0x97bb,0x93bc,0x97bd,0x97be,0x93bf,0x97c0,0x93c1,\n");
7054 fprintf(fp, " 0x93c2,0x97c3,0x93c4,0x97c5,0x97c6,0x93c7,0x93c8,0x97c9,\n");
7055 fprintf(fp, " 0x97ca,0x93cb,0x97cc,0x93cd,0x93ce,0x97cf,0x93d0,0x97d1,\n");
7056 fprintf(fp, " 0x97d2,0x93d3,0x97d4,0x93d5,0x93d6,0x97d7,0x97d8,0x93d9,\n");
7057 fprintf(fp, " 0x93da,0x97db,0x93dc,0x97dd,0x97de,0x93df,0x93e0,0x97e1,\n");
7058 fprintf(fp, " 0x97e2,0x93e3,0x97e4,0x93e5,0x93e6,0x97e7,0x97e8,0x93e9,\n");
7059 fprintf(fp, " 0x93ea,0x97eb,0x93ec,0x97ed,0x97ee,0x93ef,0x97f0,0x93f1,\n");
7060 fprintf(fp, " 0x93f2,0x97f3,0x93f4,0x97f5,0x97f6,0x93f7,0x93f8,0x97f9,\n");
7061 fprintf(fp, " 0x97fa,0x93fb,0x97fc,0x93fd,0x93fe,0x97ff,0x5700,0x1301,\n");
7062 fprintf(fp, " 0x1302,0x1703,0x1304,0x1705,0x1706,0x1307,0x1308,0x1709,\n");
7063 fprintf(fp, " 0x170a,0x130b,0x170c,0x130d,0x130e,0x170f,0x1310,0x1711,\n");
7064 fprintf(fp, " 0x1712,0x1313,0x1714,0x1315,0x1316,0x1717,0x1718,0x1319,\n");
7065 fprintf(fp, " 0x131a,0x171b,0x131c,0x171d,0x171e,0x131f,0x1320,0x1721,\n");
7066 fprintf(fp, " 0x1722,0x1323,0x1724,0x1325,0x1326,0x1727,0x1728,0x1329,\n");
7067 fprintf(fp, " 0x132a,0x172b,0x132c,0x172d,0x172e,0x132f,0x1730,0x1331,\n");
7068 fprintf(fp, " 0x1332,0x1733,0x1334,0x1735,0x1736,0x1337,0x1338,0x1739,\n");
7069 fprintf(fp, " 0x173a,0x133b,0x173c,0x133d,0x133e,0x173f,0x1340,0x1741,\n");
7070 fprintf(fp, " 0x1742,0x1343,0x1744,0x1345,0x1346,0x1747,0x1748,0x1349,\n");
7071 fprintf(fp, " 0x134a,0x174b,0x134c,0x174d,0x174e,0x134f,0x1750,0x1351,\n");
7072 fprintf(fp, " 0x1352,0x1753,0x1354,0x1755,0x1756,0x1357,0x1358,0x1759,\n");
7073 fprintf(fp, " 0x175a,0x135b,0x175c,0x135d,0x135e,0x175f,0x1760,0x1361,\n");
7074 fprintf(fp, " 0x1362,0x1763,0x1364,0x1765,0x1766,0x1367,0x1368,0x1769,\n");
7075 fprintf(fp, " 0x176a,0x136b,0x176c,0x136d,0x136e,0x176f,0x1370,0x1771,\n");
7076 fprintf(fp, " 0x1772,0x1373,0x1774,0x1375,0x1376,0x1777,0x1778,0x1379,\n");
7077 fprintf(fp, " 0x137a,0x177b,0x137c,0x177d,0x177e,0x137f,0x9380,0x9781,\n");
7078 fprintf(fp, " 0x9782,0x9383,0x9784,0x9385,0x9386,0x9787,0x9788,0x9389,\n");
7079 fprintf(fp, " 0x938a,0x978b,0x938c,0x978d,0x978e,0x938f,0x9790,0x9391,\n");
7080 fprintf(fp, " 0x9392,0x9793,0x9394,0x9795,0x9796,0x9397,0x9398,0x9799 \n");
7081 fprintf(fp, "};\n\n");
7083 fprintf(fp, "void DDFDCBHandler(UINT32 dwWhich);\n\n");
7085 fprintf(fp, "\n");
7087 else
7089 abort();
7093 void CodeSegmentBegin(void)
7095 if (MZ80_ASSEMBLY_X86 == bWhat)
7097 fprintf(fp, " section .text use32 flat class=code\n");
7099 else
7100 if (MZ80_C == bWhat)
7102 fprintf(fp, "static void InvalidInstruction(UINT32 dwCount)\n");
7103 fprintf(fp, "{\n");
7105 fprintf(fp, " pbPC -= dwCount; /* Invalid instruction - back up */\n");
7106 fprintf(fp, " dwReturnCode = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
7107 fprintf(fp, " dwOriginalCycles -= sdwCyclesRemaining;\n");
7108 fprintf(fp, " sdwCyclesRemaining = 0;\n");
7110 fprintf(fp, "}\n\n");
7112 else
7114 abort();
7118 void CodeSegmentEnd(void)
7122 void ProgramEnd(void)
7124 if (MZ80_ASSEMBLY_X86 == bWhat)
7126 fprintf(fp, "\n");
7127 fprintf(fp, "%%ifdef NASM_STACK_NOEXEC\n");
7128 fprintf(fp, "section .note.GNU-stack noalloc noexec nowrite progbits\n");
7129 fprintf(fp, "%%endif\n");
7131 else
7132 if (MZ80_C == bWhat)
7135 else
7137 abort();
7141 void EmitRegularInstructions(void)
7143 UINT32 dwLoop = 0;
7144 UINT32 dwLoop2 = 0;
7146 bCurrentMode = TIMING_REGULAR;
7148 if (MZ80_ASSEMBLY_X86 == bWhat)
7150 while (dwLoop < 0x100)
7152 dwLoop2 = 0;
7153 sprintf(procname, "RegInst%.2x", dwLoop);
7155 while (StandardOps[dwLoop2].bOpCode != dwLoop && StandardOps[dwLoop2].bOpCode != 0xffffffff)
7156 dwLoop2++;
7158 assert(dwLoop2 < 0x100);
7159 if (StandardOps[dwLoop2].Emitter
7160 && StandardOps[dwLoop2].bOpCode != 0xffffffff)
7161 StandardOps[dwLoop2].Emitter((UINT32) dwLoop);
7163 dwLoop++;
7166 else
7167 if (MZ80_C == bWhat)
7169 fprintf(fp, "/* Main execution entry point */\n\n");
7171 fprintf(fp, "UINT32 %sexec(UINT32 dwCycles)\n", cpubasename);
7172 fprintf(fp, "{\n");
7173 fprintf(fp, " UINT8 bOpcode;\n\n");
7175 fprintf(fp, " dwReturnCode = 0x80000000; /* Assume it'll work */\n");
7177 fprintf(fp, " sdwCyclesRemaining = dwCycles;\n");
7178 fprintf(fp, " dwOriginalCycles = dwCycles;\n");
7180 fprintf(fp, " if (cpu.z80halted)\n");
7181 fprintf(fp, " {\n");
7183 fprintf(fp, " dwElapsedTicks += dwCycles;\n");
7184 fprintf(fp, " return(0x80000000);\n");
7186 fprintf(fp, " }\n\n");
7189 fprintf(fp, " pbPC = cpu.z80Base + cpu.z80pc;\n\n");
7191 fprintf(fp, " while (sdwCyclesRemaining > 0)\n");
7193 fprintf(fp, " {\n");
7194 fprintf(fp, " bOpcode = *pbPC++;\n");
7195 fprintf(fp, " switch (bOpcode)\n");
7196 fprintf(fp, " {\n");
7198 while (dwLoop < 0x100)
7200 dwLoop2 = 0;
7202 fprintf(fp, " case 0x%.2x:\n", dwLoop);
7203 fprintf(fp, " {\n");
7205 while (StandardOps[dwLoop2].bOpCode != dwLoop && StandardOps[dwLoop2].bOpCode != 0xffffffff)
7206 dwLoop2++;
7208 if (bTimingRegular[dwLoop])
7210 fprintf(fp, " sdwCyclesRemaining -= %" PRIu32 ";\n", bTimingRegular[dwLoop]);
7213 if (StandardOps[dwLoop2].Emitter)
7215 StandardOps[dwLoop2].Emitter(dwLoop);
7218 fprintf(fp, " break;\n");
7219 fprintf(fp, " }\n");
7220 ++dwLoop;
7223 fprintf(fp, " }\n");
7224 fprintf(fp, " }\n\n");
7226 fprintf(fp, " dwElapsedTicks += (dwOriginalCycles - sdwCyclesRemaining);\n\n");
7228 fprintf(fp, " cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
7230 fprintf(fp, " return(dwReturnCode); /* Indicate success */\n");
7231 fprintf(fp, "}\n\n");
7233 else
7235 abort();
7239 void EmitCBInstructions(void)
7241 UINT32 dwLoop = 0;
7242 UINT32 dwLoop2 = 0;
7244 bCurrentMode = TIMING_CB;
7246 if (MZ80_ASSEMBLY_X86 == bWhat)
7248 while (dwLoop < 0x100)
7250 sprintf(procname, "CBInst%.2x", dwLoop);
7251 dwLoop2 = 0;
7253 while (CBOps[dwLoop2].bOpCode != dwLoop && CBOps[dwLoop2].bOpCode != 0xffffffff)
7254 dwLoop2++;
7256 assert(dwLoop2 < 0x100);
7257 if (CBOps[dwLoop2].Emitter && CBOps[dwLoop2].bOpCode != 0xffffffff)
7258 CBOps[dwLoop2].Emitter((UINT32) dwLoop);
7260 dwLoop++;
7263 else
7264 if (MZ80_C == bWhat)
7266 fprintf(fp, "void CBHandler(void)\n");
7267 fprintf(fp, "{\n");
7268 fprintf(fp, " switch (*pbPC++)\n");
7269 fprintf(fp, " {\n");
7271 while (dwLoop < 0x100)
7273 dwLoop2 = 0;
7275 fprintf(fp, " case 0x%.2x:\n", dwLoop);
7276 fprintf(fp, " {\n");
7278 while (CBOps[dwLoop2].bOpCode != dwLoop && CBOps[dwLoop2].bOpCode != 0xffffffff)
7279 dwLoop2++;
7281 if (bTimingCB[dwLoop])
7283 fprintf(fp, " sdwCyclesRemaining -= %" PRIu32 ";\n", bTimingCB[dwLoop]);
7286 if (CBOps[dwLoop2].Emitter)
7288 CBOps[dwLoop2].Emitter(dwLoop);
7290 else
7292 InvalidInstructionC(2);
7295 fprintf(fp, " break;\n");
7296 fprintf(fp, " }\n");
7297 ++dwLoop;
7300 fprintf(fp, " }\n");
7301 fprintf(fp, "}\n");
7303 else
7305 abort();
7309 void EmitEDInstructions(void)
7311 UINT32 dwLoop = 0;
7312 UINT32 dwLoop2 = 0;
7314 bCurrentMode = TIMING_ED;
7316 if (MZ80_ASSEMBLY_X86 == bWhat)
7318 while (dwLoop < 0x100)
7320 sprintf(procname, "EDInst%.2x", dwLoop);
7321 dwLoop2 = 0;
7323 while (EDOps[dwLoop2].bOpCode != dwLoop && EDOps[dwLoop2].bOpCode != 0xffffffff)
7324 dwLoop2++;
7326 assert(dwLoop2 < 0x100);
7327 if (EDOps[dwLoop2].Emitter && EDOps[dwLoop2].bOpCode != 0xffffffff)
7328 EDOps[dwLoop2].Emitter((UINT32) dwLoop);
7330 dwLoop++;
7333 else
7334 if (MZ80_C == bWhat)
7336 fprintf(fp, "void EDHandler(void)\n");
7337 fprintf(fp, "{\n");
7338 fprintf(fp, " switch (*pbPC++)\n");
7339 fprintf(fp, " {\n");
7341 while (dwLoop < 0x100)
7343 dwLoop2 = 0;
7345 fprintf(fp, " case 0x%.2x:\n", dwLoop);
7346 fprintf(fp, " {\n");
7348 while (EDOps[dwLoop2].bOpCode != dwLoop && EDOps[dwLoop2].bOpCode != 0xffffffff)
7349 dwLoop2++;
7351 if (bTimingED[dwLoop])
7353 fprintf(fp, " sdwCyclesRemaining -= %" PRIu32 ";\n", bTimingED[dwLoop]);
7356 if (EDOps[dwLoop2].Emitter)
7358 EDOps[dwLoop2].Emitter(dwLoop);
7360 else
7362 InvalidInstructionC(2);
7365 fprintf(fp, " break;\n");
7366 fprintf(fp, " }\n");
7367 ++dwLoop;
7370 fprintf(fp, " }\n");
7371 fprintf(fp, "}\n");
7373 else
7375 abort();
7378 fprintf(fp, "\n");
7381 void EmitDDInstructions(void)
7383 UINT32 dwLoop = 0;
7384 UINT32 dwLoop2 = 0;
7386 bCurrentMode = TIMING_DDFD;
7388 if (MZ80_ASSEMBLY_X86 == bWhat)
7390 while (dwLoop < 0x100)
7392 sprintf(procname, "DDInst%.2x", dwLoop);
7393 dwLoop2 = 0;
7395 while (DDFDOps[dwLoop2].bOpCode != dwLoop && DDFDOps[dwLoop2].bOpCode != 0xffffffff)
7396 dwLoop2++;
7398 assert(dwLoop2 < 0x100);
7399 if (DDFDOps[dwLoop2].Emitter && DDFDOps[dwLoop2].bOpCode != 0xffffffff)
7400 DDFDOps[dwLoop2].Emitter((UINT32) dwLoop);
7402 dwLoop++;
7405 bCurrentMode = TIMING_XXCB;
7407 dwLoop = 0;
7409 while (dwLoop < 0x100)
7411 sprintf(procname, "DDFDCBInst%.2x", dwLoop);
7412 dwLoop2 = 0;
7414 while (DDFDCBOps[dwLoop2].bOpCode != dwLoop && DDFDCBOps[dwLoop2].bOpCode != 0xffffffff)
7415 dwLoop2++;
7417 assert(dwLoop2 < 0x100);
7418 if (DDFDCBOps[dwLoop2].Emitter && DDFDCBOps[dwLoop2].bOpCode != 0xffffffff)
7419 DDFDCBOps[dwLoop2].Emitter((UINT32) dwLoop);
7421 dwLoop++;
7424 else
7425 if (MZ80_C == bWhat)
7427 fprintf(fp, "void DDHandler(void)\n");
7428 fprintf(fp, "{\n");
7429 fprintf(fp, " switch (*pbPC++)\n");
7430 fprintf(fp, " {\n");
7432 while (dwLoop < 0x100)
7434 dwLoop2 = 0;
7436 fprintf(fp, " case 0x%.2x:\n", dwLoop);
7437 fprintf(fp, " {\n");
7439 while (DDFDOps[dwLoop2].bOpCode != dwLoop && DDFDOps[dwLoop2].bOpCode != 0xffffffff)
7440 dwLoop2++;
7442 if (bTimingDDFD[dwLoop])
7444 fprintf(fp, " sdwCyclesRemaining -= %" PRIu32 ";\n", bTimingDDFD[dwLoop]);
7447 if (DDFDOps[dwLoop2].Emitter)
7449 DDFDOps[dwLoop2].Emitter(dwLoop);
7451 else
7453 InvalidInstructionC(2);
7456 fprintf(fp, " break;\n");
7457 fprintf(fp, " }\n");
7458 ++dwLoop;
7461 fprintf(fp, " }\n");
7462 fprintf(fp, "}\n");
7464 // DDFD Handler
7466 bCurrentMode = TIMING_XXCB;
7468 dwLoop = 0;
7470 fprintf(fp, "void DDFDCBHandler(UINT32 dwWhich)\n");
7471 fprintf(fp, "{\n");
7472 fprintf(fp, " if (dwWhich)\n");
7473 fprintf(fp, " {\n");
7474 fprintf(fp, " dwAddr = (UINT32) ((INT32) cpu.z80IY + ((INT32) *pbPC++)) & 0xffff;\n");
7475 fprintf(fp, " }\n");
7476 fprintf(fp, " else\n");
7477 fprintf(fp, " {\n");
7478 fprintf(fp, " dwAddr = (UINT32) ((INT32) cpu.z80IX + ((INT32) *pbPC++)) & 0xffff;\n");
7479 fprintf(fp, " }\n\n");
7481 ReadValueFromMemory("dwAddr", "bTemp");
7483 fprintf(fp, " switch (*pbPC++)\n");
7484 fprintf(fp, " {\n");
7486 while (dwLoop < 0x100)
7488 dwLoop2 = 0;
7490 fprintf(fp, " case 0x%.2x:\n", dwLoop);
7491 fprintf(fp, " {\n");
7493 while (DDFDCBOps[dwLoop2].bOpCode != dwLoop && DDFDCBOps[dwLoop2].bOpCode != 0xffffffff)
7494 dwLoop2++;
7496 if (bTimingXXCB[dwLoop])
7498 fprintf(fp, " sdwCyclesRemaining -= %" PRIu32 ";\n", bTimingXXCB[dwLoop]);
7501 if (DDFDCBOps[dwLoop2].Emitter)
7503 DDFDCBOps[dwLoop2].Emitter(dwLoop);
7505 else
7507 InvalidInstructionC(4);
7510 fprintf(fp, " break;\n");
7511 fprintf(fp, " }\n");
7512 ++dwLoop;
7515 fprintf(fp, " }\n");
7516 fprintf(fp, "}\n");
7518 else
7520 abort();
7524 void EmitFDInstructions(void)
7526 UINT32 dwLoop = 0;
7527 UINT32 dwLoop2 = 0;
7529 bCurrentMode = TIMING_DDFD;
7531 if (MZ80_ASSEMBLY_X86 == bWhat)
7533 while (dwLoop < 0x100)
7535 sprintf(procname, "FDInst%.2x", dwLoop);
7536 dwLoop2 = 0;
7538 while (DDFDOps[dwLoop2].bOpCode != dwLoop && DDFDOps[dwLoop2].bOpCode != 0xffffffff)
7539 dwLoop2++;
7541 assert(dwLoop2 < 0x100);
7542 if (DDFDOps[dwLoop2].Emitter && DDFDOps[dwLoop2].bOpCode != 0xffffffff)
7543 DDFDOps[dwLoop2].Emitter((UINT32) dwLoop);
7545 dwLoop++;
7548 else
7549 if (MZ80_C == bWhat)
7551 fprintf(fp, "void FDHandler(void)\n");
7552 fprintf(fp, "{\n");
7553 fprintf(fp, " switch (*pbPC++)\n");
7554 fprintf(fp, " {\n");
7556 while (dwLoop < 0x100)
7558 dwLoop2 = 0;
7560 fprintf(fp, " case 0x%.2x:\n", dwLoop);
7561 fprintf(fp, " {\n");
7563 while (DDFDOps[dwLoop2].bOpCode != dwLoop && DDFDOps[dwLoop2].bOpCode != 0xffffffff)
7564 dwLoop2++;
7566 if (bTimingDDFD[dwLoop])
7568 fprintf(fp, " sdwCyclesRemaining -= %" PRIu32 ";\n", bTimingDDFD[dwLoop]);
7571 if (DDFDOps[dwLoop2].Emitter)
7573 DDFDOps[dwLoop2].Emitter(dwLoop);
7575 else
7577 InvalidInstructionC(2);
7580 fprintf(fp, " break;\n");
7581 fprintf(fp, " }\n");
7582 ++dwLoop;
7585 fprintf(fp, " }\n");
7586 fprintf(fp, "}\n");
7588 else
7590 abort();
7594 /* These are the meta routines */
7596 void ReadMemoryByteHandler()
7598 if (MZ80_ASSEMBLY_X86 == bWhat)
7600 Alignment();
7601 fprintf(fp, "; This is a generic read memory byte handler when a foreign\n");
7602 fprintf(fp, "; handler is to be called\n\n");
7603 fprintf(fp, "; EDI=Handler address, EDX=Address\n");
7604 fprintf(fp, "; On return, EDX & EDI are undisturbed and AL=Byte read\n\n");
7605 fprintf(fp, "ReadMemoryByte:\n");
7607 fprintf(fp, " mov [_z80af], ax ; Save AF\n");
7608 fprintf(fp, " cmp [edi+8], dword 0 ; Null handler?\n");
7609 fprintf(fp, " je directReadHandler ; Yep! It's a direct read!\n\n");
7611 fprintf(fp, " mov [_z80hl], bx ; Save HL\n");
7612 fprintf(fp, " mov [_z80bc], cx ; Save BC\n");
7614 fprintf(fp, " sub esi, ebp ; Our program counter\n");
7615 fprintf(fp, " mov [_z80pc], si ; Save our program counter\n");
7617 // Now adjust the proper timing
7619 fprintf(fp, " mov esi, [dwOriginalExec] \n");
7620 fprintf(fp, " sub esi, [cyclesRemaining]\n");
7621 fprintf(fp, " add [dwElapsedTicks], esi\n");
7622 fprintf(fp, " add [_z80rCounter], esi\n");
7623 fprintf(fp, " sub [dwOriginalExec], esi\n");
7625 fprintf(fp, " push edi ; Save our structure address\n");
7626 fprintf(fp, " push edx ; And our desired address\n");
7628 if (FALSE == bUseStack)
7630 fprintf(fp, " mov eax, edx ; Get our desired address reg\n");
7631 fprintf(fp, " mov edx, edi ; Pointer to the structure\n");
7634 fprintf(fp, " call dword [edi + 8] ; Go call our handler\n");
7636 fprintf(fp, " pop edx ; Restore our address\n");
7637 fprintf(fp, " pop edi ; Restore our handler's address\n");
7639 fprintf(fp, " xor ebx, ebx ; Zero our future HL\n");
7640 fprintf(fp, " xor esi, esi ; Zero it!\n");
7641 fprintf(fp, " mov ebp, [_z80Base] ; Base pointer comes back\n");
7642 fprintf(fp, " mov si, [_z80pc] ; Get our program counter back\n");
7643 fprintf(fp, " xor ecx, ecx ; Zero our future BC\n");
7644 fprintf(fp, " add esi, ebp ; Rebase it properly\n");
7646 fprintf(fp, " mov bx, [_z80hl] ; Get HL back\n");
7647 fprintf(fp, " mov cx, [_z80bc] ; Get BC back\n");
7649 // Note: the callee must restore AF!
7651 fprintf(fp, " ret\n\n");
7652 fprintf(fp, "directReadHandler:\n");
7653 fprintf(fp, " mov eax, [edi+12] ; Get our base address\n");
7654 fprintf(fp, " sub edx, [edi] ; Subtract our base (low) address\n");
7655 fprintf(fp, " mov al, [edx+eax] ; Get our data byte\n");
7656 fprintf(fp, " and eax, 0ffh ; Only the lower byte matters!\n");
7657 fprintf(fp, " add edx, [edi] ; Add our base back\n");
7658 fprintf(fp, " ret ; Return to caller!\n\n");
7660 else
7661 if (MZ80_C == bWhat)
7664 else
7666 abort();
7670 void WriteMemoryByteHandler()
7672 if (MZ80_ASSEMBLY_X86 == bWhat)
7674 Alignment();
7675 fprintf(fp, "; This is a generic read memory byte handler when a foreign\n");
7676 fprintf(fp, "; handler is to be called.\n");
7677 fprintf(fp, "; EDI=Handler address, AL=Byte to write, EDX=Address\n");
7678 fprintf(fp, "; EDI and EDX Are undisturbed on exit\n\n");
7679 fprintf(fp, "WriteMemoryByte:\n");
7681 fprintf(fp, " cmp [edi+8], dword 0 ; Null handler?\n");
7682 fprintf(fp, " je directWriteHandler\n\n");
7685 fprintf(fp, " mov [_z80hl], bx ; Save HL\n");
7686 fprintf(fp, " mov [_z80bc], cx ; Save BX\n");
7688 fprintf(fp, " sub esi, ebp ; Our program counter\n");
7689 fprintf(fp, " mov [_z80pc], si ; Save our program counter\n");
7691 // Now adjust the proper timing
7693 fprintf(fp, " mov esi, [dwOriginalExec] \n");
7694 fprintf(fp, " sub esi, [cyclesRemaining]\n");
7695 fprintf(fp, " add [dwElapsedTicks], esi\n");
7696 fprintf(fp, " add [_z80rCounter], esi\n");
7697 fprintf(fp, " sub [dwOriginalExec], esi\n");
7699 fprintf(fp, " push edi ; Save our structure address\n");
7701 if (bUseStack)
7702 fprintf(fp, " push eax ; Data to write\n");
7704 fprintf(fp, " push edx ; And our desired address\n");
7706 if (FALSE == bUseStack)
7708 fprintf(fp, " xchg eax, edx ; Swap address/data around\n");
7709 fprintf(fp, " mov ebx, edi ; Our MemoryWriteByte structure address\n");
7712 fprintf(fp, " call dword [edi + 8] ; Go call our handler\n");
7714 fprintf(fp, " pop edx ; Restore our address\n");
7716 if (bUseStack)
7717 fprintf(fp, " pop eax ; Restore our data written\n");
7719 fprintf(fp, " pop edi ; Save our structure address\n");
7721 fprintf(fp, " xor ebx, ebx ; Zero our future HL\n");
7722 fprintf(fp, " xor ecx, ecx ; Zero our future BC\n");
7723 fprintf(fp, " mov bx, [_z80hl] ; Get HL back\n");
7724 fprintf(fp, " mov cx, [_z80bc] ; Get BC back\n");
7725 fprintf(fp, " mov ax, [_z80af] ; Get AF back\n");
7726 fprintf(fp, " xor esi, esi ; Zero it!\n");
7727 fprintf(fp, " mov si, [_z80pc] ; Get our program counter back\n");
7728 fprintf(fp, " mov ebp, [_z80Base] ; Base pointer comes back\n");
7729 fprintf(fp, " add esi, ebp ; Rebase it properly\n");
7731 fprintf(fp, " ret\n\n");
7733 fprintf(fp, "directWriteHandler:\n");
7734 fprintf(fp, " sub edx, [edi] ; Subtract our offset\n");
7735 fprintf(fp, " add edx, [edi+12] ; Add in the base address\n");
7736 fprintf(fp, " mov [edx], al ; Store our byte\n");
7737 fprintf(fp, " sub edx, [edi+12] ; Restore our base address\n");
7738 fprintf(fp, " add edx, [edi] ; And put our offset back\n");
7739 fprintf(fp, " ret\n\n");
7741 else
7742 if (MZ80_C == bWhat)
7745 else
7747 abort();
7751 void PushWordHandler()
7753 if (MZ80_ASSEMBLY_X86 == bWhat)
7755 Alignment();
7757 fprintf(fp, ";\n");
7758 fprintf(fp, "; DX=Top of SP, [_wordval]=word value to push\n");
7759 fprintf(fp, ";\n\n");
7760 fprintf(fp, "PushWord:\n");
7761 fprintf(fp, " mov dx, [_z80sp]\n");
7762 fprintf(fp, " dec dx\n");
7763 WriteValueToMemory("dx", "byte [_wordval+1]");
7764 fprintf(fp, " dec dx\n");
7765 WriteValueToMemory("dx", "byte [_wordval]");
7766 fprintf(fp, " sub [_z80sp], word 2\n");
7767 fprintf(fp, " xor edx, edx\n");
7768 fprintf(fp, " ret\n\n");
7772 void PopWordHandler()
7774 if (MZ80_ASSEMBLY_X86 == bWhat)
7776 Alignment();
7778 fprintf(fp, ";\n");
7779 fprintf(fp, "; [_z80sp]=Top of SP, DX=Word value read\n");
7780 fprintf(fp, ";\n\n");
7781 fprintf(fp, "PopWord:\n");
7782 fprintf(fp, " mov dx, [_z80sp]\n");
7784 ReadWordFromMemory("dx", "dx");
7785 fprintf(fp, " ret\n\n");
7789 void ReadIoHandler()
7791 if (MZ80_ASSEMBLY_X86 == bWhat)
7793 Alignment();
7795 fprintf(fp, "; This is a generic I/O read byte handler for when a foreign\n");
7796 fprintf(fp, "; handler is to be called\n");
7798 fprintf(fp, "; EDI=Handler address, EDX=I/O Address\n");
7799 fprintf(fp, "; On return, EDX & EDI are undisturbed and AL=Byte read\n\n");
7800 fprintf(fp, "ReadIOByte:\n");
7802 fprintf(fp, " mov [_z80af], ax ; Save AF\n");
7803 fprintf(fp, " mov [_z80hl], bx ; Save HL\n");
7804 fprintf(fp, " mov [_z80bc], cx ; Save BC\n");
7806 fprintf(fp, " sub esi, ebp ; Our program counter\n");
7807 fprintf(fp, " mov [_z80pc], si ; Save our program counter\n");
7809 // Now adjust the proper timing
7811 fprintf(fp, " mov esi, [dwOriginalExec] \n");
7812 fprintf(fp, " sub esi, [cyclesRemaining]\n");
7813 fprintf(fp, " add [dwElapsedTicks], esi\n");
7814 fprintf(fp, " add [_z80rCounter], esi\n");
7815 fprintf(fp, " sub [dwOriginalExec], esi\n");
7817 fprintf(fp, " push edi ; Save our structure address\n");
7818 fprintf(fp, " push edx ; And our desired I/O port\n");
7820 if (FALSE == bUseStack)
7822 fprintf(fp, " mov eax, edx ; Get our desired address reg\n");
7823 fprintf(fp, " mov edx, edi ; Pointer to the structure\n");
7826 fprintf(fp, " call dword [edi + 4] ; Go call our handler\n");
7828 fprintf(fp, " pop edx ; Restore our address\n");
7829 fprintf(fp, " pop edi ; Restore our handler's address\n");
7831 fprintf(fp, " xor ebx, ebx ; Zero our future HL\n");
7832 fprintf(fp, " xor ecx, ecx ; Zero our future BC\n");
7833 fprintf(fp, " xor esi, esi ; Zero it!\n");
7834 fprintf(fp, " mov si, [_z80pc] ; Get our program counter back\n");
7835 fprintf(fp, " mov ebp, [_z80Base] ; Base pointer comes back\n");
7836 fprintf(fp, " add esi, ebp ; Rebase it properly\n");
7838 fprintf(fp, " mov bx, [_z80hl] ; Get HL back\n");
7839 fprintf(fp, " mov cx, [_z80bc] ; Get BC back\n");
7841 // Note: the callee must restore AF!
7843 fprintf(fp, " ret\n\n");
7845 else
7846 if (MZ80_C == bWhat)
7849 else
7851 abort();
7855 void WriteIoHandler()
7857 if (MZ80_ASSEMBLY_X86 == bWhat)
7859 Alignment();
7861 fprintf(fp, "; This is a generic write I/O byte handler when a foreign handler is to\n");
7862 fprintf(fp, "; be called\n");
7863 fprintf(fp, "; EDI=Handler address, AL=Byte to write, EDX=I/O Address\n");
7864 fprintf(fp, "; EDI and EDX Are undisturbed on exit\n\n");
7865 fprintf(fp, "WriteIOByte:\n");
7867 fprintf(fp, " mov [_z80hl], bx ; Save HL\n");
7868 fprintf(fp, " mov [_z80bc], cx ; Save BX\n");
7870 fprintf(fp, " sub esi, ebp ; Our program counter\n");
7871 fprintf(fp, " mov [_z80pc], si ; Save our program counter\n");
7873 // Now adjust the proper timing
7875 fprintf(fp, " mov esi, [dwOriginalExec] \n");
7876 fprintf(fp, " sub esi, [cyclesRemaining]\n");
7877 fprintf(fp, " add [dwElapsedTicks], esi\n");
7878 fprintf(fp, " add [_z80rCounter], esi\n");
7879 fprintf(fp, " sub [dwOriginalExec], esi\n");
7881 fprintf(fp, " push edi ; Save our structure address\n");
7883 if (bUseStack)
7884 fprintf(fp, " push eax ; Data to write\n");
7886 fprintf(fp, " push edx ; And our desired I/O address\n");
7888 if (FALSE == bUseStack)
7890 fprintf(fp, " xchg eax, edx ; Swap address/data around\n");
7891 fprintf(fp, " mov ebx, edi ; Our z80IoWrite structure address\n");
7894 fprintf(fp, " call dword [edi + 4] ; Go call our handler\n");
7896 fprintf(fp, " pop edx ; Restore our address\n");
7898 if (bUseStack)
7899 fprintf(fp, " pop eax ; Restore our data written\n");
7901 fprintf(fp, " pop edi ; Save our structure address\n");
7903 fprintf(fp, " xor ebx, ebx ; Zero our future HL\n");
7904 fprintf(fp, " xor ecx, ecx ; Zero our future BC\n");
7905 fprintf(fp, " mov bx, [_z80hl] ; Get HL back\n");
7906 fprintf(fp, " mov cx, [_z80bc] ; Get BC back\n");
7907 fprintf(fp, " mov ax, [_z80af] ; Get AF back\n");
7908 fprintf(fp, " xor esi, esi ; Zero it!\n");
7909 fprintf(fp, " mov si, [_z80pc] ; Get our program counter back\n");
7910 fprintf(fp, " mov ebp, [_z80Base] ; Base pointer comes back\n");
7911 fprintf(fp, " add esi, ebp ; Rebase it properly\n");
7913 fprintf(fp, " ret\n\n");
7915 else
7916 if (MZ80_C == bWhat)
7919 else
7921 abort();
7925 void ExecCode(void)
7927 if (MZ80_ASSEMBLY_X86 == bWhat)
7929 fprintf(fp, " global _%sexec\n", cpubasename);
7930 fprintf(fp, " global %sexec_\n", cpubasename);
7932 if (bPlain)
7933 fprintf(fp, " global %sexec\n", cpubasename);
7935 sprintf(procname, "%sexec_", cpubasename);
7936 ProcBegin(0xffffffff);
7938 fprintf(fp, "_%sexec:\n", cpubasename);
7940 if (bPlain)
7941 fprintf(fp, "%sexec:\n", cpubasename);
7943 if (bUseStack)
7944 fprintf(fp, " mov eax, [esp+4] ; Get our execution cycle count\n");
7946 fprintf(fp, " push ebx ; Save all registers we use\n");
7947 fprintf(fp, " push ecx\n");
7948 fprintf(fp, " push edx\n");
7949 fprintf(fp, " push ebp\n");
7950 fprintf(fp, " push esi\n");
7951 fprintf(fp, " push edi\n");
7952 fprintf(fp, "\n");
7954 fprintf(fp, " mov edi, eax\n");
7955 fprintf(fp, " mov dword [cyclesRemaining], eax ; Store # of instructions to\n");
7956 fprintf(fp, " mov [dwLastRSample], eax\n");
7957 fprintf(fp, " mov [dwOriginalExec], eax ; Store this!\n");
7959 fprintf(fp, " cmp dword [_z80halted], 0\n");
7960 fprintf(fp, " je goCpu\n");
7961 fprintf(fp, " add [_z80rCounter], eax\n");
7963 if (FALSE == bNoTiming)
7965 fprintf(fp, " add dword [dwElapsedTicks], eax\n");
7968 fprintf(fp, " mov dword [cyclesRemaining], 0 ; Nothing left!\n");
7969 fprintf(fp, " mov eax, 80000000h ; Successful exection\n");
7970 fprintf(fp, " jmp popReg\n");
7971 fprintf(fp, "goCpu:\n");
7972 fprintf(fp, " cld ; Go forward!\n");
7973 fprintf(fp, "\n");
7974 fprintf(fp, " xor eax, eax ; Zero EAX 'cause we use it!\n");
7975 fprintf(fp, " xor ebx, ebx ; Zero EBX, too\n");
7976 fprintf(fp, " xor ecx, ecx ; Zero ECX\n");
7977 fprintf(fp, " xor edx, edx ; And EDX\n");
7978 fprintf(fp, " xor esi, esi ; Zero our source address\n");
7979 fprintf(fp, "\n");
7980 fprintf(fp, " mov ax, [_z80af] ; Accumulator & flags\n");
7981 fprintf(fp, " xchg ah, al ; Swap these for later\n");
7982 fprintf(fp, " mov bx, [_z80hl] ; Get our HL value\n");
7983 fprintf(fp, " mov cx, [_z80bc] ; And our BC value\n");
7984 fprintf(fp, " mov ebp, [_z80Base] ; Get the base address\n");
7985 fprintf(fp, " mov si, [_z80pc] ; Get our program counter\n");
7986 fprintf(fp, " add esi, ebp ; Add in our base address\n");
7988 fprintf(fp, " cmp [_z80intPending], byte 0 ; Interrupt pending?\n");
7989 fprintf(fp, " jz masterExecTarget\n\n");
7990 fprintf(fp, " call causeInternalInterrupt\n\n");
7991 fprintf(fp, "masterExecTarget:\n");
7992 fprintf(fp, " mov dl, [esi]\n");
7993 fprintf(fp, " inc esi\n");
7994 fprintf(fp, " jmp dword [z80regular+edx*4]\n\n");
7995 fprintf(fp, "; We get to invalidInsWord if it's a double byte invalid opcode\n");
7996 fprintf(fp, "\n");
7997 fprintf(fp, "invalidInsWord:\n");
7999 fprintf(fp, " dec esi\n");
8000 fprintf(fp, "\n");
8001 fprintf(fp, "; We get to invalidInsByte if it's a single byte invalid opcode\n");
8002 fprintf(fp, "\n");
8004 fprintf(fp, "invalidInsByte:\n");
8005 fprintf(fp, " xchg ah, al ; Swap them back so they look good\n");
8006 fprintf(fp, " mov [_z80af], ax ; Store A & flags\n");
8007 fprintf(fp, " dec esi ; Back up one instruction...\n");
8008 fprintf(fp, " mov edx, esi ; Get our address in EAX\n");
8009 fprintf(fp, " sub edx, ebp ; And subtract our base for\n");
8010 fprintf(fp, " ; an invalid instruction\n");
8011 fprintf(fp, " jmp short emulateEnd\n");
8012 fprintf(fp, "\n");
8013 fprintf(fp, "noMoreExec:\n");
8014 fprintf(fp, " cmp [bEIExit], byte 0 ; Are we exiting because of an EI?\n");
8015 fprintf(fp, " jne checkEI\n");
8016 fprintf(fp, "noMoreExecNoEI:\n");
8017 fprintf(fp, " xchg ah, al ; Swap these for later\n");
8018 fprintf(fp, " mov [_z80af], ax ; Store A & flags\n");
8020 fprintf(fp, " mov edx, [dwOriginalExec] ; Original exec time\n");
8021 fprintf(fp, " sub edx, edi ; Subtract # of cycles remaining\n");
8022 fprintf(fp, " add [_z80rCounter], edx\n");
8023 fprintf(fp, " add [dwElapsedTicks], edx ; Add our executed time\n");
8025 fprintf(fp, " mov edx, 80000000h ; Indicate successful exec\n");
8026 fprintf(fp, " jmp short emulateEnd ; All finished!\n");
8027 fprintf(fp, "\n");
8028 fprintf(fp, "; Now let's tuck away the virtual registers for next time\n");
8029 fprintf(fp, "\n");
8030 fprintf(fp, "storeFlags:\n");
8031 fprintf(fp, " xchg ah, al ; Swap these for later\n");
8032 fprintf(fp, " mov [_z80af], ax ; Store A & flags\n");
8033 fprintf(fp, "emulateEnd:\n");
8034 fprintf(fp, " mov [_z80hl], bx ; Store HL\n");
8035 fprintf(fp, " mov [_z80bc], cx ; Store BC\n");
8036 fprintf(fp, " sub esi, [_z80Base] ; Knock off physical address\n");
8037 fprintf(fp, " mov [_z80pc], si ; And store virtual address\n");
8038 fprintf(fp, " mov eax, edx ; Result code return\n");
8039 fprintf(fp, "\n");
8040 fprintf(fp, "popReg:\n");
8041 fprintf(fp, " pop edi ; Restore registers\n");
8042 fprintf(fp, " pop esi\n");
8043 fprintf(fp, " pop ebp\n");
8044 fprintf(fp, " pop edx\n");
8045 fprintf(fp, " pop ecx\n");
8046 fprintf(fp, " pop ebx\n");
8047 fprintf(fp, "\n");
8048 fprintf(fp, " ret\n");
8049 fprintf(fp, "\n");
8050 Alignment();
8051 fprintf(fp, "checkEI:\n");
8052 fprintf(fp, " xor edx, edx\n");
8053 fprintf(fp, " mov [bEIExit], byte 0\n");
8054 fprintf(fp, " sub edx, edi ; Find out how much time has passed\n");
8055 fprintf(fp, " mov edi, [dwEITiming]\n");
8056 fprintf(fp, " sub edi, edx\n");
8057 fprintf(fp, " js noMoreExecNoEI\n");
8058 fprintf(fp, " xor edx, edx\n");
8060 fprintf(fp, " cmp [_z80intPending], byte 0\n");
8061 fprintf(fp, " je near masterExecTarget\n");
8062 fprintf(fp, " call causeInternalInterrupt\n");
8063 fprintf(fp, " jmp masterExecTarget\n\n");
8065 Alignment();
8066 fprintf(fp, "causeInternalInterrupt:\n");
8067 fprintf(fp, " mov dword [_z80halted], 0 ; We're not halted anymore!\n");
8068 fprintf(fp, " test [_z80iff], byte IFF1 ; Interrupt enabled yet?\n");
8069 fprintf(fp, " jz near internalInterruptsDisabled\n");
8071 fprintf(fp, "\n; Interrupts enabled. Clear IFF1 and IFF2\n\n");
8073 fprintf(fp, " mov [_z80intPending], byte 0\n");
8075 fprintf(fp, "\n; Save off our active register sets\n\n");
8077 fprintf(fp, " xchg ah, al ; Swap these for later\n");
8078 fprintf(fp, " mov [_z80af], ax ; Store A & flags\n");
8079 fprintf(fp, " mov [_z80hl], bx ; Store HL\n");
8080 fprintf(fp, " mov [_z80bc], cx ; Store BC\n");
8081 fprintf(fp, " sub esi, ebp ; Knock off physical address\n");
8082 fprintf(fp, " mov [_z80pc], si ; And store virtual address\n");
8084 fprintf(fp, " xor eax, eax\n");
8085 fprintf(fp, " mov al, [_intData]\n\n");
8087 fprintf(fp, "\n");
8088 fprintf(fp, " push edi\n");
8089 fprintf(fp, "\n");
8091 if (bThroughCallHandler)
8093 fprintf(fp, " pushad\n" );
8094 fprintf(fp, " xor edx, edx\n" );
8095 fprintf(fp, " mov ax, [_z80pc]\n");
8096 fprintf(fp, " mov [_wordval], ax\n");
8097 fprintf(fp, " push ecx\n");
8098 fprintf(fp, " push ebx\n");
8099 fprintf(fp, " push esi\n");
8101 fprintf(fp, " mov ax, [_z80af]\n"); // Get AF
8102 fprintf(fp, " mov bx, [_z80hl]\n"); // Get HL
8103 fprintf(fp, " mov cx, [_z80bc]\n"); // Get BC
8104 fprintf(fp, " call PushWord\n");
8106 fprintf(fp, " pop esi\n");
8107 fprintf(fp, " pop ebx\n");
8108 fprintf(fp, " pop ecx\n");
8109 fprintf(fp, " popad\n" );
8111 else
8113 fprintf(fp, " mov dx, [_z80pc]\n");
8114 fprintf(fp, " xor edi, edi\n");
8115 fprintf(fp, " mov di, word [_z80sp]\n");
8116 fprintf(fp, " sub di, 2\n");
8117 fprintf(fp, " mov word [_z80sp], di\n");
8118 fprintf(fp, " mov [ebp+edi], dx\n");
8121 fprintf(fp, " cmp dword [_z80interruptMode], 2 ; Are we lower than mode 2?\n");
8122 fprintf(fp, " jb internalJustModeTwo\n");
8123 fprintf(fp, " mov ah, [_z80i] ; Get our high address here\n");
8124 fprintf(fp, " and eax, 0ffffh ; Only the lower part\n");
8125 fprintf(fp, " mov ax, [eax+ebp] ; Get our vector\n");
8126 fprintf(fp, " jmp short internalSetNewVector ; Go set it!\n");
8127 fprintf(fp, "internalJustModeTwo:\n");
8128 fprintf(fp, " mov ax, word [_z80intAddr]\n");
8129 fprintf(fp, "internalSetNewVector:\n");
8130 fprintf(fp, " mov [_z80pc], ax\n");
8131 fprintf(fp, "\n");
8132 fprintf(fp, " pop edi\n");
8133 fprintf(fp, "\n");
8134 fprintf(fp, " xor eax, eax ; Zero this so we can use it as an index\n");
8136 fprintf(fp, " mov al, [_z80interruptMode]\n");
8137 fprintf(fp, " mov al, [intModeTStates+eax]\n");
8138 fprintf(fp, " sub edi, eax\n");
8139 fprintf(fp, " add [_z80rCounter], eax\n");
8141 fprintf(fp, "\n; Restore all the registers and whatnot\n\n");
8143 fprintf(fp, " mov ax, [_z80af] ; Accumulator & flags\n");
8144 fprintf(fp, " xchg ah, al ; Swap these for later\n");
8145 fprintf(fp, " mov bx, [_z80hl] ; Get our HL value\n");
8146 fprintf(fp, " mov cx, [_z80bc] ; And our BC value\n");
8147 fprintf(fp, " mov ebp, [_z80Base] ; Get the base address\n");
8148 fprintf(fp, " mov si, [_z80pc] ; Get our program counter\n");
8149 fprintf(fp, " add esi, ebp ; Add in our base address\n");
8151 fprintf(fp, "internalInterruptsDisabled:\n");
8152 fprintf(fp, " xor edx, edx\n");
8153 fprintf(fp, " ret\n");
8155 else
8156 if (MZ80_C == bWhat)
8159 else
8161 abort();
8165 void NmiCode(void)
8167 if (MZ80_ASSEMBLY_X86 == bWhat)
8169 fprintf(fp, " global _%snmi\n", cpubasename);
8170 fprintf(fp, " global %snmi_\n", cpubasename);
8172 if (bPlain)
8173 fprintf(fp, " global %snmi\n", cpubasename);
8175 sprintf(procname, "%snmi_", cpubasename);
8176 ProcBegin(0xffffffff);
8177 fprintf(fp, "_%snmi:\n", cpubasename);
8179 if (bPlain)
8180 fprintf(fp, "%snmi:\n", cpubasename);
8182 fprintf(fp, " mov dword [_z80halted], 0 ; We're not halted anymore!\n");
8183 fprintf(fp, " mov al, [_z80iff] ; Get our IFF setting\n");
8184 fprintf(fp, " and al, IFF1 ; Just IFF 1\n");
8185 fprintf(fp, " shl al, 1 ; Makes IFF1->IFF2 and zeros IFF1\n");
8186 fprintf(fp, " mov [_z80iff], al ; Store it back to the interrupt state!\n");
8187 fprintf(fp, "\n");
8188 fprintf(fp, " push ebp\n");
8189 fprintf(fp, " push edi\n");
8190 fprintf(fp, " mov ebp, [_z80Base]\n");
8191 fprintf(fp, "\n");
8193 fprintf(fp, " xor eax, eax\n");
8194 fprintf(fp, " mov ax, [_z80pc]\n");
8196 if (bThroughCallHandler)
8198 fprintf(fp, " push esi\n");
8199 fprintf(fp, " push ebx\n");
8200 fprintf(fp, " push ecx\n");
8202 fprintf(fp, " mov [_wordval], ax\n");
8203 fprintf(fp, " mov esi, ebp\n");
8204 fprintf(fp, " add esi, eax\n");
8205 fprintf(fp, " mov ax, [_z80af]\n"); // Get AF
8206 fprintf(fp, " mov bx, [_z80hl]\n"); // Get HL
8207 fprintf(fp, " mov cx, [_z80bc]\n"); // Get BC
8208 fprintf(fp, " push ebx\n");
8209 fprintf(fp, " push ecx\n");
8210 fprintf(fp, " push edx\n");
8211 fprintf(fp, " push esi\n");
8212 fprintf(fp, " push eax\n");
8213 fprintf(fp, " call PushWord\n");
8214 fprintf(fp, " pop eax\n");
8215 fprintf(fp, " pop esi\n");
8216 fprintf(fp, " pop edx\n");
8217 fprintf(fp, " pop ecx\n");
8218 fprintf(fp, " pop ebx\n");
8220 fprintf(fp, " pop ecx\n");
8221 fprintf(fp, " pop ebx\n");
8222 fprintf(fp, " pop esi\n");
8224 else
8226 fprintf(fp, " xor edi, edi\n");
8227 fprintf(fp, " mov di, word [_z80sp]\n");
8228 fprintf(fp, " sub di, 2\n");
8229 fprintf(fp, " mov word [_z80sp], di\n");
8230 fprintf(fp, " mov [ebp+edi], ax\n");
8233 fprintf(fp, " mov ax, [_z80nmiAddr]\n");
8234 fprintf(fp, " mov [_z80pc], ax\n");
8235 fprintf(fp, "\n");
8236 fprintf(fp, " add [dwElapsedTicks], dword 11 ; 11 T-States for NMI\n");
8237 fprintf(fp, " add [_z80rCounter], dword 11\n");
8238 fprintf(fp, " pop edi\n");
8239 fprintf(fp, " pop ebp\n");
8240 fprintf(fp, "\n");
8241 fprintf(fp, " xor eax, eax ; Indicate we took the interrupt\n");
8242 fprintf(fp, " ret\n");
8244 else
8245 if (MZ80_C == bWhat)
8247 fprintf(fp, "/* NMI Handler */\n\n");
8248 fprintf(fp, "UINT32 %snmi(void)\n", cpubasename);
8249 fprintf(fp, "{\n");
8251 fprintf(fp, " cpu.z80halted = 0;\n");
8252 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp - 1); /* Normalize the stack pointer */\n");
8253 fprintf(fp, " *pbSP-- = cpu.z80pc >> 8; /* LSB */\n");
8254 fprintf(fp, " *pbSP = (UINT8) cpu.z80pc; /* MSB */\n");
8255 fprintf(fp, " cpu.z80sp -= 2; /* Back our stack up */\n");
8256 fprintf(fp, " cpu.z80pc = cpu.z80nmiAddr; /* Our NMI */\n");
8258 fprintf(fp, " return(0);\n");
8259 fprintf(fp, "}\n\n");
8261 else
8263 abort();
8267 void IntCode(void)
8269 if (MZ80_ASSEMBLY_X86 == bWhat)
8271 fprintf(fp, " global _%sint\n", cpubasename);
8272 fprintf(fp, " global %sint_\n", cpubasename);
8274 if (bPlain)
8275 fprintf(fp, " global %sint\n", cpubasename);
8277 sprintf(procname, "%sint_", cpubasename);
8278 ProcBegin(0xffffffff);
8279 fprintf(fp, "_%sint:\n", cpubasename);
8281 if (bPlain)
8282 fprintf(fp, "%sint:\n", cpubasename);
8284 if (bUseStack)
8285 fprintf(fp, " mov eax, [esp+4] ; Get our (potential) lower interrupt address\n");
8287 fprintf(fp, " mov dword [_z80halted], 0 ; We're not halted anymore!\n");
8289 fprintf(fp, " mov ah, IFF1 ; Is IFF1 enabled?\n");
8290 fprintf(fp, " and ah, [_z80iff] ; Well, is it?\n");
8291 fprintf(fp, " jz near interruptsDisabled\n");
8293 fprintf(fp, "\n; Interrupts enabled. Clear IFF1 and IFF2\n\n");
8295 fprintf(fp, " and dword [_z80iff], ~(IFF1 | IFF2);\n\n");
8296 fprintf(fp, " mov [_z80intPending], byte 0\n");
8298 fprintf(fp, "\n");
8299 fprintf(fp, " push ebp\n");
8300 fprintf(fp, " push edi\n");
8301 fprintf(fp, " push edx\n");
8302 fprintf(fp, " mov ebp, [_z80Base]\n");
8303 fprintf(fp, "\n");
8306 if (bThroughCallHandler)
8308 fprintf(fp, " pushad\n" );
8309 fprintf(fp, " xor edx, edx\n" );
8310 fprintf(fp, " mov ax, [_z80pc]\n");
8311 fprintf(fp, " mov [_wordval], ax\n");
8312 fprintf(fp, " push ecx\n");
8313 fprintf(fp, " push ebx\n");
8314 fprintf(fp, " push esi\n");
8316 fprintf(fp, " mov ax, [_z80af]\n"); // Get AF
8317 fprintf(fp, " mov bx, [_z80hl]\n"); // Get HL
8318 fprintf(fp, " mov cx, [_z80bc]\n"); // Get BC
8319 fprintf(fp, " call PushWord\n");
8321 fprintf(fp, " pop esi\n");
8322 fprintf(fp, " pop ebx\n");
8323 fprintf(fp, " pop ecx\n");
8324 fprintf(fp, " popad\n" );
8326 else
8328 fprintf(fp, " mov dx, [_z80pc]\n");
8329 fprintf(fp, " xor edi, edi\n");
8330 fprintf(fp, " mov di, word [_z80sp]\n");
8331 fprintf(fp, " sub di, 2\n");
8332 fprintf(fp, " mov word [_z80sp], di\n");
8333 fprintf(fp, " mov [ebp+edi], dx\n");
8336 fprintf(fp, " cmp dword [_z80interruptMode], 2 ; Are we lower than mode 2?\n");
8337 fprintf(fp, " jb justModeTwo\n");
8338 fprintf(fp, " mov ah, [_z80i] ; Get our high address here\n");
8339 fprintf(fp, " and eax, 0ffffh ; Only the lower part\n");
8340 fprintf(fp, " mov ax, [eax+ebp] ; Get our vector\n");
8341 fprintf(fp, " jmp short setNewVector ; Go set it!\n");
8342 fprintf(fp, "justModeTwo:\n");
8343 fprintf(fp, " mov ax, word [_z80intAddr]\n");
8344 fprintf(fp, "setNewVector:\n");
8345 fprintf(fp, " mov [_z80pc], ax\n");
8346 fprintf(fp, "\n");
8347 fprintf(fp, " pop edx\n");
8348 fprintf(fp, " pop edi\n");
8349 fprintf(fp, " pop ebp\n");
8350 fprintf(fp, "\n");
8351 fprintf(fp, " xor eax, eax ; Zero this so we can use it as an index\n");
8353 fprintf(fp, " mov al, [_z80interruptMode]\n");
8354 fprintf(fp, " mov al, [intModeTStates+eax]\n");
8355 fprintf(fp, " add [dwElapsedTicks], eax\n");
8356 fprintf(fp, " add [_z80rCounter], eax\n");
8357 fprintf(fp, " xor eax, eax ; Indicate we took the interrupt\n");
8359 fprintf(fp, " jmp short z80intExit\n");
8360 fprintf(fp, "\n");
8361 fprintf(fp, "interruptsDisabled:\n");
8362 fprintf(fp, " mov [_z80intPending], byte 1\n");
8363 fprintf(fp, " mov [_intData], al ; Save this info for later\n");
8364 fprintf(fp, " mov eax, 0ffffffffh ; Indicate we didn't take it\n");
8365 fprintf(fp, "\n");
8366 fprintf(fp, "z80intExit:\n");
8367 fprintf(fp, " ret\n\n");
8370 fprintf(fp, " global _%sClearPendingInterrupt\n", cpubasename);
8371 fprintf(fp, " global %sClearPendingInterrupt_\n", cpubasename);
8373 if (bPlain)
8374 fprintf(fp, " global %sClearPendingInterrupt\n", cpubasename);
8376 sprintf(procname, "%sClearPendingInterrupt_", cpubasename);
8377 ProcBegin(0xffffffff);
8378 fprintf(fp, "_%sClearPendingInterrupt:\n", cpubasename);
8380 if (bPlain)
8381 fprintf(fp, "%sClearPendingInterrupt:\n", cpubasename);
8383 fprintf(fp, " mov [_z80intPending], byte 0\n");
8384 fprintf(fp, " ret\n\n");
8386 else
8387 if (MZ80_C == bWhat)
8389 fprintf(fp, "/* Interrupt handler */\n\n");
8390 fprintf(fp, "UINT32 %sint(UINT32 dwLowAddr)\n", cpubasename);
8391 fprintf(fp, "{\n");
8392 fprintf(fp, " cpu.z80halted = 0;\n");
8394 fprintf(fp, " if (0 == (cpu.z80iff & IFF1))\n");
8395 fprintf(fp, " return(0xffffffff);\n");
8397 fprintf(fp, " cpu.z80iff &= ~(IFF1 | IFF2);\n");
8398 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp - 1); /* Normalize the stack pointer */\n");
8399 fprintf(fp, " *pbSP-- = cpu.z80pc >> 8; /* LSB */\n");
8400 fprintf(fp, " *pbSP = (UINT8) cpu.z80pc; /* MSB */\n");
8401 fprintf(fp, " cpu.z80sp -= 2; /* Back our stack up */\n");
8403 fprintf(fp, " if (2 == cpu.z80interruptMode)\n");
8404 fprintf(fp, " {\n");
8405 fprintf(fp, " cpu.z80pc = ((UINT16) cpu.z80i << 8) | (dwLowAddr & 0xff);\n");
8406 fprintf(fp, " cpu.z80pc = ((UINT16) cpu.z80Base[cpu.z80pc + 1] << 8) | (cpu.z80Base[cpu.z80pc]);\n");
8407 fprintf(fp, " }\n");
8408 fprintf(fp, " else\n");
8409 fprintf(fp, " {\n");
8410 fprintf(fp, " cpu.z80pc = cpu.z80intAddr;\n");
8411 fprintf(fp, " }\n");
8413 fprintf(fp, " pbPC = cpu.z80Base + cpu.z80pc; /* Normalize the address */\n");
8415 fprintf(fp, " return(0);\n");
8416 fprintf(fp, "}\n\n");
8417 fprintf(fp, "void %sClearPendingInterrupt(void)\n", cpubasename);
8418 fprintf(fp, "{\n");
8419 fprintf(fp, " cpu.z80intPending = 0;\n");
8420 fprintf(fp, "}\n\n");
8422 else
8424 abort();
8428 void ResetCode(void)
8430 if (MZ80_ASSEMBLY_X86 == bWhat)
8432 fprintf(fp, " global _%sreset\n", cpubasename);
8433 fprintf(fp, " global %sreset_\n", cpubasename);
8435 if (bPlain)
8436 fprintf(fp, " global %sreset\n", cpubasename);
8437 sprintf(procname, "%sreset_", cpubasename);
8438 ProcBegin(0xffffffff);
8440 fprintf(fp, "_%sreset:\n", cpubasename);
8442 if (bPlain)
8443 fprintf(fp, "%sreset:\n", cpubasename);
8445 fprintf(fp, " xor eax, eax ; Zero AX\n");
8446 fprintf(fp, "\n");
8447 fprintf(fp, " mov dword [_z80halted], eax ; We're not halted anymore!\n");
8448 fprintf(fp, " mov word [_z80af], 0040h ; Zero A & flags - zero flag set\n");
8449 fprintf(fp, " mov word [_z80bc], ax ; Zero BC\n");
8450 fprintf(fp, " mov word [_z80de], ax ; Zero DE\n");
8451 fprintf(fp, " mov word [_z80hl], ax ; Zero HL\n");
8452 fprintf(fp, " mov word [_z80afprime], ax ; Zero AF Prime\n");
8453 fprintf(fp, " mov word [_z80bcprime], ax ; Zero BC prime\n");
8454 fprintf(fp, " mov word [_z80deprime], ax ; Zero DE prime\n");
8455 fprintf(fp, " mov word [_z80hlprime], ax ; Zero HL prime\n");
8456 fprintf(fp, " mov byte [_z80i], al ; Zero Interrupt register\n");
8457 fprintf(fp, " mov byte [_z80r], al ; Zero refresh register\n");
8458 fprintf(fp, " mov word [_z80ix], 0ffffh ; Default mz80Index register\n");
8459 fprintf(fp, " mov word [_z80iy], 0ffffh ; Default mz80Index register\n");
8460 fprintf(fp, " mov word [_z80pc], ax ; Zero program counter\n");
8461 fprintf(fp, " mov word [_z80sp], ax ; And the stack pointer\n");
8462 fprintf(fp, " mov dword [_z80iff], eax ; IFF1/IFF2 disabled!\n");
8463 fprintf(fp, " mov dword [_z80interruptMode], eax ; Clear our interrupt mode (0)\n");
8464 fprintf(fp, " mov word [_z80intAddr], 38h ; Set default interrupt address\n");
8465 fprintf(fp, " mov word [_z80nmiAddr], 66h ; Set default nmi addr\n");
8466 fprintf(fp, "\n");
8467 fprintf(fp, " ret\n");
8468 fprintf(fp, "\n");
8470 else
8471 if (MZ80_C == bWhat)
8473 fprintf(fp, "/* This routine is mz80's reset handler */\n\n");
8474 fprintf(fp, "void %sreset(void)\n", cpubasename);
8475 fprintf(fp, "{\n");
8476 fprintf(fp, " cpu.z80halted = 0;\n");
8477 fprintf(fp, " cpu.z80AF = 0;\n");
8478 fprintf(fp, " cpu.z80F = Z80_FLAG_ZERO;\n");
8479 fprintf(fp, " cpu.z80BC = 0;\n");
8480 fprintf(fp, " cpu.z80DE = 0;\n");
8481 fprintf(fp, " cpu.z80HL = 0;\n");
8482 fprintf(fp, " cpu.z80afprime = 0;\n");
8483 fprintf(fp, " cpu.z80bcprime = 0;\n");
8484 fprintf(fp, " cpu.z80deprime = 0;\n");
8485 fprintf(fp, " cpu.z80hlprime = 0;\n");
8486 fprintf(fp, " cpu.z80i = 0;\n");
8487 fprintf(fp, " cpu.z80r = 0;\n");
8488 fprintf(fp, " cpu.z80IX = 0xffff; /* Yes, this is intentional */\n");
8489 fprintf(fp, " cpu.z80IY = 0xffff; /* Yes, this is intentional */\n");
8490 fprintf(fp, " cpu.z80pc = 0;\n");
8491 fprintf(fp, " cpu.z80sp = 0xffff; /* Prevent segfault on reset */\n");
8492 fprintf(fp, " cpu.z80interruptMode = 0;\n");
8493 fprintf(fp, " cpu.z80intAddr = 0x38;\n");
8494 fprintf(fp, " cpu.z80nmiAddr = 0x66;\n");
8495 fprintf(fp, "}\n\n");
8497 else
8499 abort();
8503 void SetContextCode(void)
8505 if (MZ80_ASSEMBLY_X86 == bWhat)
8507 fprintf(fp, " global _%sSetContext\n", cpubasename);
8508 fprintf(fp, " global %sSetContext_\n", cpubasename);
8510 if (bPlain)
8511 fprintf(fp, " global %sSetContext\n", cpubasename);
8513 sprintf(procname, "%sSetContext_", cpubasename);
8514 ProcBegin(0xffffffff);
8515 fprintf(fp, "_%sSetContext:\n", cpubasename);
8517 if (bPlain)
8518 fprintf(fp, "%sSetContext:\n", cpubasename);
8520 if (bUseStack)
8521 fprintf(fp, " mov eax, [esp+4] ; Get our context address\n");
8523 fprintf(fp, " push esi ; Save registers we use\n");
8524 fprintf(fp, " push edi\n");
8525 fprintf(fp, " push ecx\n");
8526 fprintf(fp, " push es\n");
8527 fprintf(fp, " mov di, ds\n");
8528 fprintf(fp, " mov es, di\n");
8529 fprintf(fp, " mov edi, _%scontextBegin\n", cpubasename);
8530 fprintf(fp, " mov esi, eax ; Source address in ESI\n");
8531 fprintf(fp, " mov ecx, (_%scontextEnd - _%scontextBegin) >> 2\n", cpubasename, cpubasename);
8532 fprintf(fp, " rep movsd\n");
8533 fprintf(fp, " mov ecx, (_%scontextEnd - _%scontextBegin) & 0x03\n", cpubasename, cpubasename);
8534 fprintf(fp, " rep movsb\n");
8535 fprintf(fp, " pop es\n");
8536 fprintf(fp, " pop ecx\n");
8537 fprintf(fp, " pop edi\n");
8538 fprintf(fp, " pop esi\n");
8539 fprintf(fp, " ret ; No return code\n");
8541 else
8542 if (MZ80_C == bWhat)
8544 fprintf(fp, "/* Set mz80's context */\n\n");
8545 fprintf(fp, "void %sSetContext(void *pData)\n", cpubasename);
8546 fprintf(fp, "{\n");
8547 fprintf(fp, " memcpy(&cpu, pData, sizeof(CONTEXTMZ80));\n");
8548 fprintf(fp, "}\n\n");
8550 else
8552 abort();
8556 void GetContextCode(void)
8558 if (MZ80_ASSEMBLY_X86 == bWhat)
8560 fprintf(fp, " global _%sGetContext\n", cpubasename);
8561 fprintf(fp, " global %sGetContext_\n", cpubasename);
8563 if (bPlain)
8564 fprintf(fp, " global %sGetContext\n", cpubasename);
8566 sprintf(procname, "%sGetContext_", cpubasename);
8567 ProcBegin(0xffffffff);
8568 fprintf(fp, "_%sGetContext:\n", cpubasename);
8570 if (bPlain)
8571 fprintf(fp, "%sGetContext:\n", cpubasename);
8573 if (bUseStack)
8574 fprintf(fp, " mov eax, [esp+4] ; Get our context address\n");
8576 fprintf(fp, " push esi ; Save registers we use\n");
8577 fprintf(fp, " push edi\n");
8578 fprintf(fp, " push ecx\n");
8579 fprintf(fp, " push es\n");
8580 fprintf(fp, " mov di, ds\n");
8581 fprintf(fp, " mov es, di\n");
8583 fprintf(fp, " mov esi, _%scontextBegin\n", cpubasename);
8584 fprintf(fp, " mov edi, eax ; Source address in ESI\n");
8586 fprintf(fp, " mov ecx, (_%scontextEnd - _%scontextBegin) >> 2\n", cpubasename, cpubasename);
8587 fprintf(fp, " rep movsd\n");
8588 fprintf(fp, " mov ecx, (_%scontextEnd - _%scontextBegin) & 0x03\n", cpubasename, cpubasename);
8589 fprintf(fp, " rep movsb\n");
8591 fprintf(fp, " pop es\n");
8592 fprintf(fp, " pop ecx\n");
8593 fprintf(fp, " pop edi\n");
8594 fprintf(fp, " pop esi\n");
8595 fprintf(fp, " ret ; No return code\n");
8597 else
8598 if (MZ80_C == bWhat)
8600 fprintf(fp, "/* Get mz80's context */\n\n");
8601 fprintf(fp, "void %sGetContext(void *pData)\n", cpubasename);
8602 fprintf(fp, "{\n");
8603 fprintf(fp, " memcpy(pData, &cpu, sizeof(CONTEXTMZ80));\n");
8604 fprintf(fp, "}\n\n");
8606 else
8608 abort();
8612 void GetContextSizeCode(void)
8614 if (MZ80_ASSEMBLY_X86 == bWhat)
8616 fprintf(fp, " global _%sGetContextSize\n", cpubasename);
8617 fprintf(fp, " global %sGetContextSize_\n", cpubasename);
8619 if (bPlain)
8620 fprintf(fp, " global %sGetContextSize\n", cpubasename);
8622 sprintf(procname, "%sGetContextSize_", cpubasename);
8623 ProcBegin(0xffffffff);
8625 fprintf(fp, "_%sGetContextSize:\n", cpubasename);
8627 if (bPlain)
8628 fprintf(fp, "%sGetContextSize:\n", cpubasename);
8630 fprintf(fp, " mov eax, _%scontextEnd - _%scontextBegin\n", cpubasename, cpubasename);
8631 fprintf(fp, " ret\n\n");
8633 else
8634 if (MZ80_C == bWhat)
8636 fprintf(fp, "/* Get mz80's context size */\n\n");
8637 fprintf(fp, "UINT32 %sGetContextSize(void)\n", cpubasename);
8638 fprintf(fp, "{\n");
8639 fprintf(fp, " return(sizeof(CONTEXTMZ80));\n");
8640 fprintf(fp, "}\n\n");
8642 else
8644 abort();
8648 void InitCode(void)
8650 if (MZ80_ASSEMBLY_X86 == bWhat)
8652 fprintf(fp, " global _%sinit\n", cpubasename);
8653 fprintf(fp, " global %sinit_\n", cpubasename);
8655 if (bPlain)
8656 fprintf(fp, " global %sinit\n", cpubasename);
8658 sprintf(procname, "%sinit_", cpubasename);
8659 ProcBegin(0xffffffff);
8661 fprintf(fp, "_%sinit:\n", cpubasename);
8663 if (bPlain)
8664 fprintf(fp, "%sinit:\n", cpubasename);
8666 fprintf(fp, " ret\n\n");
8668 else
8669 if (MZ80_C == bWhat)
8671 fprintf(fp, "/* Initialize MZ80 for action */\n\n");
8672 fprintf(fp, "void %sinit(void)\n", cpubasename);
8673 fprintf(fp, "{\n");
8675 fprintf(fp, " UINT32 dwLoop;\n");
8676 fprintf(fp, " UINT8 *pbTempPtr;\n");
8677 fprintf(fp, " UINT8 *pbTempPtr2;\n");
8678 fprintf(fp, " UINT8 bNewAdd;\n");
8679 fprintf(fp, " UINT8 bNewSub;\n");
8680 fprintf(fp, " UINT8 bFlag;\n");
8681 fprintf(fp, " UINT8 bLow;\n");
8682 fprintf(fp, " UINT8 bHigh;\n");
8683 fprintf(fp, " UINT8 bCarry;\n");
8684 fprintf(fp, "\n");
8685 fprintf(fp, " if (NULL == pbAddAdcTable)\n");
8686 fprintf(fp, " {\n");
8687 fprintf(fp, " static UINT8 paat[256 * 256 * 2];");
8688 fprintf(fp, " static UINT8 psst[256 * 256 * 2];");
8689 fprintf(fp, "\n");
8690 fprintf(fp, " pbAddAdcTable = paat;\n");
8691 fprintf(fp, "\n");
8692 fprintf(fp, " pbTempPtr = pbAddAdcTable;\n\n");
8693 fprintf(fp, " pbSubSbcTable = psst;\n");
8694 fprintf(fp, "\n");
8695 fprintf(fp, " pbTempPtr2 = pbSubSbcTable;\n");
8696 fprintf(fp, "\n");
8697 fprintf(fp, " for (dwLoop = 0; dwLoop < (256*256*2); dwLoop++)\n");
8698 fprintf(fp, " {\n");
8699 fprintf(fp, " bLow = dwLoop & 0xff;\n");
8700 fprintf(fp, " bHigh = (dwLoop >> 8) & 0xff;\n");
8701 fprintf(fp, " bCarry = (dwLoop >> 16);\n");
8702 fprintf(fp, "\n");
8703 fprintf(fp, " bFlag = 0;\n");
8704 fprintf(fp, " bNewAdd = bHigh + bLow + bCarry;\n");
8705 fprintf(fp, "\n");
8706 fprintf(fp, " if (0 == bNewAdd)\n");
8707 fprintf(fp, " {\n");
8708 fprintf(fp, " bFlag |= Z80_FLAG_ZERO;\n");
8709 fprintf(fp, " }\n");
8710 fprintf(fp, " else\n");
8711 fprintf(fp, " {\n");
8712 fprintf(fp, " bFlag = bNewAdd & 0x80; /* Sign flag */\n");
8713 fprintf(fp, " }\n");
8714 fprintf(fp, "\n");
8715 fprintf(fp, " if (((UINT32) bLow + (UINT32) bHigh + (UINT32) bCarry) >= 0x100)\n");
8716 fprintf(fp, " {\n");
8717 fprintf(fp, " bFlag |= Z80_FLAG_CARRY;\n");
8718 fprintf(fp, " }\n");
8719 fprintf(fp, "\n");
8720 fprintf(fp, " if ( ((bLow ^ bHigh ^ 0x80) & (bLow ^ (bNewAdd & 0x80))) & 0x80)\n");
8721 fprintf(fp, " {\n");
8722 fprintf(fp, " bFlag |= Z80_FLAG_OVERFLOW_PARITY;\n");
8723 fprintf(fp, " }\n");
8724 fprintf(fp, "\n");
8725 fprintf(fp, " if (((bLow & 0x0f) + (bHigh & 0x0f) + bCarry) >= 0x10)\n");
8726 fprintf(fp, " {\n");
8727 fprintf(fp, " bFlag |= Z80_FLAG_HALF_CARRY;\n");
8728 fprintf(fp, " }\n");
8729 fprintf(fp, "\n");
8730 fprintf(fp, " *pbTempPtr++ = bFlag; /* Store our new flag */\n\n");
8732 fprintf(fp, " // Now do subtract - Zero\n");
8733 fprintf(fp, "\n");
8734 fprintf(fp, " bFlag = Z80_FLAG_NEGATIVE;\n");
8735 fprintf(fp, " bNewSub = bHigh - bLow - bCarry;\n");
8736 fprintf(fp, "\n");
8737 fprintf(fp, " if (0 == bNewSub)\n");
8738 fprintf(fp, " {\n");
8739 fprintf(fp, " bFlag |= Z80_FLAG_ZERO;\n");
8740 fprintf(fp, " }\n");
8741 fprintf(fp, " else\n");
8742 fprintf(fp, " {\n");
8743 fprintf(fp, " bFlag |= bNewSub & 0x80; /* Sign flag */\n");
8744 fprintf(fp, " }\n");
8745 fprintf(fp, "\n");
8746 fprintf(fp, " if ( ((INT32) bHigh - (INT32) bLow - (INT32) bCarry) < 0)\n");
8747 fprintf(fp, " {\n");
8748 fprintf(fp, " bFlag |= Z80_FLAG_CARRY;\n");
8749 fprintf(fp, " }\n");
8750 fprintf(fp, "\n");
8751 fprintf(fp, " if ( ((INT32) (bHigh & 0xf) - (INT32) (bLow & 0x0f) - (INT32) bCarry) < 0)\n");
8752 fprintf(fp, " {\n");
8753 fprintf(fp, " bFlag |= Z80_FLAG_HALF_CARRY;\n");
8754 fprintf(fp, " }\n");
8755 fprintf(fp, "\n");
8756 fprintf(fp, " if ( ((bLow ^ bHigh) & (bHigh ^ bNewSub) & 0x80) )\n");
8757 fprintf(fp, " {\n");
8758 fprintf(fp, " bFlag |= Z80_FLAG_OVERFLOW_PARITY;\n");
8759 fprintf(fp, " }\n");
8760 fprintf(fp, "\n");
8761 fprintf(fp, " *pbTempPtr2++ = bFlag; /* Store our sub flag */\n");
8762 fprintf(fp, "\n");
8763 fprintf(fp, " }\n");
8764 fprintf(fp, " }\n");
8765 fprintf(fp, "}\n");
8767 else
8769 abort();
8773 void ShutdownCode(void)
8775 if (MZ80_ASSEMBLY_X86 == bWhat)
8777 fprintf(fp, " global _%sshutdown\n", cpubasename);
8778 fprintf(fp, " global %sshutdown_\n", cpubasename);
8780 if (bPlain)
8781 fprintf(fp, " global %sshutdown\n", cpubasename);
8783 sprintf(procname, "%sshutdown_", cpubasename);
8784 ProcBegin(0xffffffff);
8786 fprintf(fp, "_%sshutdown:\n", cpubasename);
8788 if (bPlain)
8789 fprintf(fp, "%sshutdown:\n", cpubasename);
8791 fprintf(fp, " ret\n\n");
8793 else
8794 if (MZ80_C == bWhat)
8796 fprintf(fp, "/* Shut down MZ80 */\n\n");
8797 fprintf(fp, "void %sshutdown(void)\n", cpubasename);
8798 fprintf(fp, "{\n");
8800 fprintf(fp, "}\n\n");
8802 else
8804 abort();
8808 void DebuggerCode(void)
8810 if (MZ80_ASSEMBLY_X86 == bWhat)
8812 Alignment();
8814 fprintf(fp, ";\n");
8815 fprintf(fp, "; In : EAX=Reg #, ESI=Context address\n");
8816 fprintf(fp, "; Out: EAX=Value of register\n");
8817 fprintf(fp, ";\n");
8819 fprintf(fp, "getRegValueInternal:\n");
8821 fprintf(fp, " push ecx\n");
8822 fprintf(fp, " push edx\n\n");
8824 fprintf(fp, " cmp eax, CPUREG_MAXINDEX\n");
8825 fprintf(fp, " jae badIndex2\n\n");
8827 fprintf(fp, " shl eax, 4 ; Times 16 for table entry size\n");
8828 fprintf(fp, " add eax, RegTable ; Now it's the memory location\n");
8830 fprintf(fp, " mov edx, [eax+4] ; Get the offset of the register\n");
8831 fprintf(fp, " mov edx, [edx + esi] ; Get our value\n");
8833 fprintf(fp, " mov ecx, [eax+8] ; Get our shift value\n");
8834 fprintf(fp, " shr edx, cl ; Shift it right by a value\n");
8836 fprintf(fp, " and edx, [eax+12] ; Mask off any unneeded bits\n");
8837 fprintf(fp, " mov eax, edx ; Put our value in EAX\n");
8838 fprintf(fp, " jmp short indexExit ; Index's exit!\n");
8840 fprintf(fp, "badIndex2:\n");
8841 fprintf(fp, " mov eax, 0ffffffffh\n\n");
8842 fprintf(fp, "indexExit:\n");
8843 fprintf(fp, " pop edx\n");
8844 fprintf(fp, " pop ecx\n");
8845 fprintf(fp, " ret\n\n");
8847 Alignment();
8849 fprintf(fp, ";\n");
8850 fprintf(fp, "; In : EAX=Value, EDX=Reg #, ESI=Context address\n");
8851 fprintf(fp, "; Out: EAX=Value of register\n");
8852 fprintf(fp, ";\n");
8854 fprintf(fp, "convertValueToText:\n");
8856 fprintf(fp, " push ecx\n");
8857 fprintf(fp, " push edx\n\n");
8859 fprintf(fp, " cmp edx, CPUREG_MAXINDEX\n");
8860 fprintf(fp, " jae badIndex3\n\n");
8862 fprintf(fp, " shl edx, 4 ; Times 16 for table entry size\n");
8863 fprintf(fp, " add edx, RegTable ; Now it's the memory location\n");
8864 fprintf(fp, " mov edx, [edx + 12] ; Shift mask\n");
8865 fprintf(fp, " xor ecx, ecx ; Zero our shift\n");
8867 fprintf(fp, "shiftLoop:\n");
8868 fprintf(fp, " test edx, 0f0000000h ; High nibble nonzero yet?\n");
8869 fprintf(fp, " jnz convertLoop ; Yup!\n");
8870 fprintf(fp, " shl edx, 4 ; Move over, bacon\n");
8871 fprintf(fp, " shl eax, 4 ; Move the value over, too\n");
8872 fprintf(fp, " jmp short shiftLoop ; Keep shiftin'\n\n");
8874 fprintf(fp, "convertLoop:\n");
8875 fprintf(fp, " mov ecx, eax ; Get our value\n");
8876 fprintf(fp, " shr ecx, 28 ; Only the top nibble\n");
8877 fprintf(fp, " add cl, '0' ; Convert to ASCII\n");
8878 fprintf(fp, " cmp cl, '9' ; Greater than 9?\n");
8879 fprintf(fp, " jbe noAdd ; Nope! Don't add it\n");
8880 fprintf(fp, " add cl, 32+7 ; Convert from lowercase a-f\n");
8881 fprintf(fp, "noAdd:\n");
8882 fprintf(fp, " mov [edi], cl ; New value storage\n");
8883 fprintf(fp, " inc edi ; Next byte, please\n");
8884 fprintf(fp, " shl eax, 4 ; Move the mask over\n");
8885 fprintf(fp, " shl edx, 4 ; Move the mask over\n");
8886 fprintf(fp, " jnz convertLoop ; Keep convertin'\n\n");
8889 fprintf(fp, "badIndex3:\n");
8890 fprintf(fp, " mov [edi], byte 0 ; Null terminate the sucker!\n");
8891 fprintf(fp, " pop edx\n");
8892 fprintf(fp, " pop ecx\n");
8893 fprintf(fp, " ret\n\n");
8895 fprintf(fp, " global _%sSetRegisterValue\n", cpubasename);
8896 fprintf(fp, " global %sSetRegisterValue_\n", cpubasename);
8898 if (bPlain)
8899 fprintf(fp, " global %sSetRegisterValue\n", cpubasename);
8901 sprintf(procname, "%sSetRegisterValue_", cpubasename);
8902 ProcBegin(0xffffffff);
8904 fprintf(fp, "_%sSetRegisterValue:\n", cpubasename);
8905 if (bPlain)
8906 fprintf(fp, "%sSetRegisterValue:\n", cpubasename);
8908 fprintf(fp, " push esi\n");
8909 fprintf(fp, " push edi\n");
8910 fprintf(fp, " push edx\n");
8911 fprintf(fp, " push ecx\n");
8913 if (bUseStack)
8915 fprintf(fp, " mov eax, [esp+20] ; Get our register #\n");
8916 fprintf(fp, " mov esi, [esp+24] ; Get our context address\n");
8917 fprintf(fp, " mov edi, [esp+28] ; Value to assign\n");
8919 else
8921 fprintf(fp, " mov esi, eax ; Get context\n");
8922 fprintf(fp, " mov eax, edx ; Get register # in EAX\n");
8923 fprintf(fp, " mov edi, ebx ; Get value to assign\n");
8926 fprintf(fp, " or esi, esi ; Are we NULL?\n");
8927 fprintf(fp, " jnz userDefined\n");
8929 fprintf(fp, " mov esi, _%scontextBegin\n", cpubasename);
8930 fprintf(fp, "userDefined:\n\n");
8931 fprintf(fp, " shl eax, 4 ; Times 16 for reg entry size\n");
8932 fprintf(fp, " add eax, RegTable\n");
8933 fprintf(fp, " mov edx, [eax+12] ; Our mask\n");
8934 fprintf(fp, " not edx ; Invert EDX!\n");
8935 fprintf(fp, " test edi, edx ; Did we set any invalid bits?\n");
8936 fprintf(fp, " jnz rangeViolation\n\n");
8938 fprintf(fp, " not edx ; Toggle it back to normal\n");
8939 fprintf(fp, " mov ecx, [eax+8] ; Get our shift value\n");
8940 fprintf(fp, " shl edx, cl ; Shift our mask\n");
8941 fprintf(fp, " shl eax, cl ; And our value to OR in\n");
8943 fprintf(fp, " not edx ; Make it the inverse of what we want\n");
8944 fprintf(fp, " mov eax, [eax+4] ; Get our offset into the context\n");
8945 fprintf(fp, " and [esi+eax], edx ; Mask off the bits we're changin\n");
8946 fprintf(fp, " or [esi+eax], edi ; Or in our new value\n\n");
8947 fprintf(fp, " xor eax, eax\n");
8948 fprintf(fp, " jmp short setExit\n\n");
8950 fprintf(fp, "rangeViolation:\n");
8951 fprintf(fp, " mov eax, 0ffffffffh\n\n");
8953 fprintf(fp, "setExit:\n");
8954 fprintf(fp, " pop ecx\n");
8955 fprintf(fp, " pop edx\n");
8956 fprintf(fp, " pop edi\n");
8957 fprintf(fp, " pop esi\n\n");
8959 fprintf(fp, " ret\n\n");
8961 Alignment();
8963 fprintf(fp, " global _%sGetRegisterValue\n", cpubasename);
8964 fprintf(fp, " global %sGetRegisterValue_\n", cpubasename);
8966 if (bPlain)
8967 fprintf(fp, " global %sGetRegisterValue\n", cpubasename);
8969 sprintf(procname, "%sGetRegisterValue_", cpubasename);
8970 ProcBegin(0xffffffff);
8972 fprintf(fp, "_%sGetRegisterValue:\n", cpubasename);
8973 if (bPlain)
8974 fprintf(fp, "%sGetRegisterValue:\n", cpubasename);
8976 fprintf(fp, " push esi\n");
8978 if (bUseStack)
8980 fprintf(fp, " mov eax, [esp+8] ; Get our register #\n");
8981 fprintf(fp, " mov esi, [esp+12] ; Get our context address\n");
8983 else
8985 fprintf(fp, " mov esi, eax ; Get context\n");
8986 fprintf(fp, " mov eax, edx ; Get register # in EAX\n");
8989 fprintf(fp, " or esi, esi ; Is context NULL?\n");
8990 fprintf(fp, " jnz getVal ; Nope - use it!\n");
8991 fprintf(fp, " mov esi, _%scontextBegin\n\n", cpubasename);
8993 fprintf(fp, "getVal:\n");
8994 fprintf(fp, " call getRegValueInternal\n\n");
8996 fprintf(fp, " pop esi\n");
8998 fprintf(fp, " ret\n\n");
9000 Alignment();
9002 fprintf(fp, " global _%sGetRegisterName\n", cpubasename);
9003 fprintf(fp, " global %sGetRegisterName_\n", cpubasename);
9005 if (bPlain)
9006 fprintf(fp, " global %sGetRegisterName\n", cpubasename);
9008 sprintf(procname, "%sGetRegisterName_", cpubasename);
9009 ProcBegin(0xffffffff);
9011 fprintf(fp, "_%sGetRegisterName:\n", cpubasename);
9012 if (bPlain)
9013 fprintf(fp, "%sGetRegisterName:\n", cpubasename);
9015 if (bUseStack)
9017 fprintf(fp, " mov eax, [esp+4] ; Get our register #\n");
9020 fprintf(fp, " cmp eax, CPUREG_MAXINDEX\n");
9021 fprintf(fp, " jae badIndex\n");
9023 fprintf(fp, " shl eax, 4 ; Times 16 bytes for each entry\n");
9024 fprintf(fp, " mov eax, [eax+RegTable]\n");
9025 fprintf(fp, " jmp nameExit\n\n");
9027 fprintf(fp, "badIndex:\n");
9028 fprintf(fp, " xor eax, eax\n\n");
9030 fprintf(fp, "nameExit:\n");
9031 fprintf(fp, " ret\n\n");
9033 Alignment();
9035 fprintf(fp, " global _%sGetRegisterTextValue\n", cpubasename);
9036 fprintf(fp, " global %sGetRegisterTextValue_\n", cpubasename);
9038 if (bPlain)
9039 fprintf(fp, " global %sGetRegisterTextValue\n", cpubasename);
9041 sprintf(procname, "%sGetRegisterTextValue_", cpubasename);
9042 ProcBegin(0xffffffff);
9044 fprintf(fp, "_%sGetRegisterTextValue:\n", cpubasename);
9045 if (bPlain)
9046 fprintf(fp, "%sGetRegisterTextValue:\n", cpubasename);
9048 fprintf(fp, " push esi\n");
9049 fprintf(fp, " push edi\n");
9050 fprintf(fp, " push edx\n");
9052 if (bUseStack)
9054 fprintf(fp, " mov eax, [esp+16] ; Get our register #\n");
9055 fprintf(fp, " mov esi, [esp+20] ; Get our context address\n");
9056 fprintf(fp, " mov edi, [esp+24] ; Address to place text\n");
9058 else
9060 fprintf(fp, " mov esi, eax ; Get context\n");
9061 fprintf(fp, " mov eax, edx ; Get register # in EAX\n");
9062 fprintf(fp, " mov edi, ebx ; Address to place text\n");
9065 fprintf(fp, " or esi, esi ; Is context NULL?\n");
9066 fprintf(fp, " jnz getVal2 ; Nope - use it!\n");
9067 fprintf(fp, " mov esi, _%scontextBegin\n\n", cpubasename);
9069 fprintf(fp, "getVal2:\n");
9070 fprintf(fp, " mov edx, eax ; Save off our index for later\n");
9071 fprintf(fp, " call getRegValueInternal\n\n");
9073 fprintf(fp, "; EAX Holds the value, EDX=Register #, and EDI=Destination!\n\n");
9075 fprintf(fp, " call convertValueToText\n\n");
9077 fprintf(fp, " pop edx\n");
9078 fprintf(fp, " pop esi\n");
9079 fprintf(fp, " pop edi\n");
9081 fprintf(fp, " ret\n\n");
9083 Alignment();
9085 fprintf(fp, " global _%sWriteValue\n", cpubasename);
9086 fprintf(fp, " global %sWriteValue_\n", cpubasename);
9088 if (bPlain)
9089 fprintf(fp, " global %sWriteValue\n", cpubasename);
9091 sprintf(procname, "%sWriteValue_", cpubasename);
9092 ProcBegin(0xffffffff);
9094 fprintf(fp, "_%sWriteValue:\n", cpubasename);
9095 if (bPlain)
9096 fprintf(fp, "%sWriteValue:\n", cpubasename);
9098 fprintf(fp, " push esi\n");
9099 fprintf(fp, " push edi\n");
9100 fprintf(fp, " push edx\n");
9101 fprintf(fp, " push ebx\n");
9102 fprintf(fp, " push ecx\n");
9103 fprintf(fp, " push ebp\n");
9105 if (bUseStack)
9107 fprintf(fp, " mov eax, [esp+28] ; What kind of write is this?\n");
9108 fprintf(fp, " mov ebx, [esp+32] ; Address\n");
9109 fprintf(fp, " mov edx, [esp+36] ; Value\n");
9111 else
9113 fprintf(fp, " xchg edx, ebx ; Addr=EBX, value=EDX\n");
9116 fprintf(fp, " cmp eax, 1 ; Is it a word write?\n");
9117 fprintf(fp, " je near invalidWrite ; Yep - it's not valid\n");
9118 fprintf(fp, " cmp eax, 2 ; Is it a dword write?\n");
9119 fprintf(fp, " je near invalidWrite ; Yep - it's not valid\n\n");
9120 fprintf(fp, " or eax, eax ; Is it a byte write?\n");
9121 fprintf(fp, " jnz itsIoDummy ; Nope... it's an I/O write\n\n");
9123 // Here we do a write memory byte
9125 fprintf(fp, " mov ebp, [_z80Base] ; Base pointer comes back\n");
9126 fprintf(fp, " mov edi, [_z80MemWrite] ; Point to the write array\n");
9128 fprintf(fp, "checkLoop:\n");
9129 fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n");
9130 fprintf(fp, " je memoryWrite ; Yes - go write it!\n");
9131 fprintf(fp, " cmp bx, [edi] ; Are we smaller?\n");
9132 fprintf(fp, " jb nextAddr ; Yes... go to the next addr\n");
9133 fprintf(fp, " cmp bx, [edi+4] ; Are we smaller?\n");
9134 fprintf(fp, " jbe callRoutine ; If not, go call it!\n");
9136 fprintf(fp, "nextAddr:\n");
9137 fprintf(fp, " add edi, 10h ; Next structure, please\n");
9138 fprintf(fp, " jmp short checkLoop\n");
9140 fprintf(fp, "callRoutine:\n");
9142 fprintf(fp, "\n;\n; EBX=Address to target, DL=Byte to write \n;\n\n");
9144 fprintf(fp, " cmp [edi+8], dword 0 ; Null handler?\n");
9145 fprintf(fp, " je directWriteHandler2\n\n");
9147 if (FALSE == bUseStack)
9149 fprintf(fp, " mov eax, ebx ; Address\n");
9150 fprintf(fp, " mov ebx, edi ; Pointer to struct (EDX Already has the byte to write)\n");
9152 else
9154 fprintf(fp, " push edi ; Handler\n");
9155 fprintf(fp, " push edx ; Byte\n");
9156 fprintf(fp, " push ebx ; Address\n");
9159 fprintf(fp, " call dword [edi + 8] ; Go call our handler\n");
9161 if (bUseStack)
9163 fprintf(fp, " add esp, 12\n");
9166 fprintf(fp, " jmp short itsGood\n");
9168 fprintf(fp, "directWriteHandler2:\n");
9169 fprintf(fp, " sub ebx, [edi] ; Subtract our offset\n");
9170 fprintf(fp, " add ebx, [edi+12] ; Add in the base address\n");
9171 fprintf(fp, " mov [ebx], dl ; Store our byte\n");
9172 fprintf(fp, " jmp short itsGood\n");
9173 fprintf(fp, "memoryWrite:\n");
9174 fprintf(fp, " mov [ebp + ebx], dl\n\n");
9175 fprintf(fp, " jmp short itsGood\n");
9177 // Here we do an "out"
9179 fprintf(fp, "itsIoDummy:\n");
9181 fprintf(fp, " mov edi, [_z80IoWrite] ; Point to the I/O write array\n");
9183 fprintf(fp, "IOCheck:\n");
9184 fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n");
9185 fprintf(fp, " je itsGood ; Yes - ignore it!\n");
9186 fprintf(fp, " cmp bx, [edi] ; Are we smaller?\n");
9187 fprintf(fp, " jb nextIOAddr ; Yes... go to the next addr\n");
9188 fprintf(fp, " cmp bx, [edi+2] ; Are we bigger?\n");
9189 fprintf(fp, " jbe callIOHandler ; If not, go call it!\n");
9191 fprintf(fp, "nextIOAddr:\n");
9192 fprintf(fp, " add edi, 0ch ; Next structure, please\n");
9193 fprintf(fp, " jmp short IOCheck\n");
9195 fprintf(fp, "callIOHandler:\n");
9197 if (FALSE == bUseStack)
9199 fprintf(fp, " mov eax, ebx ; Address\n");
9200 fprintf(fp, " mov ebx, edi ; Pointer to struct (EDX Already has the byte to write)\n");
9202 else
9204 fprintf(fp, " push edi ; Handler\n");
9205 fprintf(fp, " push edx ; Byte\n");
9206 fprintf(fp, " push ebx ; Address\n");
9209 fprintf(fp, " call dword [edi+4] ; Call the handler!\n");
9211 if (bUseStack)
9212 fprintf(fp, " add esp, 12\n");
9214 fprintf(fp, " jmp short itsGood\n\n");
9216 // Errors and whatnot
9218 fprintf(fp, "invalidWrite:\n");
9219 fprintf(fp, " mov eax, 0ffffffffh\n");
9220 fprintf(fp, " jmp short writeValueExit\n\n");
9222 fprintf(fp, "itsGood:\n");
9223 fprintf(fp, " xor eax, eax\n\n");
9225 fprintf(fp, "writeValueExit:\n");
9227 fprintf(fp, " pop ebp\n");
9228 fprintf(fp, " pop ecx\n");
9229 fprintf(fp, " pop ebx\n");
9230 fprintf(fp, " pop edx\n");
9231 fprintf(fp, " pop esi\n");
9232 fprintf(fp, " pop edi\n");
9234 fprintf(fp, " ret\n\n");
9236 Alignment();
9238 fprintf(fp, " global _%sReadValue\n", cpubasename);
9239 fprintf(fp, " global %sReadValue_\n", cpubasename);
9241 if (bPlain)
9242 fprintf(fp, " global %sReadValue\n", cpubasename);
9244 sprintf(procname, "%sReadValue_", cpubasename);
9245 ProcBegin(0xffffffff);
9247 fprintf(fp, "_%sReadValue:\n", cpubasename);
9248 if (bPlain)
9249 fprintf(fp, "%sReadValue:\n", cpubasename);
9251 fprintf(fp, " push esi\n");
9252 fprintf(fp, " push edi\n");
9253 fprintf(fp, " push edx\n");
9254 fprintf(fp, " push ebx\n");
9255 fprintf(fp, " push ecx\n");
9256 fprintf(fp, " push ebp\n");
9258 if (bUseStack)
9260 fprintf(fp, " mov eax, [esp+28] ; What kind of read is this?\n");
9261 fprintf(fp, " mov ebx, [esp+32] ; Address\n");
9263 else
9265 fprintf(fp, " xchg edx, ebx ; Addr=EBX\n");
9268 fprintf(fp, " cmp eax, 1 ; Is it a word read?\n");
9269 fprintf(fp, " je near invalidRead ; Yep - it's not valid\n");
9270 fprintf(fp, " cmp eax, 2 ; Is it a dword read?\n");
9271 fprintf(fp, " je near invalidRead ; Yep - it's not valid\n\n");
9272 fprintf(fp, " or eax, eax ; Is it a byte read?\n");
9273 fprintf(fp, " jnz itsIoDummyRead ; Nope... it's an I/O read\n\n");
9275 // Here we do a read memory byte
9277 fprintf(fp, " mov ebp, [_z80Base] ; Base pointer comes back\n");
9278 fprintf(fp, " mov edi, [_z80MemRead] ; Point to the read array\n");
9280 fprintf(fp, "checkLoopRead:\n");
9281 fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n");
9282 fprintf(fp, " je memoryRead ; Yes - go read it!\n");
9283 fprintf(fp, " cmp bx, [edi] ; Are we smaller?\n");
9284 fprintf(fp, " jb nextAddrRead ; Yes... go to the next addr\n");
9285 fprintf(fp, " cmp bx, [edi+4] ; Are we smaller?\n");
9286 fprintf(fp, " jbe callRoutineRead ; If not, go call it!\n");
9288 fprintf(fp, "nextAddrRead:\n");
9289 fprintf(fp, " add edi, 10h ; Next structure, please\n");
9290 fprintf(fp, " jmp short checkLoopRead\n");
9292 fprintf(fp, "callRoutineRead:\n");
9294 fprintf(fp, "\n;\n; EBX=Address to target\n;\n\n");
9296 fprintf(fp, " cmp [edi+8], dword 0 ; NULL HAndler?\n");
9297 fprintf(fp, " je handleSharedRead\n\n");
9299 if (FALSE == bUseStack)
9301 fprintf(fp, " mov eax, ebx ; Address\n");
9302 fprintf(fp, " mov edx, edi ; Pointer to struct\n");
9304 else
9306 fprintf(fp, " push edi ; Handler\n");
9307 fprintf(fp, " push ebx ; Address\n");
9310 fprintf(fp, " call dword [edi + 8] ; Go call our handler\n");
9311 fprintf(fp, " mov dl, al ; Get our byte read\n");
9313 if (bUseStack)
9315 fprintf(fp, " add esp, 8\n");
9318 fprintf(fp, " jmp short itsGoodRead\n\n");
9320 fprintf(fp, "memoryRead:\n");
9321 fprintf(fp, " mov dl, [ebp+ebx]\n\n");
9322 fprintf(fp, " jmp short itsGoodRead\n\n");
9324 fprintf(fp, "handleSharedRead:\n");
9325 fprintf(fp, " sub ebx, [edi]\n");
9326 fprintf(fp, " add ebx, [edi+12]\n");
9327 fprintf(fp, " mov dl, [ebx]\n");
9328 fprintf(fp, " jmp short itsGoodRead\n\n");
9330 // Here we do an "out"
9332 fprintf(fp, "itsIoDummyRead:\n");
9334 fprintf(fp, " mov edi, [_z80IoRead] ; Point to the I/O read array\n");
9335 fprintf(fp, " mov dl, 0ffh ; Assume no handler\n");
9337 fprintf(fp, "IOCheckRead:\n");
9338 fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n");
9339 fprintf(fp, " je itsGoodRead ; Yes - ignore it!\n");
9340 fprintf(fp, " cmp bx, [edi] ; Are we smaller?\n");
9341 fprintf(fp, " jb nextIOAddrRead ; Yes... go to the next addr\n");
9342 fprintf(fp, " cmp bx, [edi+2] ; Are we bigger?\n");
9343 fprintf(fp, " jbe callIOHandlerRead ; If not, go call it!\n");
9345 fprintf(fp, "nextIOAddrRead:\n");
9346 fprintf(fp, " add edi, 0ch ; Next structure, please\n");
9347 fprintf(fp, " jmp short IOCheckRead\n");
9349 fprintf(fp, "callIOHandlerRead:\n");
9351 if (FALSE == bUseStack)
9353 fprintf(fp, " mov eax, ebx ; Address\n");
9354 fprintf(fp, " mov edx, edi ; Pointer to struct (EDX Already has the byte to write)\n");
9356 else
9358 fprintf(fp, " push edi ; Handler\n");
9359 fprintf(fp, " push ebx ; Address\n");
9362 fprintf(fp, " call dword [edi+4] ; Call the handler!\n");
9363 fprintf(fp, " mov dl, al ; Get our byte read\n");
9365 if (bUseStack)
9366 fprintf(fp, " add esp, 8\n");
9368 fprintf(fp, " jmp short itsGoodRead\n\n");
9370 // Errors and whatnot
9372 fprintf(fp, "invalidRead:\n");
9373 fprintf(fp, " mov eax, 0ffffffffh\n");
9374 fprintf(fp, " jmp short ReadValueExit\n\n");
9376 fprintf(fp, "itsGoodRead:\n");
9377 fprintf(fp, " xor eax, eax\n");
9378 fprintf(fp, " mov al, dl\n\n");
9380 fprintf(fp, "ReadValueExit:\n");
9382 fprintf(fp, " pop ebp\n");
9383 fprintf(fp, " pop ecx\n");
9384 fprintf(fp, " pop ebx\n");
9385 fprintf(fp, " pop edx\n");
9386 fprintf(fp, " pop esi\n");
9387 fprintf(fp, " pop edi\n");
9389 fprintf(fp, " ret\n\n");
9394 else
9395 if (MZ80_C == bWhat)
9401 void EmitCode(void)
9403 CodeSegmentBegin();
9404 EmitCBInstructions();
9405 EmitEDInstructions();
9407 if (MZ80_ASSEMBLY_X86 == bWhat)
9408 strcpy(mz80Index, "ix");
9410 else
9412 strcpy(mz80Index, "cpu.z80IX");
9413 strcpy(mz80IndexHalfHigh, "cpu.z80XH");
9414 strcpy(mz80IndexHalfLow, "cpu.z80XL");
9417 strcpy(majorOp, "DD");
9418 EmitDDInstructions();
9420 if (MZ80_ASSEMBLY_X86 == bWhat)
9421 strcpy(mz80Index, "iy");
9422 else
9424 strcpy(mz80Index, "cpu.z80IY");
9425 strcpy(mz80IndexHalfHigh, "cpu.z80YH");
9426 strcpy(mz80IndexHalfLow, "cpu.z80YL");
9429 strcpy(majorOp, "FD");
9430 EmitFDInstructions();
9431 majorOp[0] = '\0';
9432 EmitRegularInstructions();
9433 ReadMemoryByteHandler();
9434 WriteMemoryByteHandler();
9436 if (bThroughCallHandler)
9438 PushWordHandler();
9439 PopWordHandler();
9442 ReadIoHandler();
9443 WriteIoHandler();
9444 GetContextCode();
9445 SetContextCode();
9446 GetContextSizeCode();
9447 GetTicksCode();
9448 ReleaseTimesliceCode();
9449 ResetCode();
9450 IntCode();
9451 NmiCode();
9452 ExecCode();
9453 InitCode();
9454 ShutdownCode();
9455 DebuggerCode();
9456 CodeSegmentEnd();
9459 int main(int argc, char **argv)
9461 int dwLoop = 0;
9463 printf("MakeZ80 - V%s - Copyright 1996-2000 Neil Bradley (neil@synthcom.com)\n", MZ80_VERSION);
9465 if (argc < 2)
9467 printf("Usage: %s outfile [option1] [option2] ....\n", argv[0]);
9468 printf("\n -s - Stack calling conventions (DJGPP, MSVC, Borland)\n");
9469 printf(" -x86 - Emit an assembly version of mz80\n");
9470 printf(" -c - Emit a C version of mz80\n");
9471 printf(" -cs - All stack operations go through handlers\n");
9472 printf(" -16 - Treat all I/O input and output as 16 bit (BC) instead of (C)\n");
9473 printf(" -l - Create 'plain' labels - ones without leading or trailing _'s\n");
9474 printf(" -nt - No timing additions occur\n");
9475 printf(" -os2 - Emit OS/2 compatible segmentation pragmas\n");
9476 exit(1);
9479 dwLoop = 1;
9481 while (dwLoop < argc)
9483 if (strcmp("-x86", argv[dwLoop]) == 0 || strcmp("-X86", argv[dwLoop]) == 0)
9484 bWhat = MZ80_ASSEMBLY_X86;
9485 if (strcmp("-c", argv[dwLoop]) == 0 || strcmp("-C", argv[dwLoop]) == 0)
9486 bWhat = MZ80_C;
9487 if (strcmp("-cs", argv[dwLoop]) == 0 || strcmp("-cs", argv[dwLoop]) == 0)
9488 bThroughCallHandler = TRUE;
9489 if (strcmp("-s", argv[dwLoop]) == 0 || strcmp("-S", argv[dwLoop]) == 0)
9490 bUseStack = 1;
9491 if (strcmp("-l", argv[dwLoop]) == 0 || strcmp("-L", argv[dwLoop]) == 0)
9492 bPlain = TRUE;
9493 if (strcmp("-16", argv[dwLoop]) == 0)
9494 b16BitIo = TRUE;
9495 if (strcmp("-os2", argv[dwLoop]) == 0 || strcmp("-OS2", argv[dwLoop]) == 0)
9496 bOS2 = TRUE;
9497 if (strcmp("-nt", argv[dwLoop]) == 0)
9499 bNoTiming = TRUE;
9502 dwLoop++;
9505 if (bWhat == MZ80_UNKNOWN)
9507 fprintf(stderr, "Need emitted type qualifier\n");
9508 exit(1);
9511 for (dwLoop = 1; dwLoop < argc; dwLoop++)
9512 if (argv[dwLoop][0] != '-')
9514 fp = fopen(argv[dwLoop], "w");
9515 break;
9518 if (NULL == fp)
9520 fprintf(stderr, "Can't open %s for writing\n", argv[1]);
9521 exit(1);
9524 strcpy(cpubasename, "mz80");
9526 StandardHeader();
9527 DataSegment();
9528 EmitCode();
9529 ProgramEnd();
9531 fclose(fp);