switch Cyclone to submodule on it's own git repo
[picodrive.git] / cpu / mz80 / makez80.c
CommitLineData
cc68a136 1/* Multi-Z80 32 Bit emulator */\r
2\r
3/* Copyright 1996, 1997, 1998, 1999, 2000 Neil Bradley, All rights reserved\r
4 *\r
5 * License agreement:\r
6 *\r
7 * (MZ80 Refers to both the assembly and C code emitted by makeZ80.c and \r
8 * makeZ80.c itself)\r
9 *\r
10 * MZ80 May be distributed in unmodified form to any medium.\r
11 *\r
12 * MZ80 May not be sold, or sold as a part of a commercial package without\r
13 * the express written permission of Neil Bradley (neil@synthcom.com). This\r
14 * includes shareware.\r
15 *\r
16 * Modified versions of MZ80 may not be publicly redistributed without author\r
17 * approval (neil@synthcom.com). This includes distributing via a publicly\r
18 * accessible LAN. You may make your own source modifications and distribute\r
19 * MZ80 in source or object form, but if you make modifications to MZ80\r
20 * then it should be noted in the top as a comment in makeZ80.c.\r
21 *\r
22 * MZ80 Licensing for commercial applications is available. Please email\r
23 * neil@synthcom.com for details.\r
24 *\r
25 * Synthcom Systems, Inc, and Neil Bradley will not be held responsible for\r
26 * any damage done by the use of MZ80. It is purely "as-is".\r
27 *\r
28 * If you use MZ80 in a freeware application, credit in the following text:\r
29 *\r
30 * "Multi-Z80 CPU emulator by Neil Bradley (neil@synthcom.com)"\r
31 *\r
32 * must accompany the freeware application within the application itself or\r
33 * in the documentation.\r
34 *\r
35 * Legal stuff aside:\r
36 *\r
37 * If you find problems with MZ80, please email the author so they can get\r
38 * resolved. If you find a bug and fix it, please also email the author so\r
39 * that those bug fixes can be propogated to the installed base of MZ80\r
40 * users. If you find performance improvements or problems with MZ80, please\r
41 * email the author with your changes/suggestions and they will be rolled in\r
42 * with subsequent releases of MZ80.\r
43 *\r
44 * The whole idea of this emulator is to have the fastest available 32 bit\r
45 * Multi-Z80 emulator for the PC, giving maximum performance. \r
46 *\r
47 */ \r
48\r
49#include <stdio.h>\r
50#include <stdlib.h>\r
51#include <string.h>\r
52#include <assert.h>\r
53\r
54#define VERSION "3.4"\r
55\r
56#define TRUE 0xff\r
57#define FALSE 0x0\r
58#define INVALID 0xff\r
59\r
60#define UINT32 unsigned long int\r
61#define UINT8 unsigned char\r
62\r
63#define TIMING_REGULAR 0x00\r
64#define TIMING_XXCB 0x01\r
65#define TIMING_CB 0xcb\r
66#define TIMING_DDFD 0xdd\r
67#define TIMING_ED 0xed\r
68#define TIMING_EXCEPT 0x02\r
69\r
70FILE *fp = NULL;\r
71char string[150];\r
72char cpubasename[150];\r
73static char mz80Index[50];\r
74static char mz80IndexHalfHigh[50];\r
75static char mz80IndexHalfLow[50];\r
76char majorOp[50];\r
77char procname[150];\r
78UINT32 dwGlobalLabel = 0;\r
79\r
80enum\r
81{\r
82 MZ80_ASSEMBLY_X86,\r
83 MZ80_C,\r
84 MZ80_UNKNOWN\r
85};\r
86\r
87UINT8 bPlain = FALSE;\r
88UINT8 bNoTiming = FALSE;\r
89UINT8 bUseStack = 0;\r
90UINT8 bCurrentMode = TIMING_REGULAR; // Current timing mode\r
91UINT8 b16BitIo = FALSE;\r
92UINT8 bThroughCallHandler = FALSE;\r
93UINT8 bOS2 = FALSE;\r
94UINT8 bWhat = MZ80_UNKNOWN;\r
95\r
96void ProcBegin(UINT32 dwOpcode);\r
97\r
98UINT8 *pbLocalReg[8] =\r
99{\r
100 "ch",\r
101 "cl",\r
102 "dh",\r
103 "dl",\r
104 "bh",\r
105 "bl",\r
106 "dl",\r
107 "al"\r
108};\r
109\r
110UINT8 *pbLocalRegC[8] =\r
111{\r
112 "cpu.z80B",\r
113 "cpu.z80C",\r
114 "cpu.z80D",\r
115 "cpu.z80E",\r
116 "cpu.z80H",\r
117 "cpu.z80L",\r
118 "barf",\r
119 "cpu.z80A"\r
120};\r
121\r
122UINT8 *pbPushReg[8] = \r
123{\r
124 "cl",\r
125 "ch",\r
126 "byte [_z80de]",\r
127 "byte [_z80de + 1]",\r
128 "bl",\r
129 "bh",\r
130 "ah",\r
131 "al"\r
132};\r
133\r
134UINT8 *pbFlags[8] =\r
135{\r
136 "nz",\r
137 "z",\r
138 "nc",\r
139 "c",\r
140 "po",\r
141 "pe",\r
142 "ns",\r
143 "s"\r
144};\r
145\r
146UINT8 *pbRegPairC[] =\r
147{\r
148 "cpu.z80BC",\r
149 "cpu.z80DE",\r
150 "cpu.z80HL",\r
151 "cpu.z80sp"\r
152};\r
153\r
154UINT8 *pbFlagsC[8] =\r
155{\r
156 "(!(cpu.z80F & Z80_FLAG_ZERO))",\r
157 "(cpu.z80F & Z80_FLAG_ZERO)",\r
158 "(!(cpu.z80F & Z80_FLAG_CARRY))",\r
159 "(cpu.z80F & Z80_FLAG_CARRY)",\r
160 "(!(cpu.z80F & Z80_FLAG_OVERFLOW_PARITY))",\r
161 "(cpu.z80F & Z80_FLAG_OVERFLOW_PARITY)",\r
162 "(!(cpu.z80F & Z80_FLAG_SIGN))",\r
163 "(cpu.z80F & Z80_FLAG_SIGN)"\r
164};\r
165\r
166UINT8 *pbMathReg[8] =\r
167{\r
168 "ch",\r
169 "cl",\r
170 "byte [_z80de + 1]",\r
171 "byte [_z80de]",\r
172 "bh",\r
173 "bl",\r
174 "INVALID",\r
175 "al"\r
176};\r
177\r
178UINT8 *pbMathRegC[8] =\r
179{\r
180 "cpu.z80B",\r
181 "cpu.z80C",\r
182 "cpu.z80D",\r
183 "cpu.z80E",\r
184 "cpu.z80H",\r
185 "cpu.z80L",\r
186 "bTemp",\r
187 "cpu.z80A"\r
188};\r
189\r
190UINT8 *pbRegPairs[4] = \r
191{\r
192 "cx", // BC\r
193 "word [_z80de]", // DE\r
194 "bx", // HL\r
195 "word [_z80sp]" // SP\r
196};\r
197\r
198UINT8 *pbRegPairsC[4] = \r
199{\r
200 "cpu.z80BC", // BC\r
201 "cpu.z80DE", // DE\r
202 "cpu.z80HL", // HL\r
203 "cpu.z80sp" // SP\r
204};\r
205\r
206UINT8 *pbPopRegPairs[4] = \r
207{\r
208 "cx", // BC\r
209 "word [_z80de]", // DE\r
210 "bx", // HL\r
211 "ax" // SP\r
212};\r
213\r
214UINT8 *pbPopRegPairC[4] = \r
215{\r
216 "cpu.z80BC",\r
217 "cpu.z80DE",\r
218 "cpu.z80HL",\r
219 "cpu.z80AF"\r
220};\r
221\r
222UINT8 *pbIndexedRegPairs[4] = \r
223{\r
224 "cx", // BC\r
225 "word [_z80de]", // DE\r
226 "di", // IX/IY\r
227 "word [_z80sp]" // SP\r
228};\r
229\r
230// Timing tables\r
231\r
232UINT8 bTimingRegular[0x100] =\r
233{\r
234 0x04, 0x0a, 0x07, 0x06, 0x04, 0x04, 0x07, 0x04, 0x04, 0x0b, 0x07, 0x06, 0x04, 0x04, 0x07, 0x04,\r
235 0x08, 0x0a, 0x07, 0x06, 0x04, 0x04, 0x07, 0x04, 0x0c, 0x0b, 0x07, 0x06, 0x04, 0x04, 0x07, 0x04,\r
236 0x07, 0x0a, 0x10, 0x06, 0x04, 0x04, 0x07, 0x04, 0x07, 0x0b, 0x10, 0x06, 0x04, 0x04, 0x07, 0x04,\r
237 0x07, 0x0a, 0x0d, 0x06, 0x0b, 0x0b, 0x0a, 0x04, 0x07, 0x0b, 0x0d, 0x06, 0x04, 0x04, 0x07, 0x04,\r
238\r
239 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,\r
240 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,\r
241 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,\r
242 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,\r
243\r
244 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,\r
245 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,\r
246 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,\r
247 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,\r
248\r
249 0x05, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x07, 0x0b, 0x05, 0x0a, 0x0a, 0x00, 0x0a, 0x11, 0x07, 0x0b,\r
250 0x05, 0x0a, 0x0a, 0x0b, 0x0a, 0x0b, 0x07, 0x0b, 0x05, 0x04, 0x0a, 0x0b, 0x0a, 0x00, 0x07, 0x0b,\r
251 0x05, 0x0a, 0x0a, 0x13, 0x0a, 0x0b, 0x07, 0x0b, 0x05, 0x04, 0x0a, 0x04, 0x0a, 0x00, 0x07, 0x0b,\r
252 0x05, 0x0a, 0x0a, 0x04, 0x0a, 0x0b, 0x07, 0x0b, 0x05, 0x06, 0x0a, 0x04, 0x0a, 0x00, 0x07, 0x0b\r
253};\r
254\r
255UINT8 bTimingCB[0x100] =\r
256{\r
257 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, \r
258 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, \r
259 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, \r
260 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, \r
261\r
262 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, \r
263 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, \r
264 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, \r
265 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, \r
266 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, \r
267 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, \r
268 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, \r
269 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, \r
270 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, \r
271 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, \r
272 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, \r
273 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08\r
274};\r
275\r
276UINT8 bTimingXXCB[0x100] =\r
277{\r
278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, \r
279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, \r
280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, \r
281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, \r
282 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,\r
283 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,\r
284 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,\r
285 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,\r
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, \r
287 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, \r
288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, \r
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, \r
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, \r
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, \r
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, \r
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00\r
294};\r
295\r
296UINT8 bTimingDDFD[0x100] =\r
297{\r
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
300 0x00, 0x0e, 0x14, 0x0a, 0x09, 0x09, 0x09, 0x00, 0x00, 0x0f, 0x14, 0x0a, 0x09, 0x09, 0x09, 0x00, \r
301 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x13, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
302\r
303 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, \r
304 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, \r
305\r
306 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x13, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x13, 0x09,\r
307 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, \r
308 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, \r
309 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, \r
310 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, \r
311 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, \r
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
314 0x00, 0x0e, 0x00, 0x17, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
316};\r
317\r
318UINT8 bTimingED[0x100] = \r
319{\r
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
324\r
325 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x0e, 0x08, 0x09, 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x0e, 0x08, 0x09,\r
326 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x09, 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x09,\r
327 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x12, 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x12,\r
328 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x00, 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x00,\r
329\r
330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
332 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, \r
333 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, \r
334\r
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \r
339};\r
340\r
341void EDHandler(UINT32 dwOpcode);\r
342void DDHandler(UINT32 dwOpcode);\r
343void FDHandler(UINT32 dwOpcode);\r
344void CBHandler(UINT32 dwOpcode);\r
345\r
346void PushPopOperations(UINT32 dwOpcode);\r
347void AddRegpairOperations(UINT32 dwOpcode);\r
348void CallHandler(UINT32 dwOpcode);\r
349void MiscHandler(UINT32 dwOpcode);\r
350void IMHandler(UINT32 dwOpcode);\r
351void IRHandler(UINT32 dwOpcode);\r
352void LdRegPairImmediate(UINT32 dwOpcode);\r
353void LoadImmediate(UINT32 dwOpcode);\r
354void LdRegpairPtrByte(UINT32 dwOpcode);\r
355void MathOperation(UINT32 dwOpcode);\r
356void RegIntoMemory(UINT32 dwOpcode);\r
357void JpHandler(UINT32 dwOpcode);\r
358void LdRegImmediate(UINT32 dwOpcode);\r
359void IncRegister(UINT32 dwOpcode);\r
360void DecRegister(UINT32 dwOpcode);\r
361void IncDecRegpair(UINT32 dwOpcode);\r
362void LdRegReg(UINT32 dwOpcode);\r
363void MathOperationDirect(UINT32 dwOpcode);\r
364void JrHandler(UINT32 dwOpcode);\r
365void RetHandler(UINT32 dwOpcode);\r
366void RestartHandler(UINT32 dwOpcode);\r
367void ToRegFromHl(UINT32);\r
368void RraRlaHandler(UINT32);\r
369void LdByteRegpair(UINT32);\r
370void IncDecHLPtr(UINT32 dwOpcode);\r
371void InOutHandler(UINT32 dwOpcode);\r
372void RLCRRCRLRRSLASRASRLHandler(UINT32 dwOpcode);\r
373void BITHandler(UINT32 dwOpcode);\r
374void RESSETHandler(UINT32 dwOpcode);\r
375void PushPopOperationsIndexed(UINT32 dwOpcode);\r
376void LDILDRLDIRLDDRHandler(UINT32);\r
377void LdRegpair(UINT32 dwOpcode);\r
378void ExtendedRegIntoMemory(UINT32 dwOpcode);\r
379void NegHandler(UINT32 dwOpcode);\r
380void ExtendedInHandler(UINT32 dwOpcode);\r
381void ExtendedOutHandler(UINT32 dwOpcode);\r
382void RetIRetNHandler(UINT32 dwOcode);\r
383void AdcSbcRegpair(UINT32 dwOpcode);\r
384void CPICPDCPIRCPDRHandler(UINT32 dwOpcode);\r
385void RRDRLDHandler(UINT32 dwOpcode);\r
386void UndocRegToIndex(UINT32 dwOpcode);\r
387void UndocIndexToReg(UINT32 dwOpcode);\r
388void MathOperationIndexed(UINT32 dwOpcode);\r
389void IncDecIndexed(UINT32 dwOpcode);\r
390void DDFDCBHandler(UINT32 dwOpcode);\r
391void JPIXIYHandler(UINT32 dwOpcode);\r
392void AddIndexHandler(UINT32 dwOpcode);\r
393void SPToIndex(UINT32 dwOpcode);\r
394void LdByteToIndex(UINT32 dwOpcode);\r
395void LdRegIndexOffset(UINT32 dwOpcode);\r
396void IncDecIndexReg(UINT32 dwOpcode);\r
397void ExIndexed(UINT32 dwOpcode);\r
398void UndocIncDecIndexReg(UINT32 dwOpcode);\r
399void UndocLoadHalfIndexReg(UINT32 dwOpcode);\r
400void UndocMathIndex(UINT32 dwOpcode);\r
401void ddcbBitWise(UINT32 dwOpcode);\r
402void LdIndexPtrReg(UINT32 dwOpcode);\r
403void StoreIndexReg(UINT32 dwOpcode);\r
404void LoadIndexReg(UINT32 dwOpcode);\r
405void OTIROTDROUTIOUTDHandler(UINT32 dwOpcode);\r
406void INIRINDRINIINDHandler(UINT32 dwOpcode);\r
407\r
408struct sOp\r
409{\r
410 UINT32 bOpCode;\r
411 void (*Emitter)(UINT32);\r
412};\r
413\r
414struct sOp StandardOps[] =\r
415{\r
416 {0xd3, InOutHandler}, // V\r
417 {0xdb, InOutHandler}, // V\r
418\r
419 {0x0a, LdByteRegpair}, // V\r
420 {0x1a, LdByteRegpair}, // V\r
421\r
422 {0x17, RraRlaHandler}, // V\r
423 {0x1f, RraRlaHandler}, // V\r
424\r
425 {0x05, DecRegister}, // V\r
426 {0x0d, DecRegister}, // V\r
427 {0x15, DecRegister}, // V\r
428 {0x1d, DecRegister}, // V\r
429 {0x25, DecRegister}, // V\r
430 {0x2d, DecRegister}, // V\r
431 {0x3d, DecRegister}, // V\r
432\r
433 {0x04, IncRegister}, // V\r
434 {0x0c, IncRegister}, // V\r
435 {0x14, IncRegister}, // V\r
436 {0x1c, IncRegister}, // V\r
437 {0x24, IncRegister}, // V\r
438 {0x2c, IncRegister}, // V\r
439 {0x3c, IncRegister}, // V\r
440\r
441 {0x32, RegIntoMemory}, // V\r
442 {0x22, RegIntoMemory}, // V\r
443\r
444 {0xc3, JpHandler}, // V\r
445 {0xc2, JpHandler}, // V\r
446 {0xca, JpHandler}, // V\r
447 {0xd2, JpHandler}, // V\r
448 {0xda, JpHandler}, // V\r
449 {0xe2, JpHandler}, // V\r
450 {0xea, JpHandler}, // V\r
451 {0xf2, JpHandler}, // V\r
452 {0xfa, JpHandler}, // V\r
453\r
454\r
455 {0x06, LdRegImmediate}, // V\r
456 {0x0e, LdRegImmediate}, // V\r
457 {0x16, LdRegImmediate}, // V\r
458 {0x1e, LdRegImmediate}, // V\r
459 {0x26, LdRegImmediate}, // V\r
460 {0x2e, LdRegImmediate}, // V\r
461 {0x3e, LdRegImmediate}, // V\r
462\r
463 {0x0b, IncDecRegpair}, // V\r
464 {0x1b, IncDecRegpair}, // V\r
465 {0x2b, IncDecRegpair}, // V\r
466 {0x3b, IncDecRegpair}, // V\r
467\r
468 {0x03, IncDecRegpair}, // V\r
469 {0x13, IncDecRegpair}, // V\r
470 {0x23, IncDecRegpair}, // V\r
471 {0x33, IncDecRegpair}, // V\r
472\r
473 {0x34, IncDecHLPtr}, // V\r
474 {0x35, IncDecHLPtr}, // V\r
475\r
476 {0xcb, CBHandler},\r
477 {0xdd, DDHandler},\r
478 {0xed, EDHandler},\r
479 {0xfd, FDHandler},\r
480\r
481 {0x01, LdRegPairImmediate}, // V\r
482 {0x11, LdRegPairImmediate}, // V\r
483 {0x21, LdRegPairImmediate}, // V\r
484 {0x31, LdRegPairImmediate}, // V\r
485\r
486 {0xe3, MiscHandler}, // V\r
487 {0x2a, MiscHandler}, // V\r
488 {0xfb, MiscHandler}, // V\r
489 {0xf9, MiscHandler}, // V\r
490 {0xd9, MiscHandler}, // V\r
491 {0x76, MiscHandler}, // V\r
492 {0x3f, MiscHandler}, // V\r
493 {0x37, MiscHandler}, // V\r
494 {0x27, MiscHandler}, // V\r
495 {0x07, MiscHandler}, // V\r
496 {0x08, MiscHandler}, // V\r
497 {0x00, MiscHandler}, // V\r
498 {0xe9, MiscHandler}, // V\r
499 {0xeb, MiscHandler}, // V\r
500 {0xf3, MiscHandler}, // V\r
501 {0x3a, MiscHandler}, // V\r
502 {0x10, MiscHandler}, // V\r
503 {0x2f, MiscHandler}, // V\r
504 {0x0f, MiscHandler}, // V\r
505\r
506 {0x02, LdRegpairPtrByte}, // V\r
507 {0x12, LdRegpairPtrByte}, // V\r
508\r
509 {0x70, LdRegpairPtrByte}, // V\r
510 {0x71, LdRegpairPtrByte}, // V\r
511 {0x72, LdRegpairPtrByte}, // V\r
512 {0x73, LdRegpairPtrByte}, // V\r
513 {0x74, LdRegpairPtrByte}, // V\r
514 {0x75, LdRegpairPtrByte}, // V\r
515 {0x77, LdRegpairPtrByte}, // V\r
516\r
517 {0x36, LdRegpairPtrByte}, // V\r
518\r
519 {0x80, MathOperation}, // V\r
520 {0x81, MathOperation}, // V\r
521 {0x82, MathOperation}, // V\r
522 {0x83, MathOperation}, // V\r
523 {0x84, MathOperation}, // V\r
524 {0x85, MathOperation}, // V\r
525 {0x86, MathOperation}, // V\r
526 {0x87, MathOperation}, // V\r
527 {0x88, MathOperation}, // V\r
528 {0x89, MathOperation}, // V\r
529 {0x8a, MathOperation}, // V\r
530 {0x8b, MathOperation}, // V\r
531 {0x8c, MathOperation}, // V\r
532 {0x8d, MathOperation}, // V\r
533 {0x8e, MathOperation}, // V\r
534 {0x8f, MathOperation}, // V\r
535 {0x90, MathOperation}, // V\r
536 {0x91, MathOperation}, // V\r
537 {0x92, MathOperation}, // V\r
538 {0x93, MathOperation}, // V\r
539 {0x94, MathOperation}, // V\r
540 {0x95, MathOperation}, // V\r
541 {0x96, MathOperation}, // V\r
542 {0x97, MathOperation}, // V\r
543 {0x98, MathOperation}, // V\r
544 {0x99, MathOperation}, // V\r
545 {0x9a, MathOperation}, // V\r
546 {0x9b, MathOperation}, // V\r
547 {0x9c, MathOperation}, // V\r
548 {0x9d, MathOperation}, // V\r
549 {0x9e, MathOperation}, // V\r
550 {0x9f, MathOperation}, // V\r
551 {0xa0, MathOperation}, // V\r
552 {0xa1, MathOperation}, // V\r
553 {0xa2, MathOperation}, // V\r
554 {0xa3, MathOperation}, // V\r
555 {0xa4, MathOperation}, // V\r
556 {0xa5, MathOperation}, // V\r
557 {0xa6, MathOperation}, // V\r
558 {0xa7, MathOperation}, // V\r
559 {0xa8, MathOperation}, // V\r
560 {0xa9, MathOperation}, // V\r
561 {0xaa, MathOperation}, // V\r
562 {0xab, MathOperation}, // V\r
563 {0xac, MathOperation}, // V\r
564 {0xad, MathOperation}, // V\r
565 {0xae, MathOperation}, // V\r
566 {0xaf, MathOperation}, // V\r
567 {0xb0, MathOperation}, // V\r
568 {0xb1, MathOperation}, // V\r
569 {0xb2, MathOperation}, // V\r
570 {0xb3, MathOperation}, // V\r
571 {0xb4, MathOperation}, // V\r
572 {0xb5, MathOperation}, // V\r
573 {0xb6, MathOperation}, // V\r
574 {0xb7, MathOperation}, // V\r
575 {0xb8, MathOperation}, // V\r
576 {0xb9, MathOperation}, // V\r
577 {0xba, MathOperation}, // V\r
578 {0xbb, MathOperation}, // V\r
579 {0xbc, MathOperation}, // V\r
580 {0xbd, MathOperation}, // V\r
581 {0xbe, MathOperation}, // V\r
582 {0xbf, MathOperation}, // V\r
583\r
584 {0x40, LdRegReg}, // V\r
585 {0x41, LdRegReg}, // V\r
586 {0x42, LdRegReg}, // V\r
587 {0x43, LdRegReg}, // V\r
588 {0x44, LdRegReg}, // V\r
589 {0x45, LdRegReg}, // V\r
590 {0x47, LdRegReg}, // V\r
591 {0x48, LdRegReg}, // V\r
592 {0x49, LdRegReg}, // V\r
593 {0x4a, LdRegReg}, // V\r
594 {0x4b, LdRegReg}, // V\r
595 {0x4c, LdRegReg}, // V\r
596 {0x4d, LdRegReg}, // V\r
597 {0x4f, LdRegReg}, // V\r
598 {0x50, LdRegReg}, // V\r
599 {0x51, LdRegReg}, // V\r
600 {0x52, LdRegReg}, // V\r
601 {0x53, LdRegReg}, // V\r
602 {0x54, LdRegReg}, // V\r
603 {0x55, LdRegReg}, // V\r
604 {0x57, LdRegReg}, // V\r
605 {0x58, LdRegReg}, // V\r
606 {0x59, LdRegReg}, // V\r
607 {0x5a, LdRegReg}, // V\r
608 {0x5b, LdRegReg}, // V\r
609 {0x5c, LdRegReg}, // V\r
610 {0x5d, LdRegReg}, // V\r
611 {0x5f, LdRegReg}, // V\r
612 {0x60, LdRegReg}, // V\r
613 {0x61, LdRegReg}, // V\r
614 {0x62, LdRegReg}, // V\r
615 {0x63, LdRegReg}, // V\r
616 {0x64, LdRegReg}, // V\r
617 {0x65, LdRegReg}, // V\r
618 {0x67, LdRegReg}, // V\r
619 {0x68, LdRegReg}, // V\r
620 {0x69, LdRegReg}, // V\r
621 {0x6a, LdRegReg}, // V\r
622 {0x6b, LdRegReg}, // V\r
623 {0x6c, LdRegReg}, // V\r
624 {0x6d, LdRegReg}, // V\r
625 {0x6f, LdRegReg}, // V\r
626 {0x78, LdRegReg}, // V\r
627 {0x79, LdRegReg}, // V\r
628 {0x7a, LdRegReg}, // V\r
629 {0x7b, LdRegReg}, // V\r
630 {0x7c, LdRegReg}, // V\r
631 {0x7d, LdRegReg}, // V\r
632 {0x7f, LdRegReg}, // V\r
633\r
634 {0xc6, MathOperationDirect}, // V\r
635 {0xce, MathOperationDirect}, // V\r
636 {0xd6, MathOperationDirect}, // V\r
637 {0xde, MathOperationDirect}, // V\r
638 {0xe6, MathOperationDirect}, // V\r
639 {0xee, MathOperationDirect}, // V\r
640 {0xf6, MathOperationDirect}, // V\r
641 {0xfe, MathOperationDirect}, // V\r
642\r
643 {0x18, JrHandler}, // V\r
644 {0x20, JrHandler}, // V\r
645 {0x28, JrHandler}, // V\r
646 {0x30, JrHandler}, // V\r
647 {0x38, JrHandler},\r
648\r
649 {0xc4, CallHandler}, // V\r
650 {0xcc, CallHandler}, // V\r
651 {0xcd, CallHandler}, // V\r
652 {0xd4, CallHandler}, // V\r
653 {0xdc, CallHandler}, // V\r
654 {0xe4, CallHandler}, // V\r
655 {0xec, CallHandler}, // V\r
656 {0xf4, CallHandler}, // V\r
657 {0xfc, CallHandler}, // V\r
658\r
659 {0xc9, RetHandler}, // V\r
660 {0xc0, RetHandler}, // V\r
661 {0xc8, RetHandler}, // V\r
662 {0xd0, RetHandler}, // V\r
663 {0xd8, RetHandler}, // V\r
664 {0xe0, RetHandler}, // V\r
665 {0xe8, RetHandler}, // V\r
666 {0xf0, RetHandler}, // V\r
667 {0xf8, RetHandler}, // V\r
668\r
669 {0xc7, RestartHandler}, // V\r
670 {0xcf, RestartHandler}, // V\r
671 {0xd7, RestartHandler}, // V\r
672 {0xdf, RestartHandler}, // V\r
673 {0xe7, RestartHandler}, // V\r
674 {0xef, RestartHandler}, // V\r
675 {0xf7, RestartHandler}, // V\r
676 {0xff, RestartHandler}, // V\r
677\r
678 {0x46, ToRegFromHl}, // V\r
679 {0x4e, ToRegFromHl}, // V\r
680 {0x56, ToRegFromHl}, // V\r
681 {0x5e, ToRegFromHl}, // V\r
682 {0x66, ToRegFromHl}, // V\r
683 {0x6e, ToRegFromHl}, // V\r
684 {0x7e, ToRegFromHl},\r
685\r
686 {0x09, AddRegpairOperations}, // V\r
687 {0x19, AddRegpairOperations}, // V\r
688 {0x29, AddRegpairOperations}, // V\r
689 {0x39, AddRegpairOperations}, // V\r
690\r
691 {0xc5, PushPopOperations}, // V\r
692 {0xd5, PushPopOperations}, // V\r
693 {0xe5, PushPopOperations}, // V\r
694 {0xf5, PushPopOperations}, // V\r
695 {0xc1, PushPopOperations}, // V\r
696 {0xd1, PushPopOperations}, // V\r
697 {0xe1, PushPopOperations}, // V\r
698 {0xf1, PushPopOperations}, // V\r
699\r
700 // Terminator\r
701\r
702 {0xffffffff, NULL} \r
703};\r
704\r
705struct sOp CBOps[] =\r
706{\r
707 {0x00, RLCRRCRLRRSLASRASRLHandler},\r
708 {0x01, RLCRRCRLRRSLASRASRLHandler},\r
709 {0x02, RLCRRCRLRRSLASRASRLHandler},\r
710 {0x03, RLCRRCRLRRSLASRASRLHandler},\r
711 {0x04, RLCRRCRLRRSLASRASRLHandler},\r
712 {0x05, RLCRRCRLRRSLASRASRLHandler},\r
713 {0x06, RLCRRCRLRRSLASRASRLHandler},\r
714 {0x07, RLCRRCRLRRSLASRASRLHandler},\r
715 {0x08, RLCRRCRLRRSLASRASRLHandler},\r
716 {0x09, RLCRRCRLRRSLASRASRLHandler},\r
717 {0x0a, RLCRRCRLRRSLASRASRLHandler},\r
718 {0x0b, RLCRRCRLRRSLASRASRLHandler},\r
719 {0x0c, RLCRRCRLRRSLASRASRLHandler},\r
720 {0x0d, RLCRRCRLRRSLASRASRLHandler},\r
721 {0x0e, RLCRRCRLRRSLASRASRLHandler},\r
722 {0x0f, RLCRRCRLRRSLASRASRLHandler},\r
723\r
724 {0x10, RLCRRCRLRRSLASRASRLHandler},\r
725 {0x11, RLCRRCRLRRSLASRASRLHandler},\r
726 {0x12, RLCRRCRLRRSLASRASRLHandler},\r
727 {0x13, RLCRRCRLRRSLASRASRLHandler},\r
728 {0x14, RLCRRCRLRRSLASRASRLHandler},\r
729 {0x15, RLCRRCRLRRSLASRASRLHandler},\r
730 {0x16, RLCRRCRLRRSLASRASRLHandler},\r
731 {0x17, RLCRRCRLRRSLASRASRLHandler},\r
732 {0x18, RLCRRCRLRRSLASRASRLHandler},\r
733 {0x19, RLCRRCRLRRSLASRASRLHandler},\r
734 {0x1a, RLCRRCRLRRSLASRASRLHandler},\r
735 {0x1b, RLCRRCRLRRSLASRASRLHandler},\r
736 {0x1c, RLCRRCRLRRSLASRASRLHandler},\r
737 {0x1d, RLCRRCRLRRSLASRASRLHandler},\r
738 {0x1e, RLCRRCRLRRSLASRASRLHandler},\r
739 {0x1f, RLCRRCRLRRSLASRASRLHandler},\r
740\r
741 {0x20, RLCRRCRLRRSLASRASRLHandler},\r
742 {0x21, RLCRRCRLRRSLASRASRLHandler},\r
743 {0x22, RLCRRCRLRRSLASRASRLHandler},\r
744 {0x23, RLCRRCRLRRSLASRASRLHandler},\r
745 {0x24, RLCRRCRLRRSLASRASRLHandler},\r
746 {0x25, RLCRRCRLRRSLASRASRLHandler},\r
747 {0x26, RLCRRCRLRRSLASRASRLHandler},\r
748 {0x27, RLCRRCRLRRSLASRASRLHandler},\r
749 {0x28, RLCRRCRLRRSLASRASRLHandler},\r
750 {0x29, RLCRRCRLRRSLASRASRLHandler},\r
751 {0x2a, RLCRRCRLRRSLASRASRLHandler},\r
752 {0x2b, RLCRRCRLRRSLASRASRLHandler},\r
753 {0x2c, RLCRRCRLRRSLASRASRLHandler},\r
754 {0x2d, RLCRRCRLRRSLASRASRLHandler},\r
755 {0x2e, RLCRRCRLRRSLASRASRLHandler},\r
756 {0x2f, RLCRRCRLRRSLASRASRLHandler},\r
757\r
758 {0x30, RLCRRCRLRRSLASRASRLHandler},\r
759 {0x31, RLCRRCRLRRSLASRASRLHandler},\r
760 {0x32, RLCRRCRLRRSLASRASRLHandler},\r
761 {0x33, RLCRRCRLRRSLASRASRLHandler},\r
762 {0x34, RLCRRCRLRRSLASRASRLHandler},\r
763 {0x35, RLCRRCRLRRSLASRASRLHandler},\r
764 {0x36, RLCRRCRLRRSLASRASRLHandler},\r
765 {0x37, RLCRRCRLRRSLASRASRLHandler},\r
766\r
767 {0x38, RLCRRCRLRRSLASRASRLHandler},\r
768 {0x39, RLCRRCRLRRSLASRASRLHandler},\r
769 {0x3a, RLCRRCRLRRSLASRASRLHandler},\r
770 {0x3b, RLCRRCRLRRSLASRASRLHandler},\r
771 {0x3c, RLCRRCRLRRSLASRASRLHandler},\r
772 {0x3d, RLCRRCRLRRSLASRASRLHandler},\r
773 {0x3e, RLCRRCRLRRSLASRASRLHandler},\r
774 {0x3f, RLCRRCRLRRSLASRASRLHandler},\r
775\r
776 {0x40, BITHandler},\r
777 {0x41, BITHandler},\r
778 {0x42, BITHandler},\r
779 {0x43, BITHandler},\r
780 {0x44, BITHandler},\r
781 {0x45, BITHandler},\r
782 {0x46, BITHandler},\r
783 {0x47, BITHandler},\r
784 {0x48, BITHandler},\r
785 {0x49, BITHandler},\r
786 {0x4a, BITHandler},\r
787 {0x4b, BITHandler},\r
788 {0x4c, BITHandler},\r
789 {0x4d, BITHandler},\r
790 {0x4e, BITHandler},\r
791 {0x4f, BITHandler},\r
792\r
793 {0x50, BITHandler},\r
794 {0x51, BITHandler},\r
795 {0x52, BITHandler},\r
796 {0x53, BITHandler},\r
797 {0x54, BITHandler},\r
798 {0x55, BITHandler},\r
799 {0x56, BITHandler},\r
800 {0x57, BITHandler},\r
801 {0x58, BITHandler},\r
802 {0x59, BITHandler},\r
803 {0x5a, BITHandler},\r
804 {0x5b, BITHandler},\r
805 {0x5c, BITHandler},\r
806 {0x5d, BITHandler},\r
807 {0x5e, BITHandler},\r
808 {0x5f, BITHandler},\r
809\r
810 {0x60, BITHandler},\r
811 {0x61, BITHandler},\r
812 {0x62, BITHandler},\r
813 {0x63, BITHandler},\r
814 {0x64, BITHandler},\r
815 {0x65, BITHandler},\r
816 {0x66, BITHandler},\r
817 {0x67, BITHandler},\r
818 {0x68, BITHandler},\r
819 {0x69, BITHandler},\r
820 {0x6a, BITHandler},\r
821 {0x6b, BITHandler},\r
822 {0x6c, BITHandler},\r
823 {0x6d, BITHandler},\r
824 {0x6e, BITHandler},\r
825 {0x6f, BITHandler},\r
826\r
827 {0x70, BITHandler},\r
828 {0x71, BITHandler},\r
829 {0x72, BITHandler},\r
830 {0x73, BITHandler},\r
831 {0x74, BITHandler},\r
832 {0x75, BITHandler},\r
833 {0x76, BITHandler},\r
834 {0x77, BITHandler},\r
835 {0x78, BITHandler},\r
836 {0x79, BITHandler},\r
837 {0x7a, BITHandler},\r
838 {0x7b, BITHandler},\r
839 {0x7c, BITHandler},\r
840 {0x7d, BITHandler},\r
841 {0x7e, BITHandler},\r
842 {0x7f, BITHandler},\r
843\r
844 // RES\r
845\r
846 {0x80, RESSETHandler},\r
847 {0x81, RESSETHandler},\r
848 {0x82, RESSETHandler},\r
849 {0x83, RESSETHandler},\r
850 {0x84, RESSETHandler},\r
851 {0x85, RESSETHandler},\r
852 {0x86, RESSETHandler},\r
853 {0x87, RESSETHandler},\r
854 {0x88, RESSETHandler},\r
855 {0x89, RESSETHandler},\r
856 {0x8a, RESSETHandler},\r
857 {0x8b, RESSETHandler},\r
858 {0x8c, RESSETHandler},\r
859 {0x8d, RESSETHandler},\r
860 {0x8e, RESSETHandler},\r
861 {0x8f, RESSETHandler},\r
862\r
863 {0x90, RESSETHandler},\r
864 {0x91, RESSETHandler},\r
865 {0x92, RESSETHandler},\r
866 {0x93, RESSETHandler},\r
867 {0x94, RESSETHandler},\r
868 {0x95, RESSETHandler},\r
869 {0x96, RESSETHandler},\r
870 {0x97, RESSETHandler},\r
871 {0x98, RESSETHandler},\r
872 {0x99, RESSETHandler},\r
873 {0x9a, RESSETHandler},\r
874 {0x9b, RESSETHandler},\r
875 {0x9c, RESSETHandler},\r
876 {0x9d, RESSETHandler},\r
877 {0x9e, RESSETHandler},\r
878 {0x9f, RESSETHandler},\r
879\r
880 {0xa0, RESSETHandler},\r
881 {0xa1, RESSETHandler},\r
882 {0xa2, RESSETHandler},\r
883 {0xa3, RESSETHandler},\r
884 {0xa4, RESSETHandler},\r
885 {0xa5, RESSETHandler},\r
886 {0xa6, RESSETHandler},\r
887 {0xa7, RESSETHandler},\r
888 {0xa8, RESSETHandler},\r
889 {0xa9, RESSETHandler},\r
890 {0xaa, RESSETHandler},\r
891 {0xab, RESSETHandler},\r
892 {0xac, RESSETHandler},\r
893 {0xad, RESSETHandler},\r
894 {0xae, RESSETHandler},\r
895 {0xaf, RESSETHandler},\r
896\r
897 {0xb0, RESSETHandler},\r
898 {0xb1, RESSETHandler},\r
899 {0xb2, RESSETHandler},\r
900 {0xb3, RESSETHandler},\r
901 {0xb4, RESSETHandler},\r
902 {0xb5, RESSETHandler},\r
903 {0xb6, RESSETHandler},\r
904 {0xb7, RESSETHandler},\r
905 {0xb8, RESSETHandler},\r
906 {0xb9, RESSETHandler},\r
907 {0xba, RESSETHandler},\r
908 {0xbb, RESSETHandler},\r
909 {0xbc, RESSETHandler},\r
910 {0xbd, RESSETHandler},\r
911 {0xbe, RESSETHandler},\r
912 {0xbf, RESSETHandler},\r
913\r
914 // SET\r
915\r
916 {0xc0, RESSETHandler},\r
917 {0xc1, RESSETHandler},\r
918 {0xc2, RESSETHandler},\r
919 {0xc3, RESSETHandler},\r
920 {0xc4, RESSETHandler},\r
921 {0xc5, RESSETHandler},\r
922 {0xc6, RESSETHandler},\r
923 {0xc7, RESSETHandler},\r
924 {0xc8, RESSETHandler},\r
925 {0xc9, RESSETHandler},\r
926 {0xca, RESSETHandler},\r
927 {0xcb, RESSETHandler},\r
928 {0xcc, RESSETHandler},\r
929 {0xcd, RESSETHandler},\r
930 {0xce, RESSETHandler},\r
931 {0xcf, RESSETHandler},\r
932\r
933 {0xd0, RESSETHandler},\r
934 {0xd1, RESSETHandler},\r
935 {0xd2, RESSETHandler},\r
936 {0xd3, RESSETHandler},\r
937 {0xd4, RESSETHandler},\r
938 {0xd5, RESSETHandler},\r
939 {0xd6, RESSETHandler},\r
940 {0xd7, RESSETHandler},\r
941 {0xd8, RESSETHandler},\r
942 {0xd9, RESSETHandler},\r
943 {0xda, RESSETHandler},\r
944 {0xdb, RESSETHandler},\r
945 {0xdc, RESSETHandler},\r
946 {0xdd, RESSETHandler},\r
947 {0xde, RESSETHandler},\r
948 {0xdf, RESSETHandler},\r
949\r
950 {0xe0, RESSETHandler},\r
951 {0xe1, RESSETHandler},\r
952 {0xe2, RESSETHandler},\r
953 {0xe3, RESSETHandler},\r
954 {0xe4, RESSETHandler},\r
955 {0xe5, RESSETHandler},\r
956 {0xe6, RESSETHandler},\r
957 {0xe7, RESSETHandler},\r
958 {0xe8, RESSETHandler},\r
959 {0xe9, RESSETHandler},\r
960 {0xea, RESSETHandler},\r
961 {0xeb, RESSETHandler},\r
962 {0xec, RESSETHandler},\r
963 {0xed, RESSETHandler},\r
964 {0xee, RESSETHandler},\r
965 {0xef, RESSETHandler},\r
966\r
967 {0xf0, RESSETHandler},\r
968 {0xf1, RESSETHandler},\r
969 {0xf2, RESSETHandler},\r
970 {0xf3, RESSETHandler},\r
971 {0xf4, RESSETHandler},\r
972 {0xf5, RESSETHandler},\r
973 {0xf6, RESSETHandler},\r
974 {0xf7, RESSETHandler},\r
975 {0xf8, RESSETHandler},\r
976 {0xf9, RESSETHandler},\r
977 {0xfa, RESSETHandler},\r
978 {0xfb, RESSETHandler},\r
979 {0xfc, RESSETHandler},\r
980 {0xfd, RESSETHandler},\r
981 {0xfe, RESSETHandler},\r
982 {0xff, RESSETHandler},\r
983\r
984 // Terminator\r
985\r
986 {0xffffffff, NULL} \r
987};\r
988\r
989struct sOp EDOps[] =\r
990{\r
991 {0x67, RRDRLDHandler},\r
992 {0x6f, RRDRLDHandler},\r
993 {0x42, AdcSbcRegpair},\r
994 {0x4a, AdcSbcRegpair},\r
995 {0x52, AdcSbcRegpair},\r
996 {0x5a, AdcSbcRegpair},\r
997 {0x62, AdcSbcRegpair},\r
998 {0x6a, AdcSbcRegpair},\r
999 {0x72, AdcSbcRegpair},\r
1000 {0x7a, AdcSbcRegpair}, \r
1001 {0x45, RetIRetNHandler},\r
1002 {0x4d, RetIRetNHandler},\r
1003 {0x44, NegHandler},\r
1004 {0xa0, LDILDRLDIRLDDRHandler},\r
1005 {0xa8, LDILDRLDIRLDDRHandler},\r
1006 {0xb0, LDILDRLDIRLDDRHandler},\r
1007 {0xb8, LDILDRLDIRLDDRHandler},\r
1008 {0x57, IRHandler},\r
1009 {0x5F, IRHandler},\r
1010 {0x47, IRHandler},\r
1011 {0x4F, IRHandler},\r
1012 {0x46, IMHandler},\r
1013 {0x56, IMHandler},\r
1014 {0x5e, IMHandler},\r
1015 {0x4b, LdRegpair},\r
1016 {0x5b, LdRegpair},\r
1017 {0x7b, LdRegpair},\r
1018 {0x43, ExtendedRegIntoMemory},\r
1019 {0x53, ExtendedRegIntoMemory},\r
1020 {0x63, ExtendedRegIntoMemory},\r
1021 {0x73, ExtendedRegIntoMemory},\r
1022 {0x40, ExtendedInHandler},\r
1023 {0x48, ExtendedInHandler},\r
1024 {0x50, ExtendedInHandler},\r
1025 {0x58, ExtendedInHandler},\r
1026 {0x60, ExtendedInHandler},\r
1027 {0x68, ExtendedInHandler},\r
1028 {0x78, ExtendedInHandler},\r
1029 {0x41, ExtendedOutHandler},\r
1030 {0x49, ExtendedOutHandler},\r
1031 {0x51, ExtendedOutHandler},\r
1032 {0x59, ExtendedOutHandler},\r
1033 {0x61, ExtendedOutHandler},\r
1034 {0x69, ExtendedOutHandler},\r
1035 {0x79, ExtendedOutHandler}, \r
1036 {0xa1, CPICPDCPIRCPDRHandler},\r
1037 {0xa9, CPICPDCPIRCPDRHandler},\r
1038 {0xb1, CPICPDCPIRCPDRHandler},\r
1039 {0xb9, CPICPDCPIRCPDRHandler},\r
1040\r
1041 {0xbb, OTIROTDROUTIOUTDHandler}, // OTDR\r
1042 {0xb3, OTIROTDROUTIOUTDHandler}, // OTIR\r
1043 {0xab, OTIROTDROUTIOUTDHandler}, // OUTD\r
1044 {0xa3, OTIROTDROUTIOUTDHandler}, // OUTI\r
1045\r
1046 {0xb2, INIRINDRINIINDHandler}, // INIR\r
1047 {0xba, INIRINDRINIINDHandler}, // INDR\r
1048 {0xa2, INIRINDRINIINDHandler}, // INI\r
1049 {0xaa, INIRINDRINIINDHandler}, // IND\r
1050\r
1051 // Terminator\r
1052\r
1053 {0xffffffff, NULL} \r
1054};\r
1055\r
1056struct sOp DDFDOps[] =\r
1057{\r
1058 {0x35, IncDecIndexed},\r
1059 {0x34, IncDecIndexed},\r
1060 {0xcb, DDFDCBHandler},\r
1061 {0x86, MathOperationIndexed},\r
1062 {0x8e, MathOperationIndexed},\r
1063 {0x96, MathOperationIndexed},\r
1064 {0x9e, MathOperationIndexed},\r
1065 {0xa6, MathOperationIndexed},\r
1066 {0xae, MathOperationIndexed},\r
1067 {0xb6, MathOperationIndexed},\r
1068 {0xbe, MathOperationIndexed},\r
1069\r
1070 {0xe1, PushPopOperationsIndexed},\r
1071 {0xe5, PushPopOperationsIndexed},\r
1072 {0x21, LoadImmediate},\r
1073 {0xe9, JPIXIYHandler},\r
1074 {0x09, AddIndexHandler},\r
1075 {0x19, AddIndexHandler},\r
1076 {0x29, AddIndexHandler},\r
1077 {0x39, AddIndexHandler},\r
1078 {0xf9, SPToIndex},\r
1079 {0x36, LdByteToIndex},\r
1080 {0x46, LdRegIndexOffset},\r
1081 {0x4e, LdRegIndexOffset},\r
1082 {0x56, LdRegIndexOffset},\r
1083 {0x5e, LdRegIndexOffset},\r
1084 {0x66, LdRegIndexOffset},\r
1085 {0x6e, LdRegIndexOffset},\r
1086 {0x7e, LdRegIndexOffset}, \r
1087\r
1088 {0x70, LdIndexPtrReg},\r
1089 {0x71, LdIndexPtrReg},\r
1090 {0x72, LdIndexPtrReg},\r
1091 {0x73, LdIndexPtrReg},\r
1092 {0x74, LdIndexPtrReg},\r
1093 {0x75, LdIndexPtrReg},\r
1094 {0x77, LdIndexPtrReg},\r
1095\r
1096 {0x23, IncDecIndexReg},\r
1097 {0x2b, IncDecIndexReg},\r
1098\r
1099 {0x22, StoreIndexReg},\r
1100 {0x2a, LoadIndexReg},\r
1101 {0xe3, ExIndexed},\r
1102\r
1103 {0x44, UndocRegToIndex},\r
1104 {0x45, UndocRegToIndex},\r
1105 {0x4c, UndocRegToIndex},\r
1106 {0x4d, UndocRegToIndex},\r
1107 {0x54, UndocRegToIndex},\r
1108 {0x55, UndocRegToIndex},\r
1109 {0x5c, UndocRegToIndex},\r
1110 {0x5d, UndocRegToIndex},\r
1111 {0x7c, UndocRegToIndex},\r
1112 {0x7d, UndocRegToIndex},\r
1113\r
1114 {0x60, UndocIndexToReg},\r
1115 {0x61, UndocIndexToReg},\r
1116 {0x62, UndocIndexToReg},\r
1117 {0x63, UndocIndexToReg},\r
1118 {0x64, UndocIndexToReg},\r
1119 {0x65, UndocIndexToReg},\r
1120 {0x67, UndocIndexToReg},\r
1121 {0x68, UndocIndexToReg},\r
1122 {0x69, UndocIndexToReg},\r
1123 {0x6a, UndocIndexToReg},\r
1124 {0x6b, UndocIndexToReg},\r
1125 {0x6c, UndocIndexToReg},\r
1126 {0x6d, UndocIndexToReg},\r
1127 {0x6f, UndocIndexToReg},\r
1128\r
1129 {0x24, UndocIncDecIndexReg},\r
1130 {0x25, UndocIncDecIndexReg},\r
1131 {0x2c, UndocIncDecIndexReg},\r
1132 {0x2d, UndocIncDecIndexReg},\r
1133\r
1134 {0x26, UndocLoadHalfIndexReg},\r
1135 {0x2e, UndocLoadHalfIndexReg},\r
1136\r
1137 {0x84, UndocMathIndex},\r
1138 {0x85, UndocMathIndex},\r
1139 {0x8c, UndocMathIndex},\r
1140 {0x8d, UndocMathIndex},\r
1141\r
1142 {0x94, UndocMathIndex},\r
1143 {0x95, UndocMathIndex},\r
1144 {0x9c, UndocMathIndex},\r
1145 {0x9d, UndocMathIndex},\r
1146\r
1147 {0xa4, UndocMathIndex},\r
1148 {0xa5, UndocMathIndex},\r
1149 {0xac, UndocMathIndex},\r
1150 {0xad, UndocMathIndex},\r
1151\r
1152 {0xb4, UndocMathIndex},\r
1153 {0xb5, UndocMathIndex},\r
1154 {0xbc, UndocMathIndex},\r
1155 {0xbd, UndocMathIndex},\r
1156\r
1157 // Terminator\r
1158\r
1159 {0xffffffff, NULL}\r
1160};\r
1161\r
1162struct sOp DDFDCBOps[] =\r
1163{\r
1164 {0x06, ddcbBitWise},\r
1165 {0x0e, ddcbBitWise},\r
1166 {0x16, ddcbBitWise},\r
1167 {0x1e, ddcbBitWise},\r
1168 {0x26, ddcbBitWise},\r
1169 {0x2e, ddcbBitWise},\r
1170 {0x3e, ddcbBitWise},\r
1171 {0x46, ddcbBitWise},\r
1172 {0x4e, ddcbBitWise},\r
1173 {0x56, ddcbBitWise},\r
1174 {0x5e, ddcbBitWise},\r
1175 {0x66, ddcbBitWise},\r
1176 {0x6e, ddcbBitWise},\r
1177 {0x76, ddcbBitWise},\r
1178 {0x7e, ddcbBitWise},\r
1179 {0x86, ddcbBitWise},\r
1180 {0x8e, ddcbBitWise},\r
1181 {0x96, ddcbBitWise},\r
1182 {0x9e, ddcbBitWise},\r
1183 {0xa6, ddcbBitWise},\r
1184 {0xae, ddcbBitWise},\r
1185 {0xb6, ddcbBitWise},\r
1186 {0xbe, ddcbBitWise},\r
1187 {0xc6, ddcbBitWise},\r
1188 {0xce, ddcbBitWise},\r
1189 {0xd6, ddcbBitWise},\r
1190 {0xde, ddcbBitWise},\r
1191 {0xe6, ddcbBitWise},\r
1192 {0xee, ddcbBitWise},\r
1193 {0xf6, ddcbBitWise},\r
1194 {0xfe, ddcbBitWise},\r
1195\r
1196 // Terminator\r
1197\r
1198 {0xffffffff, NULL}\r
1199};\r
1200\r
1201void InvalidInstructionC(UINT32 dwCount)\r
1202{\r
1203 fprintf(fp, " InvalidInstruction(%ld);\n", dwCount);\r
1204}\r
1205\r
1206UINT32 Timing(UINT8 bWho, UINT32 dwOpcode)\r
1207{\r
1208 UINT32 dwTiming = 0;\r
1209\r
1210 assert(dwOpcode < 0x100);\r
1211\r
1212 if (TIMING_REGULAR == bWho) // Regular?\r
1213 dwTiming = bTimingRegular[dwOpcode];\r
1214 else\r
1215 if (TIMING_CB == bWho)\r
1216 dwTiming = bTimingCB[dwOpcode];\r
1217 else\r
1218 if (TIMING_DDFD == bWho)\r
1219 dwTiming = bTimingDDFD[dwOpcode];\r
1220 else\r
1221 if (TIMING_ED == bWho)\r
1222 dwTiming = bTimingED[dwOpcode];\r
1223 else\r
1224 if (TIMING_XXCB == bWho)\r
1225 dwTiming = bTimingXXCB[dwOpcode];\r
1226 else\r
1227 if (TIMING_EXCEPT == bWho)\r
1228 dwTiming = dwOpcode;\r
1229 else\r
1230 assert(0);\r
1231\r
1232 if (0 == dwTiming)\r
1233 { \r
1234 fprintf(stderr, "Opcode: %.2x:%.2x - Not zero!\n", bWho, dwOpcode);\r
1235 fclose(fp);\r
1236 exit(1);\r
1237 }\r
1238\r
1239 return(dwTiming);\r
1240}\r
1241\r
1242void IndexedOffset(UINT8 *Localmz80Index)\r
1243{\r
1244 fprintf(fp, " mov dl, [esi] ; Fetch our offset\n");\r
1245 fprintf(fp, " inc esi ; Move past the offset\n");\r
1246 fprintf(fp, " or dl, dl ; Is this bad boy signed?\n");\r
1247 fprintf(fp, " jns notSigned%ld ; Nope!\n", dwGlobalLabel);\r
1248 fprintf(fp, " dec dh ; Make it FFable\n");\r
1249 fprintf(fp, "notSigned%ld:\n", dwGlobalLabel);\r
1250 fprintf(fp, " add dx, [_z80%s] ; Our offset!\n", Localmz80Index);\r
1251 ++dwGlobalLabel;\r
1252}\r
1253\r
1254void CBHandler(UINT32 dwOpcode)\r
1255{\r
1256 if (MZ80_ASSEMBLY_X86 == bWhat)\r
1257 {\r
1258 fprintf(fp, ";\n");\r
1259 fprintf(fp, "; Handler for all CBxx instructions\n");\r
1260 fprintf(fp, ";\n");\r
1261 sprintf(string, "RegInst%.2x", dwOpcode);\r
1262 ProcBegin(0xffffffff);\r
1263 fprintf(fp, " mov dl, [esi]\n");\r
1264 fprintf(fp, " inc esi\n");\r
1265 fprintf(fp, " jmp dword [z80PrefixCB+edx*4]\n\n");\r
1266 fprintf(fp, "\n\n");\r
1267 }\r
1268 else\r
1269 if (MZ80_C == bWhat)\r
1270 {\r
1271 fprintf(fp, " CBHandler();\n");\r
1272 }\r
1273 else\r
1274 {\r
1275 assert(0); \r
1276 }\r
1277}\r
1278\r
1279void EDHandler(UINT32 dwOpcode)\r
1280{\r
1281 if (MZ80_ASSEMBLY_X86 == bWhat)\r
1282 {\r
1283 fprintf(fp, ";\n");\r
1284 fprintf(fp, "; Handler for all EDxx instructions\n");\r
1285 fprintf(fp, ";\n");\r
1286 sprintf(string, "RegInst%.2x", dwOpcode);\r
1287 ProcBegin(0xffffffff);\r
1288 fprintf(fp, " mov dl, [esi]\n");\r
1289 fprintf(fp, " inc esi\n");\r
1290 fprintf(fp, " jmp dword [z80PrefixED+edx*4]\n\n");\r
1291 fprintf(fp, "\n\n");\r
1292 }\r
1293 else\r
1294 if (MZ80_C == bWhat)\r
1295 {\r
1296 fprintf(fp, " EDHandler();\n");\r
1297 }\r
1298 else\r
1299 {\r
1300 assert(0); \r
1301 }\r
1302}\r
1303\r
1304void DDHandler(UINT32 dwOpcode)\r
1305{\r
1306 if (MZ80_ASSEMBLY_X86 == bWhat)\r
1307 {\r
1308 fprintf(fp, ";\n");\r
1309 fprintf(fp, "; Handler for all DDxx instructions\n");\r
1310 fprintf(fp, ";\n");\r
1311 sprintf(string, "RegInst%.2x", dwOpcode);\r
1312 ProcBegin(0xffffffff);\r
1313 fprintf(fp, " mov dl, [esi]\n");\r
1314 fprintf(fp, " inc esi\n");\r
1315 fprintf(fp, " jmp dword [z80PrefixDD+edx*4]\n\n");\r
1316 fprintf(fp, "\n\n");\r
1317 }\r
1318 else\r
1319 if (MZ80_C == bWhat)\r
1320 {\r
1321 fprintf(fp, " DDHandler();\n");\r
1322 }\r
1323 else\r
1324 {\r
1325 assert(0); \r
1326 }\r
1327}\r
1328\r
1329void FDHandler(UINT32 dwOpcode)\r
1330{\r
1331 if (MZ80_ASSEMBLY_X86 == bWhat)\r
1332 {\r
1333 fprintf(fp, ";\n");\r
1334 fprintf(fp, "; Handler for all FDxx instructions\n");\r
1335 fprintf(fp, ";\n");\r
1336 sprintf(string, "RegInst%.2x", dwOpcode);\r
1337 ProcBegin(0xffffffff);\r
1338 fprintf(fp, " mov dl, [esi]\n");\r
1339 fprintf(fp, " inc esi\n");\r
1340 fprintf(fp, " jmp dword [z80PrefixFD+edx*4]\n\n");\r
1341 fprintf(fp, "\n\n");\r
1342 }\r
1343 else\r
1344 if (MZ80_C == bWhat)\r
1345 {\r
1346 fprintf(fp, " FDHandler();\n");\r
1347 }\r
1348 else\r
1349 {\r
1350 assert(0); \r
1351 }\r
1352}\r
1353\r
1354StandardHeader()\r
1355{\r
1356 if (MZ80_ASSEMBLY_X86 == bWhat)\r
1357 {\r
1358 fprintf(fp,"; For assembly by NASM only\n");\r
1359 fprintf(fp,"bits 32\n\n");\r
1360\r
1361 fprintf(fp,"; Theory of operation\n\n");\r
1362 fprintf(fp,"; EDI=General purpose\n");\r
1363 fprintf(fp,"; ESI=Program counter + base address\n");\r
1364 fprintf(fp,"; EBP=z80Base\n");\r
1365 fprintf(fp,"; AX=AF\n");\r
1366 fprintf(fp,"; BX=HL\n");\r
1367 fprintf(fp,"; CX=BC\n");\r
1368 fprintf(fp,"; DX=General purpose\n\n"); \r
1369\r
1370 if (bUseStack)\r
1371 fprintf(fp, "; Using stack calling conventions\n");\r
1372 else\r
1373 fprintf(fp, "; Using register calling conventions\n");\r
1374\r
1375 if (b16BitIo)\r
1376 fprintf(fp, "; Extended input/output instructions treat (BC) as I/O address\n");\r
1377 else\r
1378 fprintf(fp, "; Extended input/output instructions treat (C) as I/O address\n\n");\r
1379\r
1380 fprintf(fp, "IFF1 equ 01h\n");\r
1381 fprintf(fp, "IFF2 equ 02h\n");\r
1382\r
1383 fprintf(fp, "CPUREG_PC equ 00h\n");\r
1384 fprintf(fp, "CPUREG_SP equ 01h\n");\r
1385 fprintf(fp, "CPUREG_AF equ 02h\n");\r
1386 fprintf(fp, "CPUREG_BC equ 03h\n");\r
1387 fprintf(fp, "CPUREG_DE equ 04h\n");\r
1388 fprintf(fp, "CPUREG_HL equ 05h\n");\r
1389 fprintf(fp, "CPUREG_AFPRIME equ 06h\n");\r
1390 fprintf(fp, "CPUREG_BCPRIME equ 07h\n");\r
1391 fprintf(fp, "CPUREG_DEPRIME equ 08h\n");\r
1392 fprintf(fp, "CPUREG_HLPRIME equ 09h\n");\r
1393 fprintf(fp, "CPUREG_IX equ 0ah\n");\r
1394 fprintf(fp, "CPUREG_IY equ 0bh\n");\r
1395 fprintf(fp, "CPUREG_I equ 0ch\n");\r
1396 fprintf(fp, "CPUREG_A equ 0dh\n");\r
1397 fprintf(fp, "CPUREG_F equ 0eh\n");\r
1398 fprintf(fp, "CPUREG_B equ 0fh\n");\r
1399 fprintf(fp, "CPUREG_C equ 10h\n");\r
1400 fprintf(fp, "CPUREG_D equ 11h\n");\r
1401 fprintf(fp, "CPUREG_E equ 12h\n");\r
1402 fprintf(fp, "CPUREG_H equ 13h\n");\r
1403 fprintf(fp, "CPUREG_L equ 14h\n");\r
1404 fprintf(fp, "CPUREG_IFF1 equ 15h\n");\r
1405 fprintf(fp, "CPUREG_IFF2 equ 16h\n");\r
1406 fprintf(fp, "CPUREG_CARRY equ 17h\n");\r
1407 fprintf(fp, "CPUREG_NEGATIVE equ 18h\n");\r
1408 fprintf(fp, "CPUREG_PARITY equ 19h\n");\r
1409 fprintf(fp, "CPUREG_OVERFLOW equ 1ah\n");\r
1410 fprintf(fp, "CPUREG_HALFCARRY equ 1bh\n");\r
1411 fprintf(fp, "CPUREG_ZERO equ 1ch\n");\r
1412 fprintf(fp, "CPUREG_SIGN equ 1dh\n");\r
1413 fprintf(fp, "CPUREG_MAXINDEX equ 1eh\n\n");\r
1414 }\r
1415 else\r
1416 if (MZ80_C == bWhat)\r
1417 {\r
1418 fprintf(fp, "/* Multi-Z80 32 Bit emulator */\n");\r
1419 fprintf(fp, "\n");\r
1420 fprintf(fp, "/* Copyright 1996-2000 Neil Bradley, All rights reserved\n");\r
1421 fprintf(fp, " *\n");\r
1422 fprintf(fp, " * License agreement:\n");\r
1423 fprintf(fp, " *\n");\r
1424 fprintf(fp, " * (MZ80 Refers to both the assembly code emitted by makeZ80.c and makeZ80.c\n");\r
1425 fprintf(fp, " * itself)\n");\r
1426 fprintf(fp, " *\n");\r
1427 fprintf(fp, " * MZ80 May be distributed in unmodified form to any medium.\n");\r
1428 fprintf(fp, " *\n");\r
1429 fprintf(fp, " * MZ80 May not be sold, or sold as a part of a commercial package without\n");\r
1430 fprintf(fp, " * the express written permission of Neil Bradley (neil@synthcom.com). This\n");\r
1431 fprintf(fp, " * includes shareware.\n");\r
1432 fprintf(fp, " *\n");\r
1433 fprintf(fp, " * Modified versions of MZ80 may not be publicly redistributed without author\n");\r
1434 fprintf(fp, " * approval (neil@synthcom.com). This includes distributing via a publicly\n");\r
1435 fprintf(fp, " * accessible LAN. You may make your own source modifications and distribute\n");\r
1436 fprintf(fp, " * MZ80 in source or object form, but if you make modifications to MZ80\n");\r
1437 fprintf(fp, " * then it should be noted in the top as a comment in makeZ80.c.\n");\r
1438 fprintf(fp, " *\n");\r
1439 fprintf(fp, " * MZ80 Licensing for commercial applications is available. Please email\n");\r
1440 fprintf(fp, " * neil@synthcom.com for details.\n");\r
1441 fprintf(fp, " *\n");\r
1442 fprintf(fp, " * Synthcom Systems, Inc, and Neil Bradley will not be held responsible for\n");\r
1443 fprintf(fp, " * any damage done by the use of MZ80. It is purely \"as-is\".\n");\r
1444 fprintf(fp, " *\n");\r
1445 fprintf(fp, " * If you use MZ80 in a freeware application, credit in the following text:\n");\r
1446 fprintf(fp, " *\n");\r
1447 fprintf(fp, " * \"Multi-Z80 CPU emulator by Neil Bradley (neil@synthcom.com)\"\n");\r
1448 fprintf(fp, " *\n");\r
1449 fprintf(fp, " * must accompany the freeware application within the application itself or\n");\r
1450 fprintf(fp, " * in the documentation.\n");\r
1451 fprintf(fp, " *\n");\r
1452 fprintf(fp, " * Legal stuff aside:\n");\r
1453 fprintf(fp, " *\n");\r
1454 fprintf(fp, " * If you find problems with MZ80, please email the author so they can get\n");\r
1455 fprintf(fp, " * resolved. If you find a bug and fix it, please also email the author so\n");\r
1456 fprintf(fp, " * that those bug fixes can be propogated to the installed base of MZ80\n");\r
1457 fprintf(fp, " * users. If you find performance improvements or problems with MZ80, please\n");\r
1458 fprintf(fp, " * email the author with your changes/suggestions and they will be rolled in\n");\r
1459 fprintf(fp, " * with subsequent releases of MZ80.\n");\r
1460 fprintf(fp, " *\n");\r
1461 fprintf(fp, " * The whole idea of this emulator is to have the fastest available 32 bit\n");\r
1462 fprintf(fp, " * Multi-Z80 emulator for the PC, giving maximum performance. \n");\r
1463 fprintf(fp, " */\n\n");\r
1464 fprintf(fp, "#include <stdio.h>\n");\r
1465 fprintf(fp, "#include <stdlib.h>\n");\r
1466 fprintf(fp, "#include <string.h>\n");\r
1467 fprintf(fp, "#include \"mz80.h\"\n");\r
1468\r
1469 // HACK HACK\r
1470\r
1471 fprintf(fp, "UINT32 z80intAddr;\n");\r
1472 fprintf(fp, "UINT32 z80pc;\n");\r
1473 } \r
1474 else\r
1475 {\r
1476 // Whoops. Unknown emission type.\r
1477\r
1478 assert(0);\r
1479 }\r
1480\r
1481 fprintf(fp, "\n\n");\r
1482}\r
1483\r
1484Alignment()\r
1485{\r
1486 fprintf(fp, "\ntimes ($$-$) & 3 nop ; pad with NOPs to 4-byte boundary\n\n");\r
1487}\r
1488\r
1489void ProcBegin(UINT32 dwOpcode)\r
1490{\r
1491 Alignment();\r
1492 fprintf(fp, "%s:\n", procname);\r
1493}\r
1494\r
1495void SetSubFlagsSZHVC(UINT8 *pszLeft, UINT8 *pszRight)\r
1496{\r
1497 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n");\r
1498 fprintf(fp, " Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n");\r
1499 fprintf(fp, " pbSubSbcTable[((UINT32) %s << 8) | %s];\n", pszLeft, pszRight);\r
1500}\r
1501\r
1502void SetSbcFlagsSZHVC(UINT8 *pszLeft, UINT8 *pszRight)\r
1503{\r
1504 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n");\r
1505 fprintf(fp, " Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n");\r
1506 fprintf(fp, " pbSubSbcTable[((UINT32) %s << 8) | %s | (((UINT32) cpu.z80F & Z80_FLAG_CARRY) << 16)];\n", pszLeft, pszRight);\r
1507}\r
1508\r
1509void SetAddFlagsSZHVC(UINT8 *pszLeft, UINT8 *pszRight)\r
1510{\r
1511 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n");\r
1512 fprintf(fp, " Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n");\r
1513 fprintf(fp, " pbAddAdcTable[((UINT32) %s << 8) | %s];\n", pszLeft, pszRight);\r
1514}\r
1515\r
1516void SetAdcFlagsSZHVC(UINT8 *pszLeft, UINT8 *pszRight)\r
1517{\r
1518 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n");\r
1519 fprintf(fp, " Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n");\r
1520 fprintf(fp, " pbAddAdcTable[((UINT32) %s << 8) | %s | (((UINT32) cpu.z80F & Z80_FLAG_CARRY) << 16)];\n", pszLeft, pszRight);\r
1521}\r
1522\r
1523UINT32 dwOverflowCount = 0;\r
1524\r
1525SetOverflow()\r
1526{\r
1527 fprintf(fp, " seto dl\n");\r
1528 fprintf(fp, " and ah, 0fbh ; Knock out parity/overflow\n");\r
1529 fprintf(fp, " shl dl, 2\n");\r
1530 fprintf(fp, " or ah, dl\n");\r
1531}\r
1532 \r
1533void FetchNextInstruction(UINT32 dwOpcode)\r
1534{\r
1535 if (0xffffffff != dwOpcode)\r
1536 {\r
1537 fprintf(fp, " sub edi, byte %ld\n", Timing(bCurrentMode, dwOpcode));\r
1538 \r
1539 if (bCurrentMode == TIMING_REGULAR)\r
1540 fprintf(fp, " js near noMoreExec\n");\r
1541 else\r
1542 fprintf(fp, " js near noMoreExec\n");\r
1543 }\r
1544\r
1545 fprintf(fp, " mov dl, byte [esi] ; Get our next instruction\n");\r
1546 fprintf(fp, " inc esi ; Increment PC\n");\r
1547 fprintf(fp, " jmp dword [z80regular+edx*4]\n\n");\r
1548}\r
1549\r
1550void WriteValueToMemory(UINT8 *pszAddress, UINT8 *pszValue)\r
1551{\r
1552 if (MZ80_ASSEMBLY_X86 == bWhat)\r
1553 {\r
1554 fprintf(fp, " mov [cyclesRemaining], edi\n");\r
1555 fprintf(fp, " mov [_z80af], ax ; Store AF\n");\r
1556\r
1557 // First off, load our byte to write into al after we've saved AF\r
1558\r
1559 if (strcmp(pszValue, "al") != 0)\r
1560 fprintf(fp, " mov al, %s ; And our data to write\n", pszValue);\r
1561 if (strcmp(pszValue, "[esi]") == 0) // Immediate value?\r
1562 fprintf(fp, " inc esi ; Increment our program counter\n");\r
1563\r
1564 // Now get the address in DX - regardless of what it is\r
1565\r
1566 if (strcmp(pszAddress, "[_z80de]") == 0 ||\r
1567 strcmp(pszAddress, "[_orgval]") == 0 ||\r
1568 strcmp(pszAddress, "[_z80ix]") == 0 ||\r
1569 strcmp(pszAddress, "[_z80iy]") == 0)\r
1570 fprintf(fp, " mov dx, %s\n", pszAddress);\r
1571\r
1572 fprintf(fp, " mov edi, [_z80MemWrite] ; Point to the write array\n\n", cpubasename);\r
1573 fprintf(fp, "checkLoop%ld:\n", dwGlobalLabel);\r
1574 fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n");\r
1575 fprintf(fp, " je memoryWrite%ld ; Yes - go write it!\n", dwGlobalLabel);\r
1576\r
1577 if (strcmp(pszAddress, "[_z80de]") == 0 ||\r
1578 strcmp(pszAddress, "[_orgval]") == 0 ||\r
1579 strcmp(pszAddress, "[_z80ix]") == 0 ||\r
1580 strcmp(pszAddress, "[_z80iy]") == 0)\r
1581 fprintf(fp, " cmp dx, [edi] ; Are we smaller?\n", pszAddress);\r
1582 else\r
1583 fprintf(fp, " cmp %s, [edi] ; Are we smaller?\n", pszAddress);\r
1584\r
1585 fprintf(fp, " jb nextAddr%ld ; Yes... go to the next addr\n", dwGlobalLabel);\r
1586\r
1587 if (strcmp(pszAddress, "[_z80de]") == 0 ||\r
1588 strcmp(pszAddress, "[_orgval]") == 0 ||\r
1589 strcmp(pszAddress, "[_z80ix]") == 0 ||\r
1590 strcmp(pszAddress, "[_z80iy]") == 0)\r
1591 fprintf(fp, " cmp dx, [edi+4] ; Are we smaller?\n", pszAddress);\r
1592 else\r
1593 fprintf(fp, " cmp %s, [edi+4] ; Are we smaller?\n", pszAddress);\r
1594 \r
1595 fprintf(fp, " jbe callRoutine%ld ; If not, go call it!\n\n", dwGlobalLabel);\r
1596 fprintf(fp, "nextAddr%ld:\n", dwGlobalLabel);\r
1597 fprintf(fp, " add edi, 10h ; Next structure, please\n");\r
1598 fprintf(fp, " jmp short checkLoop%ld\n\n", dwGlobalLabel);\r
1599 fprintf(fp, "callRoutine%ld:\n", dwGlobalLabel);\r
1600 \r
1601 // Save off our registers!\r
1602 \r
1603 if ((strcmp(pszAddress, "dx") != 0) && (strcmp(pszAddress, "[_z80de]") != 0) &&\r
1604 (strcmp(pszAddress, "[_z80ix]") != 0) &&\r
1605 (strcmp(pszAddress, "[_orgval]") != 0) &&\r
1606 (strcmp(pszAddress, "[_z80iy]") != 0))\r
1607 fprintf(fp, " mov dx, %s ; Get our address to target\n", pszAddress);\r
1608 \r
1609 fprintf(fp, " call WriteMemoryByte ; Go write the data!\n");\r
1610 fprintf(fp, " jmp short WriteMacroExit%ld\n", dwGlobalLabel);\r
1611 \r
1612 fprintf(fp, "memoryWrite%ld:\n", dwGlobalLabel);\r
1613 \r
1614 if (strcmp(pszValue, "[esi]") == 0)\r
1615 fprintf(fp, " mov [ebp + e%s], al ; Store our direct value\n", pszAddress);\r
1616 else\r
1617 {\r
1618 if (pszValue[0] == 'b' && pszValue[1] == 'y' && pszValue[2] == 't')\r
1619 {\r
1620 fprintf(fp, " mov edi, edx\n");\r
1621 assert(strcmp(pszValue, "dl") != 0);\r
1622 \r
1623 fprintf(fp, " mov dl, %s\n", pszValue);\r
1624 \r
1625 if (strcmp(pszAddress, "dx") == 0)\r
1626 fprintf(fp, " mov [ebp + edi], dl\n");\r
1627 else\r
1628 fprintf(fp, " mov [ebp + e%s], dl\n", pszAddress);\r
1629 \r
1630 fprintf(fp, " mov edx, edi\n");\r
1631 }\r
1632 else\r
1633 {\r
1634 if (strcmp(pszAddress, "[_z80de]") != 0 &&\r
1635 strcmp(pszAddress, "[_orgval]") != 0 &&\r
1636 strcmp(pszAddress, "[_z80ix]") != 0 &&\r
1637 strcmp(pszAddress, "[_z80iy]") != 0)\r
1638 fprintf(fp, " mov [ebp + e%s], %s\n", pszAddress, pszValue);\r
1639 else\r
1640 fprintf(fp, " mov [ebp + edx], al\n");\r
1641 }\r
1642 }\r
1643\r
1644 fprintf(fp, " mov ax, [_z80af] ; Get our accumulator and flags\n");\r
1645 \r
1646 fprintf(fp, "WriteMacroExit%ld:\n", dwGlobalLabel);\r
1647 fprintf(fp, " mov edi, [cyclesRemaining]\n");\r
1648\r
1649 ++dwGlobalLabel;\r
1650 }\r
1651 else\r
1652 if (MZ80_C == bWhat)\r
1653 {\r
1654 fprintf(fp, " psMemWrite = cpu.z80MemWrite; /* Beginning of our handler */\n");\r
1655 fprintf(fp, " while (psMemWrite->lowAddr != 0xffffffff)\n");\r
1656 fprintf(fp, " {\n");\r
1657 fprintf(fp, " if ((%s >= psMemWrite->lowAddr) && (%s <= psMemWrite->highAddr))\n", pszAddress, pszAddress);\r
1658 fprintf(fp, " {\n");\r
1659 fprintf(fp, " cpu.z80pc = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
1660 fprintf(fp, " if (psMemWrite->memoryCall)\n");\r
1661 fprintf(fp, " {\n");\r
1662 fprintf(fp, " psMemWrite->memoryCall(%s, %s, psMemWrite);\n", pszAddress, pszValue);\r
1663 fprintf(fp, " }\n");\r
1664 fprintf(fp, " else\n");\r
1665 fprintf(fp, " {\n");\r
1666 fprintf(fp, " *((UINT8 *) psMemWrite->pUserArea + (%s - psMemWrite->lowAddr)) = %s;\n", pszAddress, pszValue);\r
1667 fprintf(fp, " }\n");\r
1668 fprintf(fp, " psMemWrite = NULL;\n");\r
1669 fprintf(fp, " break;\n");\r
1670 fprintf(fp, " }\n");\r
1671 fprintf(fp, " ++psMemWrite;\n");\r
1672 fprintf(fp, " }\n\n");\r
1673 fprintf(fp, " if (psMemWrite)\n");\r
1674 fprintf(fp, " {\n");\r
1675 fprintf(fp, " cpu.z80Base[%s] = (UINT8) %s;\n", pszAddress, pszValue);\r
1676 fprintf(fp, " }\n\n");\r
1677 }\r
1678}\r
1679\r
1680void WriteWordToMemory(UINT8 *pszAddress, UINT8 *pszTarget)\r
1681{\r
1682 if (MZ80_ASSEMBLY_X86 == bWhat)\r
1683 {\r
1684 fprintf(fp, " mov [cyclesRemaining], edi\n");\r
1685 fprintf(fp, " mov edi, [_z80MemWrite] ; Point to the write array\n\n", cpubasename);\r
1686 fprintf(fp, "checkLoop%ld:\n", dwGlobalLabel);\r
1687 fprintf(fp, " cmp [edi], word 0ffffh ; End of the list?\n");\r
1688 fprintf(fp, " je memoryWrite%ld\n", dwGlobalLabel);\r
1689 fprintf(fp, " cmp %s, [edi] ; Are we smaller?\n", pszAddress);\r
1690 fprintf(fp, " jb nextAddr%ld ; Yes, go to the next address\n", dwGlobalLabel);\r
1691 fprintf(fp, " cmp %s, [edi+4] ; Are we bigger?\n", pszAddress);\r
1692 fprintf(fp, " jbe callRoutine%ld\n\n", dwGlobalLabel);\r
1693 fprintf(fp, "nextAddr%ld:\n", dwGlobalLabel);\r
1694 fprintf(fp, " add edi, 10h ; Next structure!\n");\r
1695 fprintf(fp, " jmp short checkLoop%ld\n\n", dwGlobalLabel);\r
1696 fprintf(fp, "callRoutine%ld:\n", dwGlobalLabel);\r
1697\r
1698 fprintf(fp, " push ax ; Save this for later\n");\r
1699\r
1700 // Write the LSB\r
1701\r
1702 fprintf(fp, " push dx\n");\r
1703\r
1704 if (strcmp(pszTarget, "ax") != 0)\r
1705 {\r
1706 fprintf(fp, " mov ax, %s\n", pszTarget);\r
1707 }\r
1708 else\r
1709 {\r
1710 fprintf(fp, " xchg ah, al\n");\r
1711 }\r
1712\r
1713 fprintf(fp, " call WriteMemoryByte\n");\r
1714 fprintf(fp, " pop dx\n");\r
1715 fprintf(fp, " pop ax\n");\r
1716 fprintf(fp, " inc dx\n\n");\r
1717\r
1718 fprintf(fp, " push ax\n");\r
1719 fprintf(fp, " push dx\n");\r
1720\r
1721 if (strcmp(pszTarget, "ax") != 0)\r
1722 {\r
1723 fprintf(fp, " mov ax, %s\n", pszTarget);\r
1724 fprintf(fp, " xchg ah, al\n");\r
1725 }\r
1726\r
1727 fprintf(fp, " call WriteMemoryByte\n");\r
1728 fprintf(fp, " pop dx\n");\r
1729 fprintf(fp, " pop ax ; Restore us!\n");\r
1730\r
1731 fprintf(fp, " jmp writeExit%ld\n\n", dwGlobalLabel);\r
1732\r
1733 fprintf(fp, "memoryWrite%ld:\n", dwGlobalLabel);\r
1734\r
1735 if (strlen(pszTarget) != 2)\r
1736 {\r
1737 fprintf(fp, " mov di, %s\n", pszTarget);\r
1738 fprintf(fp, " mov [ebp + e%s], di ; Store our word\n", pszAddress);\r
1739 }\r
1740 else\r
1741 {\r
1742 if (strcmp(pszTarget, "ax") != 0)\r
1743 {\r
1744 fprintf(fp, " mov [ebp + e%s], %s ; Store our word\n", pszAddress, pszTarget);\r
1745 }\r
1746 else\r
1747 {\r
1748 fprintf(fp, " xchg ah, al ; Swap for later\n");\r
1749 fprintf(fp, " mov [ebp + e%s], %s ; Store our word\n", pszAddress, pszTarget);\r
1750 fprintf(fp, " xchg ah, al ; Restore\n");\r
1751 }\r
1752 }\r
1753 \r
1754 fprintf(fp, "writeExit%ld:\n", dwGlobalLabel);\r
1755 fprintf(fp, " mov edi, [cyclesRemaining]\n");\r
1756 \r
1757 dwGlobalLabel++;\r
1758 }\r
1759 else\r
1760 if (MZ80_C == bWhat)\r
1761 {\r
1762 fprintf(fp, " psMemWrite = cpu.z80MemWrite; /* Beginning of our handler */\n");\r
1763 fprintf(fp, " while (psMemWrite->lowAddr != 0xffffffff)\n");\r
1764 fprintf(fp, " {\n");\r
1765 fprintf(fp, " if ((%s >= psMemWrite->lowAddr) && (%s <= psMemWrite->highAddr))\n", pszAddress, pszAddress);\r
1766 fprintf(fp, " {\n");\r
1767 fprintf(fp, " cpu.z80pc = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
1768\r
1769 fprintf(fp, " if (psMemWrite->memoryCall)\n");\r
1770 fprintf(fp, " {\n");\r
1771 fprintf(fp, " psMemWrite->memoryCall(%s, (%s & 0xff), psMemWrite);\n", pszAddress, pszTarget);\r
1772 fprintf(fp, " psMemWrite->memoryCall(%s + 1, (%s >> 8), psMemWrite);\n", pszAddress, pszTarget);\r
1773 fprintf(fp, " }\n");\r
1774 fprintf(fp, " else\n");\r
1775 fprintf(fp, " {\n");\r
1776 fprintf(fp, " *((UINT8 *) psMemWrite->pUserArea + (%s - psMemWrite->lowAddr)) = %s;\n", pszAddress, pszTarget);\r
1777 fprintf(fp, " *((UINT8 *) psMemWrite->pUserArea + (%s - psMemWrite->lowAddr) + 1) = %s >> 8;\n", pszAddress, pszTarget);\r
1778 fprintf(fp, " }\n");\r
1779\r
1780 fprintf(fp, " psMemWrite = NULL;\n");\r
1781 fprintf(fp, " break;\n");\r
1782 fprintf(fp, " }\n");\r
1783 fprintf(fp, " ++psMemWrite;\n");\r
1784 fprintf(fp, " }\n\n");\r
1785 fprintf(fp, " if (psMemWrite)\n");\r
1786 fprintf(fp, " {\n");\r
1787 fprintf(fp, " cpu.z80Base[%s] = (UINT8) %s;\n", pszAddress, pszTarget);\r
1788 fprintf(fp, " cpu.z80Base[%s + 1] = (UINT8) ((UINT32) %s >> 8);\n", pszAddress, pszTarget);\r
1789 fprintf(fp, " }\n\n");\r
1790 }\r
1791 else\r
1792 {\r
1793 assert(0);\r
1794 }\r
1795}\r
1796\r
1797void WriteValueToIo(UINT8 *pszIoAddress, UINT8 *pszValue)\r
1798{\r
1799 if (MZ80_ASSEMBLY_X86 == bWhat)\r
1800 {\r
1801 fprintf(fp, " mov [cyclesRemaining], edi\n");\r
1802 fprintf(fp, " mov [_z80af], ax ; Store AF\n");\r
1803\r
1804 if (strcmp(pszValue, "al") != 0)\r
1805 fprintf(fp, " mov al, %s ; And our data to write\n", pszValue);\r
1806 if (strcmp(pszValue, "[esi]") == 0) // Immediate value?\r
1807 fprintf(fp, " inc esi ; Increment our program counter\n");\r
1808\r
1809 fprintf(fp, " mov edi, [_z80IoWrite] ; Point to the I/O write array\n\n", cpubasename);\r
1810 fprintf(fp, "checkLoop%ld:\n", dwGlobalLabel);\r
1811 fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n");\r
1812 fprintf(fp, " je WriteMacroExit%ld ; Yes - ignore it!\n", dwGlobalLabel);\r
1813 fprintf(fp, " cmp %s, [edi] ; Are we smaller?\n", pszIoAddress);\r
1814 fprintf(fp, " jb nextAddr%ld ; Yes... go to the next addr\n", dwGlobalLabel);\r
1815 fprintf(fp, " cmp %s, [edi+2] ; Are we bigger?\n", pszIoAddress);\r
1816 fprintf(fp, " jbe callRoutine%ld ; If not, go call it!\n\n", dwGlobalLabel);\r
1817 fprintf(fp, "nextAddr%ld:\n", dwGlobalLabel);\r
1818 fprintf(fp, " add edi, 0ch ; Next structure, please\n");\r
1819 fprintf(fp, " jmp short checkLoop%ld\n\n", dwGlobalLabel);\r
1820 fprintf(fp, "callRoutine%ld:\n", dwGlobalLabel);\r
1821\r
1822 // Save off our registers!\r
1823\r
1824 if (strcmp(pszIoAddress, "dx") != 0)\r
1825 fprintf(fp, " mov dx, %s ; Get our address to target\n", pszIoAddress);\r
1826\r
1827 fprintf(fp, " call WriteIOByte ; Go write the data!\n");\r
1828 \r
1829 fprintf(fp, "WriteMacroExit%ld:\n", dwGlobalLabel);\r
1830 fprintf(fp, " mov edi, [cyclesRemaining]\n");\r
1831 }\r
1832 else\r
1833 if (MZ80_C == bWhat)\r
1834 {\r
1835 fprintf(fp, " psIoWrite = cpu.z80IoWrite; /* Beginning of our handler */\n");\r
1836 fprintf(fp, " while (psIoWrite->lowIoAddr != 0xffff)\n");\r
1837 fprintf(fp, " {\n");\r
1838 fprintf(fp, " if ((%s >= psIoWrite->lowIoAddr) && (%s <= psIoWrite->highIoAddr))\n", pszIoAddress, pszIoAddress);\r
1839 fprintf(fp, " {\n");\r
1840 fprintf(fp, " cpu.z80pc = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
1841 fprintf(fp, " psIoWrite->IOCall(%s, %s, psIoWrite);\n", pszIoAddress, pszValue);\r
1842 fprintf(fp, " psIoWrite = NULL;\n");\r
1843 fprintf(fp, " break;\n");\r
1844 fprintf(fp, " }\n");\r
1845 fprintf(fp, " ++psIoWrite;\n");\r
1846 fprintf(fp, " }\n\n");\r
1847 }\r
1848 else\r
1849 {\r
1850 assert(0);\r
1851 } \r
1852 \r
1853 ++dwGlobalLabel;\r
1854}\r
1855\r
1856void ReadValueFromMemory(UINT8 *pszAddress, UINT8 *pszTarget)\r
1857{\r
1858 if (MZ80_ASSEMBLY_X86 == bWhat)\r
1859 {\r
1860 fprintf(fp, " mov [cyclesRemaining], edi\n");\r
1861 fprintf(fp, " mov edi, [_z80MemRead] ; Point to the read array\n\n", cpubasename);\r
1862 fprintf(fp, "checkLoop%ld:\n", dwGlobalLabel);\r
1863 fprintf(fp, " cmp [edi], word 0ffffh ; End of the list?\n");\r
1864 fprintf(fp, " je memoryRead%ld\n", dwGlobalLabel);\r
1865 fprintf(fp, " cmp e%s, [edi] ; Are we smaller?\n", pszAddress);\r
1866 fprintf(fp, " jb nextAddr%ld ; Yes, go to the next address\n", dwGlobalLabel);\r
1867 fprintf(fp, " cmp e%s, [edi+4] ; Are we bigger?\n", pszAddress);\r
1868 fprintf(fp, " jbe callRoutine%ld\n\n", dwGlobalLabel);\r
1869 fprintf(fp, "nextAddr%ld:\n", dwGlobalLabel);\r
1870 fprintf(fp, " add edi, 10h ; Next structure!\n");\r
1871 fprintf(fp, " jmp short checkLoop%ld\n\n", dwGlobalLabel);\r
1872 fprintf(fp, "callRoutine%ld:\n", dwGlobalLabel);\r
1873\r
1874 if (strcmp(pszAddress, "dx") != 0)\r
1875 fprintf(fp, " mov dx, %s ; Get our address\n", pszAddress);\r
1876 \r
1877 fprintf(fp, " call ReadMemoryByte ; Standard read routine\n");\r
1878 \r
1879 // Yes, these are intentionally reversed!\r
1880 \r
1881 if (strcmp(pszTarget, "al") == 0)\r
1882 fprintf(fp, " mov [_z80af], al ; Save our new accumulator\n");\r
1883 else\r
1884 if (strcmp(pszTarget, "ah") == 0)\r
1885 fprintf(fp, " mov [_z80af + 1], al ; Save our new flags\n");\r
1886 else\r
1887 fprintf(fp, " mov %s, al ; Put our returned value here\n", pszTarget);\r
1888 \r
1889 // And are properly restored HERE:\r
1890 \r
1891 fprintf(fp, " mov ax, [_z80af] ; Get our AF back\n");\r
1892 \r
1893 // Restore registers here...\r
1894 \r
1895 fprintf(fp, " jmp short readExit%ld\n\n", dwGlobalLabel);\r
1896 fprintf(fp, "memoryRead%ld:\n", dwGlobalLabel);\r
1897 \r
1898 if (pszTarget[0] == 'b' && pszTarget[1] == 'y' && pszTarget[2] == 't')\r
1899 {\r
1900 fprintf(fp, " mov di, dx\n");\r
1901 fprintf(fp, " mov dl, [ebp + e%s]\n", pszAddress);\r
1902 fprintf(fp, " mov %s, dl\n", pszTarget);\r
1903 fprintf(fp, " mov dx, di\n");\r
1904 }\r
1905 else\r
1906 fprintf(fp, " mov %s, [ebp + e%s] ; Get our data\n\n", pszTarget, pszAddress);\r
1907 \r
1908 fprintf(fp, "readExit%ld:\n", dwGlobalLabel);\r
1909 fprintf(fp, " mov edi, [cyclesRemaining]\n");\r
1910 \r
1911 dwGlobalLabel++;\r
1912 }\r
1913 else\r
1914 if (MZ80_C == bWhat)\r
1915 {\r
1916 fprintf(fp, " psMemRead = cpu.z80MemRead; /* Beginning of our handler */\n");\r
1917 fprintf(fp, " while (psMemRead->lowAddr != 0xffffffff)\n");\r
1918 fprintf(fp, " {\n");\r
1919 fprintf(fp, " if ((%s >= psMemRead->lowAddr) && (%s <= psMemRead->highAddr))\n", pszAddress, pszAddress);\r
1920 fprintf(fp, " {\n");\r
1921 fprintf(fp, " cpu.z80pc = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
1922 fprintf(fp, " if (psMemRead->memoryCall)\n");\r
1923 fprintf(fp, " {\n");\r
1924 fprintf(fp, " %s = psMemRead->memoryCall(%s, psMemRead);\n", pszTarget, pszAddress);\r
1925 fprintf(fp, " }\n");\r
1926 fprintf(fp, " else\n");\r
1927 fprintf(fp, " {\n");\r
1928 fprintf(fp, " %s = *((UINT8 *) psMemRead->pUserArea + (%s - psMemRead->lowAddr));\n", pszTarget, pszAddress);\r
1929 fprintf(fp, " }\n");\r
1930 fprintf(fp, " psMemRead = NULL;\n");\r
1931 fprintf(fp, " break;\n");\r
1932 fprintf(fp, " }\n");\r
1933 fprintf(fp, " ++psMemRead;\n");\r
1934 fprintf(fp, " }\n\n");\r
1935 fprintf(fp, " if (psMemRead)\n");\r
1936 fprintf(fp, " {\n");\r
1937 fprintf(fp, " %s = cpu.z80Base[%s];\n", pszTarget, pszAddress);\r
1938 fprintf(fp, " }\n\n");\r
1939 }\r
1940 else\r
1941 {\r
1942 assert(0);\r
1943 }\r
1944}\r
1945\r
1946\r
1947void ReadWordFromMemory(UINT8 *pszAddress, UINT8 *pszTarget)\r
1948{\r
1949 if (MZ80_ASSEMBLY_X86 == bWhat)\r
1950 {\r
1951 fprintf(fp, " mov [cyclesRemaining], edi\n");\r
1952 fprintf(fp, " mov edi, [_z80MemRead] ; Point to the read array\n\n", cpubasename);\r
1953 fprintf(fp, "checkLoop%ld:\n", dwGlobalLabel);\r
1954 fprintf(fp, " cmp [edi], word 0ffffh ; End of the list?\n");\r
1955 fprintf(fp, " je memoryRead%ld\n", dwGlobalLabel);\r
1956 fprintf(fp, " cmp %s, [edi] ; Are we smaller?\n", pszAddress);\r
1957 fprintf(fp, " jb nextAddr%ld ; Yes, go to the next address\n", dwGlobalLabel);\r
1958 fprintf(fp, " cmp %s, [edi+4] ; Are we bigger?\n", pszAddress);\r
1959 fprintf(fp, " jbe callRoutine%ld\n\n", dwGlobalLabel);\r
1960 fprintf(fp, "nextAddr%ld:\n", dwGlobalLabel);\r
1961 fprintf(fp, " add edi, 10h ; Next structure!\n");\r
1962 fprintf(fp, " jmp short checkLoop%ld\n\n", dwGlobalLabel);\r
1963 fprintf(fp, "callRoutine%ld:\n", dwGlobalLabel);\r
1964\r
1965 if (strcmp(pszAddress, "dx") != 0)\r
1966 fprintf(fp, " mov dx, %s ; Get our address\n", pszAddress);\r
1967\r
1968 if (strcmp(pszTarget, "ax") != 0)\r
1969 fprintf(fp, " push ax ; Save this for later\n");\r
1970\r
1971 fprintf(fp, " push dx ; Save address\n");\r
1972 fprintf(fp, " call ReadMemoryByte ; Standard read routine\n");\r
1973 fprintf(fp, " pop dx ; Restore our address\n");\r
1974\r
1975 fprintf(fp, " inc dx ; Next byte, please\n");\r
1976\r
1977 fprintf(fp, " push ax ; Save returned byte\n");\r
1978 fprintf(fp, " call ReadMemoryByte ; Standard read routine\n");\r
1979 fprintf(fp, " xchg ah, al ; Swap for endian's sake\n");\r
1980 fprintf(fp, " pop dx ; Restore LSB\n");\r
1981\r
1982 fprintf(fp, " mov dh, ah ; Our word is now in DX\n");\r
1983\r
1984 // DX Now has our data and our address is toast\r
1985 \r
1986 if (strcmp(pszTarget, "ax") != 0)\r
1987 {\r
1988 fprintf(fp, " pop ax ; Restore this\n");\r
1989 \r
1990 if (strcmp(pszTarget, "dx") != 0)\r
1991 {\r
1992 fprintf(fp, " mov %s, dx ; Store our word\n", pszTarget);\r
1993 }\r
1994 }\r
1995 else\r
1996 fprintf(fp, " mov ax, dx\n");\r
1997\r
1998 if (strcmp(pszTarget, "ax") == 0)\r
1999 {\r
2000 fprintf(fp, " xchg ah, al\n");\r
2001 }\r
2002 \r
2003 fprintf(fp, " jmp readExit%ld\n\n", dwGlobalLabel);\r
2004 \r
2005 fprintf(fp, "memoryRead%ld:\n", dwGlobalLabel);\r
2006 \r
2007 if (strlen(pszTarget) == 2)\r
2008 {\r
2009 fprintf(fp, " mov %s, [ebp + e%s]\n", pszTarget, pszAddress);\r
2010 if (strcmp(pszTarget, "ax") == 0)\r
2011 {\r
2012 fprintf(fp, " xchg ah, al\n");\r
2013 }\r
2014 }\r
2015 else\r
2016 {\r
2017 fprintf(fp, " mov dx, [ebp + e%s]\n", pszAddress);\r
2018 fprintf(fp, " mov %s, dx\n", pszTarget);\r
2019 }\r
2020 \r
2021 fprintf(fp, "readExit%ld:\n", dwGlobalLabel);\r
2022 fprintf(fp, " mov edi, [cyclesRemaining]\n");\r
2023 }\r
2024 else\r
2025 if (MZ80_C == bWhat)\r
2026 {\r
2027 fprintf(fp, " psMemRead = cpu.z80MemRead; /* Beginning of our handler */\n");\r
2028 fprintf(fp, " while (psMemRead->lowAddr != 0xffffffff)\n");\r
2029 fprintf(fp, " {\n");\r
2030 fprintf(fp, " if ((%s >= psMemRead->lowAddr) && (%s <= psMemRead->highAddr))\n", pszAddress, pszAddress);\r
2031 fprintf(fp, " {\n");\r
2032 fprintf(fp, " cpu.z80pc = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
2033 fprintf(fp, " if (psMemRead->memoryCall)\n");\r
2034 fprintf(fp, " {\n");\r
2035 fprintf(fp, " %s = psMemRead->memoryCall(%s, psMemRead);\n", pszTarget, pszAddress);\r
2036 fprintf(fp, " %s |= (UINT32) ((UINT32) psMemRead->memoryCall(%s + 1, psMemRead) << 8);\n", pszTarget, pszAddress);\r
2037 fprintf(fp, " }\n");\r
2038 fprintf(fp, " else\n");\r
2039 fprintf(fp, " {\n");\r
2040 fprintf(fp, " %s = *((UINT8 *) psMemRead->pUserArea + (%s - psMemRead->lowAddr));\n", pszTarget, pszAddress);\r
2041 fprintf(fp, " %s |= (UINT32) ((UINT32) *((UINT8 *) psMemRead->pUserArea + (%s - psMemRead->lowAddr + 1)) << 8);\n", pszTarget, pszAddress);\r
2042 fprintf(fp, " }\n");\r
2043 fprintf(fp, " psMemRead = NULL;\n");\r
2044 fprintf(fp, " break;\n");\r
2045 fprintf(fp, " }\n");\r
2046 fprintf(fp, " ++psMemRead;\n");\r
2047 fprintf(fp, " }\n\n");\r
2048 fprintf(fp, " if (psMemRead)\n");\r
2049 fprintf(fp, " {\n");\r
2050 fprintf(fp, " %s = cpu.z80Base[%s];\n", pszTarget, pszAddress);\r
2051 fprintf(fp, " %s |= (UINT32) ((UINT32) cpu.z80Base[%s + 1] << 8);\n", pszTarget, pszAddress);\r
2052 fprintf(fp, " }\n\n");\r
2053 }\r
2054 else\r
2055 {\r
2056 assert(0);\r
2057 }\r
2058\r
2059 dwGlobalLabel++;\r
2060}\r
2061\r
2062\r
2063void ReadValueFromIo(UINT8 *pszIoAddress, UINT8 *pszTarget)\r
2064{\r
2065 if (MZ80_ASSEMBLY_X86 == bWhat)\r
2066 {\r
2067 fprintf(fp, " mov [cyclesRemaining], edi\n");\r
2068 fprintf(fp, " mov edi, [_z80IoRead] ; Point to the read array\n\n", cpubasename);\r
2069 fprintf(fp, "checkLoop%ld:\n", dwGlobalLabel);\r
2070 fprintf(fp, " cmp [edi], word 0ffffh ; End of the list?\n");\r
2071 fprintf(fp, " je ioRead%ld\n", dwGlobalLabel);\r
2072 fprintf(fp, " cmp %s, [edi] ; Are we smaller?\n", pszIoAddress);\r
2073 fprintf(fp, " jb nextAddr%ld ; Yes, go to the next address\n", dwGlobalLabel);\r
2074 fprintf(fp, " cmp %s, [edi+2] ; Are we bigger?\n", pszIoAddress);\r
2075 fprintf(fp, " jbe callRoutine%ld\n\n", dwGlobalLabel);\r
2076 fprintf(fp, "nextAddr%ld:\n", dwGlobalLabel);\r
2077 fprintf(fp, " add edi, 0ch ; Next structure!\n");\r
2078 fprintf(fp, " jmp short checkLoop%ld\n\n", dwGlobalLabel);\r
2079 fprintf(fp, "callRoutine%ld:\n", dwGlobalLabel);\r
2080\r
2081 if (strcmp(pszIoAddress, "dx") != 0)\r
2082 fprintf(fp, " mov dx, %s ; Get our address\n", pszIoAddress);\r
2083\r
2084 fprintf(fp, " call ReadIOByte ; Standard read routine\n");\r
2085\r
2086 // Yes, these are intentionally reversed!\r
2087 \r
2088 if (strcmp(pszTarget, "al") == 0)\r
2089 fprintf(fp, " mov [_z80af], al ; Save our new accumulator\n");\r
2090 else\r
2091 if (strcmp(pszTarget, "ah") == 0)\r
2092 fprintf(fp, " mov [_z80af + 1], ah ; Save our new flags\n");\r
2093 else\r
2094 if (strcmp(pszTarget, "dl") == 0)\r
2095 fprintf(fp, " mov [_z80de], al ; Put it in E\n");\r
2096 else\r
2097 if (strcmp(pszTarget, "dh") == 0)\r
2098 fprintf(fp, " mov [_z80de + 1], al ; Put it in D\n");\r
2099 else\r
2100 if (strcmp(pszTarget, "*dl") == 0)\r
2101 fprintf(fp, " mov dl, al ; Put it in DL for later consumption\n");\r
2102 else\r
2103 fprintf(fp, " mov %s, al ; Put our returned value here\n", pszTarget);\r
2104\r
2105 // And are properly restored HERE:\r
2106\r
2107 fprintf(fp, " mov ax, [_z80af] ; Get our AF back\n");\r
2108\r
2109 // Restore registers here...\r
2110\r
2111 fprintf(fp, " jmp short readExit%ld\n\n", dwGlobalLabel);\r
2112 fprintf(fp, "ioRead%ld:\n", dwGlobalLabel);\r
2113 \r
2114 if (strcmp(pszTarget, "*dl") == 0)\r
2115 fprintf(fp, " mov dl, 0ffh ; An unreferenced read\n");\r
2116 else\r
2117 fprintf(fp, " mov %s, 0ffh ; An unreferenced read\n", pszTarget);\r
2118 fprintf(fp, "readExit%ld:\n", dwGlobalLabel);\r
2119 fprintf(fp, " mov edi, [cyclesRemaining]\n");\r
2120 }\r
2121 else\r
2122 if (MZ80_C == bWhat)\r
2123 {\r
2124 fprintf(fp, " psIoRead = cpu.z80IoRead; /* Beginning of our handler */\n");\r
2125 fprintf(fp, " while (psIoRead->lowIoAddr != 0xffff)\n");\r
2126 fprintf(fp, " {\n");\r
2127 fprintf(fp, " if ((%s >= psIoRead->lowIoAddr) && (%s <= psIoRead->highIoAddr))\n", pszIoAddress, pszIoAddress);\r
2128 fprintf(fp, " {\n");\r
2129 fprintf(fp, " cpu.z80pc = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
2130 fprintf(fp, " %s = psIoRead->IOCall(%s, psIoRead);\n", pszTarget, pszIoAddress);\r
2131 fprintf(fp, " psIoRead = NULL;\n");\r
2132 fprintf(fp, " break;\n");\r
2133 fprintf(fp, " }\n");\r
2134 fprintf(fp, " ++psIoRead;\n");\r
2135 fprintf(fp, " }\n\n");\r
2136 fprintf(fp, " if (psIoRead)\n");\r
2137 fprintf(fp, " {\n");\r
2138 fprintf(fp, " %s = 0xff; /* Unclaimed I/O read */\n", pszTarget);\r
2139 fprintf(fp, " }\n\n");\r
2140 }\r
2141 else\r
2142 {\r
2143 assert(0);\r
2144 }\r
2145\r
2146 dwGlobalLabel++;\r
2147}\r
2148\r
2149// Basic instruction set area\r
2150\r
2151void MiscHandler(UINT32 dwOpcode)\r
2152{\r
2153 if (MZ80_ASSEMBLY_X86 == bWhat)\r
2154 {\r
2155 ProcBegin(dwOpcode);\r
2156\r
2157 if (dwOpcode == 0xe3)\r
2158 {\r
2159 if (bThroughCallHandler)\r
2160 {\r
2161 fprintf(fp, " call PopWord\n");\r
2162 fprintf(fp, " xchg bx, [_wordval]\n");\r
2163 fprintf(fp, " call PushWord\n");\r
2164 }\r
2165 else\r
2166 {\r
2167 fprintf(fp, " mov dx, word [_z80sp]\n");\r
2168 fprintf(fp, " xchg bx, [ebp+edx]\n");\r
2169 fprintf(fp, " xor edx, edx\n");\r
2170 }\r
2171 }\r
2172\r
2173 if (dwOpcode == 0x2a)\r
2174 {\r
2175 fprintf(fp, " mov dx, [esi] ; Get address to load\n");\r
2176 fprintf(fp, " add esi, 2 ; Skip over it so we don't execute it\n");\r
2177\r
2178 ReadWordFromMemory("dx", "bx");\r
2179 fprintf(fp, " xor edx, edx\n");\r
2180 }\r
2181\r
2182 if (dwOpcode == 0xfb)\r
2183 {\r
2184 fprintf(fp, " or dword [_z80iff], IFF1 ; Indicate interrupts are enabled now\n");\r
2185 fprintf(fp, " sub edi, 4 ; Takes 4 cycles!\n");\r
2186 fprintf(fp, " mov [dwEITiming], edi ; Snapshot our current timing\n");\r
2187 fprintf(fp, " mov [bEIExit], byte 1 ; Indicate we're exiting because of an EI\n");\r
2188 fprintf(fp, " xor edi, edi ; Force next instruction to exit\n");\r
2189 fprintf(fp, " mov dl, byte [esi] ; Get our next instruction\n");\r
2190 fprintf(fp, " inc esi ; Next PC\n");\r
2191 fprintf(fp, " jmp dword [z80regular+edx*4]\n\n");\r
2192 }\r
2193\r
2194 if (dwOpcode == 0xf9)\r
2195 fprintf(fp, " mov word [_z80sp], bx\n");\r
2196\r
2197 if (dwOpcode == 0xd9)\r
2198 {\r
2199 fprintf(fp, " mov [cyclesRemaining], edi\n");\r
2200 fprintf(fp, " mov di, [_z80de]\n");\r
2201 fprintf(fp, " xchg cx, [_z80bcprime]\n");\r
2202 fprintf(fp, " xchg di, [_z80deprime]\n");\r
2203 fprintf(fp, " xchg bx, [_z80hlprime]\n");\r
2204 fprintf(fp, " mov [_z80de], di\n");\r
2205 fprintf(fp, " mov edi, [cyclesRemaining]\n");\r
2206 }\r
2207\r
2208 if (dwOpcode == 0x76)\r
2209 {\r
2210 fprintf(fp, " mov dword [_z80halted], 1 ; We've halted the chip!\n");\r
2211 \r
2212 if (FALSE == bNoTiming)\r
2213 {\r
2214 fprintf(fp, " xor edi, edi\n");\r
2215 fprintf(fp, " mov [cyclesRemaining], edi\n");\r
2216 }\r
2217 \r
2218 fprintf(fp, " jmp noMoreExec\n");\r
2219 return;\r
2220 }\r
2221 \r
2222 if (dwOpcode == 0x3f)\r
2223 {\r
2224 fprintf(fp, " mov dl, ah\n");\r
2225 fprintf(fp, " and dl, 01h\n");\r
2226 fprintf(fp, " shl dl, 4\n");\r
2227 fprintf(fp, " xor ah, 01h\n");\r
2228 fprintf(fp, " and ah, 0edh\n");\r
2229 fprintf(fp, " or ah, dl\n");\r
2230 }\r
2231 \r
2232 if (dwOpcode == 0x37)\r
2233 {\r
2234 fprintf(fp, " or ah, 1\n");\r
2235 fprintf(fp, " and ah,0edh\n");\r
2236 }\r
2237 \r
2238 if (dwOpcode == 0x27)\r
2239 {\r
2240 fprintf(fp, " mov dh, ah\n");\r
2241 fprintf(fp, " and dh, 02ah\n");\r
2242 fprintf(fp, " test ah, 02h ; Were we doing a subtraction?\n");\r
2243 fprintf(fp, " jnz handleNeg ; Nope!\n");\r
2244 fprintf(fp, " sahf\n");\r
2245 fprintf(fp, " daa\n");\r
2246 fprintf(fp, " lahf\n");\r
2247 fprintf(fp, " jmp short endDaa\n");\r
2248 fprintf(fp, "handleNeg:\n");\r
2249 fprintf(fp, " sahf\n");\r
2250 fprintf(fp, " das\n");\r
2251 fprintf(fp, " lahf\n");\r
2252 fprintf(fp, "endDaa:\n");\r
2253 fprintf(fp, " and ah, 0d5h\n");\r
2254 fprintf(fp, " or ah, dh\n");\r
2255 fprintf(fp, " xor edx, edx\n");\r
2256 }\r
2257 \r
2258 if (dwOpcode == 0x08)\r
2259 {\r
2260 fprintf(fp, " xchg ah, al\n");\r
2261 fprintf(fp, " xchg ax, [_z80afprime]\n");\r
2262 fprintf(fp, " xchg ah, al\n");\r
2263 }\r
2264 \r
2265 if (dwOpcode == 0x07)\r
2266 {\r
2267 fprintf(fp, " sahf\n");\r
2268 fprintf(fp, " rol al, 1\n");\r
2269 fprintf(fp, " lahf\n");\r
2270 fprintf(fp, " and ah, 0edh\n");\r
2271 }\r
2272 \r
2273 if (dwOpcode == 0x0f)\r
2274 {\r
2275 fprintf(fp, " sahf\n");\r
2276 fprintf(fp, " ror al, 1\n");\r
2277 fprintf(fp, " lahf\n");\r
2278 fprintf(fp, " and ah, 0edh\n");\r
2279 }\r
2280 \r
2281 if (dwOpcode == 0xe9)\r
2282 {\r
2283 fprintf(fp, " mov si, bx\n");\r
2284 fprintf(fp, " and esi, 0ffffh\n");\r
2285 fprintf(fp, " add esi, ebp\n");\r
2286 }\r
2287 \r
2288 if (dwOpcode == 0xeb)\r
2289 fprintf(fp, " xchg [_z80de], bx ; Exchange DE & HL\n");\r
2290 \r
2291 if (dwOpcode == 0x2f)\r
2292 {\r
2293 fprintf(fp, " not al\n");\r
2294 fprintf(fp, " or ah, 012h ; N And H are now on!\n");\r
2295 }\r
2296 \r
2297 if (dwOpcode == 0x10) // DJNZ\r
2298 {\r
2299 fprintf(fp, " mov dl, [esi] ; Get our relative offset\n");\r
2300 fprintf(fp, " inc esi ; Next instruction, please!\n");\r
2301 fprintf(fp, " dec ch ; Decrement B\n");\r
2302 fprintf(fp, " jz noJump ; Don't take the jump if it's done!\n");\r
2303 fprintf(fp, "; Otherwise, take the jump\n");\r
2304 \r
2305 fprintf(fp, " sub edi, 5\n");\r
2306 \r
2307 fprintf(fp, " xchg eax, edx\n");\r
2308 fprintf(fp, " cbw\n");\r
2309 fprintf(fp, " xchg eax, edx\n");\r
2310 fprintf(fp, " sub esi, ebp\n");\r
2311 fprintf(fp, " add si, dx\n");\r
2312 fprintf(fp, " add esi, ebp\n");\r
2313 fprintf(fp, "noJump:\n");\r
2314 fprintf(fp, " xor edx, edx\n");\r
2315 }\r
2316 \r
2317 if (dwOpcode == 0x3a) // LD A,(xxxx)\r
2318 {\r
2319 fprintf(fp, " mov dx, [esi] ; Get our address\n");\r
2320 fprintf(fp, " add esi, 2 ; Skip past the address\n");\r
2321 ReadValueFromMemory("dx", "al");\r
2322 fprintf(fp, " xor edx, edx ; Make sure we don't hose things\n");\r
2323 }\r
2324 \r
2325 if (dwOpcode == 0xf3) // DI\r
2326 {\r
2327 fprintf(fp, " and dword [_z80iff], (~IFF1) ; Not in an interrupt\n");\r
2328 }\r
2329 \r
2330 FetchNextInstruction(dwOpcode);\r
2331 }\r
2332 else\r
2333 if (MZ80_C == bWhat)\r
2334 {\r
2335 if (dwOpcode == 0x76) // HALT!\r
2336 {\r
2337 fprintf(fp, " cpu.z80halted = 1;\n");\r
2338 fprintf(fp, " dwElapsedTicks += sdwCyclesRemaining;\n");\r
2339\r
2340 fprintf(fp, " sdwCyclesRemaining = 0;\n");\r
2341 }\r
2342 else\r
2343 if (dwOpcode == 0x2f) // CPL\r
2344 {\r
2345 fprintf(fp, " cpu.z80A ^= 0xff;\n");\r
2346 fprintf(fp, " cpu.z80F |= (Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");\r
2347 }\r
2348 else\r
2349 if (dwOpcode == 0xd9) // EXX\r
2350 {\r
2351 fprintf(fp, " dwTemp = cpu.z80DE;\n");\r
2352 fprintf(fp, " cpu.z80DE = cpu.z80deprime;\n");\r
2353 fprintf(fp, " cpu.z80deprime = dwTemp;\n");\r
2354\r
2355 fprintf(fp, " dwTemp = cpu.z80BC;\n");\r
2356 fprintf(fp, " cpu.z80BC = cpu.z80bcprime;\n");\r
2357 fprintf(fp, " cpu.z80bcprime = dwTemp;\n");\r
2358\r
2359 fprintf(fp, " dwTemp = cpu.z80HL;\n");\r
2360 fprintf(fp, " cpu.z80HL = cpu.z80hlprime;\n");\r
2361 fprintf(fp, " cpu.z80hlprime = dwTemp;\n");\r
2362 }\r
2363 else\r
2364 if (dwOpcode == 0xf9) // LD SP, HL\r
2365 {\r
2366 fprintf(fp, " cpu.z80sp = cpu.z80HL;\n");\r
2367 }\r
2368 else\r
2369 if (dwOpcode == 0x27) // DAA\r
2370 {\r
2371 fprintf(fp, " dwAddr = (((cpu.z80F & Z80_FLAG_CARRY) | \n");\r
2372 fprintf(fp, " ((cpu.z80F & Z80_FLAG_HALF_CARRY) >> 3) | \n");\r
2373 fprintf(fp, " ((cpu.z80F & Z80_FLAG_NEGATIVE) << 1)) << 8) | cpu.z80A;\n");\r
2374 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");\r
2375 fprintf(fp, " cpu.z80F |= (wDAATable[dwAddr] >> 8);\n");\r
2376 fprintf(fp, " cpu.z80A = wDAATable[dwAddr] & 0xff;\n");\r
2377 }\r
2378 else\r
2379 if (dwOpcode == 0x2a)\r
2380 {\r
2381 fprintf(fp, " dwAddr = *pbPC++;\n");\r
2382 fprintf(fp, " dwAddr |= ((UINT32) *pbPC++ << 8);\n");\r
2383 ReadWordFromMemory("dwAddr", "cpu.z80HL");\r
2384 }\r
2385 else\r
2386 if (dwOpcode == 0xe3) // EX (SP), HL\r
2387 {\r
2388 ReadWordFromMemory("cpu.z80sp", "dwAddr");\r
2389 WriteWordToMemory("cpu.z80sp", "cpu.z80HL");\r
2390 fprintf(fp, " cpu.z80HL = dwAddr;\n");\r
2391 }\r
2392 else\r
2393 if (dwOpcode == 0xe9) // JP (HL)\r
2394 {\r
2395 fprintf(fp, " pbPC = cpu.z80Base + cpu.z80HL;\n");\r
2396 }\r
2397 else\r
2398 if (0x08 == dwOpcode) // EX AF, AF'\r
2399 {\r
2400 fprintf(fp, " dwAddr = (UINT32) cpu.z80AF;\n");\r
2401 fprintf(fp, " cpu.z80AF = cpu.z80afprime;\n");\r
2402 fprintf(fp, " cpu.z80afprime = dwAddr;\n");\r
2403 }\r
2404 else\r
2405 if (0xeb == dwOpcode) // EX DE, HL\r
2406 {\r
2407 fprintf(fp, " dwAddr = cpu.z80DE;\n");\r
2408 fprintf(fp, " cpu.z80DE = cpu.z80HL;\n");\r
2409 fprintf(fp, " cpu.z80HL = dwAddr;\n");\r
2410 }\r
2411 else\r
2412 if (0x10 == dwOpcode) // DJNZ\r
2413 {\r
2414 fprintf(fp, " sdwAddr = (INT8) *pbPC++; /* Get LSB first */\n");\r
2415 fprintf(fp, " if (--cpu.z80B)\n");\r
2416 fprintf(fp, " {\n");\r
2417 fprintf(fp, " dwElapsedTicks += 5; /* 5 More for jump taken */\n");\r
2418 fprintf(fp, " cpu.z80pc = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
2419 fprintf(fp, " sdwAddr = (sdwAddr + (INT32) cpu.z80pc) & 0xffff;\n");\r
2420 fprintf(fp, " pbPC = cpu.z80Base + sdwAddr; /* Normalize the address */\n");\r
2421 fprintf(fp, " }\n");\r
2422 }\r
2423 else\r
2424 if (0x37 == dwOpcode) // SCF\r
2425 {\r
2426 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_NEGATIVE);\n");\r
2427 fprintf(fp, " cpu.z80F |= Z80_FLAG_CARRY;\n");\r
2428 }\r
2429 else\r
2430 if (0x3f == dwOpcode) // CCF\r
2431 {\r
2432 fprintf(fp, " bTemp = (cpu.z80F & Z80_FLAG_CARRY) << 4;\n");\r
2433 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_NEGATIVE);\n");\r
2434 fprintf(fp, " cpu.z80F ^= Z80_FLAG_CARRY;\n");\r
2435 }\r
2436 else\r
2437 if (0x07 == dwOpcode) // RLCA\r
2438 {\r
2439 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");\r
2440 fprintf(fp, " cpu.z80F |= (cpu.z80A >> 7);\n");\r
2441 fprintf(fp, " cpu.z80A = (cpu.z80A << 1) | (cpu.z80A >> 7);\n");\r
2442 }\r
2443 else\r
2444 if (0x0f == dwOpcode) // RRCA\r
2445 {\r
2446 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");\r
2447 fprintf(fp, " cpu.z80F |= (cpu.z80A & Z80_FLAG_CARRY);\n");\r
2448 fprintf(fp, " cpu.z80A = (cpu.z80A >> 1) | (cpu.z80A << 7);\n");\r
2449 }\r
2450 else\r
2451 if (0x3a == dwOpcode) // LD A, (xxxxh)\r
2452 {\r
2453 fprintf(fp, " dwTemp = *pbPC++;\n");\r
2454 fprintf(fp, " dwTemp |= (((UINT32) *pbPC++) << 8);\n");\r
2455 ReadValueFromMemory("dwTemp", "cpu.z80A");\r
2456 }\r
2457 else\r
2458 if (0xf3 == dwOpcode) // DI\r
2459 {\r
2460 fprintf(fp, " cpu.z80iff &= (~IFF1);\n");\r
2461 }\r
2462 else\r
2463 if (0xfb == dwOpcode) // EI\r
2464 {\r
2465 fprintf(fp, " cpu.z80iff |= IFF1;\n");\r
2466 }\r
2467 else\r
2468 if (0x00 == dwOpcode) // NOP\r
2469 {\r
2470 fprintf(fp, " /* Intentionally not doing anything - NOP! */\n");\r
2471 }\r
2472 else\r
2473 {\r
2474 InvalidInstructionC(1);\r
2475 }\r
2476 }\r
2477 else\r
2478 {\r
2479 assert(0);\r
2480 }\r
2481 \r
2482}\r
2483\r
2484void LdRegPairImmediate(UINT32 dwOpcode)\r
2485{\r
2486 UINT8 bOp = 0;\r
2487\r
2488 bOp = (dwOpcode >> 4) & 0x3;\r
2489\r
2490 if (MZ80_ASSEMBLY_X86 == bWhat)\r
2491 {\r
2492 ProcBegin(dwOpcode);\r
2493\r
2494 if (bOp == 0)\r
2495 fprintf(fp, " mov cx, [esi] ; Get our immediate value of BC\n");\r
2496 else\r
2497 if (bOp == 2)\r
2498 fprintf(fp, " mov bx, [esi] ; Get our immediate value of HL\n");\r
2499 else\r
2500 if (bOp == 1)\r
2501 {\r
2502 fprintf(fp, " mov dx, [esi] ; Get our immediate value of DE\n");\r
2503 fprintf(fp, " mov word [_z80de], dx ; Store DE\n");\r
2504 fprintf(fp, " xor edx, edx\n");\r
2505 }\r
2506 else\r
2507 if (bOp == 3)\r
2508 {\r
2509 fprintf(fp, " mov dx, [esi] ; Get our immediate value of SP\n");\r
2510 fprintf(fp, " mov word [_z80sp], dx ; Store it!\n");\r
2511 fprintf(fp, " xor edx, edx\n");\r
2512 }\r
2513 \r
2514 fprintf(fp, " add esi, 2\n");\r
2515 FetchNextInstruction(dwOpcode);\r
2516 }\r
2517 else\r
2518 if (MZ80_C == bWhat)\r
2519 {\r
2520 fprintf(fp, " %s = *pbPC++; /* LSB First */\n", pbRegPairC[bOp]);\r
2521 fprintf(fp, " %s |= (((UINT32) *pbPC++ << 8)); /* Now the MSB */\n", pbRegPairC[bOp]);\r
2522 }\r
2523 else\r
2524 {\r
2525 assert(0);\r
2526 }\r
2527}\r
2528\r
2529void LdRegpairPtrByte(UINT32 dwOpcode)\r
2530{\r
2531 if (MZ80_ASSEMBLY_X86 == bWhat)\r
2532 {\r
2533 ProcBegin(dwOpcode);\r
2534\r
2535 if (dwOpcode == 0x36) // Immediate into (HL)\r
2536 WriteValueToMemory("bx", "[esi]");\r
2537\r
2538 if (dwOpcode == 0x12)\r
2539 WriteValueToMemory("[_z80de]", "al"); // (DE), A\r
2540\r
2541 if (dwOpcode == 0x2) // (BC), A\r
2542 WriteValueToMemory("cx", "al");\r
2543\r
2544 if (dwOpcode >= 0x70 && dwOpcode < 0x78)\r
2545 WriteValueToMemory("bx", pbMathReg[dwOpcode & 0x07]);\r
2546\r
2547 fprintf(fp, " xor edx, edx\n");\r
2548 FetchNextInstruction(dwOpcode);\r
2549 }\r
2550 else\r
2551 if (MZ80_C == bWhat)\r
2552 {\r
2553 if (dwOpcode == 0x36)\r
2554 WriteValueToMemory("cpu.z80HL", "*pbPC++");\r
2555\r
2556 if (dwOpcode == 0x12)\r
2557 WriteValueToMemory("cpu.z80DE", "cpu.z80A");\r
2558\r
2559 if (dwOpcode == 0x02)\r
2560 WriteValueToMemory("cpu.z80BC", "cpu.z80A");\r
2561\r
2562 if (dwOpcode >= 0x70 && dwOpcode < 0x78)\r
2563 WriteValueToMemory("cpu.z80HL", pbMathRegC[dwOpcode & 0x07]);\r
2564 }\r
2565 else\r
2566 {\r
2567 assert(0);\r
2568 }\r
2569}\r
2570\r
2571void MathOperation(UINT32 dwOrgOpcode)\r
2572{\r
2573 UINT8 bRegister;\r
2574 UINT32 dwOpcode;\r
2575 UINT8 tempstr[150];\r
2576\r
2577 if (MZ80_ASSEMBLY_X86 == bWhat)\r
2578 {\r
2579 ProcBegin(dwOrgOpcode);\r
2580\r
2581 dwOpcode = dwOrgOpcode;\r
2582 bRegister = dwOpcode & 0x07;\r
2583 dwOpcode &= 0xf8;\r
2584\r
2585 if (dwOpcode == 0x80)\r
2586 strcpy(tempstr, "add");\r
2587 if (dwOpcode == 0x88)\r
2588 strcpy(tempstr, "adc");\r
2589 if (dwOpcode == 0x90)\r
2590 strcpy(tempstr, "sub");\r
2591 if (dwOpcode == 0x98)\r
2592 strcpy(tempstr, "sbb");\r
2593 if (dwOpcode == 0xa0)\r
2594 strcpy(tempstr, "and");\r
2595 if (dwOpcode == 0xa8)\r
2596 strcpy(tempstr, "xor");\r
2597 if (dwOpcode == 0xb0)\r
2598 strcpy(tempstr, "or");\r
2599 if (dwOpcode == 0xb8)\r
2600 strcpy(tempstr, "cmp");\r
2601 \r
2602 // Let's see if we have to deal with (HL) or #xxh\r
2603 \r
2604 if (bRegister == 0x6)\r
2605 {\r
2606 // We have to deal with (HL)\r
2607 \r
2608 ReadValueFromMemory("bx", "dl");\r
2609 }\r
2610 \r
2611 if (bRegister != 0x06 && bRegister < 0xff)\r
2612 {\r
2613 fprintf(fp, " sahf\n");\r
2614 fprintf(fp, " %s al, %s\n", tempstr, pbMathReg[bRegister]);\r
2615 fprintf(fp, " lahf\n");\r
2616 }\r
2617 else // If it's (HL)....\r
2618 {\r
2619 fprintf(fp, " sahf\n");\r
2620 fprintf(fp, " %s al, dl\n", tempstr);\r
2621 fprintf(fp, " lahf\n");\r
2622 }\r
2623 \r
2624 if (dwOpcode != 0xa8 && dwOpcode != 0xa0 && dwOpcode != 0xb0)\r
2625 SetOverflow();\r
2626 \r
2627 if (dwOpcode == 0xa8)\r
2628 fprintf(fp, " and ah, 0ech ; Only these flags matter!\n");\r
2629 \r
2630 if (dwOpcode == 0xa0)\r
2631 {\r
2632 fprintf(fp, " and ah, 0ech ; Only these flags matter!\n");\r
2633 fprintf(fp, " or ah, 010h ; Half carry gets set\n");\r
2634 }\r
2635 \r
2636 if (dwOpcode == 0xb0)\r
2637 fprintf(fp, " and ah, 0ech ; No H, N, or C\n");\r
2638 \r
2639 if (dwOpcode == 0xb8)\r
2640 fprintf(fp, " or ah, 02h ; Set N for compare!\n");\r
2641 \r
2642 if (dwOpcode == 0x80 || dwOpcode == 0x88)\r
2643 fprintf(fp, " and ah, 0fdh ; No N!\n");\r
2644 \r
2645 if (dwOpcode == 0x90 || dwOpcode == 0x98)\r
2646 fprintf(fp, " or ah, 02h ; N Gets set!\n");\r
2647\r
2648 if (bRegister == 0x6)\r
2649 fprintf(fp, " xor edx, edx ; Zero this...\n");\r
2650 \r
2651 FetchNextInstruction(dwOrgOpcode);\r
2652 }\r
2653 else\r
2654 if (MZ80_C == bWhat)\r
2655 {\r
2656 dwOpcode = dwOrgOpcode;\r
2657 bRegister = dwOpcode & 0x07;\r
2658 dwOpcode &= 0xf8;\r
2659\r
2660 if (6 == bRegister) // Deal with (HL)\r
2661 {\r
2662 ReadValueFromMemory("cpu.z80HL", "bTemp");\r
2663 }\r
2664\r
2665 if (dwOpcode == 0xa0)\r
2666 {\r
2667 fprintf(fp, " cpu.z80A &= %s;\n", pbMathRegC[bRegister]);\r
2668 }\r
2669 else\r
2670 if (dwOpcode == 0xa8)\r
2671 {\r
2672 fprintf(fp, " cpu.z80A ^= %s;\n", pbMathRegC[bRegister]);\r
2673 }\r
2674 else\r
2675 if (dwOpcode == 0xb0)\r
2676 {\r
2677 fprintf(fp, " cpu.z80A |= %s;\n", pbMathRegC[bRegister]);\r
2678 }\r
2679 else\r
2680 if (dwOpcode == 0xb8)\r
2681 {\r
2682 // Don't do anything. We just do flags!\r
2683 }\r
2684 else\r
2685 if (dwOpcode == 0x88) // ADC\r
2686 {\r
2687 fprintf(fp, " bTemp2 = cpu.z80A + %s + (cpu.z80F & Z80_FLAG_CARRY);\n", pbMathRegC[bRegister]);\r
2688 }\r
2689 else\r
2690 if (dwOpcode == 0x90) // SUB\r
2691 {\r
2692 fprintf(fp, " bTemp2 = cpu.z80A - %s;\n", pbMathRegC[bRegister]);\r
2693 } \r
2694 else\r
2695 if (dwOpcode == 0x80) // ADD\r
2696 {\r
2697 fprintf(fp, " bTemp2 = cpu.z80A + %s;\n", pbMathRegC[bRegister]);\r
2698 }\r
2699 else\r
2700 if (dwOpcode == 0x98) // SBC\r
2701 {\r
2702 fprintf(fp, " bTemp2 = cpu.z80A - %s - (cpu.z80F & Z80_FLAG_CARRY);\n", pbMathRegC[bRegister]);\r
2703 }\r
2704 else\r
2705 {\r
2706 InvalidInstructionC(1);\r
2707 }\r
2708\r
2709 // Now do flag fixup\r
2710\r
2711 if (0xb0 == dwOpcode || 0xa8 == dwOpcode)\r
2712 {\r
2713 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");\r
2714 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");\r
2715 }\r
2716\r
2717 if (0xa0 == dwOpcode)\r
2718 {\r
2719 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");\r
2720 fprintf(fp, " cpu.z80F |= bPostANDFlags[cpu.z80A];\n\n");\r
2721 }\r
2722\r
2723 if (0xb8 == dwOpcode || 0x90 == dwOpcode)\r
2724 {\r
2725 SetSubFlagsSZHVC("cpu.z80A", pbMathRegC[bRegister]);\r
2726\r
2727 if (0x90 == dwOpcode)\r
2728 {\r
2729 fprintf(fp, " cpu.z80A = bTemp2;\n");\r
2730 }\r
2731 }\r
2732\r
2733 if (0x80 == dwOpcode) // Add fixup\r
2734 {\r
2735 SetAddFlagsSZHVC("cpu.z80A", pbMathRegC[bRegister]);\r
2736 fprintf(fp, " cpu.z80A = bTemp2;\n");\r
2737 }\r
2738\r
2739 if (0x88 == dwOpcode) // Adc fixup\r
2740 {\r
2741 SetAdcFlagsSZHVC("cpu.z80A", pbMathRegC[bRegister]);\r
2742 fprintf(fp, " cpu.z80A = bTemp2;\n");\r
2743 }\r
2744\r
2745 if (0x98 == dwOpcode) // Sbc fixup\r
2746 {\r
2747 SetSbcFlagsSZHVC("cpu.z80A", pbMathRegC[bRegister]);\r
2748 fprintf(fp, " cpu.z80A = bTemp2;\n");\r
2749 }\r
2750 }\r
2751 else\r
2752 {\r
2753 assert(0);\r
2754 }\r
2755}\r
2756\r
2757void RegIntoMemory(UINT32 dwOpcode)\r
2758{\r
2759 if (MZ80_ASSEMBLY_X86 == bWhat)\r
2760 {\r
2761 ProcBegin(dwOpcode);\r
2762\r
2763 fprintf(fp, " mov dx, [esi] ; Get our address to write to\n");\r
2764 fprintf(fp, " add esi, 2 ; Next address, please...\n");\r
2765\r
2766 if (0x32 == dwOpcode) // LD (xxxx), A\r
2767 WriteValueToMemory("dx", "al");\r
2768 if (0x22 == dwOpcode) // LD (xxxx), HL\r
2769 {\r
2770 WriteWordToMemory("dx", "bx");\r
2771 }\r
2772\r
2773 fprintf(fp, " xor edx, edx ; Zero our upper byte\n");\r
2774\r
2775 FetchNextInstruction(dwOpcode);\r
2776 }\r
2777 else\r
2778 if (MZ80_C == bWhat)\r
2779 {\r
2780 fprintf(fp, " dwTemp = *pbPC++;\n");\r
2781 fprintf(fp, " dwTemp |= ((UINT32) *pbPC++ << 8);\n");\r
2782\r
2783 if (0x32 == dwOpcode)\r
2784 WriteValueToMemory("dwTemp", "cpu.z80A");\r
2785 if (0x22 == dwOpcode)\r
2786 WriteWordToMemory("dwTemp", "cpu.z80HL");\r
2787\r
2788 return;\r
2789 }\r
2790 else\r
2791 {\r
2792 assert(0);\r
2793 }\r
2794}\r
2795\r
2796void JpHandler(UINT32 dwOpcode)\r
2797{\r
2798 if (MZ80_ASSEMBLY_X86 == bWhat)\r
2799 {\r
2800 ProcBegin(dwOpcode);\r
2801\r
2802 if (0xc3 == dwOpcode) // If it's a straight jump...\r
2803 {\r
2804 fprintf(fp, " mov si, [esi] ; Get our new address\n");\r
2805 fprintf(fp, " and esi, 0ffffh ; Only the lower 16 bits\n");\r
2806 fprintf(fp, " add esi, ebp ; Our new address!\n");\r
2807 }\r
2808 else // It's a conditional handler...\r
2809 {\r
2810 fprintf(fp, " sahf ; Restore our flags\n");\r
2811 fprintf(fp, " j%s takeJump%ld ; We're going to take a jump\n", pbFlags[(dwOpcode >> 3) & 0x07], dwGlobalLabel);\r
2812 fprintf(fp, " add esi, 2 ; Skip past the address\n");\r
2813 fprintf(fp, " jmp short nextInst%ld ; Go execute the next instruction\n", dwGlobalLabel);\r
2814 fprintf(fp, "takeJump%ld:\n", dwGlobalLabel);\r
2815 \r
2816 fprintf(fp, " mov si, [esi] ; Get our new offset\n");\r
2817 fprintf(fp, " and esi, 0ffffh ; Only the lower WORD is valid\n");\r
2818 fprintf(fp, " add esi, ebp ; Our new address!\n");\r
2819 fprintf(fp, "nextInst%ld:\n", dwGlobalLabel);\r
2820 ++dwGlobalLabel;\r
2821 }\r
2822 \r
2823 FetchNextInstruction(dwOpcode);\r
2824 }\r
2825 else\r
2826 if (MZ80_C == bWhat)\r
2827 {\r
2828 fprintf(fp, " dwAddr = *pbPC++; /* Get LSB first */\n");\r
2829 fprintf(fp, " dwAddr |= ((UINT32) *pbPC++ << 8); /* Get MSB last */\n");\r
2830\r
2831 if (0xc3 != dwOpcode)\r
2832 {\r
2833 fprintf(fp, " if %s\n", pbFlagsC[(dwOpcode >> 3) & 0x07]);\r
2834 fprintf(fp, " {\n");\r
2835 fprintf(fp, " pbPC = cpu.z80Base + dwAddr; /* Normalize the address */\n");\r
2836 fprintf(fp, " }\n");\r
2837 }\r
2838 else // Regular jump here\r
2839 {\r
2840 fprintf(fp, " pbPC = cpu.z80Base + dwAddr; /* Normalize the address */\n");\r
2841 }\r
2842 }\r
2843 else\r
2844 {\r
2845 assert(0);\r
2846 }\r
2847}\r
2848\r
2849void LdRegImmediate(UINT32 dwOpcode)\r
2850{\r
2851 UINT8 bOp;\r
2852\r
2853 bOp = (dwOpcode >> 3) & 0x7;\r
2854\r
2855 if (MZ80_ASSEMBLY_X86 == bWhat)\r
2856 {\r
2857 ProcBegin(dwOpcode);\r
2858\r
2859\r
2860 if (bOp != 2 && bOp != 3)\r
2861 fprintf(fp, " mov %s, [esi] ; Get our immediate value\n", pbMathReg[bOp]);\r
2862 else\r
2863 {\r
2864 fprintf(fp, " mov dl, [esi] ; Get our immediate value\n");\r
2865 fprintf(fp, " mov %s, dl ; Store our new value\n", pbMathReg[bOp]);\r
2866 }\r
2867 \r
2868 fprintf(fp, " inc esi\n");\r
2869 \r
2870 FetchNextInstruction(dwOpcode);\r
2871 }\r
2872 else\r
2873 if (MZ80_C == bWhat)\r
2874 {\r
2875 fprintf(fp, " %s = *pbPC++; /* Get immediate byte into register */\n", pbMathRegC[bOp]);\r
2876 }\r
2877 else\r
2878 {\r
2879 assert(0);\r
2880 }\r
2881}\r
2882\r
2883void IncRegister(UINT32 dwOpcode)\r
2884{\r
2885 UINT32 dwOpcode1 = 0;\r
2886\r
2887 dwOpcode1 = (dwOpcode >> 3) & 0x07;\r
2888\r
2889 if (MZ80_ASSEMBLY_X86 == bWhat)\r
2890 {\r
2891 ProcBegin(dwOpcode);\r
2892\r
2893 fprintf(fp, " sahf\n");\r
2894 fprintf(fp, " inc %s\n", pbMathReg[dwOpcode1]);\r
2895 fprintf(fp, " lahf\n");\r
2896 SetOverflow();\r
2897 fprintf(fp, " and ah, 0fdh ; Knock out N!\n");\r
2898\r
2899 FetchNextInstruction(dwOpcode);\r
2900 }\r
2901 else\r
2902 if (MZ80_C == bWhat)\r
2903 {\r
2904 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");\r
2905 fprintf(fp ," cpu.z80F |= bPostIncFlags[%s++];\n", pbMathRegC[dwOpcode1]);\r
2906 }\r
2907 else\r
2908 {\r
2909 assert(0);\r
2910 }\r
2911}\r
2912\r
2913void DecRegister(UINT32 dwOpcode)\r
2914{\r
2915 UINT32 dwOpcode1 = 0;\r
2916\r
2917 dwOpcode1 = (dwOpcode >> 3) & 0x07;\r
2918\r
2919 if (MZ80_ASSEMBLY_X86 == bWhat)\r
2920 {\r
2921 ProcBegin(dwOpcode);\r
2922\r
2923 fprintf(fp, " sahf\n");\r
2924 fprintf(fp, " dec %s\n", pbMathReg[dwOpcode1]);\r
2925 fprintf(fp, " lahf\n");\r
2926 SetOverflow();\r
2927 fprintf(fp, " or ah, 02h ; Set negative!\n");\r
2928\r
2929 FetchNextInstruction(dwOpcode);\r
2930 }\r
2931 else\r
2932 if (MZ80_C == bWhat)\r
2933 {\r
2934 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY);\n");\r
2935 fprintf(fp ," cpu.z80F |= bPostDecFlags[%s--];\n", pbMathRegC[dwOpcode1]);\r
2936 }\r
2937 else\r
2938 {\r
2939 assert(0);\r
2940 }\r
2941}\r
2942\r
2943void IncDecRegpair(UINT32 dwOpcode)\r
2944{\r
2945 UINT32 dwOpcode1 = 0;\r
2946\r
2947 if (MZ80_ASSEMBLY_X86 == bWhat)\r
2948 {\r
2949 ProcBegin(dwOpcode);\r
2950\r
2951 if ((dwOpcode & 0x0f) == 3) // Increment?\r
2952 fprintf(fp, " inc %s\n", pbRegPairs[(dwOpcode >> 4) & 0x03]);\r
2953 else\r
2954 fprintf(fp, " dec %s\n", pbRegPairs[(dwOpcode >> 4) & 0x03]);\r
2955\r
2956 FetchNextInstruction(dwOpcode);\r
2957 }\r
2958 else\r
2959 if (MZ80_C == bWhat)\r
2960 {\r
2961 if ((dwOpcode & 0x0f) == 3) // Increment\r
2962 fprintf(fp, " %s++;\n", pbRegPairC[(dwOpcode >> 4) & 0x03]);\r
2963 else\r
2964 fprintf(fp, " %s--;\n", pbRegPairC[(dwOpcode >> 4) & 0x03]);\r
2965 fprintf(fp, " %s &= 0xffff;\n", pbRegPairC[(dwOpcode >> 4) & 0x03]);\r
2966 }\r
2967 else\r
2968 {\r
2969 assert(0);\r
2970 }\r
2971}\r
2972\r
2973void LdRegReg(UINT32 dwOpcode)\r
2974{\r
2975 UINT8 bDestination;\r
2976 UINT8 bSource;\r
2977\r
2978 bDestination = (dwOpcode >> 3) & 0x07;\r
2979 bSource = (dwOpcode) & 0x07;\r
2980\r
2981 if (MZ80_ASSEMBLY_X86 == bWhat)\r
2982 {\r
2983\r
2984 ProcBegin(dwOpcode);\r
2985 \r
2986 if (bSource != bDestination)\r
2987 {\r
2988 if (bSource == 2 && bDestination == 3)\r
2989 {\r
2990 fprintf(fp, " mov dl, byte [_z80de + 1]\n");\r
2991 fprintf(fp, " mov [_z80de], dl\n");\r
2992 }\r
2993 else\r
2994 if (bSource == 3 && bDestination == 2)\r
2995 {\r
2996 fprintf(fp, " mov dl, byte [_z80de]\n");\r
2997 fprintf(fp, " mov [_z80de + 1], dl\n");\r
2998 }\r
2999 else\r
3000 fprintf(fp, " mov %s, %s\n", pbMathReg[bDestination], pbMathReg[bSource]);\r
3001 }\r
3002 \r
3003 FetchNextInstruction(dwOpcode);\r
3004 }\r
3005 else\r
3006 if (MZ80_C == bWhat)\r
3007 {\r
3008 if (bDestination != bSource)\r
3009 {\r
3010 fprintf(fp, " %s = %s;\n",\r
3011 pbMathRegC[bDestination],\r
3012 pbMathRegC[bSource]);\r
3013 }\r
3014 }\r
3015 else\r
3016 {\r
3017 assert(0);\r
3018 }\r
3019}\r
3020\r
3021void MathOperationDirect(UINT32 dwOpcode)\r
3022{\r
3023 UINT8 tempstr[4];\r
3024\r
3025 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3026 {\r
3027 if (dwOpcode == 0xc6)\r
3028 strcpy(tempstr, "add");\r
3029 if (dwOpcode == 0xce)\r
3030 strcpy(tempstr, "adc");\r
3031 if (dwOpcode == 0xd6)\r
3032 strcpy(tempstr, "sub");\r
3033 if (dwOpcode == 0xde)\r
3034 strcpy(tempstr, "sbb");\r
3035 if (dwOpcode == 0xe6)\r
3036 strcpy(tempstr, "and");\r
3037 if (dwOpcode == 0xee)\r
3038 strcpy(tempstr, "xor");\r
3039 if (dwOpcode == 0xf6)\r
3040 strcpy(tempstr, "or");\r
3041 if (dwOpcode == 0xfe)\r
3042 strcpy(tempstr, "cmp");\r
3043 \r
3044 ProcBegin(dwOpcode);\r
3045 \r
3046 // Let's see if we have to deal with (HL) or #xxh\r
3047 \r
3048 fprintf(fp, " sahf\n");\r
3049 fprintf(fp, " %s al, [esi]\n", tempstr);\r
3050 fprintf(fp, " lahf\n");\r
3051 \r
3052 if (dwOpcode != 0xee && dwOpcode != 0xe6 && dwOpcode != 0xf6)\r
3053 {\r
3054 SetOverflow();\r
3055 }\r
3056 \r
3057 if (dwOpcode == 0xe6)\r
3058 {\r
3059 fprintf(fp, " and ah, 0ech ; Only parity, half carry, sign, zero\n");\r
3060 fprintf(fp, " or ah, 10h ; Half carry\n");\r
3061 }\r
3062 \r
3063 if (dwOpcode == 0xc6 || dwOpcode == 0xce)\r
3064 fprintf(fp, " and ah, 0fdh ; Knock out N!\n");\r
3065 \r
3066 if (dwOpcode == 0xd6 || dwOpcode == 0xde || dwOpcode == 0xfe)\r
3067 fprintf(fp, " or ah, 02h ; Set negative!\n");\r
3068\r
3069 if (dwOpcode == 0xf6 || dwOpcode == 0xee)\r
3070 fprintf(fp, " and ah, 0ech ; No H, N, or C\n");\r
3071 \r
3072 fprintf(fp, " inc esi\n");\r
3073 \r
3074 FetchNextInstruction(dwOpcode);\r
3075 }\r
3076 else\r
3077 if (MZ80_C == bWhat)\r
3078 {\r
3079 if (0xfe == dwOpcode) // Cp\r
3080 {\r
3081 SetSubFlagsSZHVC("cpu.z80A", "*pbPC++");\r
3082 }\r
3083 else\r
3084 if (0xe6 == dwOpcode) // And\r
3085 {\r
3086 fprintf(fp, " cpu.z80A &= *pbPC++;\n");\r
3087 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");\r
3088 fprintf(fp, " cpu.z80F |= bPostANDFlags[cpu.z80A];\n\n");\r
3089 }\r
3090 else\r
3091 if (0xf6 == dwOpcode) // Or\r
3092 {\r
3093 fprintf(fp, " cpu.z80A |= *pbPC++;\n");\r
3094 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");\r
3095 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");\r
3096 }\r
3097 else\r
3098 if (0xc6 == dwOpcode) // Add\r
3099 {\r
3100 fprintf(fp, " bTemp = *pbPC++;\n");\r
3101 SetAddFlagsSZHVC("cpu.z80A", "bTemp");\r
3102 fprintf(fp, " cpu.z80A += bTemp;\n");\r
3103 }\r
3104 else\r
3105 if (0xce == dwOpcode) // Adc\r
3106 {\r
3107 fprintf(fp, " bTemp = *pbPC++ + (cpu.z80F & Z80_FLAG_CARRY);\n");\r
3108 SetAdcFlagsSZHVC("cpu.z80A", "bTemp");\r
3109 fprintf(fp, " cpu.z80A += bTemp;\n");\r
3110 }\r
3111 else\r
3112 if (0xd6 == dwOpcode) // Sub\r
3113 {\r
3114 fprintf(fp, " bTemp = *pbPC++;\n");\r
3115 SetSubFlagsSZHVC("cpu.z80A", "bTemp");\r
3116 fprintf(fp, " cpu.z80A -= bTemp;\n");\r
3117 }\r
3118 else\r
3119 if (0xde == dwOpcode) // Sbc\r
3120 {\r
3121 fprintf(fp, " bTemp = *pbPC++ + (cpu.z80F & Z80_FLAG_CARRY);\n");\r
3122 SetSbcFlagsSZHVC("cpu.z80A", "bTemp");\r
3123 fprintf(fp, " cpu.z80A = cpu.z80A - bTemp;\n");\r
3124 }\r
3125 else\r
3126 if (0xee == dwOpcode) // Xor\r
3127 {\r
3128 fprintf(fp, " cpu.z80A ^= *pbPC++;\n");\r
3129 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");\r
3130 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");\r
3131 }\r
3132 else\r
3133 InvalidInstructionC(1);\r
3134 }\r
3135 else\r
3136 {\r
3137 assert(0);\r
3138 }\r
3139}\r
3140\r
3141// JR cc, addr\r
3142\r
3143void JrHandler(UINT32 dwOpcode)\r
3144{\r
3145 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3146 {\r
3147 ProcBegin(dwOpcode);\r
3148 \r
3149 fprintf(fp, " sub esi, ebp\n");\r
3150 fprintf(fp, " and esi, 0ffffh\n");\r
3151 fprintf(fp, " add esi, ebp\n");\r
3152\r
3153 fprintf(fp, " mov dl, [esi] ; Get our relative offset\n");\r
3154 fprintf(fp, " inc esi ; Next instruction, please!\n");\r
3155\r
3156 if (dwOpcode != 0x18)\r
3157 {\r
3158 fprintf(fp, " sahf\n");\r
3159 fprintf(fp, " j%s takeJump%ld\n", pbFlags[(dwOpcode >> 3) & 0x3], dwGlobalLabel);\r
3160 fprintf(fp, " jmp short noJumpMan%ld\n", dwGlobalLabel);\r
3161 fprintf(fp, "takeJump%ld:\n", dwGlobalLabel);\r
3162\r
3163 if (FALSE == bNoTiming)\r
3164 {\r
3165 fprintf(fp, " sub edi, 5\n");\r
3166 }\r
3167 }\r
3168 else // It's a JR\r
3169 {\r
3170 fprintf(fp, " cmp dl, 0feh ; Jump to self?\n");\r
3171 fprintf(fp, " je yesJrMan ; Yup! Bail out!\n");\r
3172 }\r
3173 \r
3174 fprintf(fp, " xchg eax, edx\n");\r
3175 fprintf(fp, " cbw\n");\r
3176 fprintf(fp, " xchg eax, edx\n");\r
3177 fprintf(fp, " sub esi, ebp\n");\r
3178 fprintf(fp, " add si, dx\n");\r
3179 fprintf(fp, " and esi, 0ffffh ; Only the lower 16 bits\n");\r
3180 fprintf(fp, " add esi, ebp\n");\r
3181 fprintf(fp, " xor dh, dh\n");\r
3182 fprintf(fp, "noJumpMan%ld:\n", dwGlobalLabel++);\r
3183\r
3184 FetchNextInstruction(dwOpcode);\r
3185 \r
3186 if (0x18 == dwOpcode)\r
3187 {\r
3188 fprintf(fp,"yesJrMan:\n");\r
3189\r
3190 fprintf(fp, " xor edx, edx ; Zero me for later\n");\r
3191 fprintf(fp, " mov edi, edx\n");\r
3192 fprintf(fp, " mov [cyclesRemaining], edx\n");\r
3193 fprintf(fp, " sub esi, 2 ; Back to the instruction again\n");\r
3194 fprintf(fp, " jmp noMoreExec\n\n");\r
3195 }\r
3196 }\r
3197 else\r
3198 if (MZ80_C == bWhat)\r
3199 {\r
3200 fprintf(fp, " sdwAddr = (INT8) *pbPC++; /* Get LSB first */\n");\r
3201 fprintf(fp, " cpu.z80pc = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
3202 fprintf(fp, " sdwAddr = (sdwAddr + (INT32) cpu.z80pc) & 0xffff;\n");\r
3203\r
3204 if (0x18 != dwOpcode)\r
3205 {\r
3206 fprintf(fp, " if %s\n", pbFlagsC[(dwOpcode >> 3) & 0x03]);\r
3207 }\r
3208\r
3209 fprintf(fp, " {\n");\r
3210\r
3211 fprintf(fp, " sdwCyclesRemaining -= 5;\n");\r
3212\r
3213 fprintf(fp, " pbPC = cpu.z80Base + sdwAddr; /* Normalize the address */\n");\r
3214 fprintf(fp, " }\n");\r
3215 \r
3216 }\r
3217 else\r
3218 {\r
3219 assert(0);\r
3220 }\r
3221}\r
3222\r
3223void CallHandler(UINT32 dwOpcode)\r
3224{\r
3225 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3226 {\r
3227 ProcBegin(dwOpcode);\r
3228\r
3229 if (dwOpcode != 0xcd)\r
3230 {\r
3231 fprintf(fp, " sahf ; Restore our flags\n");\r
3232 fprintf(fp, " j%s takeJump%ld ; We're going call in this case\n", pbFlags[(dwOpcode >> 3) & 0x07], dwGlobalLabel);\r
3233 fprintf(fp, " add esi, 2 ; Skip past the address\n");\r
3234 fprintf(fp, " jmp short noCallTaken%ld ; Go execute the next instruction\n", dwGlobalLabel);\r
3235 fprintf(fp, "takeJump%ld:\n", dwGlobalLabel);\r
3236 \r
3237 fprintf(fp, " sub edi, 7\n");\r
3238 }\r
3239\r
3240\r
3241 if (bThroughCallHandler)\r
3242 {\r
3243 fprintf(fp, " mov dx, [esi] ; Get our call to address\n");\r
3244 fprintf(fp, " mov [_z80pc], dx ; Store our new program counter\n");\r
3245 fprintf(fp, " add esi, 2 ; Skip to our new address to be pushed\n");\r
3246 fprintf(fp, " sub esi, ebp ; Value to push onto the \"stack\"\n");\r
3247 fprintf(fp, " mov [_wordval], si ; Store our return address on the stack\n");\r
3248 fprintf(fp, " mov si, dx ; Our new address\n");\r
3249 fprintf(fp, " add esi, ebp ; And our base address\n");\r
3250 fprintf(fp, " call PushWord ; Go push our orgval to the stack\n");\r
3251 }\r
3252 else\r
3253 {\r
3254 fprintf(fp, " mov dx, [esi] ; Get our call to address\n");\r
3255 fprintf(fp, " mov [_z80pc], dx ; Store our new program counter\n");\r
3256 fprintf(fp, " add esi, 2 ; Skip to our new address to be pushed\n");\r
3257 fprintf(fp, " sub esi, ebp ; Value to push onto the \"stack\"\n");\r
3258 fprintf(fp, " mov dx, word [_z80sp] ; Get the current stack pointer\n");\r
3259 fprintf(fp, " sub dx, 2 ; Back up two bytes\n");\r
3260 fprintf(fp, " mov [ebp+edx], si ; PUSH It!\n");\r
3261 fprintf(fp, " mov word [_z80sp], dx ; Store our new stack pointer\n");\r
3262 fprintf(fp, " mov si, [_z80pc] ; Get our new program counter\n");\r
3263 fprintf(fp, " add esi, ebp ; Naturalize it!\n");\r
3264 }\r
3265\r
3266 if (dwOpcode != 0xcd)\r
3267 fprintf(fp, "noCallTaken%ld:\n", dwGlobalLabel++);\r
3268\r
3269 fprintf(fp, " xor edx, edx\n");\r
3270 FetchNextInstruction(dwOpcode);\r
3271 }\r
3272 else\r
3273 if (MZ80_C == bWhat)\r
3274 {\r
3275 fprintf(fp, " dwAddr = *pbPC++; /* Get LSB first */\n");\r
3276 fprintf(fp, " dwAddr |= ((UINT32) *pbPC++ << 8); /* Get MSB last */\n");\r
3277\r
3278 if (0xcd != dwOpcode)\r
3279 {\r
3280 fprintf(fp, " if %s\n", pbFlagsC[(dwOpcode >> 3) & 0x07]);\r
3281 fprintf(fp, " {\n");\r
3282 fprintf(fp, " cpu.z80pc = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
3283 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp - 1); /* Normalize the stack pointer */\n");\r
3284 fprintf(fp, " *pbSP-- = cpu.z80pc >> 8; /* MSB */\n");\r
3285 fprintf(fp, " *pbSP = (UINT8) cpu.z80pc; /* LSB */\n");\r
3286 fprintf(fp, " cpu.z80sp -= 2; /* Back our stack up */\n");\r
3287 fprintf(fp, " pbPC = cpu.z80Base + dwAddr; /* Normalize the address */\n");\r
3288 fprintf(fp, " }\n");\r
3289 }\r
3290 else // Just a regular call\r
3291 {\r
3292 fprintf(fp, " cpu.z80pc = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
3293 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp - 1); /* Normalize the stack pointer */\n");\r
3294 fprintf(fp, " *pbSP-- = cpu.z80pc >> 8; /* LSB */\n");\r
3295 fprintf(fp, " *pbSP = (UINT8) cpu.z80pc; /* MSB */\n");\r
3296 fprintf(fp, " cpu.z80sp -= 2; /* Back our stack up */\n");\r
3297 fprintf(fp, " pbPC = cpu.z80Base + dwAddr; /* Normalize the address */\n");\r
3298 }\r
3299 }\r
3300 else\r
3301 {\r
3302 assert(0);\r
3303 }\r
3304}\r
3305\r
3306void RetHandler(UINT32 dwOpcode)\r
3307{\r
3308 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3309 {\r
3310 ProcBegin(dwOpcode);\r
3311\r
3312 if (dwOpcode != 0xc9)\r
3313 {\r
3314 fprintf(fp, " sahf\n");\r
3315 fprintf(fp, " j%s takeReturn%ld\n", pbFlags[(dwOpcode >> 3) & 0x07], dwGlobalLabel);\r
3316 fprintf(fp, " jmp short retNotTaken%ld\n", dwGlobalLabel);\r
3317 fprintf(fp, "takeReturn%ld:\n", dwGlobalLabel);\r
3318\r
3319 if (FALSE == bNoTiming)\r
3320 {\r
3321 fprintf(fp, " sub edi, byte 6\n");\r
3322 }\r
3323 }\r
3324\r
3325\r
3326 if (bThroughCallHandler)\r
3327 {\r
3328 fprintf(fp, " call PopWord\n");\r
3329 fprintf(fp, " xor esi, esi\n");\r
3330 fprintf(fp, " mov si, dx\n");\r
3331 fprintf(fp, " add esi, ebp\n");\r
3332 fprintf(fp, " xor edx, edx\n");\r
3333 }\r
3334 else \r
3335 {\r
3336 fprintf(fp, " mov dx, word [_z80sp] ; Get our current stack pointer\n");\r
3337 fprintf(fp, " mov si, [edx+ebp] ; Get our return address\n");\r
3338 fprintf(fp, " and esi, 0ffffh ; Only within 64K!\n");\r
3339 fprintf(fp, " add esi, ebp ; Add in our base address\n");\r
3340 fprintf(fp, " add word [_z80sp], 02h ; Remove our two bytes from the stack\n");\r
3341 fprintf(fp, " xor edx, edx\n");\r
3342 }\r
3343\r
3344 if (dwOpcode != 0xc9)\r
3345 fprintf(fp, "retNotTaken%ld:\n", dwGlobalLabel++);\r
3346\r
3347 FetchNextInstruction(dwOpcode);\r
3348 }\r
3349 else\r
3350 if (MZ80_C == bWhat)\r
3351 {\r
3352 if (dwOpcode != 0xc9)\r
3353 {\r
3354 fprintf(fp, " if %s\n", pbFlagsC[(dwOpcode >> 3) & 0x07]);\r
3355 fprintf(fp, " {\n");\r
3356 fprintf(fp, " dwElapsedTicks += 6;\n");\r
3357 }\r
3358\r
3359 fprintf(fp, " pbSP = cpu.z80Base + cpu.z80sp; /* Normalize our stack PTR */\n");\r
3360 fprintf(fp, " dwAddr = *pbSP++; /* Pop LSB */\n");\r
3361 fprintf(fp, " dwAddr |= ((UINT32) *pbSP << 8); /* Pop MSB */\n");\r
3362 fprintf(fp, " cpu.z80sp += 2; /* Pop the word off */\n");\r
3363 fprintf(fp, " pbPC = (cpu.z80Base + dwAddr); /* Point PC to our return address */\n");\r
3364\r
3365 if (dwOpcode != 0xc9)\r
3366 {\r
3367 fprintf(fp, " }\n");\r
3368 }\r
3369 }\r
3370 else\r
3371 {\r
3372 assert(0);\r
3373 }\r
3374}\r
3375\r
3376void RestartHandler(UINT32 dwOpcode)\r
3377{\r
3378 UINT32 dwOpcode1 = 0;\r
3379\r
3380 dwOpcode1 = dwOpcode & 0x38;\r
3381\r
3382 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3383 {\r
3384 ProcBegin(dwOpcode);\r
3385\r
3386 if (bThroughCallHandler)\r
3387 {\r
3388 fprintf(fp, " sub esi, ebp\n");\r
3389 fprintf(fp, " mov [_wordval], si ; Store our return address\n");\r
3390 fprintf(fp, " call PushWord\n");\r
3391 fprintf(fp, " xor esi, esi\n");\r
3392 fprintf(fp, " mov si, %.4lxh\n", dwOpcode1);\r
3393 fprintf(fp, " add esi, ebp\n");\r
3394 }\r
3395 else \r
3396 {\r
3397 fprintf(fp, " mov dx, word [_z80sp] ; Get our stack pointer\n");\r
3398 fprintf(fp, " sub dx, 2 ; Make room for the new value!\n");\r
3399 fprintf(fp, " mov word [_z80sp], dx ; Store our new stack pointer\n");\r
3400 fprintf(fp, " sub esi, ebp ; Get our real PC\n");\r
3401 fprintf(fp, " mov [ebp+edx], si ; Our return address\n");\r
3402 fprintf(fp, " mov si, 0%.2xh ; Our new call address\n", dwOpcode1);\r
3403 fprintf(fp, " add esi, ebp ; Back to the base!\n");\r
3404 }\r
3405 \r
3406 fprintf(fp, " xor edx, edx\n");\r
3407 FetchNextInstruction(dwOpcode);\r
3408 }\r
3409 else\r
3410 if (MZ80_C == bWhat)\r
3411 {\r
3412 fprintf(fp, " cpu.z80pc = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
3413 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp - 1); /* Normalize the stack pointer */\n");\r
3414 fprintf(fp, " *pbSP-- = cpu.z80pc >> 8; /* LSB */\n");\r
3415 fprintf(fp, " *pbSP = (UINT8) cpu.z80pc; /* MSB */\n");\r
3416 fprintf(fp, " cpu.z80sp -= 2; /* Back our stack up */\n");\r
3417 fprintf(fp, " pbPC = cpu.z80Base + 0x%.2x; /* Normalize the address */\n", dwOpcode1);\r
3418 }\r
3419 else\r
3420 {\r
3421 assert(0);\r
3422 }\r
3423}\r
3424\r
3425void ToRegFromHl(UINT32 dwOpcode)\r
3426{\r
3427 UINT8 bReg;\r
3428\r
3429 bReg = (dwOpcode >> 3) & 0x07;\r
3430\r
3431 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3432 {\r
3433 ProcBegin(dwOpcode);\r
3434\r
3435 if (bReg != 2 && bReg != 3)\r
3436 ReadValueFromMemory("bx", pbMathReg[bReg]);\r
3437 else\r
3438 {\r
3439 ReadValueFromMemory("bx", pbLocalReg[bReg]);\r
3440 fprintf(fp, " mov %s, %s\n", pbMathReg[bReg], pbLocalReg[bReg]);\r
3441 }\r
3442\r
3443 fprintf(fp, " xor edx, edx\n");\r
3444 FetchNextInstruction(dwOpcode);\r
3445 }\r
3446 else\r
3447 if (MZ80_C == bWhat)\r
3448 {\r
3449 ReadValueFromMemory("cpu.z80HL", pbLocalRegC[bReg]);\r
3450 }\r
3451 else\r
3452 {\r
3453 assert(0);\r
3454 }\r
3455}\r
3456\r
3457void AddRegpairOperations(UINT32 dwOpcode)\r
3458{\r
3459 UINT8 bRegpair;\r
3460\r
3461 bRegpair = (dwOpcode >> 4) & 0x3;\r
3462\r
3463 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3464 {\r
3465 ProcBegin(dwOpcode);\r
3466\r
3467 fprintf(fp, " mov dh, ah ; Get our flags\n");\r
3468 fprintf(fp, " and dh, 0ech ; Preserve the top three and bits 2 & 3\n");\r
3469 \r
3470 fprintf(fp, " mov [_orgval], bx ; Store our original value\n");\r
3471 fprintf(fp, " add bx, %s\n", pbRegPairs[bRegpair]);\r
3472 fprintf(fp, " lahf\n");\r
3473 \r
3474 fprintf(fp, " mov [cyclesRemaining], edi\n");\r
3475 fprintf(fp, " mov di, [_orgval] ; Get original\n");\r
3476 fprintf(fp, " xor di, bx ; XOR It with our computed value\n");\r
3477 fprintf(fp, " xor di, %s\n", pbRegPairs[bRegpair]);\r
3478 fprintf(fp, " and di, 1000h ; Just our half carry\n");\r
3479 fprintf(fp, " or dx, di ; Or in our flags\n");\r
3480 fprintf(fp, " and ah, 01h ; Just carry\n");\r
3481 fprintf(fp, " or ah, dh\n");\r
3482 fprintf(fp, " mov edi, [cyclesRemaining]\n"); \r
3483 fprintf(fp, " xor edx, edx\n"); \r
3484 \r
3485 FetchNextInstruction(dwOpcode);\r
3486 }\r
3487 else\r
3488 if (MZ80_C == bWhat)\r
3489 {\r
3490 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");\r
3491 fprintf(fp, " dwTemp = cpu.z80HL + %s;\n", pbRegPairsC[bRegpair]);\r
3492 fprintf(fp, " cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY) | (((cpu.z80HL ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", pbRegPairsC[bRegpair]);\r
3493 fprintf(fp, " cpu.z80HL = dwTemp & 0xffff;\n");\r
3494\r
3495 return;\r
3496 }\r
3497 else\r
3498 {\r
3499 assert(0);\r
3500 }\r
3501}\r
3502\r
3503void PushPopOperations(UINT32 dwOpcode)\r
3504{\r
3505 UINT8 bRegPair;\r
3506\r
3507 bRegPair = ((dwOpcode >> 4) & 0x3) << 1;\r
3508\r
3509 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3510 {\r
3511 ProcBegin(dwOpcode);\r
3512\r
3513 if ((dwOpcode & 0xcf) == 0xc5) // Push\r
3514 {\r
3515 fprintf(fp, " sub word [_z80sp], 2\n");\r
3516 fprintf(fp, " mov dx, [_z80sp]\n");\r
3517 WriteWordToMemory("dx", pbPopRegPairs[bRegPair >> 1]);\r
3518 }\r
3519 else // Pop\r
3520 {\r
3521 fprintf(fp, " mov dx, [_z80sp]\n");\r
3522 ReadWordFromMemory("dx", pbPopRegPairs[bRegPair >> 1]);\r
3523 fprintf(fp, " add word [_z80sp], 2\n");\r
3524 } \r
3525\r
3526 fprintf(fp, " xor edx, edx\n");\r
3527 FetchNextInstruction(dwOpcode);\r
3528 }\r
3529 else\r
3530 if (MZ80_C == bWhat)\r
3531 {\r
3532 if ((dwOpcode & 0xcf) == 0xc5) // Push?\r
3533 {\r
3534 fprintf(fp, " cpu.z80sp -= 2;\n");\r
3535 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp); /* Normalize the stack pointer */\n");\r
3536 \r
3537 WriteWordToMemory("cpu.z80sp", pbPopRegPairC[bRegPair >> 1]);\r
3538 return;\r
3539 }\r
3540 else\r
3541 {\r
3542 ReadWordFromMemory("cpu.z80sp", pbPopRegPairC[bRegPair >> 1]);\r
3543\r
3544 fprintf(fp, " cpu.z80sp += 2;\n");\r
3545 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp); /* Normalize the stack pointer */\n");\r
3546 return;\r
3547 }\r
3548 \r
3549 InvalidInstructionC(1);\r
3550 }\r
3551 else\r
3552 {\r
3553 assert(0);\r
3554 }\r
3555}\r
3556\r
3557void RraRlaHandler(UINT32 dwOpcode)\r
3558{\r
3559 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3560 {\r
3561 ProcBegin(dwOpcode);\r
3562\r
3563 fprintf(fp, " sahf\n");\r
3564 if (dwOpcode == 0x1f)\r
3565 fprintf(fp, " rcr al, 1\n");\r
3566 else\r
3567 fprintf(fp, " rcl al, 1\n");\r
3568 \r
3569 fprintf(fp, " lahf\n");\r
3570 fprintf(fp, " and ah, 0edh\n");\r
3571 \r
3572 FetchNextInstruction(dwOpcode);\r
3573 }\r
3574 else\r
3575 if (MZ80_C == bWhat)\r
3576 {\r
3577 if (0x1f == dwOpcode) // RRA\r
3578 {\r
3579 fprintf(fp, " bTemp = (cpu.z80F & Z80_FLAG_CARRY) << 7;\n");\r
3580 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY)) | (cpu.z80A & Z80_FLAG_CARRY);\n");\r
3581 fprintf(fp, " cpu.z80A = ((cpu.z80A >> 1) | bTemp);\n");\r
3582 }\r
3583 else // RLA\r
3584 {\r
3585 fprintf(fp, " bTemp = cpu.z80A >> 7;\n");\r
3586 fprintf(fp, " cpu.z80A = (cpu.z80A << 1) | (cpu.z80F & Z80_FLAG_CARRY);\n");\r
3587 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY)) | bTemp;\n");\r
3588 }\r
3589 }\r
3590 else\r
3591 {\r
3592 assert(0);\r
3593 }\r
3594}\r
3595\r
3596void LdByteRegpair(UINT32 dwOpcode)\r
3597{\r
3598 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3599 {\r
3600 ProcBegin(dwOpcode);\r
3601\r
3602 if (dwOpcode == 0x0a)\r
3603 ReadValueFromMemory("cx", "al");\r
3604 if (dwOpcode == 0x1a)\r
3605 {\r
3606 fprintf(fp, " mov dx, [_z80de]\n");\r
3607 ReadValueFromMemory("dx", "al");\r
3608 }\r
3609\r
3610 fprintf(fp, " xor edx, edx\n");\r
3611 FetchNextInstruction(dwOpcode);\r
3612 }\r
3613 else\r
3614 if (MZ80_C == bWhat)\r
3615 {\r
3616 if (dwOpcode == 0x0a)\r
3617 ReadValueFromMemory("cpu.z80BC", "cpu.z80A");\r
3618 if (dwOpcode == 0x1a)\r
3619 ReadValueFromMemory("cpu.z80DE", "cpu.z80A");\r
3620 }\r
3621 else\r
3622 {\r
3623 assert(0);\r
3624 }\r
3625}\r
3626\r
3627void IncDecHLPtr(UINT32 dwOpcode)\r
3628{\r
3629 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3630 {\r
3631 ProcBegin(dwOpcode);\r
3632\r
3633 ReadValueFromMemory("bx", "dl");\r
3634\r
3635 fprintf(fp, " sahf\n");\r
3636\r
3637 if (dwOpcode == 0x34)\r
3638 fprintf(fp, " inc dl\n");\r
3639 else\r
3640 fprintf(fp, " dec dl\n");\r
3641 fprintf(fp, " lahf\n");\r
3642\r
3643 fprintf(fp, " o16 pushf\n");\r
3644 fprintf(fp, " shl edx, 16\n");\r
3645 fprintf(fp, " and ah, 0fbh ; Knock out parity/overflow\n");\r
3646 fprintf(fp, " pop dx\n");\r
3647 fprintf(fp, " and dh, 08h ; Just the overflow\n");\r
3648 fprintf(fp, " shr dh, 1 ; Shift it into position\n");\r
3649 fprintf(fp, " or ah, dh ; OR It in with the real flags\n");\r
3650 \r
3651 fprintf(fp, " shr edx, 16\n");\r
3652 \r
3653 if (dwOpcode == 0x34)\r
3654 fprintf(fp, " and ah, 0fdh ; Knock out N!\n");\r
3655 else\r
3656 fprintf(fp, " or ah, 02h ; Make it N!\n");\r
3657 \r
3658 WriteValueToMemory("bx", "dl");\r
3659 fprintf(fp, " xor edx, edx\n");\r
3660\r
3661 FetchNextInstruction(dwOpcode);\r
3662 }\r
3663 else\r
3664 if (MZ80_C == bWhat)\r
3665 {\r
3666 ReadValueFromMemory("cpu.z80HL", "bTemp");\r
3667\r
3668 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");\r
3669\r
3670 if (0x34 == dwOpcode)\r
3671 fprintf(fp ," cpu.z80F |= bPostIncFlags[bTemp];\n");\r
3672 else\r
3673 fprintf(fp ," cpu.z80F |= bPostDecFlags[bTemp];\n");\r
3674 \r
3675 if (0x34 == dwOpcode)\r
3676 fprintf(fp, " bTemp++;\n");\r
3677 else\r
3678 fprintf(fp, " bTemp--;\n");\r
3679 \r
3680 WriteValueToMemory("cpu.z80HL", "bTemp");\r
3681 return;\r
3682 }\r
3683 else\r
3684 {\r
3685 assert(0);\r
3686 }\r
3687}\r
3688\r
3689void InOutHandler(UINT32 dwOpcode)\r
3690{\r
3691 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3692 {\r
3693 ProcBegin(dwOpcode);\r
3694\r
3695 fprintf(fp, " mov dl, [esi] ; Get our address to 'out' to\n");\r
3696 fprintf(fp, " inc esi ; Next address\n");\r
3697\r
3698 if (b16BitIo)\r
3699 {\r
3700 fprintf(fp, " mov dh, al ; Upper 8 bits are the A register for 16 bit addressing\n");\r
3701 }\r
3702\r
3703 if (0xd3 == dwOpcode)\r
3704 WriteValueToIo("dx", "al");\r
3705 else\r
3706 ReadValueFromIo("dx", "al");\r
3707\r
3708 fprintf(fp, " xor edx, edx\n");\r
3709 FetchNextInstruction(dwOpcode);\r
3710 }\r
3711 else\r
3712 if (MZ80_C == bWhat)\r
3713 {\r
3714 fprintf(fp ," dwTemp = *pbPC++;\n");\r
3715\r
3716 if (0xd3 == dwOpcode)\r
3717 WriteValueToIo("dwTemp", "cpu.z80A");\r
3718 else\r
3719 ReadValueFromIo("dwTemp", "cpu.z80A");\r
3720\r
3721 // Not supposed to set flags for immediate instruction!\r
3722\r
3723 return;\r
3724 }\r
3725 else\r
3726 {\r
3727 assert(0);\r
3728 }\r
3729}\r
3730\r
3731// CB Area\r
3732\r
3733void RESSETHandler(UINT32 dwOpcode)\r
3734{\r
3735 UINT8 op = 0;\r
3736\r
3737 op = dwOpcode & 0x07;\r
3738\r
3739 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3740 {\r
3741 ProcBegin(dwOpcode);\r
3742\r
3743 if ((2 == op) || (3 == op))\r
3744 fprintf(fp, " mov dx, [_z80de] ; Move DE into something half usable\n");\r
3745\r
3746 if ((dwOpcode & 0x07) == 6) // (HL)?\r
3747 ReadValueFromMemory("bx", "dl");\r
3748\r
3749 if ((dwOpcode & 0xc0) == 0x80)\r
3750 fprintf(fp, " and %s, 0%.2xh ; Reset a bit\n", \r
3751 pbLocalReg[op],\r
3752 0xff - (1 << ((dwOpcode >> 3) & 0x7)));\r
3753\r
3754 if ((dwOpcode & 0xc0) == 0xc0)\r
3755 fprintf(fp, " or %s, 0%.2xh ; Set a bit\n", \r
3756 pbLocalReg[op],\r
3757 (1 << ((dwOpcode >> 3) & 0x7)));\r
3758\r
3759 if ((2 == op) || (3 == op))\r
3760 {\r
3761 fprintf(fp, " mov [_z80de], dx ; Once modified, put it back\n");\r
3762 fprintf(fp, " xor edx, edx\n");\r
3763 }\r
3764\r
3765 if ((dwOpcode & 0x07) == 6) // (HL)?\r
3766 {\r
3767 WriteValueToMemory("bx", "dl");\r
3768 fprintf(fp, " xor edx, edx\n");\r
3769 }\r
3770\r
3771 FetchNextInstruction(dwOpcode);\r
3772 }\r
3773 else\r
3774 if (MZ80_C == bWhat)\r
3775 {\r
3776 if (6 == op) // (HL)?\r
3777 ReadValueFromMemory("cpu.z80HL", "bTemp");\r
3778\r
3779 if ((dwOpcode & 0xc0) == 0x80) // RES\r
3780 fprintf(fp, " %s &= 0x%.2x;\n", pbMathRegC[op], (UINT8) ~((UINT8) 1 << ((dwOpcode >> 3) & 0x07)));\r
3781 else // SET\r
3782 fprintf(fp, " %s |= 0x%.2x;\n", pbMathRegC[op], 1 << ((dwOpcode >> 3) & 0x07));\r
3783\r
3784 if (6 == op) // (HL)?\r
3785 WriteValueToMemory("cpu.z80HL", "bTemp");\r
3786 }\r
3787 else\r
3788 assert(0);\r
3789}\r
3790\r
3791void BITHandler(UINT32 dwOpcode)\r
3792{\r
3793 UINT8 op = 0;\r
3794 UINT8 bBitVal = 0;\r
3795\r
3796 op = dwOpcode & 0x07;\r
3797 bBitVal = 1 << ((dwOpcode >> 3) & 0x07);\r
3798\r
3799 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3800 {\r
3801 ProcBegin(dwOpcode);\r
3802\r
3803 if ((dwOpcode & 0x07) == 6) // (HL)?\r
3804 ReadValueFromMemory("bx", "dl");\r
3805\r
3806 fprintf(fp, " mov byte [_z80af], ah ; Store F\n");\r
3807 fprintf(fp, " sahf\n");\r
3808\r
3809 if ((dwOpcode & 0x07) == 6)\r
3810 fprintf(fp, " test dl, 0%.2xh ; Do a bitwise check\n", 1 << ((dwOpcode >> 3) & 0x7));\r
3811 else\r
3812 fprintf(fp, " test %s, 0%.2xh ; Do a bitwise check\n", pbMathReg[op], 1 << ((dwOpcode >> 3) & 0x7));\r
3813\r
3814 fprintf(fp, " lahf\n");\r
3815 fprintf(fp, " and ah, 0c0h ; Only care about Z and S\n");\r
3816 fprintf(fp, " or ah, 10h ; Set half carry to 1\n");\r
3817\r
3818 fprintf(fp, " and byte [_z80af], 029h ; Only zero/non-zero!\n");\r
3819 fprintf(fp, " or ah, byte [_z80af] ; Put it in with the real flags\n");\r
3820\r
3821 if (6 == (dwOpcode & 0x07)) // (HL)?\r
3822 fprintf(fp, " xor edx, edx\n");\r
3823\r
3824 FetchNextInstruction(dwOpcode);\r
3825 }\r
3826 else\r
3827 if (MZ80_C == bWhat)\r
3828 {\r
3829 if (6 == op) // (HL)?\r
3830 ReadValueFromMemory("cpu.z80HL", "bTemp");\r
3831\r
3832 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_ZERO);\n");\r
3833 fprintf(fp, " cpu.z80F |= (Z80_FLAG_HALF_CARRY);\n");\r
3834 fprintf(fp, " if (!(%s & 0x%.2lx))\n", pbMathRegC[op], bBitVal);\r
3835 fprintf(fp, " {\n");\r
3836 fprintf(fp, " cpu.z80F |= Z80_FLAG_ZERO;\n");\r
3837 fprintf(fp, " }\n");\r
3838 }\r
3839 else\r
3840 assert(0);\r
3841}\r
3842\r
3843void RLCRRCRLRRSLASRASRLHandler(UINT32 dwOpcode)\r
3844{\r
3845 UINT8 op = 0;\r
3846\r
3847 op = dwOpcode & 0x07;\r
3848\r
3849 if (MZ80_ASSEMBLY_X86 == bWhat)\r
3850 {\r
3851 ProcBegin(dwOpcode);\r
3852\r
3853 if ((2 == op) || (3 == op))\r
3854 fprintf(fp, " mov dx, [_z80de] ; Move DE into something half usable\n");\r
3855\r
3856 if ((dwOpcode & 0x07) == 6) // (HL)?\r
3857 ReadValueFromMemory("bx", "dl");\r
3858\r
3859 fprintf(fp, " sahf\n");\r
3860\r
3861 if ((dwOpcode & 0xf8) == 0)\r
3862 fprintf(fp, " rol %s, 1\n", pbLocalReg[op]);\r
3863 else\r
3864 if ((dwOpcode & 0xf8) == 0x08)\r
3865 fprintf(fp, " ror %s, 1\n", pbLocalReg[op]);\r
3866 else\r
3867 if ((dwOpcode & 0xf8) == 0x10)\r
3868 fprintf(fp, " rcl %s, 1\n", pbLocalReg[op]);\r
3869 else\r
3870 if ((dwOpcode & 0xf8) == 0x18)\r
3871 fprintf(fp, " rcr %s, 1\n", pbLocalReg[op]);\r
3872 else\r
3873 if ((dwOpcode & 0xf8) == 0x20 || (dwOpcode & 0xf8) == 0x30)\r
3874 fprintf(fp, " shl %s, 1\n", pbLocalReg[op]);\r
3875 else\r
3876 if ((dwOpcode & 0xf8) == 0x28)\r
3877 fprintf(fp, " sar %s, 1\n", pbLocalReg[op]);\r
3878 else\r
3879 if ((dwOpcode & 0xf8) == 0x38)\r
3880 fprintf(fp, " shr %s, 1\n", pbLocalReg[op]);\r
3881 else\r
3882 assert(0);\r
3883 \r
3884 fprintf(fp, " lahf\n");\r
3885\r
3886 if ((dwOpcode & 0xf8) >= 0x20)\r
3887 {\r
3888 if ((dwOpcode & 0xf8) == 0x30)\r
3889 fprintf(fp, " or %s, 1 ; Slide in a 1 bit (SLIA)\n", pbLocalReg[op]);\r
3890 fprintf(fp, " and ah, 0edh ; Clear H and N\n");\r
3891 }\r
3892 else\r
3893 {\r
3894 fprintf(fp, " and ah, 029h ; Clear H and N\n");\r
3895 fprintf(fp, " mov byte [_z80af], ah\n");\r
3896\r
3897 fprintf(fp, " or %s, %s\n", pbLocalReg[op], pbLocalReg[op]);\r
3898 \r
3899 fprintf(fp, " lahf\n");\r
3900 fprintf(fp, " and ah, 0c4h ; Sign, zero, and parity\n");\r
3901 fprintf(fp, " or ah, byte [_z80af]\n");\r
3902 }\r
3903\r
3904 if ((2 == op) || (3 == op))\r
3905 {\r
3906 fprintf(fp, " mov [_z80de], dx ; Once modified, put it back\n");\r
3907 fprintf(fp, " xor edx, edx\n");\r
3908 }\r
3909\r
3910 if ((dwOpcode & 0x07) == 6) // (HL)?\r
3911 {\r
3912 WriteValueToMemory("bx", "dl");\r
3913 fprintf(fp, " xor edx, edx\n");\r
3914 }\r
3915\r
3916 FetchNextInstruction(dwOpcode);\r
3917 }\r
3918 else\r
3919 if (MZ80_C == bWhat)\r
3920 {\r
3921 if (6 == op) // (HL)?\r
3922 ReadValueFromMemory("cpu.z80HL", "bTemp");\r
3923\r
3924 dwOpcode &= 0xf8; // Just the instruction\r
3925\r
3926 if (0 == dwOpcode) // RLC\r
3927 {\r
3928 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");\r
3929 fprintf(fp, " bTemp2 = (%s >> 7);\n", pbMathRegC[op]);\r
3930 fprintf(fp, " %s = (%s << 1) | bTemp2;\n", pbMathRegC[op], pbMathRegC[op]);\r
3931 fprintf(fp, " cpu.z80F |= bTemp2 | bPostORFlags[%s];\n", pbMathRegC[op]);\r
3932 }\r
3933 else\r
3934 if (0x08 == dwOpcode) // RRC\r
3935 {\r
3936 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");\r
3937 fprintf(fp, " cpu.z80F |= (%s & Z80_FLAG_CARRY);\n", pbMathRegC[op]);\r
3938 fprintf(fp, " %s = (%s >> 1) | (%s << 7);\n", pbMathRegC[op], pbMathRegC[op], pbMathRegC[op]);\r
3939 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);\r
3940 }\r
3941 else\r
3942 if (0x10 == dwOpcode) // RL\r
3943 {\r
3944 fprintf(fp, " bTemp2 = cpu.z80F & Z80_FLAG_CARRY;\n");\r
3945 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");\r
3946 fprintf(fp, " cpu.z80F |= (%s >> 7);\n", pbMathRegC[op]);\r
3947 fprintf(fp, " %s = (%s << 1) | bTemp2;\n", pbMathRegC[op], pbMathRegC[op]);\r
3948 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);\r
3949 }\r
3950 else\r
3951 if (0x18 == dwOpcode) // RR\r
3952 {\r
3953 fprintf(fp, " bTemp2 = (cpu.z80F & Z80_FLAG_CARRY) << 7;\n");\r
3954 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");\r
3955 fprintf(fp, " cpu.z80F |= (%s & Z80_FLAG_CARRY);\n", pbMathRegC[op]);\r
3956 fprintf(fp, " %s = (%s >> 1) | bTemp2;\n", pbMathRegC[op], pbMathRegC[op]);\r
3957 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);\r
3958 }\r
3959 else\r
3960 if ((0x20 == dwOpcode) || (0x30 == dwOpcode)) // SLA/SRL\r
3961 {\r
3962 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");\r
3963 fprintf(fp, " cpu.z80F |= (%s >> 7);\n", pbMathRegC[op]);\r
3964 fprintf(fp, " %s = (%s << 1);\n", pbMathRegC[op], pbMathRegC[op]);\r
3965 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);\r
3966 }\r
3967 else\r
3968 if (0x28 == dwOpcode) // SRA\r
3969 {\r
3970 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");\r
3971 fprintf(fp, " cpu.z80F |= (%s & Z80_FLAG_CARRY);\n", pbMathRegC[op]);\r
3972 fprintf(fp, " %s = (%s >> 1) | (%s & 0x80);\n", pbMathRegC[op], pbMathRegC[op], pbMathRegC[op]);\r
3973 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);\r
3974 }\r
3975 else\r
3976 if (0x38 == dwOpcode) // SRL\r
3977 {\r
3978 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");\r
3979 fprintf(fp, " cpu.z80F |= (%s & Z80_FLAG_CARRY);\n", pbMathRegC[op]);\r
3980 fprintf(fp, " %s = (%s >> 1);\n", pbMathRegC[op], pbMathRegC[op], pbMathRegC[op]);\r
3981 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);\r
3982 }\r
3983 else\r
3984 {\r
3985 InvalidInstructionC(2);\r
3986 }\r
3987\r
3988 if (6 == op) // (HL)?\r
3989 WriteValueToMemory("cpu.z80HL", "bTemp");\r
3990 }\r
3991 else\r
3992 assert(0);\r
3993}\r
3994\r
3995// ED Area\r
3996\r
3997void RRDRLDHandler(UINT32 dwOpcode)\r
3998{\r
3999 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4000 {\r
4001 ProcBegin(dwOpcode);\r
4002\r
4003 ReadValueFromMemory("bx", "dl"); // Get (HL)\r
4004 fprintf(fp, " mov dh, dl ; Put a copy in DH\n");\r
4005\r
4006 if (0x6f == dwOpcode) // RLD\r
4007 {\r
4008 fprintf(fp, " shr dh, 4 ; Get our upper nibble in position\n");\r
4009 fprintf(fp, " shl dl, 4 ; Get our lower nibble into the higher position\n");\r
4010 fprintf(fp, " shl ecx, 16 ; Save this for later\n");\r
4011 fprintf(fp, " mov cl, al\n");\r
4012 fprintf(fp, " and cl, 0fh\n ; Only the lower nibble\n");\r
4013 fprintf(fp, " or dl, cl ; OR In A->(HL) transfer\n");\r
4014 fprintf(fp, " and al, 0f0h ; Only the upper 4 bits remain\n");\r
4015 fprintf(fp, " or al, dh ; OR It in to our accumulator\n");\r
4016 fprintf(fp, " shr ecx, 16 ; Restore this\n");\r
4017 }\r
4018 else // RRD\r
4019 if (0x67 == dwOpcode)\r
4020 {\r
4021 fprintf(fp, " shr dl, 4 ; Upper nibble to lower nibble\n");\r
4022 fprintf(fp, " shl ecx, 16 ; Save this\n");\r
4023 fprintf(fp, " mov cl, al\n");\r
4024 fprintf(fp, " shl cl, 4\n");\r
4025 fprintf(fp, " or dl, cl ; OR In what was in A\n");\r
4026 fprintf(fp, " and al, 0f0h ; Knock out lower part\n");\r
4027 fprintf(fp, " and dh, 0fh ; Only the lower nibble\n");\r
4028 fprintf(fp, " or al, dh ; OR In our nibble\n");\r
4029 fprintf(fp, " shr ecx, 16 ; Restore this\n");\r
4030 }\r
4031 else // Whoops!\r
4032 assert(0);\r
4033\r
4034 // This routine assumes that the new value to be placed at (HL) is in DL\r
4035\r
4036 fprintf(fp, " and ah, 29h ; Retain carry & two undefined bits\n");\r
4037 fprintf(fp, " mov dh, ah ; Store our flags away for later\n");\r
4038\r
4039 fprintf(fp, " or al, al ; Get our flags\n");\r
4040 fprintf(fp, " lahf\n");\r
4041 fprintf(fp, " and ah,0c4h ; Only partiy, zero, and sign\n");\r
4042 fprintf(fp, " or ah, dh ; OR In our old flags\n");\r
4043\r
4044 // Now go write the value back\r
4045\r
4046 WriteValueToMemory("bx", "dl");\r
4047 fprintf(fp, " xor edx, edx ; Zero out this for later\n");\r
4048 \r
4049 FetchNextInstruction(dwOpcode);\r
4050 }\r
4051 else\r
4052 if (MZ80_C == bWhat)\r
4053 {\r
4054 if (0x67 == dwOpcode) // RRD\r
4055 {\r
4056 ReadValueFromMemory("cpu.z80HL", "bTemp");\r
4057 fprintf(fp, " bTemp2 = (cpu.z80A & 0x0f) << 4;\n");\r
4058 fprintf(fp, " cpu.z80A = (cpu.z80A & 0xf0) | (bTemp & 0x0f);\n");\r
4059 fprintf(fp, " bTemp = (bTemp >> 4) | bTemp2;\n");\r
4060\r
4061 WriteValueToMemory("cpu.z80HL", "bTemp");\r
4062 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");\r
4063 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n");\r
4064 }\r
4065 else\r
4066 if (0x6f == dwOpcode) // RLD\r
4067 {\r
4068 ReadValueFromMemory("cpu.z80HL", "bTemp");\r
4069\r
4070 fprintf(fp, " bTemp2 = (cpu.z80A & 0x0f);\n");\r
4071 fprintf(fp, " cpu.z80A = (cpu.z80A & 0xf0) | (bTemp >> 4);\n");\r
4072 fprintf(fp, " bTemp = (bTemp << 4) | bTemp2;\n");\r
4073\r
4074 WriteValueToMemory("cpu.z80HL", "bTemp");\r
4075 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");\r
4076 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n");\r
4077 }\r
4078 else\r
4079 InvalidInstructionC(2);\r
4080 }\r
4081 else\r
4082 assert(0);\r
4083}\r
4084\r
4085void CPICPDCPIRCPDRHandler(UINT32 dwOpcode)\r
4086{\r
4087 UINT32 dwRepeatOb = 0;\r
4088\r
4089 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4090 {\r
4091 ProcBegin(dwOpcode);\r
4092\r
4093 if (dwOpcode == 0xb1 || dwOpcode == 0xb9)\r
4094 {\r
4095 fprintf(fp, "cpRepeat%ld:\n", dwGlobalLabel);\r
4096 dwRepeatOb = dwGlobalLabel;\r
4097 ++dwGlobalLabel;\r
4098 }\r
4099\r
4100 // Now go get the data from the source\r
4101\r
4102 ReadValueFromMemory("bx", "dl");\r
4103\r
4104 // Target data is in DL\r
4105\r
4106 fprintf(fp, " mov byte [_z80af], ah\n");\r
4107 fprintf(fp, " sahf\n");\r
4108 fprintf(fp, " cmp al, dl ; Do our comparison\n");\r
4109 fprintf(fp, " lahf\n");\r
4110 fprintf(fp, " and ah, 0fah ; No P/V or carry!\n");\r
4111 fprintf(fp, " dec cx ; Dec BC\n");\r
4112 fprintf(fp, " jz notBcZero%ld\n", dwGlobalLabel);\r
4113 fprintf(fp, " or ah, 04h ; P/V set when BC not zero\n");\r
4114 fprintf(fp, "notBcZero%ld:\n", dwGlobalLabel);\r
4115 fprintf(fp, " or ah, 02h ; N Gets set when we do compares\n");\r
4116 fprintf(fp, " mov dl, byte [_z80af]\n");\r
4117 fprintf(fp, " and dl, 01h\n");\r
4118 fprintf(fp, " or ah, dl ; Preserve carry!\n");\r
4119 \r
4120 if (dwOpcode == 0xa1 || dwOpcode == 0xb1)\r
4121 fprintf(fp, " inc bx ; Increment!\n");\r
4122 if (dwOpcode == 0xa9 || dwOpcode == 0xb9)\r
4123 fprintf(fp, " dec bx ; Decrement!\n");\r
4124\r
4125 // Let's see if we repeat...\r
4126 \r
4127 if (dwOpcode == 0xb1 || dwOpcode == 0xb9)\r
4128 {\r
4129 fprintf(fp, " sahf\n");\r
4130 fprintf(fp, " jz BCDone%ld\n", dwRepeatOb);\r
4131 fprintf(fp, " jnp BCDone%ld\n", dwRepeatOb);\r
4132\r
4133 if (FALSE == bNoTiming)\r
4134 {\r
4135 fprintf(fp, " sub edi, dword 21\n");\r
4136 fprintf(fp, " js BCDoneExit%ld\n", dwRepeatOb);\r
4137 }\r
4138\r
4139 fprintf(fp, " jmp cpRepeat%ld\n", dwRepeatOb);\r
4140\r
4141 fprintf(fp, "BCDoneExit%ld:\n", dwRepeatOb);\r
4142 fprintf(fp, " sub esi, 2 ; Back up to the instruction again\n");\r
4143 fprintf(fp, " jmp noMoreExec\n\n");\r
4144 fprintf(fp, "BCDone%ld:\n", dwRepeatOb);\r
4145 }\r
4146 \r
4147 fprintf(fp, " xor edx, edx\n");\r
4148 \r
4149 FetchNextInstruction(dwOpcode);\r
4150 }\r
4151 else\r
4152 if (MZ80_C == bWhat)\r
4153 {\r
4154 if (0xb1 == dwOpcode || 0xb9 == dwOpcode) // Repeat instruction?\r
4155 {\r
4156 fprintf(fp, " while ((sdwCyclesRemaining >= 0) && (cpu.z80BC))\n");\r
4157 }\r
4158\r
4159 fprintf(fp, " {\n"); \r
4160\r
4161 ReadValueFromMemory("cpu.z80HL", "bTemp");\r
4162\r
4163 if (0xb1 == dwOpcode || 0xa1 == dwOpcode)\r
4164 {\r
4165 fprintf(fp, " cpu.z80HL++;\n");\r
4166 fprintf(fp, " cpu.z80HL &= 0xffff;\n");\r
4167 }\r
4168 else\r
4169 {\r
4170 fprintf(fp, " cpu.z80HL--;\n");\r
4171 fprintf(fp, " cpu.z80HL &= 0xffff;\n");\r
4172 }\r
4173\r
4174 fprintf(fp, " cpu.z80BC--;\n");\r
4175 fprintf(fp, " cpu.z80BC &= 0xffff;\n");\r
4176\r
4177 if (0xb1 == dwOpcode || 0xb9 == dwOpcode) // Repeat?\r
4178 {\r
4179 fprintf(fp, " sdwCyclesRemaining -= 16;\n");\r
4180 fprintf(fp, " if (cpu.z80A == bTemp)\n");\r
4181 fprintf(fp, " {\n");\r
4182 fprintf(fp, " break;\n");\r
4183 fprintf(fp, " }\n");\r
4184 }\r
4185\r
4186 fprintf(fp, " }\n");\r
4187\r
4188 // Now figure out what's going on\r
4189\r
4190 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");\r
4191 fprintf(fp, " cpu.z80F |= (pbSubSbcTable[((UINT32) cpu.z80A << 8) | bTemp] & (Z80_FLAG_SIGN | Z80_FLAG_NEGATIVE | Z80_FLAG_ZERO));\n");\r
4192 fprintf(fp, " if (cpu.z80BC)\n");\r
4193 fprintf(fp, " {\n");\r
4194 fprintf(fp, " cpu.z80F |= Z80_FLAG_OVERFLOW_PARITY;\n");\r
4195\r
4196 fprintf(fp, " }\n");\r
4197 }\r
4198 else\r
4199 assert(0);\r
4200}\r
4201\r
4202void INIRINDRINIINDHandler(UINT32 dwOpcode)\r
4203{\r
4204 UINT32 dwTempLabel = 0;\r
4205\r
4206 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4207 {\r
4208 ProcBegin(dwOpcode);\r
4209\r
4210 dwTempLabel = dwGlobalLabel;\r
4211 dwGlobalLabel++;\r
4212\r
4213 if (0xba == dwOpcode || 0xb2 == dwOpcode)\r
4214 fprintf(fp, "loopIt%ld:\n", dwTempLabel);\r
4215\r
4216 // Fetch what's at (C) and put it in (HL)\r
4217\r
4218 fprintf(fp, " push cx ; Save BC\n");\r
4219 \r
4220 if (b16BitIo == FALSE)\r
4221 fprintf(fp, " xor ch, ch ; We want 8 bit ports\n");\r
4222 \r
4223 ReadValueFromIo("cx", "*dl"); // Put our value in DL\r
4224 fprintf(fp, " pop cx ; Restore BC\n");\r
4225 \r
4226 WriteValueToMemory("bx", "dl");\r
4227 \r
4228 if (0xa2 == dwOpcode || 0xb2 == dwOpcode)\r
4229 fprintf(fp, " inc bx ; Increment HL\n");\r
4230 else\r
4231 if (0xaa == dwOpcode || 0xba == dwOpcode)\r
4232 fprintf(fp, " dec bx ; Decrement HL\n");\r
4233 \r
4234 // Now we decrement B\r
4235 \r
4236 fprintf(fp, " dec ch ; Decrement B (of C)\n");\r
4237 \r
4238 // Emit this instruction if we repeat\r
4239 \r
4240 if (0xba == dwOpcode || 0xb2 == dwOpcode)\r
4241 {\r
4242 fprintf(fp, " jz near finalExit%ld\n", dwTempLabel);\r
4243\r
4244 // Otherwise, we need to loop again\r
4245\r
4246 if (FALSE == bNoTiming)\r
4247 {\r
4248 fprintf(fp, " sub edi, dword 21\n");\r
4249 fprintf(fp, " js loopExit%ld\n", dwTempLabel);\r
4250 }\r
4251\r
4252 fprintf(fp, " jmp loopIt%ld\n\n", dwTempLabel);\r
4253 fprintf(fp, "loopExit%ld:\n", dwTempLabel);\r
4254 fprintf(fp, " sub esi, 2\n");\r
4255 fprintf(fp, " jmp noMoreExec\n\n");\r
4256 }\r
4257 \r
4258 // Now let's fix up the flags\r
4259\r
4260 fprintf(fp, "finalExit%ld:\n", dwTempLabel); \r
4261 fprintf(fp, " jnz clearFlag%ld\n", dwTempLabel);\r
4262 fprintf(fp, " or ah, 040h ; Set the Zero flag!\n");\r
4263 fprintf(fp, " jmp short continue%ld\n", dwTempLabel);\r
4264 fprintf(fp, "clearFlag%ld:\n", dwTempLabel);\r
4265 fprintf(fp, " and ah, 0bfh ; Clear the zero flag\n");\r
4266 fprintf(fp, "continue%ld:\n", dwTempLabel);\r
4267 fprintf(fp, " or ah, 02h ; Set negative!\n");\r
4268 fprintf(fp, " xor edx, edx\n");\r
4269 FetchNextInstruction(dwOpcode);\r
4270 }\r
4271 else\r
4272 if (MZ80_C == bWhat)\r
4273 {\r
4274 if (0xb2 == dwOpcode || 0xba == dwOpcode) // Repeat instruction?\r
4275 {\r
4276 fprintf(fp, " while ((sdwCyclesRemaining > 0) && (cpu.z80B))\n");\r
4277 }\r
4278\r
4279 fprintf(fp, " {\n"); \r
4280\r
4281 ReadValueFromIo("cpu.z80B", "bTemp");\r
4282 WriteValueToMemory("cpu.z80HL", "bTemp");\r
4283\r
4284 if (0xb2 == dwOpcode || 0xa2 == dwOpcode)\r
4285 {\r
4286 fprintf(fp, " cpu.z80HL++;\n");\r
4287 fprintf(fp, " cpu.z80HL &= 0xffff;\n");\r
4288 }\r
4289 else\r
4290 {\r
4291 fprintf(fp, " cpu.z80HL--;\n");\r
4292 fprintf(fp, " cpu.z80HL &= 0xffff;\n");\r
4293 }\r
4294\r
4295 fprintf(fp, " sdwCyclesRemaining -= 16;\n");\r
4296 \r
4297 fprintf(fp, " cpu.z80B--;\n");\r
4298 fprintf(fp, " }\n");\r
4299\r
4300 // Now figure out what's going on\r
4301\r
4302 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");\r
4303 fprintf(fp, " cpu.z80F |= (bPostORFlags[bTemp] & (Z80_FLAG_SIGN | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY));\n");\r
4304 fprintf(fp, " if (cpu.z80B)\n");\r
4305 fprintf(fp, " {\n");\r
4306 fprintf(fp, " cpu.z80F |= Z80_FLAG_OVERFLOW_PARITY;\n");\r
4307\r
4308 fprintf(fp, " pbPC -= 2;\n");\r
4309\r
4310 fprintf(fp, " }\n");\r
4311 }\r
4312 else\r
4313 assert(0);\r
4314}\r
4315\r
4316void OTIROTDROUTIOUTDHandler(UINT32 dwOpcode)\r
4317{\r
4318 UINT32 dwTempLabel = 0;\r
4319\r
4320 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4321 {\r
4322 ProcBegin(dwOpcode);\r
4323\r
4324 dwTempLabel = dwGlobalLabel;\r
4325 dwGlobalLabel++;\r
4326\r
4327 if (0xbb == dwOpcode || 0xb3 == dwOpcode)\r
4328 fprintf(fp, "loopIt%ld:\n", dwTempLabel);\r
4329\r
4330 // Fetch what's at (HL) and put it in DL\r
4331\r
4332 ReadValueFromMemory("bx", "dl");\r
4333\r
4334 fprintf(fp, " push cx ; Save BC\n");\r
4335 if (b16BitIo == FALSE)\r
4336 fprintf(fp, " xor ch, ch ; No 16 bit for this instruction!\n");\r
4337 WriteValueToIo("cx", "dl");\r
4338 fprintf(fp, " pop cx ; Restore BC now that it has been \"OUT\"ed\n");\r
4339 \r
4340 if (0xa3 == dwOpcode || 0xb3 == dwOpcode)\r
4341 fprintf(fp, " inc bx ; Increment HL\n");\r
4342 else\r
4343 if (0xab == dwOpcode || 0xbb == dwOpcode)\r
4344 fprintf(fp, " dec bx ; Decrement HL\n");\r
4345 \r
4346 // Now we decrement B\r
4347\r
4348 fprintf(fp, " dec ch ; Decrement B (of C)\n");\r
4349 \r
4350 // Emit this instruction if we repeat\r
4351 \r
4352 if (0xbb == dwOpcode || 0xb3 == dwOpcode)\r
4353 {\r
4354 fprintf(fp, " jz near finalExit%ld\n", dwTempLabel);\r
4355\r
4356 // Otherwise, we need to loop again\r
4357\r
4358 if (FALSE == bNoTiming)\r
4359 {\r
4360 fprintf(fp, " sub edi, dword 21\n");\r
4361 fprintf(fp, " js loopExit%ld\n", dwTempLabel);\r
4362 }\r
4363\r
4364 fprintf(fp, " jmp loopIt%ld\n\n", dwTempLabel);\r
4365 fprintf(fp, "loopExit%ld:\n", dwTempLabel);\r
4366 fprintf(fp, " sub esi, 2\n");\r
4367 fprintf(fp, " jmp noMoreExec\n\n");\r
4368 }\r
4369 \r
4370 // Now let's fix up the flags\r
4371\r
4372 fprintf(fp, "finalExit%ld:\n", dwTempLabel); \r
4373 fprintf(fp, " jnz clearFlag%ld\n", dwTempLabel);\r
4374 fprintf(fp, " or ah, 040h ; Set the Zero flag!\n");\r
4375 fprintf(fp, " jmp short continue%ld\n", dwTempLabel);\r
4376 fprintf(fp, "clearFlag%ld:\n", dwTempLabel);\r
4377 fprintf(fp, " and ah, 0bfh ; Clear the zero flag\n");\r
4378 fprintf(fp, "continue%ld:\n", dwTempLabel);\r
4379 fprintf(fp, " or ah, 02h ; Set negative!\n");\r
4380 fprintf(fp, " xor edx, edx\n");\r
4381 FetchNextInstruction(dwOpcode);\r
4382 }\r
4383 else\r
4384 if (MZ80_C == bWhat)\r
4385 {\r
4386 if (0xb3 == dwOpcode || 0xbb == dwOpcode) // Repeat instruction?\r
4387 {\r
4388 fprintf(fp, " while ((sdwCyclesRemaining > 0) && (cpu.z80B))\n");\r
4389 }\r
4390\r
4391 fprintf(fp, " {\n");\r
4392 \r
4393 ReadValueFromMemory("cpu.z80HL", "bTemp");\r
4394 WriteValueToIo("cpu.z80BC", "bTemp");\r
4395\r
4396 if (0xb3 == dwOpcode || 0xa3 == dwOpcode)\r
4397 {\r
4398 fprintf(fp, " cpu.z80HL++;\n");\r
4399 fprintf(fp, " cpu.z80HL &= 0xffff;\n");\r
4400 }\r
4401 else\r
4402 {\r
4403 fprintf(fp, " cpu.z80HL--;\n");\r
4404 fprintf(fp, " cpu.z80HL &= 0xffff;\n");\r
4405 }\r
4406\r
4407 fprintf(fp, " sdwCyclesRemaining -= 16;\n");\r
4408 \r
4409 fprintf(fp, " cpu.z80B--;\n");\r
4410 fprintf(fp, " }\n");\r
4411\r
4412 // Now figure out what's going on\r
4413\r
4414 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");\r
4415 fprintf(fp, " cpu.z80F |= (bPostORFlags[bTemp] & (Z80_FLAG_SIGN | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY));\n");\r
4416 fprintf(fp, " if (cpu.z80B)\n");\r
4417 fprintf(fp, " {\n");\r
4418 fprintf(fp, " cpu.z80F |= Z80_FLAG_OVERFLOW_PARITY;\n");\r
4419\r
4420 fprintf(fp, " }\n");\r
4421 }\r
4422 else\r
4423 assert(0);\r
4424}\r
4425\r
4426void AdcSbcRegpair(UINT32 dwOpcode)\r
4427{\r
4428 UINT8 bOp = 0;\r
4429\r
4430 bOp = (dwOpcode >> 4) & 0x03;\r
4431\r
4432 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4433 {\r
4434 ProcBegin(dwOpcode);\r
4435\r
4436 fprintf(fp, " mov dx, %s ; Get our original register\n", pbRegPairs[bOp]);\r
4437 fprintf(fp, " mov [_orgval], dx ; Store this for later half carry computation\n");\r
4438 fprintf(fp, " mov [_orgval2], bx ; Store this, too\n");\r
4439 fprintf(fp, " sahf ; Restore our flags\n");\r
4440\r
4441 if ((dwOpcode & 0xcf) == 0x4a)\r
4442 fprintf(fp, " adc bx, dx ; Do the operation!\n");\r
4443 else\r
4444 fprintf(fp, " sbb bx, dx ; Do the operation!\n");\r
4445\r
4446 fprintf(fp, " lahf ; Get our new flags\n");\r
4447 \r
4448 if ((dwOpcode & 0xcf) != 0x4a)\r
4449 {\r
4450 SetOverflow();\r
4451 fprintf(fp, " and ah, 0edh ; Knock out negative & half carry flags\n");\r
4452 fprintf(fp, " or ah, 02h ; Negative!\n");\r
4453 fprintf(fp, " mov [_z80hl], bx\n");\r
4454 fprintf(fp, " xor bx, [_orgval]\n");\r
4455 fprintf(fp, " xor bx, [_orgval2]\n");\r
4456 fprintf(fp, " and bh, 10h ; Half carry?\n");\r
4457 fprintf(fp, " or ah, bh ; OR It in if so\n");\r
4458 fprintf(fp, " mov bx, [_z80hl]\n");\r
4459 }\r
4460 else\r
4461 {\r
4462 SetOverflow();\r
4463 fprintf(fp, " and ah, 0edh ; Knock out negative & half carry flags\n");\r
4464 fprintf(fp, " mov [_z80hl], bx\n");\r
4465 fprintf(fp, " xor bx, [_orgval]\n");\r
4466 fprintf(fp, " xor bx, [_orgval2]\n");\r
4467 fprintf(fp, " and bh, 10h ; Half carry?\n");\r
4468 fprintf(fp, " or ah, bh ; OR It in if so\n");\r
4469 fprintf(fp, " mov bx, [_z80hl]\n");\r
4470 }\r
4471\r
4472 fprintf(fp, " xor edx, edx ; Make sure we don't hose things\n");\r
4473 FetchNextInstruction(dwOpcode);\r
4474 }\r
4475 else\r
4476 if (MZ80_C == bWhat)\r
4477 {\r
4478 if ((dwOpcode & 0xcf) == 0x4a) // ADC\r
4479 {\r
4480 fprintf(fp, " dwTemp = cpu.z80HL + %s + (cpu.z80F & Z80_FLAG_CARRY);\n", pbRegPairsC[bOp]);\r
4481 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");\r
4482 fprintf(fp, " cpu.z80F |= ((dwTemp >> 8) & Z80_FLAG_SIGN);\n");\r
4483 fprintf(fp, " if (0 == (dwTemp & 0xffff))\n");\r
4484 fprintf(fp, " {\n");\r
4485 fprintf(fp, " cpu.z80F |= Z80_FLAG_ZERO;\n");\r
4486 fprintf(fp, " }\n");\r
4487 fprintf(fp, " cpu.z80F |= (((cpu.z80HL ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", pbRegPairsC[bOp]);\r
4488 fprintf(fp, " cpu.z80F |= ((((%s ^ cpu.z80HL ^ 0x8000) & (%s ^ dwTemp)) >> 13) & Z80_FLAG_OVERFLOW_PARITY);\n", pbRegPairsC[bOp], pbRegPairsC[bOp]);\r
4489 fprintf(fp, " cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY);\n");\r
4490 fprintf(fp, " cpu.z80HL = dwTemp & 0xffff;\n");\r
4491 return;\r
4492 }\r
4493 else // SBC\r
4494 {\r
4495 fprintf(fp, " dwTemp = cpu.z80HL - %s - (cpu.z80F & Z80_FLAG_CARRY);\n", pbRegPairsC[bOp]);\r
4496 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");\r
4497 fprintf(fp, " cpu.z80F |= ((dwTemp >> 8) & Z80_FLAG_SIGN);\n");\r
4498 fprintf(fp, " if (0 == (dwTemp & 0xffff))\n");\r
4499 fprintf(fp, " {\n");\r
4500 fprintf(fp, " cpu.z80F |= Z80_FLAG_ZERO;\n");\r
4501 fprintf(fp, " }\n");\r
4502 fprintf(fp, " cpu.z80F |= (((cpu.z80HL ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", pbRegPairsC[bOp]);\r
4503 fprintf(fp, " cpu.z80F |= ((((%s ^ cpu.z80HL) & (%s ^ dwTemp)) >> 13) & Z80_FLAG_OVERFLOW_PARITY);\n", pbRegPairsC[bOp], pbRegPairsC[bOp]);\r
4504 fprintf(fp, " cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY);\n");\r
4505 fprintf(fp, " cpu.z80HL = dwTemp & 0xffff;\n");\r
4506 return;\r
4507 }\r
4508 }\r
4509 else\r
4510 assert(0);\r
4511}\r
4512\r
4513void RetIRetNHandler(UINT32 dwOpcode)\r
4514{\r
4515 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4516 {\r
4517 ProcBegin(dwOpcode);\r
4518\r
4519 if (bThroughCallHandler)\r
4520 {\r
4521 fprintf(fp, " call PopWord\n");\r
4522 fprintf(fp, " xor esi, esi\n");\r
4523 fprintf(fp, " mov si, dx\n");\r
4524 fprintf(fp, " add esi, ebp\n");\r
4525 }\r
4526 else \r
4527 {\r
4528 fprintf(fp, " mov dx, word [_z80sp] ; Get our current stack pointer\n");\r
4529 fprintf(fp, " mov si, [edx+ebp] ; Get our return address\n");\r
4530 fprintf(fp, " and esi, 0ffffh ; Only within 64K!\n");\r
4531 fprintf(fp, " add esi, ebp ; Add in our base address\n");\r
4532 fprintf(fp, " add word [_z80sp], 02h ; Remove our two bytes from the stack\n");\r
4533 }\r
4534 \r
4535 if (dwOpcode == 0x45)\r
4536 {\r
4537 fprintf(fp, " xor edx, edx\n");\r
4538 fprintf(fp, " mov dl, [_z80iff] ; Get interrupt flags\n");\r
4539 fprintf(fp, " shr dl, 1 ; Move IFF2->IFF1\n");\r
4540 fprintf(fp, " and [_z80iff], dword (~IFF1) ; Get rid of IFF 1\n");\r
4541 fprintf(fp, " and dl, IFF1 ; Just want the IFF 1 value now\n");\r
4542 fprintf(fp, " or dword [_z80iff], edx\n");\r
4543 }\r
4544\r
4545 fprintf(fp, " xor edx, edx ; Make sure we don't hose things\n");\r
4546 FetchNextInstruction(dwOpcode);\r
4547 }\r
4548 else\r
4549 if (MZ80_C == bWhat)\r
4550 {\r
4551 if (0x4d == dwOpcode) // RETI\r
4552 {\r
4553 fprintf(fp, " pbSP = cpu.z80Base + cpu.z80sp; /* Normalize our stack PTR */\n");\r
4554 fprintf(fp, " dwAddr = *pbSP++; /* Pop LSB */\n");\r
4555 fprintf(fp, " dwAddr |= ((UINT32) *pbSP << 8); /* Pop MSB */\n");\r
4556 fprintf(fp, " cpu.z80sp += 2; /* Pop the word off */\n");\r
4557 fprintf(fp, " pbPC = (cpu.z80Base + dwAddr); /* Point PC to our return address */\n");\r
4558 }\r
4559 else\r
4560 if (0x45 == dwOpcode) // RETN\r
4561 {\r
4562 fprintf(fp, " pbSP = cpu.z80Base + cpu.z80sp; /* Normalize our stack PTR */\n");\r
4563 fprintf(fp, " dwAddr = *pbSP++; /* Pop LSB */\n");\r
4564 fprintf(fp, " dwAddr |= ((UINT32) *pbSP << 8); /* Pop MSB */\n");\r
4565 fprintf(fp, " cpu.z80sp += 2; /* Pop the word off */\n");\r
4566 fprintf(fp, " pbPC = (cpu.z80Base + dwAddr); /* Point PC to our return address */\n");\r
4567 fprintf(fp, " cpu.z80iff &= ~(IFF1); /* Keep IFF2 around */\n");\r
4568 fprintf(fp, " cpu.z80iff |= ((cpu.z80iff >> 1) & IFF1); /* IFF2->IFF1 */\n");\r
4569 }\r
4570 else\r
4571 {\r
4572 InvalidInstructionC(2);\r
4573 }\r
4574 }\r
4575 else\r
4576 assert(0);\r
4577}\r
4578\r
4579void ExtendedOutHandler(UINT32 dwOpcode)\r
4580{\r
4581 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4582 {\r
4583 ProcBegin(dwOpcode);\r
4584\r
4585 if (b16BitIo == FALSE)\r
4586 fprintf(fp, " mov dl, cl ; Address in DX... (C)\n");\r
4587 else\r
4588 fprintf(fp, " mov dx, cx ; Address in DX... (BC)\n");\r
4589 \r
4590 WriteValueToIo("dx", pbMathReg[(dwOpcode >> 3) & 0x07]);\r
4591\r
4592 fprintf(fp, " xor edx, edx\n");\r
4593 FetchNextInstruction(dwOpcode);\r
4594 }\r
4595 else\r
4596 if (MZ80_C == bWhat)\r
4597 {\r
4598 if (b16BitIo == FALSE)\r
4599 fprintf(fp, " dwAddr = cpu.z80C;\n");\r
4600 else\r
4601 fprintf(fp, " dwAddr = cpu.z80BC;\n");\r
4602\r
4603 WriteValueToIo("dwAddr", pbMathRegC[(dwOpcode >> 3) & 0x07]);\r
4604 }\r
4605 else\r
4606 assert(0);\r
4607}\r
4608\r
4609void ExtendedInHandler(UINT32 dwOpcode)\r
4610{\r
4611 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4612 {\r
4613 ProcBegin(dwOpcode);\r
4614\r
4615 if (b16BitIo == FALSE)\r
4616 fprintf(fp, " mov dl, cl ; Address in DX... (C)\n");\r
4617 else\r
4618 fprintf(fp, " mov dx, cx ; Address in DX... (BC)\n");\r
4619 \r
4620 ReadValueFromIo("dx", pbMathReg[(dwOpcode >> 3) & 0x07]);\r
4621\r
4622 fprintf(fp, ";\n; Remember, this variant of the IN instruction modifies the flags\n;\n\n");\r
4623 fprintf(fp, " sahf ; Restore our flags\n");\r
4624 fprintf(fp, " mov dh, ah ; Save flags for later\n");\r
4625 \r
4626 if (0x50 == dwOpcode || 0x58 == dwOpcode)\r
4627 {\r
4628 fprintf(fp, " mov dl, %s\n", pbMathReg[(dwOpcode >> 3) & 0x07]);\r
4629 fprintf(fp, " or dl, dl\n");\r
4630 }\r
4631 else\r
4632 fprintf(fp, " or %s, %s;\n", pbMathReg[(dwOpcode >> 3) & 0x07], pbMathReg[(dwOpcode >> 3) & 0x07]);\r
4633\r
4634 fprintf(fp, " lahf\n");\r
4635 fprintf(fp, " and dh, 029h ; Only keep carry and two unused flags\n");\r
4636 fprintf(fp, " and ah, 0d4h\n");\r
4637 fprintf(fp, " or ah, dh\n");\r
4638\r
4639 fprintf(fp, " xor edx, edx\n");\r
4640\r
4641 FetchNextInstruction(dwOpcode);\r
4642 }\r
4643 else\r
4644 if (MZ80_C == bWhat)\r
4645 {\r
4646 if (b16BitIo == FALSE)\r
4647 fprintf(fp, " dwAddr = cpu.z80C;\n");\r
4648 else\r
4649 fprintf(fp, " dwAddr = cpu.z80BC;\n");\r
4650\r
4651 ReadValueFromIo("dwAddr", pbMathRegC[(dwOpcode >> 3) & 0x07]);\r
4652\r
4653 // Set flags!\r
4654\r
4655 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");\r
4656 fprintf(fp, " cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[(dwOpcode >> 3) & 0x07]);\r
4657 }\r
4658 else\r
4659 assert(0);\r
4660}\r
4661\r
4662void NegHandler(UINT32 dwOpcode)\r
4663{\r
4664 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4665 {\r
4666 ProcBegin(dwOpcode);\r
4667\r
4668 fprintf(fp, " sahf\n");\r
4669 fprintf(fp, " sub dh, al\n");\r
4670 fprintf(fp, " lahf\n");\r
4671 fprintf(fp, " mov al, dh\n");\r
4672 \r
4673 SetOverflow();\r
4674 fprintf(fp, " or ah, 02h\n");\r
4675 fprintf(fp, " xor edx, edx\n");\r
4676\r
4677 FetchNextInstruction(dwOpcode);\r
4678 }\r
4679 else\r
4680 if (MZ80_C == bWhat)\r
4681 {\r
4682 SetSubFlagsSZHVC("0", "cpu.z80A");\r
4683 fprintf(fp, " cpu.z80A = 0 - cpu.z80A;\n");\r
4684 }\r
4685 else\r
4686 assert(0);\r
4687}\r
4688\r
4689void ExtendedRegIntoMemory(UINT32 dwOpcode)\r
4690{\r
4691 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4692 {\r
4693 ProcBegin(dwOpcode);\r
4694\r
4695 fprintf(fp, " mov dx, [esi] ; Get our address to write to\n");\r
4696 fprintf(fp, " add esi, 2 ; Next address, please...\n");\r
4697\r
4698 if (dwOpcode == 0x43)\r
4699 WriteValueToMemory("dx", "cl");\r
4700 if (dwOpcode == 0x53)\r
4701 WriteValueToMemory("dx", "byte [_z80de]");\r
4702 if (dwOpcode == 0x63)\r
4703 WriteValueToMemory("dx", "bl");\r
4704 if (dwOpcode == 0x73)\r
4705 WriteValueToMemory("dx", "byte [_z80sp]");\r
4706\r
4707 fprintf(fp, " inc dx\n");\r
4708\r
4709 if (dwOpcode == 0x43)\r
4710 WriteValueToMemory("dx", "ch");\r
4711 if (dwOpcode == 0x53)\r
4712 WriteValueToMemory("dx", "byte [_z80de + 1]");\r
4713 if (dwOpcode == 0x63)\r
4714 WriteValueToMemory("dx", "bh");\r
4715 if (dwOpcode == 0x73)\r
4716 WriteValueToMemory("dx", "byte [_z80sp + 1]");\r
4717 \r
4718 fprintf(fp, " xor edx, edx ; Zero our upper word\n");\r
4719\r
4720 FetchNextInstruction(dwOpcode);\r
4721 }\r
4722 else\r
4723 if (MZ80_C == bWhat)\r
4724 {\r
4725 fprintf(fp, " dwTemp = *pbPC++;\n");\r
4726 fprintf(fp, " dwTemp |= ((UINT32) *pbPC++ << 8);\n");\r
4727\r
4728 if (0x43 == dwOpcode) // LD (xxxxh), BC\r
4729 WriteWordToMemory("dwTemp", "cpu.z80BC");\r
4730 if (0x53 == dwOpcode) // LD (xxxxh), DE\r
4731 WriteWordToMemory("dwTemp", "cpu.z80DE");\r
4732 if (0x63 == dwOpcode) // LD (xxxxh), HL\r
4733 WriteWordToMemory("dwTemp", "cpu.z80HL");\r
4734 if (0x73 == dwOpcode) // LD (xxxxh), SP\r
4735 WriteWordToMemory("dwTemp", "cpu.z80sp");\r
4736 }\r
4737 else\r
4738 assert(0);\r
4739}\r
4740\r
4741void LdRegpair(UINT32 dwOpcode)\r
4742{\r
4743 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4744 {\r
4745 ProcBegin(dwOpcode);\r
4746\r
4747 fprintf(fp, " mov dx, [esi] ; Get address to load\n");\r
4748 fprintf(fp, " add esi, 2 ; Skip over it so we don't execute it\n");\r
4749 \r
4750 if (dwOpcode == 0x4b)\r
4751 ReadValueFromMemory("dx", "cl");\r
4752 if (dwOpcode == 0x5b)\r
4753 ReadValueFromMemory("dx", "byte [_z80de]");\r
4754 if (dwOpcode == 0x7b)\r
4755 ReadValueFromMemory("dx", "byte [_z80sp]");\r
4756 \r
4757 fprintf(fp, " inc dx\n");\r
4758 \r
4759 if (dwOpcode == 0x4b)\r
4760 ReadValueFromMemory("dx", "ch");\r
4761 if (dwOpcode == 0x5b)\r
4762 ReadValueFromMemory("dx", "byte [_z80de + 1]");\r
4763 if (dwOpcode == 0x7b)\r
4764 ReadValueFromMemory("dx", "byte [_z80sp + 1]");\r
4765\r
4766 fprintf(fp, " xor edx, edx\n");\r
4767\r
4768 FetchNextInstruction(dwOpcode);\r
4769 }\r
4770 else\r
4771 if (MZ80_C == bWhat)\r
4772 {\r
4773 fprintf(fp, " dwTemp = *pbPC++;\n");\r
4774 fprintf(fp, " dwTemp |= ((UINT32) *pbPC++ << 8);\n");\r
4775\r
4776 if (0x4b == dwOpcode)\r
4777 ReadWordFromMemory("dwTemp", "cpu.z80BC");\r
4778 if (0x5b == dwOpcode)\r
4779 ReadWordFromMemory("dwTemp", "cpu.z80DE");\r
4780 if (0x7b == dwOpcode)\r
4781 ReadWordFromMemory("dwTemp", "cpu.z80sp");\r
4782 }\r
4783 else\r
4784 assert(0);\r
4785}\r
4786\r
4787void LDILDRLDIRLDDRHandler(UINT32 dwOpcode)\r
4788{\r
4789 UINT32 dwOrgGlobal = 0;\r
4790\r
4791 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4792 {\r
4793 ProcBegin(dwOpcode);\r
4794\r
4795 if (dwOpcode == 0xb0 || dwOpcode == 0xb8)\r
4796 {\r
4797 dwOrgGlobal = dwGlobalLabel;\r
4798 fprintf(fp, "ldRepeat%ld:\n", dwGlobalLabel);\r
4799 }\r
4800\r
4801 ReadValueFromMemory("bx", "dl"); \r
4802\r
4803 // Here we write the byte back to the target\r
4804 \r
4805 WriteValueToMemory("[_z80de]", "dl");\r
4806\r
4807 // Now we decide what to do\r
4808 \r
4809 if ((dwOpcode & 0x0f) == 0)\r
4810 {\r
4811 fprintf(fp, " inc bx ; Increment HL\n");\r
4812 fprintf(fp, " inc word [_z80de] ; Increment DE\n");\r
4813 }\r
4814 else\r
4815 {\r
4816 fprintf(fp, " dec bx ; Decrement HL\n");\r
4817 fprintf(fp, " dec word [_z80de] ; Decrement DE\n");\r
4818 }\r
4819 \r
4820 fprintf(fp, " dec cx ; Decrement BC\n");\r
4821 \r
4822 if (dwOpcode == 0xb0 || dwOpcode == 0xb8)\r
4823 {\r
4824 if (FALSE == bNoTiming)\r
4825 {\r
4826 fprintf(fp, " jz noMore%ld\n", dwGlobalLabel);\r
4827 fprintf(fp, " sub edi, dword 16 ; 16 T-States per iteration\n");\r
4828 fprintf(fp, " js noMore%ld\n", dwGlobalLabel);\r
4829 }\r
4830 else\r
4831 {\r
4832 fprintf(fp, " jz noMore%ld\n", dwGlobalLabel);\r
4833 }\r
4834 \r
4835 fprintf(fp, " jmp ldRepeat%ld ; Loop until we're done!\n", dwOrgGlobal);\r
4836 fprintf(fp, "noMore%ld:\n", dwGlobalLabel);\r
4837 }\r
4838 \r
4839 fprintf(fp, " and ah, 0e9h ; Knock out H & N and P/V\n");\r
4840 fprintf(fp, " or cx, cx ; Flag BC\n");\r
4841 fprintf(fp, " jz atZero%ld ; We're done!\n", dwGlobalLabel);\r
4842 \r
4843 if (dwOpcode == 0xb0 || dwOpcode == 0xb8)\r
4844 {\r
4845 // It's a repeat, so let's readjust ESI, shall we?\r
4846 \r
4847 fprintf(fp, " or ah, 04h ; Non-zero - we're still going!\n");\r
4848 fprintf(fp, " sub esi, 2 ; Adjust back to the beginning of the instruction\n");\r
4849 fprintf(fp, " jmp noMoreExec\n\n");\r
4850 }\r
4851 else\r
4852 if (dwOpcode == 0xa0 || dwOpcode == 0xa8)\r
4853 {\r
4854 fprintf(fp, " or ah, 04h ; Non-zero - we're still going!\n");\r
4855 }\r
4856 \r
4857 fprintf(fp, "atZero%ld:\n", dwGlobalLabel);\r
4858 ++dwGlobalLabel;\r
4859 \r
4860 fprintf(fp, " xor edx, edx ; Make sure we don't hose things\n");\r
4861 FetchNextInstruction(dwOpcode);\r
4862 }\r
4863 else\r
4864 if (MZ80_C == bWhat)\r
4865 {\r
4866 // This is the actual move\r
4867\r
4868 if (0xb0 == dwOpcode || 0xb8 == dwOpcode) // Repeat instruction?\r
4869 {\r
4870 fprintf(fp, " while ((sdwCyclesRemaining > 0) && (cpu.z80BC))\n");\r
4871\r
4872 fprintf(fp, " {\n"); \r
4873 }\r
4874\r
4875 ReadValueFromMemory("cpu.z80HL", "bTemp");\r
4876 WriteValueToMemory("cpu.z80DE", "bTemp");\r
4877\r
4878 if ((dwOpcode & 0x0f) == 0)\r
4879 {\r
4880 fprintf(fp, " ++cpu.z80HL;\n");\r
4881 fprintf(fp, " ++cpu.z80DE;\n");\r
4882 }\r
4883 else \r
4884 {\r
4885 fprintf(fp, " --cpu.z80HL;\n");\r
4886 fprintf(fp, " --cpu.z80DE;\n");\r
4887 }\r
4888\r
4889 fprintf(fp, " --cpu.z80BC;\n");\r
4890 fprintf(fp, " cpu.z80HL &= 0xffff;\n");\r
4891 fprintf(fp, " cpu.z80DE &= 0xffff;\n");\r
4892 fprintf(fp, " cpu.z80BC &= 0xffff;\n");\r
4893\r
4894 if (0xb0 == dwOpcode || 0xb8 == dwOpcode) // Repeat instruction?\r
4895 {\r
4896 fprintf(fp, " sdwCyclesRemaining -= 21;\n");\r
4897\r
4898 fprintf(fp, " }\n");\r
4899 }\r
4900\r
4901 // Time for a flag fixup!\r
4902\r
4903 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY);\n");\r
4904 fprintf(fp, " if (cpu.z80BC)\n");\r
4905 fprintf(fp, " {\n");\r
4906\r
4907 if (0xb0 == dwOpcode || 0xb8 == dwOpcode)\r
4908 {\r
4909 fprintf(fp, " pbPC -= 2; /* Back up so we hit this instruction again */\n");\r
4910 }\r
4911\r
4912 fprintf(fp, " cpu.z80F |= Z80_FLAG_OVERFLOW_PARITY;\n");\r
4913 fprintf(fp, " }\n");\r
4914\r
4915 if (0xb0 == dwOpcode || 0xb8 == dwOpcode) // Repeat instruction?\r
4916 {\r
4917 fprintf(fp, " sdwCyclesRemaining -= 16;\n");\r
4918 }\r
4919 }\r
4920 else\r
4921 assert(0);\r
4922}\r
4923\r
4924void IMHandler(UINT32 dwOpcode)\r
4925{\r
4926 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4927 {\r
4928 ProcBegin(dwOpcode);\r
4929\r
4930 if (dwOpcode == 0x46)\r
4931 fprintf(fp, " mov dword [_z80interruptMode], 0 ; IM 0\n");\r
4932\r
4933 if (dwOpcode == 0x56)\r
4934 {\r
4935 fprintf(fp, " mov dword [_z80interruptMode], 1 ; Interrupt mode 1\n");\r
4936 fprintf(fp, " mov word [_z80intAddr], 038h ; Interrupt mode 1 cmd!\n");\r
4937 }\r
4938\r
4939 if (dwOpcode == 0x5e)\r
4940 fprintf(fp, " mov dword [_z80interruptMode], 2 ; IM 2\n");\r
4941\r
4942 FetchNextInstruction(dwOpcode);\r
4943 }\r
4944 else\r
4945 if (MZ80_C == bWhat)\r
4946 {\r
4947 if (0x46 == dwOpcode) // IM 0\r
4948 fprintf(fp, " cpu.z80interruptMode = 0;\n");\r
4949\r
4950 if (0x56 == dwOpcode) // IM 1\r
4951 {\r
4952 fprintf(fp, " cpu.z80interruptMode = 1;\n");\r
4953 fprintf(fp, " cpu.z80intAddr = 0x38;\n");\r
4954 }\r
4955\r
4956 if (0x5e == dwOpcode) // IM 2\r
4957 fprintf(fp, " cpu.z80interruptMode = 2;\n");\r
4958 }\r
4959 else\r
4960 assert(0);\r
4961 \r
4962}\r
4963\r
4964void IRHandler(UINT32 dwOpcode)\r
4965{\r
4966 char *src, *dst;\r
4967\r
4968 if (MZ80_ASSEMBLY_X86 == bWhat)\r
4969 {\r
4970 switch(dwOpcode) \r
4971 {\r
4972 case 0x57: \r
4973 dst = "al"; src="[_z80i]"; break;\r
4974 case 0x5F: \r
4975 dst = "al"; src="[_z80r]"; break;\r
4976 case 0x47: \r
4977 dst = "[_z80i]"; src="al"; break;\r
4978 case 0x4F: \r
4979 dst = "[_z80r]"; src="al"; break;\r
4980 }\r
4981\r
4982 ProcBegin(dwOpcode);\r
4983\r
4984 fprintf(fp, " mov %s, %s\n",dst,src);\r
4985 \r
4986 if (dwOpcode == 0x5f)\r
4987 {\r
4988 fprintf(fp, " and ah, 029h ; No N, H, Z, or S!\n");\r
4989 fprintf(fp, " or al,al ; Get appropriate flags\n");\r
4990 fprintf(fp, " o16 pushf\n");\r
4991 fprintf(fp, " pop dx\n");\r
4992 fprintf(fp, " and dl, 0c0h\n");\r
4993 fprintf(fp, " or ah, dl ; OR In our S & Z flags\n");\r
4994 \r
4995 fprintf(fp, " mov dl, [_z80iff]\n");\r
4996 fprintf(fp, " and dl, IFF2\n");\r
4997 fprintf(fp, " shl dl, 1\n");\r
4998 fprintf(fp, " or ah, dl\n");\r
4999\r
5000 // Randomize R\r
5001\r
5002 fprintf(fp, " mov edx, [dwLastRSample]\n");\r
5003 fprintf(fp, " sub edx, edi\n");\r
5004 fprintf(fp, " add edx, [_z80rCounter]\n");\r
5005 fprintf(fp, " shr edx, 2\n");\r
5006 fprintf(fp, " and edx, 07fh\n");\r
5007 fprintf(fp, " and byte [_z80r], 80h\n");\r
5008 fprintf(fp, " or byte [_z80r], dl\n");\r
5009\r
5010 fprintf(fp, " xor edx, edx\n");\r
5011 fprintf(fp, " mov [dwLastRSample], edi\n");\r
5012 }\r
5013\r
5014 FetchNextInstruction(dwOpcode);\r
5015 }\r
5016 else\r
5017 if (MZ80_C == bWhat)\r
5018 {\r
5019 if (0x5f == dwOpcode) // LD A, R\r
5020 {\r
5021 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");\r
5022 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80r];\n");\r
5023 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_OVERFLOW_PARITY)) | ((cpu.z80iff & IFF2) << 1);\n");\r
5024 fprintf(fp, " cpu.z80A = cpu.z80r;\n");\r
5025\r
5026 // Now randomize a little\r
5027\r
5028 fprintf(fp, " bTemp = (cpu.z80r + (cpu.z80B + sdwCyclesRemaining + 1 + cpu.z80H)) ^ cpu.z80A;\n");\r
5029 fprintf(fp, " cpu.z80r = (cpu.z80r & 0x80) | (bTemp & 0x7f);\n");\r
5030 }\r
5031 else\r
5032 if (0x47 == dwOpcode) // LD I, A\r
5033 {\r
5034 fprintf(fp, " cpu.z80i = cpu.z80A;\n");\r
5035 }\r
5036 else\r
5037 if (0x57 == dwOpcode) // LD A, I\r
5038 {\r
5039 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");\r
5040 fprintf(fp, " cpu.z80F |= ((cpu.z80iff & IFF2) << 1);\n");\r
5041 fprintf(fp, " cpu.z80A = cpu.z80i;\n");\r
5042 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n");\r
5043 }\r
5044 else\r
5045 if (0x4f == dwOpcode) // LD R, A\r
5046 {\r
5047 fprintf(fp, " cpu.z80r = cpu.z80A;\n");\r
5048 }\r
5049 else\r
5050 {\r
5051 InvalidInstructionC(2);\r
5052 }\r
5053 }\r
5054 else\r
5055 assert(0);\r
5056}\r
5057\r
5058// DD/FD Area\r
5059\r
5060void DDFDCBHandler(UINT32 dwOpcode)\r
5061{\r
5062 UINT32 dwData = 0;\r
5063\r
5064 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5065 {\r
5066 fprintf(fp, "%sInst%.2x:\n", majorOp, dwOpcode);\r
5067 fprintf(fp, " mov dx, [esi] ; Get our instruction (and offset)\n");\r
5068 fprintf(fp, " add esi, 2 ; Increment our PC\n");\r
5069\r
5070 fprintf(fp, " mov byte [_orgval], dl ; Store our value\n");\r
5071 fprintf(fp, " or dl, dl\n");\r
5072 fprintf(fp, " js notNeg%ld\n", dwGlobalLabel);\r
5073 fprintf(fp, " mov byte [_orgval + 1], 00h;\n");\r
5074\r
5075 fprintf(fp, " jmp short jumpHandler%ld\n", dwGlobalLabel);\r
5076 fprintf(fp, "notNeg%ld:\n", dwGlobalLabel);\r
5077 fprintf(fp, " mov byte [_orgval + 1], 0ffh; It's negative\n");\r
5078 fprintf(fp, "jumpHandler%ld:\n", dwGlobalLabel++);\r
5079 fprintf(fp, " shl ebx, 16 ; Save BX away\n");\r
5080 fprintf(fp, " mov bx, [_z80%s]\n", mz80Index);\r
5081 fprintf(fp, " add [_orgval], bx\n");\r
5082 fprintf(fp, " shr ebx, 16 ; Restore BX\n");\r
5083 fprintf(fp, " mov dl, dh ; Get our instruction\n");\r
5084 fprintf(fp, " xor dh, dh ; Zero this\n");\r
5085 fprintf(fp, " jmp dword [z80ddfdcbInstructions+edx*4]\n\n");\r
5086 }\r
5087 else\r
5088 if (MZ80_C == bWhat)\r
5089 {\r
5090 if (strcmp("cpu.z80IX", mz80Index) == 0)\r
5091 dwData = 0;\r
5092 else\r
5093 dwData = 1;\r
5094\r
5095 fprintf(fp, " DDFDCBHandler(%d);\n", dwData);\r
5096 }\r
5097 else\r
5098 assert(0);\r
5099}\r
5100\r
5101void LoadIndexReg(UINT32 dwOpcode)\r
5102{\r
5103 UINT8 string[150];\r
5104\r
5105 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5106 {\r
5107 ProcBegin(dwOpcode);\r
5108\r
5109 sprintf(string, "[_z80%s]", mz80Index);\r
5110\r
5111 fprintf(fp, " mov dx, [esi] ; Get our address to store\n");\r
5112 fprintf(fp, " add esi, 2\n");\r
5113\r
5114 ReadWordFromMemory("dx", string);\r
5115 fprintf(fp, " xor edx, edx\n");\r
5116 FetchNextInstruction(dwOpcode);\r
5117 }\r
5118 else\r
5119 if (MZ80_C == bWhat)\r
5120 {\r
5121 fprintf(fp, " dwAddr = *pbPC++;\n");\r
5122 fprintf(fp, " dwAddr |= ((UINT32) *pbPC++ << 8);\n");\r
5123 ReadWordFromMemory("dwAddr", mz80Index);\r
5124 }\r
5125 else\r
5126 assert(0);\r
5127}\r
5128\r
5129void StoreIndexReg(UINT32 dwOpcode)\r
5130{\r
5131 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5132 {\r
5133 ProcBegin(dwOpcode);\r
5134\r
5135 fprintf(fp, " mov dx, [esi] ; Get our address to store\n");\r
5136 fprintf(fp, " add esi, 2\n");\r
5137 fprintf(fp, " mov [_orgval], dx\n");\r
5138\r
5139 fprintf(fp, " mov dl, [_z80%s]\n", mz80Index);\r
5140 WriteValueToMemory("[_orgval]", "dl");\r
5141\r
5142 fprintf(fp, " inc word [_orgval]\n");\r
5143\r
5144 fprintf(fp, " mov dl, [_z80%s + 1]\n", mz80Index);\r
5145 WriteValueToMemory("[_orgval]", "dl");\r
5146 fprintf(fp, " xor edx, edx\n");\r
5147 \r
5148 FetchNextInstruction(dwOpcode);\r
5149 }\r
5150 else\r
5151 if (MZ80_C == bWhat)\r
5152 {\r
5153 fprintf(fp, " dwAddr = *pbPC++;\n");\r
5154 fprintf(fp, " dwAddr |= ((UINT32) *pbPC++ << 8);\n");\r
5155 WriteWordToMemory("dwAddr", mz80Index);\r
5156 }\r
5157 else\r
5158 assert(0);\r
5159}\r
5160\r
5161void LdIndexPtrReg(UINT32 dwOpcode)\r
5162{\r
5163 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5164 {\r
5165 ProcBegin(dwOpcode);\r
5166\r
5167 IndexedOffset(mz80Index);\r
5168\r
5169 // DX Contains the address\r
5170\r
5171 WriteValueToMemory("dx", pbMathReg[dwOpcode & 0x07]);\r
5172 fprintf(fp, " xor edx, edx\n");\r
5173\r
5174 FetchNextInstruction(dwOpcode);\r
5175 }\r
5176 else\r
5177 if (MZ80_C == bWhat)\r
5178 {\r
5179 fprintf(fp, " sdwAddr = (INT8) *pbPC++; // Get the offset\n");\r
5180 fprintf(fp, " sdwAddr = ((INT32) %s + sdwAddr) & 0xffff;\n", mz80Index);\r
5181\r
5182 WriteValueToMemory("sdwAddr", pbMathRegC[dwOpcode & 0x07]);\r
5183 }\r
5184 else\r
5185 assert(0);\r
5186}\r
5187\r
5188void UndocMathIndex(UINT32 dwOpcode)\r
5189{\r
5190 UINT32 dwOpcode1 = 0;\r
5191 UINT8 *pbIndexReg = NULL;\r
5192\r
5193 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5194 {\r
5195 ProcBegin(dwOpcode);\r
5196\r
5197 if (dwOpcode & 1)\r
5198 fprintf(fp, " mov dl, byte [_z80%s]\n", mz80Index);\r
5199 else\r
5200 fprintf(fp, " mov dl, byte [_z80%s + 1]\n", mz80Index);\r
5201\r
5202 // Info is in DL - let's do the math operation\r
5203\r
5204 fprintf(fp, " sahf ; Store our flags in x86 flag reg\n");\r
5205\r
5206 dwOpcode1 = (dwOpcode & 0xf8); // Only the operation\r
5207\r
5208 if (dwOpcode1 == 0x80)\r
5209 fprintf(fp, " add al, dl\n");\r
5210 else\r
5211 if (dwOpcode1 == 0x88)\r
5212 fprintf(fp, " adc al, dl\n");\r
5213 else\r
5214 if (dwOpcode1 == 0x90)\r
5215 fprintf(fp, " sub al, dl\n");\r
5216 else\r
5217 if (dwOpcode1 == 0x98)\r
5218 fprintf(fp, " sbb al, dl\n");\r
5219 else\r
5220 if (dwOpcode1 == 0xa0)\r
5221 fprintf(fp, " and al, dl\n");\r
5222 else\r
5223 if (dwOpcode1 == 0xa8)\r
5224 fprintf(fp, " xor al, dl\n");\r
5225 else\r
5226 if (dwOpcode1 == 0xb0)\r
5227 fprintf(fp, " or al, dl\n");\r
5228 else\r
5229 if (dwOpcode1 == 0xb8)\r
5230 fprintf(fp, " cmp al, dl\n");\r
5231 else\r
5232 assert(0);\r
5233\r
5234 fprintf(fp, " lahf ; Get flags back into AH\n");\r
5235\r
5236 if (dwOpcode1 != 0xa8 && dwOpcode1 != 0xa0 && dwOpcode1 != 0xb0)\r
5237 {\r
5238 SetOverflow();\r
5239 }\r
5240\r
5241 if (dwOpcode1 == 0xa8)\r
5242 fprintf(fp, " and ah, 0ech ; Only these flags matter!\n");\r
5243\r
5244 if (dwOpcode1 == 0xa0)\r
5245 {\r
5246 fprintf(fp, " and ah, 0ech ; Only these flags matter!\n");\r
5247 fprintf(fp, " or ah, 010h ; Half carry gets set\n");\r
5248 }\r
5249\r
5250 if (dwOpcode1 == 0xb0)\r
5251 fprintf(fp, " and ah, 0ech ; No H, N, or C\n");\r
5252 \r
5253 if (dwOpcode1 == 0xb8)\r
5254 fprintf(fp, " or ah, 02h ; Negative gets set on a compare\n");\r
5255 \r
5256 if (dwOpcode1 == 0x80 || dwOpcode1 == 0x88)\r
5257 fprintf(fp, " and ah, 0fdh ; No N!\n");\r
5258 \r
5259 if (dwOpcode1 == 0x90 || dwOpcode1 == 0x98)\r
5260 fprintf(fp, " or ah, 02h ; N Gets set!\n");\r
5261 \r
5262 if (dwOpcode1 == 0xb0)\r
5263 fprintf(fp, " and ah, 0ech ; No H, N, or C\n");\r
5264 \r
5265 FetchNextInstruction(dwOpcode);\r
5266 }\r
5267 else\r
5268 if (MZ80_C == bWhat)\r
5269 {\r
5270 if (dwOpcode & 1)\r
5271 pbIndexReg = mz80IndexHalfLow;\r
5272 else\r
5273 pbIndexReg = mz80IndexHalfHigh;\r
5274\r
5275 dwOpcode1 = (dwOpcode & 0xf8); // Only the operation\r
5276\r
5277 if (0x80 == dwOpcode1) // ADD\r
5278 {\r
5279 fprintf(fp, " bTemp2 = cpu.z80A + %s;\n", pbIndexReg);\r
5280 SetAddFlagsSZHVC("cpu.z80A", pbIndexReg);\r
5281 }\r
5282 else\r
5283 if (0x88 == dwOpcode1) // ADC\r
5284 {\r
5285 fprintf(fp, " bTemp2 = cpu.z80A + %s + (cpu.z80F & Z80_FLAG_CARRY);\n", pbIndexReg);\r
5286 SetAdcFlagsSZHVC("cpu.z80A", pbIndexReg);\r
5287 }\r
5288 else\r
5289 if (0x90 == dwOpcode1) // SUB\r
5290 {\r
5291 fprintf(fp, " bTemp2 = cpu.z80A - %s;\n", pbIndexReg);\r
5292 SetSubFlagsSZHVC("cpu.z80A", pbIndexReg);\r
5293 }\r
5294 else \r
5295 if (0x98 == dwOpcode1) // SBC\r
5296 {\r
5297 fprintf(fp, " bTemp2 = cpu.z80A - %s - (cpu.z80F & Z80_FLAG_CARRY);\n", pbIndexReg);\r
5298 SetSbcFlagsSZHVC("cpu.z80A", pbIndexReg);\r
5299 }\r
5300 else\r
5301 if (0xa0 == dwOpcode1) // AND\r
5302 {\r
5303 fprintf(fp, " cpu.z80A &= %s;\n", pbIndexReg);\r
5304 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");\r
5305 fprintf(fp, " cpu.z80F |= bPostANDFlags[cpu.z80A];\n\n");\r
5306 }\r
5307 else\r
5308 if (0xa8 == dwOpcode1) // XOR\r
5309 {\r
5310 fprintf(fp, " cpu.z80A ^= %s;\n", pbIndexReg);\r
5311 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");\r
5312 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");\r
5313 }\r
5314 else\r
5315 if (0xb0 == dwOpcode1) // OR\r
5316 {\r
5317 fprintf(fp, " cpu.z80A |= %s;\n", pbIndexReg);\r
5318 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");\r
5319 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");\r
5320 }\r
5321 else\r
5322 if (0xb8 == dwOpcode1) // CP - Don't do anything! Just flags!\r
5323 {\r
5324 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");\r
5325 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");\r
5326 }\r
5327 else\r
5328 {\r
5329 assert(0);\r
5330 }\r
5331\r
5332 InvalidInstructionC(2);\r
5333 }\r
5334 else\r
5335 assert(0);\r
5336}\r
5337\r
5338void UndocLoadHalfIndexReg(UINT32 dwOpcode)\r
5339{\r
5340 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5341 {\r
5342 ProcBegin(dwOpcode);\r
5343\r
5344 fprintf(fp, " mov dl, [esi] ; Get immediate byte to load\n");\r
5345 fprintf(fp, " inc esi ; Next byte\n");\r
5346\r
5347 if (dwOpcode == 0x26)\r
5348 fprintf(fp, " mov byte [_z80%s + 1], dl\n", mz80Index);\r
5349 if (dwOpcode == 0x2e)\r
5350 fprintf(fp, " mov byte [_z80%s], dl\n", mz80Index);\r
5351\r
5352 FetchNextInstruction(dwOpcode);\r
5353 }\r
5354 else\r
5355 if (MZ80_C == bWhat)\r
5356 {\r
5357 if (dwOpcode & 0x08)\r
5358 fprintf(fp, " %s = *pbPC++;\n", mz80IndexHalfLow);\r
5359 else\r
5360 fprintf(fp, " %s = *pbPC++;\n", mz80IndexHalfHigh);\r
5361 }\r
5362 else\r
5363 assert(0);\r
5364}\r
5365\r
5366void UndocIncDecIndexReg(UINT32 dwOpcode)\r
5367{\r
5368 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5369 {\r
5370 ProcBegin(dwOpcode);\r
5371\r
5372 fprintf(fp, " sahf\n");\r
5373\r
5374 if (dwOpcode == 0x24)\r
5375 fprintf(fp, " inc byte [_z80%s + 1]\n", mz80Index);\r
5376 if (dwOpcode == 0x25)\r
5377 fprintf(fp, " dec byte [_z80%s + 1]\n", mz80Index);\r
5378\r
5379 if (dwOpcode == 0x2c)\r
5380 fprintf(fp, " inc byte [_z80%s]\n", mz80Index);\r
5381 if (dwOpcode == 0x2d)\r
5382 fprintf(fp, " dec byte [_z80%s]\n", mz80Index);\r
5383\r
5384 fprintf(fp, " lahf\n");\r
5385 SetOverflow();\r
5386\r
5387 if ((0x24 == dwOpcode) || (0x2c == dwOpcode))\r
5388 fprintf(fp, " and ah, 0fdh ; Knock out N!\n");\r
5389 else\r
5390 fprintf(fp, " or ah, 02h ; Set negative!\n");\r
5391\r
5392 FetchNextInstruction(dwOpcode);\r
5393 }\r
5394 else\r
5395 if (MZ80_C == bWhat)\r
5396 {\r
5397 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");\r
5398\r
5399 if (0x24 == dwOpcode || 0x2c == dwOpcode)\r
5400 {\r
5401 if (dwOpcode & 0x08)\r
5402 fprintf(fp, " cpu.z80F |= bPostIncFlags[%s++];\n", mz80IndexHalfLow);\r
5403 else \r
5404 fprintf(fp, " cpu.z80F |= bPostIncFlags[%s++];\n", mz80IndexHalfHigh);\r
5405 }\r
5406 else\r
5407 {\r
5408 if (dwOpcode & 0x08)\r
5409 fprintf(fp, " cpu.z80F |= bPostDecFlags[%s--];\n", mz80IndexHalfLow);\r
5410 else \r
5411 fprintf(fp, " cpu.z80F |= bPostDecFlags[%s--];\n", mz80IndexHalfHigh);\r
5412 }\r
5413 }\r
5414 else\r
5415 assert(0);\r
5416}\r
5417\r
5418void ExIndexed(UINT32 dwOpcode)\r
5419{\r
5420 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5421 {\r
5422 ProcBegin(dwOpcode);\r
5423\r
5424 if( bThroughCallHandler )\r
5425 {\r
5426 fprintf(fp, " mov dx, word [_z80%s]\n", mz80Index);\r
5427 fprintf(fp, " push dx\n");\r
5428 fprintf(fp, " call PopWord\n");\r
5429 fprintf(fp, " mov [_z80%s], dx\n", mz80Index);\r
5430 fprintf(fp, " pop dx\n");\r
5431 fprintf(fp, " mov [_wordval], dx\n" );\r
5432 fprintf(fp, " call PushWord\n" );\r
5433 } \r
5434 else \r
5435 {\r
5436 fprintf(fp, " mov [cyclesRemaining], edi\n");\r
5437 fprintf(fp, " mov dx, word [_z80sp]\n");\r
5438 fprintf(fp, " xor edi, edi\n");\r
5439 fprintf(fp, " mov di, [_z80%s]\n", mz80Index);\r
5440 fprintf(fp, " xchg di, [ebp+edx]\n");\r
5441 fprintf(fp, " mov [_z80%s], di\n", mz80Index);\r
5442 fprintf(fp, " xor edx, edx\n");\r
5443 fprintf(fp, " mov edi, [cyclesRemaining]\n");\r
5444 }\r
5445\r
5446 FetchNextInstruction(dwOpcode);\r
5447 }\r
5448 else\r
5449 if (MZ80_C == bWhat)\r
5450 {\r
5451 ReadWordFromMemory("cpu.z80sp", "dwAddr");\r
5452 WriteWordToMemory("cpu.z80sp", mz80Index);\r
5453 fprintf(fp, " %s = dwAddr;\n", mz80Index);\r
5454 }\r
5455 else\r
5456 assert(0);\r
5457}\r
5458\r
5459void IncDecIndexReg(UINT32 dwOpcode)\r
5460{\r
5461 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5462 {\r
5463 ProcBegin(dwOpcode);\r
5464\r
5465 if (dwOpcode == 0x23)\r
5466 fprintf(fp, " inc word [_z80%s] ; Increment our mz80Index register\n", mz80Index);\r
5467 else\r
5468 fprintf(fp, " dec word [_z80%s] ; Increment our mz80Index register\n", mz80Index);\r
5469\r
5470 FetchNextInstruction(dwOpcode);\r
5471 }\r
5472 else\r
5473 if (MZ80_C == bWhat)\r
5474 {\r
5475 if (0x23 == dwOpcode)\r
5476 {\r
5477 fprintf(fp, " %s++;\n", mz80Index);\r
5478 }\r
5479 else\r
5480 {\r
5481 fprintf(fp, " %s--;\n", mz80Index);\r
5482 }\r
5483\r
5484 fprintf(fp, " %s &= 0xffff;\n", mz80Index);\r
5485 }\r
5486 else\r
5487 assert(0);\r
5488}\r
5489\r
5490void LdRegIndexOffset(UINT32 dwOpcode)\r
5491{\r
5492 UINT32 dwOpcode1 = 0;\r
5493\r
5494 dwOpcode1 = (dwOpcode & 0x38) >> 3;\r
5495 \r
5496 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5497 {\r
5498 ProcBegin(dwOpcode);\r
5499\r
5500 IndexedOffset(mz80Index);\r
5501 \r
5502 ReadValueFromMemory("dx", pbMathReg[dwOpcode1]);\r
5503 \r
5504 fprintf(fp, " xor edx, edx ; Make sure we don't hose things\n");\r
5505 dwGlobalLabel++;\r
5506 FetchNextInstruction(dwOpcode);\r
5507 }\r
5508 else\r
5509 if (MZ80_C == bWhat)\r
5510 {\r
5511 fprintf(fp, " sdwAddr = (INT8) *pbPC++; // Get the offset\n");\r
5512 fprintf(fp, " sdwAddr = ((INT32) %s + sdwAddr) & 0xffff;\n", mz80Index);\r
5513\r
5514 ReadValueFromMemory("sdwAddr", pbMathRegC[dwOpcode1]);\r
5515 }\r
5516 else\r
5517 assert(0);\r
5518}\r
5519\r
5520void LdByteToIndex(UINT32 dwOpcode)\r
5521{\r
5522 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5523 {\r
5524 ProcBegin(dwOpcode);\r
5525\r
5526 fprintf(fp, " mov dx, [esi] ; Get our address\n");\r
5527 fprintf(fp, " add esi, 2 ; Skip over our storage bytes\n");\r
5528 fprintf(fp, " mov [cyclesRemaining], edi\n");\r
5529 fprintf(fp, " mov di, dx ; Store it here for later\n");\r
5530 fprintf(fp, " xor dh, dh\n");\r
5531 fprintf(fp, " or dl, dl\n");\r
5532 fprintf(fp, " jns noNegate%ld\n", dwGlobalLabel);\r
5533 fprintf(fp, " dec dh\n");\r
5534 fprintf(fp, "noNegate%ld:\n", dwGlobalLabel);\r
5535 fprintf(fp, " add dx, [_z80%s] ; Add in our index\n", mz80Index);\r
5536 fprintf(fp, " mov [_orgval], dx ; Store our address to write to\n");\r
5537 fprintf(fp, " mov dx, di\n");\r
5538 fprintf(fp, " xchg dh, dl\n");\r
5539 fprintf(fp, " mov edi, [cyclesRemaining]\n");\r
5540 \r
5541 WriteValueToMemory("[_orgval]", "dl");\r
5542 \r
5543 fprintf(fp, " xor edx, edx\n");\r
5544 ++dwGlobalLabel;\r
5545 FetchNextInstruction(dwOpcode);\r
5546 }\r
5547 else\r
5548 if (MZ80_C == bWhat)\r
5549 {\r
5550 fprintf(fp, " sdwAddr = (INT8) *pbPC++; // Get the offset\n");\r
5551 fprintf(fp, " sdwAddr = ((INT32) %s + sdwAddr) & 0xffff;\n", mz80Index);\r
5552\r
5553 WriteValueToMemory("sdwAddr", "*pbPC++");\r
5554 }\r
5555 else\r
5556 assert(0);\r
5557}\r
5558\r
5559\r
5560void SPToIndex(UINT32 dwOpcode)\r
5561{\r
5562 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5563 {\r
5564 ProcBegin(dwOpcode);\r
5565\r
5566 fprintf(fp, " mov dx, [_z80%s] ; Get our source register\n", mz80Index);\r
5567 fprintf(fp, " mov word [_z80sp], dx ; Store our new SP\n");\r
5568 fprintf(fp, " xor edx, edx\n");\r
5569\r
5570 FetchNextInstruction(dwOpcode);\r
5571 }\r
5572 else\r
5573 if (MZ80_C == bWhat)\r
5574 {\r
5575 fprintf(fp, " cpu.z80sp = %s;\n", mz80Index);\r
5576 }\r
5577 else\r
5578 assert(0);\r
5579}\r
5580\r
5581void AddIndexHandler(UINT32 dwOpcode)\r
5582{\r
5583 UINT8 bRegPair;\r
5584\r
5585 bRegPair = dwOpcode >> 4;\r
5586\r
5587 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5588 {\r
5589 ProcBegin(dwOpcode);\r
5590\r
5591 fprintf(fp, " mov dh, ah ; Get our flags\n");\r
5592 fprintf(fp, " and dh, 0ech ; Preserve the top three and bits 2 & 3\n");\r
5593\r
5594 fprintf(fp, " mov [cyclesRemaining], edi\n");\r
5595 fprintf(fp, " mov di, [_z80%s] ; Get our value\n", mz80Index);\r
5596 fprintf(fp, " mov [_orgval], di ; Store our original value\n");\r
5597 fprintf(fp, " add di, %s\n", pbIndexedRegPairs[(dwOpcode & 0x30) >> 4]);\r
5598 fprintf(fp, " lahf\n");\r
5599 fprintf(fp, " mov [_z80%s], di ; Store our register back\n", mz80Index);\r
5600\r
5601 fprintf(fp, " mov di, [_orgval] ; Get original\n");\r
5602 fprintf(fp, " xor di, word [_z80%s] ; XOR It with our computed value\n", mz80Index);\r
5603 fprintf(fp, " xor di, %s\n", pbIndexedRegPairs[(dwOpcode & 0x30) >> 4]);\r
5604 fprintf(fp, " and di, 1000h ; Just our half carry\n");\r
5605 fprintf(fp, " or dx, di ; Or in our flags\n");\r
5606 fprintf(fp, " and ah, 01h ; Just carry\n");\r
5607 fprintf(fp, " or ah, dh\n");\r
5608 fprintf(fp, " mov edi, [cyclesRemaining]\n");\r
5609 fprintf(fp, " xor edx, edx\n");\r
5610 FetchNextInstruction(dwOpcode);\r
5611 }\r
5612 else\r
5613 if (MZ80_C == bWhat)\r
5614 {\r
5615 if (bRegPair != 2)\r
5616 { \r
5617 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");\r
5618 fprintf(fp, " dwTemp = %s + %s;\n", mz80Index, pbRegPairsC[bRegPair]);\r
5619 fprintf(fp, " cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY) | (((%s ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", mz80Index, pbRegPairsC[bRegPair]);\r
5620 fprintf(fp, " %s = dwTemp & 0xffff;\n", mz80Index);\r
5621 }\r
5622 else\r
5623 {\r
5624 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");\r
5625 fprintf(fp, " dwTemp = %s + %s;\n", mz80Index, mz80Index);\r
5626 fprintf(fp, " cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY) | (((%s ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", mz80Index, pbRegPairsC[bRegPair]);\r
5627 fprintf(fp, " %s = dwTemp & 0xffff;\n", mz80Index);\r
5628 }\r
5629 }\r
5630 else\r
5631 assert(0);\r
5632}\r
5633\r
5634void JPIXIYHandler(UINT32 dwOpcode)\r
5635{\r
5636 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5637 {\r
5638 ProcBegin(dwOpcode);\r
5639\r
5640 fprintf(fp, " mov dx, [_z80%s] ; Get our value\n", mz80Index);\r
5641 fprintf(fp, " mov esi, edx ; New PC!\n");\r
5642 fprintf(fp, " add esi, ebp ; Add in our base\n");\r
5643 fprintf(fp, " xor edx, edx\n");\r
5644 FetchNextInstruction(dwOpcode);\r
5645 }\r
5646 else\r
5647 if (MZ80_C == bWhat)\r
5648 {\r
5649 fprintf(fp, " pbPC = cpu.z80Base + %s;\n", mz80Index);\r
5650 }\r
5651 else\r
5652 assert(0);\r
5653}\r
5654\r
5655void IncDecIndexed(UINT32 dwOpcode)\r
5656{\r
5657 UINT8 szIndex[30];\r
5658\r
5659 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5660 {\r
5661 ProcBegin(dwOpcode);\r
5662\r
5663 IndexedOffset(mz80Index);\r
5664\r
5665 fprintf(fp, " mov [_orgval], dx\n");\r
5666\r
5667 ReadValueFromMemory("dx", "dl");\r
5668\r
5669 fprintf(fp, " sahf\n");\r
5670\r
5671 if (dwOpcode == 0x34)\r
5672 fprintf(fp, " inc dl\n");\r
5673 else\r
5674 fprintf(fp, " dec dl\n");\r
5675 fprintf(fp, " lahf\n");\r
5676\r
5677 fprintf(fp, " o16 pushf\n");\r
5678 fprintf(fp, " shl edx, 16\n");\r
5679 fprintf(fp, " and ah, 0fbh ; Knock out parity/overflow\n");\r
5680 fprintf(fp, " pop dx\n");\r
5681 fprintf(fp, " and dh, 08h ; Just the overflow\n");\r
5682 fprintf(fp, " shr dh, 1 ; Shift it into position\n");\r
5683 fprintf(fp, " or ah, dh ; OR It in with the real flags\n");\r
5684\r
5685 fprintf(fp, " shr edx, 16\n");\r
5686\r
5687 if (dwOpcode == 0x34)\r
5688 fprintf(fp, " and ah, 0fdh ; Knock out N!\n");\r
5689 else\r
5690 fprintf(fp, " or ah, 02h ; Make it N!\n");\r
5691\r
5692 WriteValueToMemory("[_orgval]", "dl");\r
5693\r
5694 fprintf(fp, " xor edx, edx\n");\r
5695\r
5696 FetchNextInstruction(dwOpcode);\r
5697 }\r
5698 else\r
5699 if (MZ80_C == bWhat)\r
5700 {\r
5701 fprintf(fp, " sdwAddr = (INT8) *pbPC++; /* Get LSB first */\n");\r
5702 fprintf(fp, " dwAddr = (sdwAddr + (INT32) %s) & 0xffff;\n", mz80Index);\r
5703\r
5704 ReadValueFromMemory("dwAddr", "bTemp");\r
5705\r
5706 fprintf(fp, " cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");\r
5707 \r
5708 if (0x34 == dwOpcode)\r
5709 {\r
5710 fprintf(fp ," cpu.z80F |= bPostIncFlags[bTemp++];\n");\r
5711 }\r
5712 else\r
5713 {\r
5714 fprintf(fp ," cpu.z80F |= bPostDecFlags[bTemp--];\n");\r
5715 }\r
5716 \r
5717 WriteValueToMemory("dwAddr", "bTemp");\r
5718 }\r
5719 else\r
5720 assert(0);\r
5721}\r
5722\r
5723void MathOperationIndexed(UINT32 dwOpcode)\r
5724{\r
5725 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5726 {\r
5727 ProcBegin(dwOpcode);\r
5728\r
5729 IndexedOffset(mz80Index);\r
5730 ReadValueFromMemory("dx", "dl");\r
5731\r
5732 fprintf(fp, " sahf\n");\r
5733\r
5734 if (dwOpcode == 0x86) // Add\r
5735 fprintf(fp, " add al, dl\n");\r
5736 if (dwOpcode == 0x8e) // Adc\r
5737 fprintf(fp, " adc al, dl\n");\r
5738 if (dwOpcode == 0x96) // Sub\r
5739 fprintf(fp, " sub al, dl\n");\r
5740 if (dwOpcode == 0x9e) // Sbc\r
5741 fprintf(fp, " sbb al, dl\n");\r
5742 if (dwOpcode == 0xa6) // And\r
5743 fprintf(fp, " and al, dl\n");\r
5744 if (dwOpcode == 0xae) // Xor\r
5745 fprintf(fp, " xor al, dl\n");\r
5746 if (dwOpcode == 0xb6) // Or\r
5747 fprintf(fp, " or al, dl\n");\r
5748 if (dwOpcode == 0xbe) // Cp\r
5749 fprintf(fp, " cmp al, dl\n");\r
5750\r
5751 fprintf(fp, " lahf\n");\r
5752\r
5753 if (dwOpcode == 0x86 || dwOpcode == 0x8e)\r
5754 {\r
5755 SetOverflow();\r
5756 fprintf(fp, " and ah, 0fdh ; Knock out negative\n");\r
5757 }\r
5758\r
5759 if (dwOpcode == 0x96 || dwOpcode == 0x9e || dwOpcode == 0xbe)\r
5760 {\r
5761 SetOverflow();\r
5762 fprintf(fp, " or ah, 02h ; Set negative\n");\r
5763 }\r
5764\r
5765 if (dwOpcode == 0xae || dwOpcode == 0xb6)\r
5766 fprintf(fp, " and ah, 0ech ; Knock out H, N, and C\n");\r
5767\r
5768 if (dwOpcode == 0xa6)\r
5769 {\r
5770 fprintf(fp, " and ah,0fch ; Knock out N & C\n");\r
5771 fprintf(fp, " or ah, 10h ; Set half carry\n");\r
5772 }\r
5773\r
5774 fprintf(fp, " xor edx, edx\n");\r
5775 FetchNextInstruction(dwOpcode);\r
5776 }\r
5777 else\r
5778 if (MZ80_C == bWhat)\r
5779 {\r
5780 fprintf(fp, " sdwAddr = (INT8) *pbPC++; /* Get LSB first */\n");\r
5781 fprintf(fp, " dwAddr = (sdwAddr + (INT32) %s) & 0xffff;\n", mz80Index);\r
5782\r
5783 ReadValueFromMemory("dwAddr", "bTemp");\r
5784\r
5785 if (0x86 == dwOpcode) // ADD A, (IX/IY+nn)\r
5786 {\r
5787 SetAddFlagsSZHVC("cpu.z80A", "bTemp");\r
5788 fprintf(fp, " cpu.z80A += bTemp;\n");\r
5789 }\r
5790 else\r
5791 if (0x8e == dwOpcode) // ADC A, (IX/IY+nn)\r
5792 {\r
5793 fprintf(fp, " bTemp2 = (cpu.z80F & Z80_FLAG_CARRY);\n");\r
5794 SetAdcFlagsSZHVC("cpu.z80A", "bTemp");\r
5795 fprintf(fp, " cpu.z80A += bTemp + bTemp2;\n");\r
5796 }\r
5797 else\r
5798 if (0x96 == dwOpcode) // SUB A, (IX/IY+nn)\r
5799 {\r
5800 SetSubFlagsSZHVC("cpu.z80A", "bTemp");\r
5801 fprintf(fp, " cpu.z80A -= bTemp;\n");\r
5802 }\r
5803 else\r
5804 if (0x9e == dwOpcode) // SBC A, (IX/IY+nn)\r
5805 {\r
5806 fprintf(fp, " bTemp2 = cpu.z80A;\n");\r
5807 fprintf(fp, " cpu.z80A = cpu.z80A - bTemp - (cpu.z80F & Z80_FLAG_CARRY);\n");\r
5808 SetSbcFlagsSZHVC("bTemp2", "bTemp");\r
5809 }\r
5810 else\r
5811 if (0xa6 == dwOpcode) // AND A, (IX/IY+nn)\r
5812 {\r
5813 fprintf(fp, " cpu.z80A &= bTemp;\n");\r
5814 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");\r
5815 fprintf(fp, " cpu.z80F |= bPostANDFlags[cpu.z80A];\n\n");\r
5816 }\r
5817 else\r
5818 if (0xae == dwOpcode) // XOR A, (IX/IY+nn)\r
5819 {\r
5820 fprintf(fp, " cpu.z80A ^= bTemp;\n");\r
5821 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");\r
5822 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");\r
5823 }\r
5824 else\r
5825 if (0xb6 == dwOpcode) // OR A, (IX/IY+nn)\r
5826 {\r
5827 fprintf(fp, " cpu.z80A |= bTemp;\n");\r
5828 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");\r
5829 fprintf(fp, " cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");\r
5830 }\r
5831 else\r
5832 if (0xbe == dwOpcode) // CP A, (IX/IY+nn)\r
5833 {\r
5834 SetSubFlagsSZHVC("cpu.z80A", "bTemp");\r
5835 }\r
5836 else\r
5837 InvalidInstructionC(2);\r
5838 }\r
5839 else\r
5840 assert(0);\r
5841}\r
5842\r
5843void UndocIndexToReg(UINT32 dwOpcode)\r
5844{\r
5845 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5846 {\r
5847 ProcBegin(dwOpcode);\r
5848\r
5849 if ((dwOpcode & 0x07) == 2 || (dwOpcode & 0x07) == 3)\r
5850 fprintf(fp, " mov dx, [_z80de] ; Get DE\n");\r
5851\r
5852 if ((dwOpcode & 0x07) == 4)\r
5853 fprintf(fp, " mov dh, byte [_z80%s + 1]\n", mz80Index);\r
5854 if ((dwOpcode & 0x07) == 5)\r
5855 fprintf(fp, " mov dl, byte [_z80%s]\n", mz80Index);\r
5856\r
5857 fprintf(fp, " mov byte [_z80%s + %ld], %s\n", mz80Index, 1 - ((dwOpcode & 0x08) >> 3), pbLocalReg[dwOpcode & 0x07]);\r
5858 fprintf(fp, " xor edx, edx\n");\r
5859 FetchNextInstruction(dwOpcode);\r
5860 }\r
5861 else\r
5862 if (MZ80_C == bWhat)\r
5863 {\r
5864 if (dwOpcode != 0x64 && dwOpcode != 0x65 && dwOpcode != 0x6c && dwOpcode != 0x6d)\r
5865 {\r
5866 if (dwOpcode & 0x08)\r
5867 fprintf(fp, " %s = %s;\n", mz80IndexHalfLow, pbLocalRegC[dwOpcode & 0x07]);\r
5868 else\r
5869 fprintf(fp, " %s = %s;\n", mz80IndexHalfHigh, pbLocalRegC[dwOpcode & 0x07]);\r
5870 }\r
5871 else // IX/IY High/low weirdness afoot...\r
5872 {\r
5873 // We don't generate any code for ld indexH, indexH and ld indexL, indexL\r
5874\r
5875 if (0x65 == dwOpcode) // LD indexH, indexL\r
5876 {\r
5877 fprintf(fp, " %s = %s;\n", mz80IndexHalfHigh, mz80IndexHalfLow);\r
5878 }\r
5879 else\r
5880 if (0x6c == dwOpcode) // LD indexH, indexL\r
5881 {\r
5882 fprintf(fp, " %s = %s;\n", mz80IndexHalfLow, mz80IndexHalfHigh);\r
5883 }\r
5884 }\r
5885 }\r
5886 else\r
5887 assert(0);\r
5888}\r
5889\r
5890void UndocRegToIndex(UINT32 dwOpcode)\r
5891{\r
5892 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5893 {\r
5894 ProcBegin(dwOpcode);\r
5895\r
5896 if ((dwOpcode & 0x38) == 0x10 || (dwOpcode & 0x38) == 0x18)\r
5897 fprintf(fp, " mov dx, [_z80de] ; Get a usable copy of DE here\n");\r
5898\r
5899 fprintf(fp, " mov %s, byte [_z80%s + %ld]\n", pbLocalReg[(dwOpcode >> 3) & 0x07], mz80Index, 1 - (dwOpcode & 1));\r
5900\r
5901 if ((dwOpcode & 0x38) == 0x10 || (dwOpcode & 0x38) == 0x18)\r
5902 fprintf(fp, " mov [_z80de], dx ; Put it back!\n");\r
5903\r
5904 fprintf(fp, " xor edx, edx\n");\r
5905 FetchNextInstruction(dwOpcode);\r
5906 }\r
5907 else\r
5908 if (MZ80_C == bWhat)\r
5909 {\r
5910 if (dwOpcode & 1)\r
5911 fprintf(fp, " %s = %s;\n", pbLocalRegC[(dwOpcode >> 3) & 0x07], mz80IndexHalfLow);\r
5912 else\r
5913 fprintf(fp, " %s = %s;\n", pbLocalRegC[(dwOpcode >> 3) & 0x07], mz80IndexHalfHigh);\r
5914 }\r
5915 else\r
5916 assert(0);\r
5917}\r
5918\r
5919void LoadImmediate(UINT32 dwOpcode)\r
5920{\r
5921 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5922 {\r
5923 ProcBegin(dwOpcode);\r
5924\r
5925 fprintf(fp, " mov dx, [esi] ; Get our word to load\n");\r
5926 fprintf(fp, " add esi, 2 ; Advance past the word\n");\r
5927 fprintf(fp, " mov [_z80%s], dx ; Store our new value\n", mz80Index);\r
5928 fprintf(fp, " xor edx, edx\n");\r
5929\r
5930 FetchNextInstruction(dwOpcode);\r
5931 }\r
5932 else\r
5933 if (MZ80_C == bWhat)\r
5934 {\r
5935 fprintf(fp, " %s = *pbPC++;\n", mz80Index);\r
5936 fprintf(fp, " %s |= ((UINT32) *pbPC++ << 8);\n", mz80Index);\r
5937 }\r
5938 else\r
5939 assert(0);\r
5940}\r
5941\r
5942void PushPopOperationsIndexed(UINT32 dwOpcode)\r
5943{\r
5944 UINT8 bRegPair;\r
5945 UINT8 bRegBaseLsb[25];\r
5946 UINT8 bRegBaseMsb[25];\r
5947 UINT8 string[150];\r
5948\r
5949 if (MZ80_ASSEMBLY_X86 == bWhat)\r
5950 {\r
5951 sprintf(bRegBaseLsb, "byte [_z80%s]", mz80Index);\r
5952 sprintf(bRegBaseMsb, "byte [_z80%s + 1]", mz80Index);\r
5953\r
5954 sprintf(string, "[_z80%s]", mz80Index);\r
5955\r
5956 ProcBegin(dwOpcode);\r
5957\r
5958 if (dwOpcode == 0xe5) // Push IX/IY\r
5959 {\r
5960 fprintf(fp, " sub word [_z80sp], 2\n");\r
5961 fprintf(fp, " mov dx, [_z80sp]\n");\r
5962 \r
5963 WriteWordToMemory("dx", string); \r
5964 }\r
5965 else // Pop\r
5966 {\r
5967 fprintf(fp, " mov dx, [_z80sp]\n");\r
5968 ReadWordFromMemory("dx", string);\r
5969 fprintf(fp, " add word [_z80sp], 2\n");\r
5970 } \r
5971\r
5972 fprintf(fp, " xor edx, edx\n");\r
5973 FetchNextInstruction(dwOpcode);\r
5974 }\r
5975 else\r
5976 if (MZ80_C == bWhat)\r
5977 {\r
5978 if (0xe5 == dwOpcode) // Push IX/IY\r
5979 {\r
5980 fprintf(fp, " cpu.z80sp -= 2;\n");\r
5981 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp); /* Normalize the stack pointer */\n");\r
5982 \r
5983 WriteWordToMemory("cpu.z80sp", mz80Index);\r
5984 }\r
5985 else\r
5986 if (0xe1 == dwOpcode) // Pop IX/IY\r
5987 {\r
5988 ReadWordFromMemory("cpu.z80sp", mz80Index);\r
5989\r
5990 fprintf(fp, " cpu.z80sp += 2;\n");\r
5991 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp); /* Normalize the stack pointer */\n");\r
5992 return;\r
5993 }\r
5994 }\r
5995 else\r
5996 assert(0);\r
5997}\r
5998\r
5999// DDFD XXCB Instructions\r
6000\r
6001void ddcbBitWise(UINT32 dwOpcode)\r
6002{\r
6003 if (MZ80_ASSEMBLY_X86 == bWhat)\r
6004 {\r
6005 ProcBegin(dwOpcode);\r
6006 \r
6007 // NOTE: _orgval contains the address to get from. It includes the offset\r
6008 // already computed plus the mz80Index register.\r
6009\r
6010 // Read our byte\r
6011\r
6012 fprintf(fp, " mov dx, [_orgval] ; Get our target address\n");\r
6013 ReadValueFromMemory("dx", "dl");\r
6014\r
6015 // Do the operation\r
6016\r
6017 if (dwOpcode != 0x06 && dwOpcode != 0x0e &&\r
6018 dwOpcode != 0x16 && dwOpcode != 0x1e &&\r
6019 dwOpcode != 0x26 && dwOpcode != 0x2e &&\r
6020 dwOpcode != 0x3e && (dwOpcode & 0xc7) != 0x86 &&\r
6021 (dwOpcode & 0xc7) != 0xc6)\r
6022 {\r
6023 fprintf(fp, " mov dh, ah ; Store our original flags\n");\r
6024 fprintf(fp, " and dh, 29h ; Keep our old flags\n");\r
6025 }\r
6026\r
6027 if ((dwOpcode & 0xc7) != 0x86 && (dwOpcode & 0xc7) != 0xc6)\r
6028 fprintf(fp, " sahf ; Restore our flags\n");\r
6029\r
6030 if (dwOpcode == 0x06)\r
6031 fprintf(fp, " rol dl, 1\n");\r
6032 if (dwOpcode == 0x0e)\r
6033 fprintf(fp, " ror dl, 1\n");\r
6034 if (dwOpcode == 0x16)\r
6035 fprintf(fp, " rcl dl, 1\n");\r
6036 if (dwOpcode == 0x1e)\r
6037 fprintf(fp, " rcr dl, 1\n");\r
6038 if (dwOpcode == 0x26)\r
6039 fprintf(fp, " shl dl, 1\n");\r
6040 if (dwOpcode == 0x2e)\r
6041 fprintf(fp, " sar dl, 1\n");\r
6042 if (dwOpcode == 0x3e)\r
6043 fprintf(fp, " shr dl, 1\n");\r
6044\r
6045 // BIT, AND, and OR\r
6046\r
6047 if ((dwOpcode & 0xc7) == 0x46)\r
6048 fprintf(fp, " test dl, 0%.2xh ; Is it set?\n", (1 << ((dwOpcode >> 3) & 0x07)));\r
6049 else\r
6050 if ((dwOpcode & 0xc7) == 0x86)\r
6051 fprintf(fp, " and dl, 0%.2xh ; Reset the bit\n", \r
6052 0xff - (1 << ((dwOpcode >> 3) & 0x07)));\r
6053 else\r
6054 if ((dwOpcode & 0xc7) == 0xc6)\r
6055 fprintf(fp, " or dl, 0%.2xh ; Set the bit\n",\r
6056 (1 << ((dwOpcode >> 3) & 0x07)));\r
6057 \r
6058 if ((dwOpcode & 0xc7) != 0x86 && (dwOpcode & 0xc7) != 0xc6)\r
6059 fprintf(fp, " lahf ; Get our flags back\n"); \r
6060\r
6061 // Do the flag fixup (if any)\r
6062\r
6063 if (dwOpcode == 0x26 || dwOpcode == 0x2e || ((dwOpcode & 0xc7) == 0x46))\r
6064 fprintf(fp, " and ah, 0edh ; No Half carry or negative!\n");\r
6065 \r
6066 if (dwOpcode == 0x06 || dwOpcode == 0x0e ||\r
6067 dwOpcode == 0x16 || dwOpcode == 0x1e ||\r
6068 dwOpcode == 0x3e)\r
6069 fprintf(fp, " and ah, 0edh ; Knock out H & N\n");\r
6070\r
6071 // BIT!\r
6072\r
6073 if ((dwOpcode & 0xc7) == 0x46)\r
6074 {\r
6075 fprintf(fp, " or ah, 10h ; OR In our half carry\n");\r
6076 fprintf(fp, " and ah, 0d0h ; New flags\n");\r
6077 fprintf(fp, " or ah, dh ; OR In our old flags\n");\r
6078 }\r
6079\r
6080 // Now write our data back if it's not a BIT instruction\r
6081\r
6082 if ((dwOpcode & 0xc7) != 0x46) // If it's not a BIT, write it back\r
6083 WriteValueToMemory("[_orgval]", "dl");\r
6084 \r
6085 fprintf(fp, " xor edx, edx\n");\r
6086 FetchNextInstruction(dwOpcode);\r
6087 }\r
6088 else\r
6089 if (MZ80_C == bWhat)\r
6090 {\r
6091 if (0x06 == dwOpcode) // RLC\r
6092 {\r
6093 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");\r
6094 fprintf(fp, " bTemp2 = (bTemp >> 7);\n");\r
6095 fprintf(fp, " bTemp = (bTemp << 1) | bTemp2;\n");\r
6096 fprintf(fp, " cpu.z80F |= bTemp2 | bPostORFlags[bTemp];\n");\r
6097 WriteValueToMemory("dwAddr", "bTemp");\r
6098 }\r
6099 else\r
6100 if (0x0e == dwOpcode) // RRC\r
6101 {\r
6102 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");\r
6103 fprintf(fp, " cpu.z80F |= (bTemp & Z80_FLAG_CARRY);\n");\r
6104 fprintf(fp, " bTemp = (bTemp >> 1) | (bTemp << 7);\n");\r
6105 fprintf(fp, " cpu.z80F |= bPostORFlags[bTemp];\n");\r
6106 WriteValueToMemory("dwAddr", "bTemp");\r
6107 }\r
6108 else\r
6109 if (0x16 == dwOpcode) // RL\r
6110 {\r
6111 fprintf(fp, " bTemp2 = cpu.z80F & Z80_FLAG_CARRY;\n");\r
6112 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");\r
6113 fprintf(fp, " cpu.z80F |= (bTemp >> 7);\n");\r
6114 fprintf(fp, " bTemp = (bTemp << 1) | bTemp2;\n");\r
6115 fprintf(fp, " cpu.z80F |= bPostORFlags[bTemp];\n");\r
6116 WriteValueToMemory("dwAddr", "bTemp");\r
6117 }\r
6118 else\r
6119 if (0x1e == dwOpcode) // RR\r
6120 {\r
6121 fprintf(fp, " bTemp2 = (cpu.z80F & Z80_FLAG_CARRY) << 7;\n");\r
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");\r
6123 fprintf(fp, " cpu.z80F |= (bTemp & Z80_FLAG_CARRY);\n");\r
6124 fprintf(fp, " bTemp = (bTemp >> 1) | bTemp2;\n");\r
6125 fprintf(fp, " cpu.z80F |= bPostORFlags[bTemp];\n");\r
6126 WriteValueToMemory("dwAddr", "bTemp");\r
6127 }\r
6128 else\r
6129 if (0x26 == dwOpcode) // SLA\r
6130 {\r
6131 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");\r
6132 fprintf(fp, " cpu.z80F |= (bTemp >> 7);\n");\r
6133 fprintf(fp, " bTemp = (bTemp << 1);\n");\r
6134 fprintf(fp, " cpu.z80F |= bPostORFlags[bTemp];\n");\r
6135 WriteValueToMemory("dwAddr", "bTemp");\r
6136 }\r
6137 else\r
6138 if (0x2e == dwOpcode) // SRA\r
6139 {\r
6140 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");\r
6141 fprintf(fp, " cpu.z80F |= (bTemp & Z80_FLAG_CARRY);\n");\r
6142 fprintf(fp, " bTemp = (bTemp >> 1) | (bTemp & 0x80);\n");\r
6143 fprintf(fp, " cpu.z80F |= bPostORFlags[bTemp];\n");\r
6144 WriteValueToMemory("dwAddr", "bTemp");\r
6145 }\r
6146 else\r
6147 if (0x3e == dwOpcode) // SRL\r
6148 {\r
6149 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");\r
6150 fprintf(fp, " cpu.z80F |= (bTemp & Z80_FLAG_CARRY);\n");\r
6151 fprintf(fp, " bTemp = (bTemp >> 1);\n");\r
6152 fprintf(fp, " cpu.z80F |= bPostORFlags[bTemp];\n");\r
6153 WriteValueToMemory("dwAddr", "bTemp");\r
6154 }\r
6155 else\r
6156 if ((dwOpcode & 0xc0) == 0x40) // BIT\r
6157 {\r
6158 fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_ZERO | Z80_FLAG_NEGATIVE)) | Z80_FLAG_HALF_CARRY;\n");\r
6159 fprintf(fp, " if (!(bTemp & 0x%.2x))\n", 1 << ((dwOpcode >> 3) & 0x07));\r
6160 fprintf(fp, " {\n");\r
6161 fprintf(fp, " cpu.z80F |= Z80_FLAG_ZERO;\n");\r
6162 fprintf(fp, " }\n");\r
6163 }\r
6164 else\r
6165 if ((dwOpcode & 0xc0) == 0x80) // RES\r
6166 {\r
6167 fprintf(fp, " bTemp &= 0x%.2x;\n", ~(1 << ((dwOpcode >> 3) & 0x07)) & 0xff);\r
6168 WriteValueToMemory("dwAddr", "bTemp");\r
6169 }\r
6170 else\r
6171 if ((dwOpcode & 0xc0) == 0xC0) // SET\r
6172 {\r
6173 fprintf(fp, " bTemp |= 0x%.2x;\n", 1 << ((dwOpcode >> 3) & 0x07));\r
6174 WriteValueToMemory("dwAddr", "bTemp");\r
6175 }\r
6176 else\r
6177 InvalidInstructionC(4);\r
6178 }\r
6179 else\r
6180 assert(0);\r
6181}\r
6182\r
6183GetTicksCode()\r
6184{\r
6185 if (MZ80_ASSEMBLY_X86 == bWhat)\r
6186 {\r
6187 fprintf(fp, " global _%sGetElapsedTicks\n", cpubasename);\r
6188 fprintf(fp, " global %sGetElapsedTicks_\n", cpubasename);\r
6189 fprintf(fp, " global %sGetElapsedTicks\n", cpubasename);\r
6190 \r
6191 Alignment();\r
6192 sprintf(procname, "%sGetElapsedTicks_", cpubasename);\r
6193 ProcBegin(0xffffffff);\r
6194 fprintf(fp, "_%sGetElapsedTicks:\n", cpubasename);\r
6195 fprintf(fp, "%sGetElapsedTicks:\n", cpubasename);\r
6196 \r
6197 if (bUseStack)\r
6198 fprintf(fp, " mov eax, [esp+4] ; Get our context address\n");\r
6199 \r
6200 fprintf(fp, " or eax, eax ; Should we clear it?\n");\r
6201 fprintf(fp, " jz getTicks\n");\r
6202 fprintf(fp, " xor eax, eax\n");\r
6203 fprintf(fp, " xchg eax, [dwElapsedTicks]\n");\r
6204 fprintf(fp, " ret\n");\r
6205 fprintf(fp, "getTicks:\n");\r
6206 fprintf(fp, " mov eax, [dwElapsedTicks]\n");\r
6207 fprintf(fp, " ret\n");\r
6208 }\r
6209 else\r
6210 if (MZ80_C == bWhat)\r
6211 {\r
6212 fprintf(fp, "/* This will return the elapsed ticks */\n\n");\r
6213 fprintf(fp, "UINT32 %sGetElapsedTicks(UINT32 dwClear)\n", cpubasename);\r
6214 fprintf(fp, "{\n");\r
6215 fprintf(fp, " UINT32 dwTemp = dwElapsedTicks;\n\n");\r
6216 fprintf(fp, " if (dwClear)\n");\r
6217 fprintf(fp, " {\n");\r
6218 fprintf(fp, " dwElapsedTicks = 0;\n");\r
6219 fprintf(fp, " }\n\n");\r
6220 fprintf(fp, " return(dwTemp);\n");\r
6221 fprintf(fp, "}\n\n");\r
6222 }\r
6223 else\r
6224 {\r
6225 assert(0);\r
6226 }\r
6227}\r
6228\r
6229ReleaseTimesliceCode()\r
6230{\r
6231 if (MZ80_ASSEMBLY_X86 == bWhat)\r
6232 {\r
6233 fprintf(fp, " global _%sReleaseTimeslice\n", cpubasename);\r
6234 fprintf(fp, " global %sReleaseTimeslice_\n", cpubasename);\r
6235 fprintf(fp, " global %sReleaseTimeslice\n", cpubasename);\r
6236 \r
6237 Alignment();\r
6238 sprintf(procname, "%sReleaseTimeslice_", cpubasename);\r
6239 ProcBegin(0xffffffff);\r
6240 fprintf(fp, "_%sReleaseTimeslice:\n", cpubasename);\r
6241 fprintf(fp, "%sReleaseTimeslice:\n", cpubasename);\r
6242 \r
6243 fprintf(fp, " mov eax, [cyclesRemaining]\n");\r
6244 fprintf(fp, " sub [dwOriginalExec], eax\n");\r
6245 fprintf(fp, " mov [cyclesRemaining], dword 0\n");\r
6246 \r
6247 fprintf(fp, " ret\n\n");\r
6248 }\r
6249 else\r
6250 if (MZ80_C == bWhat)\r
6251 {\r
6252 fprintf(fp, "/* Releases mz80 from its current timeslice */\n\n");\r
6253 fprintf(fp, "void %sReleaseTimeslice(void)\n", cpubasename);\r
6254 fprintf(fp, "{\n");\r
6255 fprintf(fp, " dwOriginalCycles -= sdwCyclesRemaining;\n");\r
6256 fprintf(fp, " sdwCyclesRemaining = 0;\n");\r
6257 fprintf(fp, "}\n\n");\r
6258 }\r
6259 else\r
6260 {\r
6261 assert(0);\r
6262 }\r
6263}\r
6264\r
6265DataSegment()\r
6266{\r
6267 UINT32 dwLoop = 0;\r
6268 UINT8 bUsed[256];\r
6269\r
6270 if (MZ80_ASSEMBLY_X86 == bWhat)\r
6271 {\r
6272 if (bOS2)\r
6273 fprintf(fp, " section .DATA32 use32 flat class=data\n");\r
6274 else\r
6275 fprintf(fp, " section .data use32 flat class=data\n");\r
6276 \r
6277 Alignment();\r
6278 fprintf(fp, " global _%scontextBegin\n", cpubasename);\r
6279 fprintf(fp, "_%scontextBegin:\n", cpubasename);\r
6280\r
6281 fprintf(fp, " global _z80pc\n");\r
6282 fprintf(fp, " global z80pc_\n");\r
6283\r
6284 if (bPlain)\r
6285 fprintf(fp, " global z80pc\n");\r
6286\r
6287 fprintf(fp, " global _z80nmiAddr\n");\r
6288 fprintf(fp, " global _z80intAddr\n");\r
6289 fprintf(fp, " global z80intAddr\n");\r
6290\r
6291 fprintf(fp, "\n");\r
6292 fprintf(fp, "; DO NOT CHANGE THE ORDER OF AF, BC, DE, HL and THE PRIME REGISTERS!\n");\r
6293 fprintf(fp, "\n");\r
6294 fprintf(fp, "_z80Base dd 0 ; Base address for Z80 stuff\n");\r
6295 fprintf(fp, "_z80MemRead dd 0 ; Offset of memory read structure array\n");\r
6296 fprintf(fp, "_z80MemWrite dd 0 ; Offset of memory write structure array\n");\r
6297 fprintf(fp, "_z80IoRead dd 0 ; Base address for I/O reads list\n");\r
6298 fprintf(fp, "_z80IoWrite dd 0 ; Base address for I/O write list\n");\r
6299 fprintf(fp, "_z80clockticks dd 0 ; # Of clock tips that have elapsed\n");\r
6300 fprintf(fp, "_z80iff dd 0 ; Non-zero if we're in an interrupt\n");\r
6301 fprintf(fp, "_z80interruptMode dd 0 ; Interrupt mode\n");\r
6302 fprintf(fp, "_z80halted dd 0 ; 0=Not halted, 1=Halted\n");\r
6303#ifdef MZ80_TRAP\r
6304 fprintf(fp, "_z80trapList dd 0 ; pointer to trap list\n");\r
6305 fprintf(fp, "_z80trapAddr dw 0 ; PC where trap occurred\n");\r
6306#endif\r
6307 fprintf(fp, "_z80af dd 0 ; A Flag & Flags\n");\r
6308 fprintf(fp, "_z80bc dd 0 ; BC\n");\r
6309 fprintf(fp, "_z80de dd 0 ; DE\n");\r
6310 fprintf(fp, "_z80hl dd 0 ; HL\n");\r
6311 fprintf(fp, "_z80afprime dd 0 ; A Flag & Flags prime\n");\r
6312 fprintf(fp, "_z80bcprime dd 0 ; BC prime\n");\r
6313 fprintf(fp, "_z80deprime dd 0 ; DE prime\n");\r
6314 fprintf(fp, "_z80hlprime dd 0 ; HL prime\n");\r
6315 fprintf(fp, "\n");\r
6316 fprintf(fp, "; The order of the following registers can be changed without adverse\n");\r
6317 fprintf(fp, "; effect. Keep the WORD and DWORDs on boundaries of two for faster access\n");\r
6318 fprintf(fp, "\n");\r
6319 fprintf(fp, "_z80ix dd 0 ; IX\n");\r
6320 fprintf(fp, "_z80iy dd 0 ; IY\n");\r
6321 fprintf(fp, "_z80sp dd 0 ; Stack pointer\n");\r
6322 \r
6323 if (bPlain)\r
6324 fprintf(fp,"z80pc:\n");\r
6325 \r
6326 fprintf(fp, "z80pc_:\n");\r
6327 fprintf(fp, "_z80pc dd 0 ; PC\n");\r
6328 fprintf(fp, "_z80nmiAddr dd 0 ; Address to jump to for NMI\n");\r
6329 fprintf(fp, "z80intAddr:\n");\r
6330 fprintf(fp, "_z80intAddr dd 0 ; Address to jump to for INT\n");\r
6331 fprintf(fp, "_z80rCounter dd 0 ; R Register counter\n");\r
6332 fprintf(fp, "_z80i db 0 ; I register\n");\r
6333 fprintf(fp, "_z80r db 0 ; R register\n");\r
6334 fprintf(fp, "_z80intPending db 0 ; Non-zero if an interrupt is pending\n");\r
6335 fprintf(fp, "\n");\r
6336 fprintf(fp, "_%scontextEnd:\n", cpubasename);\r
6337 Alignment();\r
6338 fprintf(fp, "dwElapsedTicks dd 0 ; # Of ticks elapsed\n");\r
6339 fprintf(fp, "cyclesRemaining dd 0 ; # Of cycles remaining\n");\r
6340 fprintf(fp, "dwOriginalExec dd 0 ; # Of cycles originally executing\n");\r
6341 fprintf(fp, "dwLastRSample dd 0 ; Last sample for R computation\n");\r
6342 fprintf(fp, "dwEITiming dd 0 ; Used when we cause an interrupt\n");\r
6343 fprintf(fp, "_orgval dw 0 ; Scratch area\n");\r
6344 fprintf(fp, "_orgval2 dw 0 ; Scratch area\n");\r
6345 fprintf(fp, "_wordval dw 0 ; Scratch area\n");\r
6346 fprintf(fp, "_intData db 0 ; Interrupt data when an interrupt is pending\n");\r
6347 fprintf(fp, "bEIExit db 0 ; Are we exiting because of an EI instruction?\n");\r
6348 fprintf(fp, "\n");\r
6349\r
6350 // Debugger junk\r
6351\r
6352 fprintf(fp, "RegTextPC db 'PC',0\n");\r
6353 fprintf(fp, "RegTextAF db 'AF',0\n");\r
6354 fprintf(fp, "RegTextBC db 'BC',0\n");\r
6355 fprintf(fp, "RegTextDE db 'DE',0\n");\r
6356 fprintf(fp, "RegTextHL db 'HL',0\n");\r
6357 fprintf(fp, "RegTextAFP db 'AF',27h,0\n");\r
6358 fprintf(fp, "RegTextBCP db 'BC',27h,0\n");\r
6359 fprintf(fp, "RegTextDEP db 'DE',27h,0\n");\r
6360 fprintf(fp, "RegTextHLP db 'HL',27h,0\n");\r
6361 fprintf(fp, "RegTextIX db 'IX',0\n");\r
6362 fprintf(fp, "RegTextIY db 'IY',0\n");\r
6363 fprintf(fp, "RegTextSP db 'SP',0\n");\r
6364 fprintf(fp, "RegTextI db 'I',0\n");\r
6365 fprintf(fp, "RegTextR db 'R',0\n");\r
6366\r
6367 // 8 Byte textual info\r
6368\r
6369 fprintf(fp, "RegTextA db 'A',0\n");\r
6370 fprintf(fp, "RegTextB db 'B',0\n");\r
6371 fprintf(fp, "RegTextC db 'C',0\n");\r
6372 fprintf(fp, "RegTextD db 'D',0\n");\r
6373 fprintf(fp, "RegTextE db 'E',0\n");\r
6374 fprintf(fp, "RegTextH db 'H',0\n");\r
6375 fprintf(fp, "RegTextL db 'L',0\n");\r
6376 fprintf(fp, "RegTextF db 'F',0\n");\r
6377\r
6378 // Individual flags\r
6379\r
6380 fprintf(fp, "RegTextCarry db 'Carry',0\n");\r
6381 fprintf(fp, "RegTextNegative db 'Negative',0\n");\r
6382 fprintf(fp, "RegTextParity db 'Parity',0\n");\r
6383 fprintf(fp, "RegTextOverflow db 'Overflow',0\n");\r
6384 fprintf(fp, "RegTextHalfCarry db 'HalfCarry',0\n");\r
6385 fprintf(fp, "RegTextZero db 'Zero',0\n");\r
6386 fprintf(fp, "RegTextSign db 'Sign',0\n");\r
6387 fprintf(fp, "RegTextIFF1 db 'IFF1',0\n");\r
6388 fprintf(fp, "RegTextIFF2 db 'IFF2',0\n\n");\r
6389\r
6390 // Timing for interrupt modes\r
6391\r
6392 fprintf(fp, "intModeTStates:\n");\r
6393 fprintf(fp, " db 13 ; IM 0 - 13 T-States\n");\r
6394 fprintf(fp, " db 11 ; IM 1 - 11 T-States\n");\r
6395 fprintf(fp, " db 11 ; IM 2 - 11 T-States\n\n");\r
6396\r
6397 // Now the master reg/flag table\r
6398\r
6399 fprintf(fp, "\n;\n");\r
6400 fprintf(fp, "; Info is in: pointer to text, address, shift value, mask value, size of data chunk\n");\r
6401 fprintf(fp, ";\n\n");\r
6402 fprintf(fp, "RegTable:\n");\r
6403\r
6404 // Pointer to text, address, shift value, mask, size\r
6405\r
6406 fprintf(fp, " dd RegTextPC, _z80pc - _%scontextBegin, 0, 0ffffh\n", cpubasename);\r
6407 fprintf(fp, " dd RegTextSP, _z80sp - _%scontextBegin, 0, 0ffffh\n", cpubasename);\r
6408 fprintf(fp, " dd RegTextAF, _z80af - _%scontextBegin, 0, 0ffffh\n", cpubasename);\r
6409 fprintf(fp, " dd RegTextBC, _z80bc - _%scontextBegin, 0, 0ffffh\n", cpubasename);\r
6410 fprintf(fp, " dd RegTextDE, _z80de - _%scontextBegin, 0, 0ffffh\n", cpubasename);\r
6411 fprintf(fp, " dd RegTextHL, _z80hl - _%scontextBegin, 0, 0ffffh\n", cpubasename);\r
6412 fprintf(fp, " dd RegTextAFP, _z80af - _%scontextBegin, 0, 0ffffh\n", cpubasename);\r
6413 fprintf(fp, " dd RegTextBCP, _z80bc - _%scontextBegin, 0, 0ffffh\n", cpubasename);\r
6414 fprintf(fp, " dd RegTextDEP, _z80de - _%scontextBegin, 0, 0ffffh\n", cpubasename);\r
6415 fprintf(fp, " dd RegTextHLP, _z80hl - _%scontextBegin, 0, 0ffffh\n", cpubasename);\r
6416 fprintf(fp, " dd RegTextIX, _z80ix - _%scontextBegin, 0, 0ffffh\n", cpubasename);\r
6417 fprintf(fp, " dd RegTextIY, _z80iy - _%scontextBegin, 0, 0ffffh\n", cpubasename);\r
6418 fprintf(fp, " dd RegTextI, _z80i - _%scontextBegin, 0, 0ffh\n", cpubasename);\r
6419 fprintf(fp, " dd RegTextR, _z80r - _%scontextBegin, 0, 0ffh\n", cpubasename);\r
6420\r
6421 // Individual regs\r
6422\r
6423 fprintf(fp, " dd RegTextA, (_z80af + 1) - _%scontextBegin, 0, 0ffh\n", cpubasename);\r
6424 fprintf(fp, " dd RegTextF, _z80af - _%scontextBegin, 0, 0ffh\n", cpubasename);\r
6425 fprintf(fp, " dd RegTextB, (_z80bc + 1) - _%scontextBegin, 0, 0ffh\n", cpubasename);\r
6426 fprintf(fp, " dd RegTextC, _z80bc - _%scontextBegin, 0, 0ffh\n", cpubasename);\r
6427 fprintf(fp, " dd RegTextD, (_z80de + 1) - _%scontextBegin, 0, 0ffh\n", cpubasename);\r
6428 fprintf(fp, " dd RegTextE, _z80de - _%scontextBegin, 0, 0ffh\n", cpubasename);\r
6429 fprintf(fp, " dd RegTextH, (_z80hl + 1) - _%scontextBegin, 0, 0ffh\n", cpubasename);\r
6430 fprintf(fp, " dd RegTextL, _z80hl - _%scontextBegin, 0, 0ffh\n", cpubasename);\r
6431\r
6432 // IFF register\r
6433\r
6434 fprintf(fp, " dd RegTextIFF1, _z80iff - _%scontextBegin, 0, 01h\n", cpubasename);\r
6435 fprintf(fp, " dd RegTextIFF2, _z80iff - _%scontextBegin, 1, 01h\n", cpubasename);\r
6436\r
6437 // Individual flags\r
6438\r
6439 fprintf(fp, " dd RegTextCarry, _z80af - _%scontextBegin, 0, 01h\n", cpubasename);\r
6440 fprintf(fp, " dd RegTextNegative, _z80af - _%scontextBegin, 1, 01h\n", cpubasename);\r
6441 fprintf(fp, " dd RegTextParity, _z80af - _%scontextBegin, 2, 01h\n", cpubasename);\r
6442 fprintf(fp, " dd RegTextOverflow, _z80af - _%scontextBegin, 2, 01h\n", cpubasename);\r
6443 fprintf(fp, " dd RegTextHalfCarry, _z80af - _%scontextBegin, 4, 01h\n", cpubasename);\r
6444 fprintf(fp, " dd RegTextZero, _z80af - _%scontextBegin, 6, 01h\n", cpubasename);\r
6445 fprintf(fp, " dd RegTextSign, _z80af - _%scontextBegin, 7, 01h\n", cpubasename);\r
6446\r
6447 // Now we write out our tables\r
6448 \r
6449 Alignment();\r
6450 \r
6451 for (dwLoop = 0; dwLoop < 256; dwLoop++)\r
6452 bUsed[dwLoop] = 0;\r
6453\r
6454 // Now rip through and find out what is and isn't used\r
6455 \r
6456 dwLoop = 0;\r
6457 \r
6458 while (StandardOps[dwLoop].Emitter)\r
6459 {\r
6460 assert(StandardOps[dwLoop].bOpCode < 0x100);\r
6461 if (bUsed[StandardOps[dwLoop].bOpCode])\r
6462 {\r
6463 fprintf(stderr, "Oops! %.2x\n", dwLoop);\r
6464 fclose(fp);\r
6465 exit(1);\r
6466 }\r
6467 bUsed[StandardOps[dwLoop].bOpCode] = 1;\r
6468 dwLoop++;\r
6469 }\r
6470 \r
6471 // Now that that's taken care of, emit the table\r
6472 \r
6473 fprintf(fp, "z80regular:\n");\r
6474 \r
6475 dwLoop = 0;\r
6476 \r
6477 while (dwLoop < 0x100)\r
6478 {\r
6479 fprintf(fp, " dd ");\r
6480 if (bUsed[dwLoop])\r
6481 fprintf(fp, "RegInst%.2x", dwLoop);\r
6482 else\r
6483 fprintf(fp, "invalidInsByte");\r
6484 fprintf(fp, "\n");\r
6485 dwLoop++;\r
6486 }\r
6487 fprintf(fp, "\n");\r
6488 \r
6489 // Now rip through and find out what is and isn't used (CB Ops)\r
6490 \r
6491 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)\r
6492 bUsed[dwLoop] = 0;\r
6493 \r
6494 dwLoop = 0;\r
6495 \r
6496 while (CBOps[dwLoop].Emitter)\r
6497 {\r
6498 assert(CBOps[dwLoop].bOpCode < 0x100);\r
6499 if (bUsed[CBOps[dwLoop].bOpCode])\r
6500 {\r
6501 fprintf(stderr, "Oops CB! %.2x\n", dwLoop);\r
6502 fclose(fp);\r
6503 exit(1);\r
6504 }\r
6505 bUsed[CBOps[dwLoop].bOpCode] = 1;\r
6506 dwLoop++;\r
6507 }\r
6508 \r
6509 dwLoop = 0;\r
6510 \r
6511 // Let's emit the CB prefixes\r
6512 \r
6513 fprintf(fp, "z80PrefixCB:\n");\r
6514 \r
6515 while (dwLoop < 0x100)\r
6516 {\r
6517 fprintf(fp, " dd ");\r
6518 if (bUsed[dwLoop])\r
6519 fprintf(fp, "CBInst%.2x", dwLoop);\r
6520 else\r
6521 fprintf(fp, "invalidInsWord");\r
6522 fprintf(fp, "\n");\r
6523 dwLoop++;\r
6524 }\r
6525 fprintf(fp, "\n");\r
6526 \r
6527 // Now rip through and find out what is and isn't used (ED Ops)\r
6528 \r
6529 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)\r
6530 bUsed[dwLoop] = 0;\r
6531 \r
6532 dwLoop = 0;\r
6533 \r
6534 while (EDOps[dwLoop].Emitter)\r
6535 {\r
6536 assert(EDOps[dwLoop].bOpCode < 0x100);\r
6537 if (bUsed[EDOps[dwLoop].bOpCode])\r
6538 {\r
6539 fprintf(stderr, "Oops ED! %.2x\n", dwLoop);\r
6540 fclose(fp);\r
6541 exit(1);\r
6542 }\r
6543 bUsed[EDOps[dwLoop].bOpCode] = 1;\r
6544 dwLoop++;\r
6545 }\r
6546 \r
6547 dwLoop = 0;\r
6548 \r
6549 // Let's emit the ED prefixes\r
6550 \r
6551 fprintf(fp, "z80PrefixED:\n");\r
6552 \r
6553 while (dwLoop < 0x100)\r
6554 {\r
6555 fprintf(fp, " dd ");\r
6556 if (bUsed[dwLoop])\r
6557 fprintf(fp, "EDInst%.2x", dwLoop);\r
6558 else\r
6559 fprintf(fp, "invalidInsWord");\r
6560 fprintf(fp, "\n");\r
6561 dwLoop++;\r
6562 }\r
6563 fprintf(fp, "\n");\r
6564 \r
6565 // Now rip through and find out what is and isn't used (DD Ops)\r
6566 \r
6567 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)\r
6568 bUsed[dwLoop] = 0;\r
6569 \r
6570 dwLoop = 0;\r
6571 \r
6572 while (DDFDOps[dwLoop].Emitter)\r
6573 {\r
6574 assert(DDFDOps[dwLoop].bOpCode < 0x100);\r
6575 if (bUsed[DDFDOps[dwLoop].bOpCode])\r
6576 {\r
6577 fprintf(stderr, "Oops DD! %.2x\n", bUsed[DDFDOps[dwLoop].bOpCode]);\r
6578 fclose(fp);\r
6579 exit(1);\r
6580 }\r
6581 bUsed[DDFDOps[dwLoop].bOpCode] = 1;\r
6582 dwLoop++;\r
6583 }\r
6584 \r
6585 dwLoop = 0;\r
6586 \r
6587 // Let's emit the DD prefixes\r
6588 \r
6589 fprintf(fp, "z80PrefixDD:\n");\r
6590 \r
6591 while (dwLoop < 0x100)\r
6592 {\r
6593 fprintf(fp, " dd ");\r
6594 if (bUsed[dwLoop])\r
6595 fprintf(fp, "DDInst%.2x", dwLoop);\r
6596 else\r
6597 fprintf(fp, "invalidInsWord");\r
6598 fprintf(fp, "\n");\r
6599 dwLoop++;\r
6600 }\r
6601 fprintf(fp, "\n");\r
6602 \r
6603 // Now rip through and find out what is and isn't used (FD Ops)\r
6604 \r
6605 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)\r
6606 bUsed[dwLoop] = 0;\r
6607 \r
6608 dwLoop = 0;\r
6609 \r
6610 while (DDFDOps[dwLoop].Emitter)\r
6611 {\r
6612 assert(DDFDOps[dwLoop].bOpCode < 0x100);\r
6613 if (bUsed[DDFDOps[dwLoop].bOpCode])\r
6614 {\r
6615 fprintf(stderr, "Oops FD! %.2x\n", dwLoop);\r
6616 fclose(fp);\r
6617 exit(1);\r
6618 }\r
6619 bUsed[DDFDOps[dwLoop].bOpCode] = 1;\r
6620 dwLoop++;\r
6621 }\r
6622 \r
6623 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)\r
6624 bUsed[dwLoop] = 0;\r
6625 \r
6626 // Let's emit the DDFD prefixes\r
6627 \r
6628 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)\r
6629 bUsed[dwLoop] = 0;\r
6630 \r
6631 dwLoop = 0;\r
6632 \r
6633 while (DDFDOps[dwLoop].Emitter)\r
6634 {\r
6635 assert(DDFDOps[dwLoop].bOpCode < 0x100);\r
6636 if (bUsed[DDFDOps[dwLoop].bOpCode])\r
6637 {\r
6638 fprintf(stderr, "Oops FD! %.2x\n", dwLoop);\r
6639 exit(1);\r
6640 }\r
6641 bUsed[DDFDOps[dwLoop].bOpCode] = 1;\r
6642 dwLoop++;\r
6643 }\r
6644 \r
6645 dwLoop = 0;\r
6646 \r
6647 // Let's emit the DDFD prefixes\r
6648 \r
6649 fprintf(fp, "z80PrefixFD:\n");\r
6650 \r
6651 while (dwLoop < 0x100)\r
6652 {\r
6653 fprintf(fp, " dd ");\r
6654 if (bUsed[dwLoop])\r
6655 fprintf(fp, "FDInst%.2x", dwLoop);\r
6656 else\r
6657 fprintf(fp, "invalidInsWord");\r
6658 fprintf(fp, "\n");\r
6659 dwLoop++;\r
6660 }\r
6661 \r
6662 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)\r
6663 bUsed[dwLoop] = 0;\r
6664 \r
6665 dwLoop = 0;\r
6666 \r
6667 while (DDFDCBOps[dwLoop].Emitter)\r
6668 {\r
6669 assert(DDFDCBOps[dwLoop].bOpCode < 0x100);\r
6670 if (bUsed[DDFDCBOps[dwLoop].bOpCode])\r
6671 {\r
6672 fprintf(stderr, "Oops CBFDDD! %.2x\n", bUsed[DDFDCBOps[dwLoop].bOpCode]);\r
6673 fclose(fp);\r
6674 exit(1);\r
6675 }\r
6676 bUsed[DDFDCBOps[dwLoop].bOpCode] = 1;\r
6677 dwLoop++;\r
6678 }\r
6679 \r
6680 // Let's emit the DDFD prefixes\r
6681 \r
6682 dwLoop = 0;\r
6683 \r
6684 fprintf(fp, "z80ddfdcbInstructions:\n");\r
6685 \r
6686 while (dwLoop < 0x100)\r
6687 {\r
6688 fprintf(fp, " dd ");\r
6689 if (bUsed[dwLoop])\r
6690 fprintf(fp, "DDFDCBInst%.2x", dwLoop);\r
6691 else\r
6692 fprintf(fp, "invalidInsWord");\r
6693 fprintf(fp, "\n");\r
6694 dwLoop++;\r
6695 }\r
6696 fprintf(fp, "\n");\r
6697 }\r
6698 else\r
6699 if (MZ80_C == bWhat)\r
6700 {\r
6701 fprintf(fp, "/* Modular global variables go here*/\n\n");\r
6702 fprintf(fp, "static CONTEXTMZ80 cpu; /* CPU Context */\n");\r
6703 fprintf(fp, "static UINT8 *pbPC; /* Program counter normalized */\n");\r
6704 fprintf(fp, "static UINT8 *pbSP; /* Stack pointer normalized */\n");\r
6705 fprintf(fp, "static struct MemoryReadByte *psMemRead; /* Read memory structure */\n");\r
6706 fprintf(fp, "static struct MemoryWriteByte *psMemWrite; /* Write memory structure */\n");\r
6707 fprintf(fp, "static struct z80PortRead *psIoRead; /* Read I/O structure */\n");\r
6708 fprintf(fp, "static struct z80PortWrite *psIoWrite; /* Write memory structure */\n");\r
6709 fprintf(fp, "static INT32 sdwCyclesRemaining; /* Used as a countdown */\n");\r
6710 fprintf(fp, "static UINT32 dwReturnCode; /* Return code from exec() */\n");\r
6711 fprintf(fp, "static UINT32 dwOriginalCycles; /* How many cycles did we start with? */\n");\r
6712 fprintf(fp, "static UINT32 dwElapsedTicks; /* How many ticks did we elapse? */\n");\r
6713 fprintf(fp, "static INT32 sdwAddr; /* Temporary address storage */\n");\r
6714 fprintf(fp, "static UINT32 dwAddr; /* Temporary stack address */\n");\r
6715 fprintf(fp, "static UINT8 *pbAddAdcTable; /* Pointer to add/adc flag table */\n");\r
6716 fprintf(fp, "static UINT8 *pbSubSbcTable; /* Pointer to sub/sbc flag table */\n");\r
6717 fprintf(fp, "static UINT32 dwTemp; /* Temporary value */\n\n");\r
6718 fprintf(fp, "static UINT8 bTemp; /* Temporary value */\n\n");\r
6719 fprintf(fp, "static UINT8 bTemp2; /* Temporary value */\n\n");\r
6720\r
6721 fprintf(fp, "/* Precomputed flag tables */\n\n");\r
6722\r
6723 fprintf(fp, "static UINT8 bPostIncFlags[0x100] = \n");\r
6724 fprintf(fp, "{\n");\r
6725 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");\r
6726 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");\r
6727 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");\r
6728 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");\r
6729 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");\r
6730 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");\r
6731 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");\r
6732 fprintf(fp, " 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,\n");\r
6733 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");\r
6734 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");\r
6735 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");\r
6736 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");\r
6737 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");\r
6738 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");\r
6739 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");\r
6740 fprintf(fp, " 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x50\n");\r
6741 fprintf(fp, "};\n\n");\r
6742\r
6743 fprintf(fp, "static UINT8 bPostDecFlags[0x100] = \n");\r
6744 fprintf(fp, "{\n");\r
6745 fprintf(fp, " 0x92,0x42,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");\r
6746 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");\r
6747 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");\r
6748 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");\r
6749 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");\r
6750 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");\r
6751 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");\r
6752 fprintf(fp, " 0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");\r
6753 fprintf(fp, " 0x16,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");\r
6754 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");\r
6755 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");\r
6756 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");\r
6757 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");\r
6758 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");\r
6759 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");\r
6760 fprintf(fp, " 0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82\n");\r
6761 fprintf(fp, "};\n\n");\r
6762\r
6763 fprintf(fp, "static UINT8 bPostORFlags[0x100] = \n");\r
6764 fprintf(fp, "{\n");\r
6765 fprintf(fp, " 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,\n");\r
6766 fprintf(fp, " 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,\n");\r
6767 fprintf(fp, " 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,\n");\r
6768 fprintf(fp, " 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,\n");\r
6769 fprintf(fp, " 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,\n");\r
6770 fprintf(fp, " 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,\n");\r
6771 fprintf(fp, " 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,\n");\r
6772 fprintf(fp, " 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,\n");\r
6773 fprintf(fp, " 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,\n");\r
6774 fprintf(fp, " 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,\n");\r
6775 fprintf(fp, " 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,\n");\r
6776 fprintf(fp, " 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,\n");\r
6777 fprintf(fp, " 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,\n");\r
6778 fprintf(fp, " 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,\n");\r
6779 fprintf(fp, " 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,\n");\r
6780 fprintf(fp, " 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84\n");\r
6781 fprintf(fp, "};\n\n");\r
6782\r
6783 fprintf(fp, "static UINT8 bPostANDFlags[0x100] = \n");\r
6784 fprintf(fp, "{\n");\r
6785 fprintf(fp, " 0x54,0x10,0x10,0x14,0x10,0x14,0x14,0x10,0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,\n");\r
6786 fprintf(fp, " 0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,\n");\r
6787 fprintf(fp, " 0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,\n");\r
6788 fprintf(fp, " 0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,\n");\r
6789 fprintf(fp, " 0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,\n");\r
6790 fprintf(fp, " 0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,\n");\r
6791 fprintf(fp, " 0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,\n");\r
6792 fprintf(fp, " 0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,\n");\r
6793 fprintf(fp, " 0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,\n");\r
6794 fprintf(fp, " 0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,\n");\r
6795 fprintf(fp, " 0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,\n");\r
6796 fprintf(fp, " 0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,\n");\r
6797 fprintf(fp, " 0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,\n");\r
6798 fprintf(fp, " 0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,\n");\r
6799 fprintf(fp, " 0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,\n");\r
6800 fprintf(fp, " 0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94\n");\r
6801 fprintf(fp, "};\n\n");\r
6802\r
6803 fprintf(fp, "static UINT16 wDAATable[0x800] = \n");\r
6804 fprintf(fp, "{\n");\r
6805 fprintf(fp, " 0x5400,0x1001,0x1002,0x1403,0x1004,0x1405,0x1406,0x1007,\n");\r
6806 fprintf(fp, " 0x1008,0x1409,0x1010,0x1411,0x1412,0x1013,0x1414,0x1015,\n");\r
6807 fprintf(fp, " 0x1010,0x1411,0x1412,0x1013,0x1414,0x1015,0x1016,0x1417,\n");\r
6808 fprintf(fp, " 0x1418,0x1019,0x1020,0x1421,0x1422,0x1023,0x1424,0x1025,\n");\r
6809 fprintf(fp, " 0x1020,0x1421,0x1422,0x1023,0x1424,0x1025,0x1026,0x1427,\n");\r
6810 fprintf(fp, " 0x1428,0x1029,0x1430,0x1031,0x1032,0x1433,0x1034,0x1435,\n");\r
6811 fprintf(fp, " 0x1430,0x1031,0x1032,0x1433,0x1034,0x1435,0x1436,0x1037,\n");\r
6812 fprintf(fp, " 0x1038,0x1439,0x1040,0x1441,0x1442,0x1043,0x1444,0x1045,\n");\r
6813 fprintf(fp, " 0x1040,0x1441,0x1442,0x1043,0x1444,0x1045,0x1046,0x1447,\n");\r
6814 fprintf(fp, " 0x1448,0x1049,0x1450,0x1051,0x1052,0x1453,0x1054,0x1455,\n");\r
6815 fprintf(fp, " 0x1450,0x1051,0x1052,0x1453,0x1054,0x1455,0x1456,0x1057,\n");\r
6816 fprintf(fp, " 0x1058,0x1459,0x1460,0x1061,0x1062,0x1463,0x1064,0x1465,\n");\r
6817 fprintf(fp, " 0x1460,0x1061,0x1062,0x1463,0x1064,0x1465,0x1466,0x1067,\n");\r
6818 fprintf(fp, " 0x1068,0x1469,0x1070,0x1471,0x1472,0x1073,0x1474,0x1075,\n");\r
6819 fprintf(fp, " 0x1070,0x1471,0x1472,0x1073,0x1474,0x1075,0x1076,0x1477,\n");\r
6820 fprintf(fp, " 0x1478,0x1079,0x9080,0x9481,0x9482,0x9083,0x9484,0x9085,\n");\r
6821 fprintf(fp, " 0x9080,0x9481,0x9482,0x9083,0x9484,0x9085,0x9086,0x9487,\n");\r
6822 fprintf(fp, " 0x9488,0x9089,0x9490,0x9091,0x9092,0x9493,0x9094,0x9495,\n");\r
6823 fprintf(fp, " 0x9490,0x9091,0x9092,0x9493,0x9094,0x9495,0x9496,0x9097,\n");\r
6824 fprintf(fp, " 0x9098,0x9499,0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,\n");\r
6825 fprintf(fp, " 0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,0x1506,0x1107,\n");\r
6826 fprintf(fp, " 0x1108,0x1509,0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,\n");\r
6827 fprintf(fp, " 0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,0x1116,0x1517,\n");\r
6828 fprintf(fp, " 0x1518,0x1119,0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,\n");\r
6829 fprintf(fp, " 0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,0x1126,0x1527,\n");\r
6830 fprintf(fp, " 0x1528,0x1129,0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,\n");\r
6831 fprintf(fp, " 0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,0x1536,0x1137,\n");\r
6832 fprintf(fp, " 0x1138,0x1539,0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,\n");\r
6833 fprintf(fp, " 0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,0x1146,0x1547,\n");\r
6834 fprintf(fp, " 0x1548,0x1149,0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,\n");\r
6835 fprintf(fp, " 0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,0x1556,0x1157,\n");\r
6836 fprintf(fp, " 0x1158,0x1559,0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,\n");\r
6837 fprintf(fp, " 0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,0x1566,0x1167,\n");\r
6838 fprintf(fp, " 0x1168,0x1569,0x1170,0x1571,0x1572,0x1173,0x1574,0x1175,\n");\r
6839 fprintf(fp, " 0x1170,0x1571,0x1572,0x1173,0x1574,0x1175,0x1176,0x1577,\n");\r
6840 fprintf(fp, " 0x1578,0x1179,0x9180,0x9581,0x9582,0x9183,0x9584,0x9185,\n");\r
6841 fprintf(fp, " 0x9180,0x9581,0x9582,0x9183,0x9584,0x9185,0x9186,0x9587,\n");\r
6842 fprintf(fp, " 0x9588,0x9189,0x9590,0x9191,0x9192,0x9593,0x9194,0x9595,\n");\r
6843 fprintf(fp, " 0x9590,0x9191,0x9192,0x9593,0x9194,0x9595,0x9596,0x9197,\n");\r
6844 fprintf(fp, " 0x9198,0x9599,0x95a0,0x91a1,0x91a2,0x95a3,0x91a4,0x95a5,\n");\r
6845 fprintf(fp, " 0x95a0,0x91a1,0x91a2,0x95a3,0x91a4,0x95a5,0x95a6,0x91a7,\n");\r
6846 fprintf(fp, " 0x91a8,0x95a9,0x91b0,0x95b1,0x95b2,0x91b3,0x95b4,0x91b5,\n");\r
6847 fprintf(fp, " 0x91b0,0x95b1,0x95b2,0x91b3,0x95b4,0x91b5,0x91b6,0x95b7,\n");\r
6848 fprintf(fp, " 0x95b8,0x91b9,0x95c0,0x91c1,0x91c2,0x95c3,0x91c4,0x95c5,\n");\r
6849 fprintf(fp, " 0x95c0,0x91c1,0x91c2,0x95c3,0x91c4,0x95c5,0x95c6,0x91c7,\n");\r
6850 fprintf(fp, " 0x91c8,0x95c9,0x91d0,0x95d1,0x95d2,0x91d3,0x95d4,0x91d5,\n");\r
6851 fprintf(fp, " 0x91d0,0x95d1,0x95d2,0x91d3,0x95d4,0x91d5,0x91d6,0x95d7,\n");\r
6852 fprintf(fp, " 0x95d8,0x91d9,0x91e0,0x95e1,0x95e2,0x91e3,0x95e4,0x91e5,\n");\r
6853 fprintf(fp, " 0x91e0,0x95e1,0x95e2,0x91e3,0x95e4,0x91e5,0x91e6,0x95e7,\n");\r
6854 fprintf(fp, " 0x95e8,0x91e9,0x95f0,0x91f1,0x91f2,0x95f3,0x91f4,0x95f5,\n");\r
6855 fprintf(fp, " 0x95f0,0x91f1,0x91f2,0x95f3,0x91f4,0x95f5,0x95f6,0x91f7,\n");\r
6856 fprintf(fp, " 0x91f8,0x95f9,0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,\n");\r
6857 fprintf(fp, " 0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,0x1506,0x1107,\n");\r
6858 fprintf(fp, " 0x1108,0x1509,0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,\n");\r
6859 fprintf(fp, " 0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,0x1116,0x1517,\n");\r
6860 fprintf(fp, " 0x1518,0x1119,0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,\n");\r
6861 fprintf(fp, " 0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,0x1126,0x1527,\n");\r
6862 fprintf(fp, " 0x1528,0x1129,0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,\n");\r
6863 fprintf(fp, " 0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,0x1536,0x1137,\n");\r
6864 fprintf(fp, " 0x1138,0x1539,0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,\n");\r
6865 fprintf(fp, " 0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,0x1146,0x1547,\n");\r
6866 fprintf(fp, " 0x1548,0x1149,0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,\n");\r
6867 fprintf(fp, " 0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,0x1556,0x1157,\n");\r
6868 fprintf(fp, " 0x1158,0x1559,0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,\n");\r
6869 fprintf(fp, " 0x1406,0x1007,0x1008,0x1409,0x140a,0x100b,0x140c,0x100d,\n");\r
6870 fprintf(fp, " 0x100e,0x140f,0x1010,0x1411,0x1412,0x1013,0x1414,0x1015,\n");\r
6871 fprintf(fp, " 0x1016,0x1417,0x1418,0x1019,0x101a,0x141b,0x101c,0x141d,\n");\r
6872 fprintf(fp, " 0x141e,0x101f,0x1020,0x1421,0x1422,0x1023,0x1424,0x1025,\n");\r
6873 fprintf(fp, " 0x1026,0x1427,0x1428,0x1029,0x102a,0x142b,0x102c,0x142d,\n");\r
6874 fprintf(fp, " 0x142e,0x102f,0x1430,0x1031,0x1032,0x1433,0x1034,0x1435,\n");\r
6875 fprintf(fp, " 0x1436,0x1037,0x1038,0x1439,0x143a,0x103b,0x143c,0x103d,\n");\r
6876 fprintf(fp, " 0x103e,0x143f,0x1040,0x1441,0x1442,0x1043,0x1444,0x1045,\n");\r
6877 fprintf(fp, " 0x1046,0x1447,0x1448,0x1049,0x104a,0x144b,0x104c,0x144d,\n");\r
6878 fprintf(fp, " 0x144e,0x104f,0x1450,0x1051,0x1052,0x1453,0x1054,0x1455,\n");\r
6879 fprintf(fp, " 0x1456,0x1057,0x1058,0x1459,0x145a,0x105b,0x145c,0x105d,\n");\r
6880 fprintf(fp, " 0x105e,0x145f,0x1460,0x1061,0x1062,0x1463,0x1064,0x1465,\n");\r
6881 fprintf(fp, " 0x1466,0x1067,0x1068,0x1469,0x146a,0x106b,0x146c,0x106d,\n");\r
6882 fprintf(fp, " 0x106e,0x146f,0x1070,0x1471,0x1472,0x1073,0x1474,0x1075,\n");\r
6883 fprintf(fp, " 0x1076,0x1477,0x1478,0x1079,0x107a,0x147b,0x107c,0x147d,\n");\r
6884 fprintf(fp, " 0x147e,0x107f,0x9080,0x9481,0x9482,0x9083,0x9484,0x9085,\n");\r
6885 fprintf(fp, " 0x9086,0x9487,0x9488,0x9089,0x908a,0x948b,0x908c,0x948d,\n");\r
6886 fprintf(fp, " 0x948e,0x908f,0x9490,0x9091,0x9092,0x9493,0x9094,0x9495,\n");\r
6887 fprintf(fp, " 0x9496,0x9097,0x9098,0x9499,0x949a,0x909b,0x949c,0x909d,\n");\r
6888 fprintf(fp, " 0x909e,0x949f,0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,\n");\r
6889 fprintf(fp, " 0x1506,0x1107,0x1108,0x1509,0x150a,0x110b,0x150c,0x110d,\n");\r
6890 fprintf(fp, " 0x110e,0x150f,0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,\n");\r
6891 fprintf(fp, " 0x1116,0x1517,0x1518,0x1119,0x111a,0x151b,0x111c,0x151d,\n");\r
6892 fprintf(fp, " 0x151e,0x111f,0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,\n");\r
6893 fprintf(fp, " 0x1126,0x1527,0x1528,0x1129,0x112a,0x152b,0x112c,0x152d,\n");\r
6894 fprintf(fp, " 0x152e,0x112f,0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,\n");\r
6895 fprintf(fp, " 0x1536,0x1137,0x1138,0x1539,0x153a,0x113b,0x153c,0x113d,\n");\r
6896 fprintf(fp, " 0x113e,0x153f,0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,\n");\r
6897 fprintf(fp, " 0x1146,0x1547,0x1548,0x1149,0x114a,0x154b,0x114c,0x154d,\n");\r
6898 fprintf(fp, " 0x154e,0x114f,0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,\n");\r
6899 fprintf(fp, " 0x1556,0x1157,0x1158,0x1559,0x155a,0x115b,0x155c,0x115d,\n");\r
6900 fprintf(fp, " 0x115e,0x155f,0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,\n");\r
6901 fprintf(fp, " 0x1566,0x1167,0x1168,0x1569,0x156a,0x116b,0x156c,0x116d,\n");\r
6902 fprintf(fp, " 0x116e,0x156f,0x1170,0x1571,0x1572,0x1173,0x1574,0x1175,\n");\r
6903 fprintf(fp, " 0x1176,0x1577,0x1578,0x1179,0x117a,0x157b,0x117c,0x157d,\n");\r
6904 fprintf(fp, " 0x157e,0x117f,0x9180,0x9581,0x9582,0x9183,0x9584,0x9185,\n");\r
6905 fprintf(fp, " 0x9186,0x9587,0x9588,0x9189,0x918a,0x958b,0x918c,0x958d,\n");\r
6906 fprintf(fp, " 0x958e,0x918f,0x9590,0x9191,0x9192,0x9593,0x9194,0x9595,\n");\r
6907 fprintf(fp, " 0x9596,0x9197,0x9198,0x9599,0x959a,0x919b,0x959c,0x919d,\n");\r
6908 fprintf(fp, " 0x919e,0x959f,0x95a0,0x91a1,0x91a2,0x95a3,0x91a4,0x95a5,\n");\r
6909 fprintf(fp, " 0x95a6,0x91a7,0x91a8,0x95a9,0x95aa,0x91ab,0x95ac,0x91ad,\n");\r
6910 fprintf(fp, " 0x91ae,0x95af,0x91b0,0x95b1,0x95b2,0x91b3,0x95b4,0x91b5,\n");\r
6911 fprintf(fp, " 0x91b6,0x95b7,0x95b8,0x91b9,0x91ba,0x95bb,0x91bc,0x95bd,\n");\r
6912 fprintf(fp, " 0x95be,0x91bf,0x95c0,0x91c1,0x91c2,0x95c3,0x91c4,0x95c5,\n");\r
6913 fprintf(fp, " 0x95c6,0x91c7,0x91c8,0x95c9,0x95ca,0x91cb,0x95cc,0x91cd,\n");\r
6914 fprintf(fp, " 0x91ce,0x95cf,0x91d0,0x95d1,0x95d2,0x91d3,0x95d4,0x91d5,\n");\r
6915 fprintf(fp, " 0x91d6,0x95d7,0x95d8,0x91d9,0x91da,0x95db,0x91dc,0x95dd,\n");\r
6916 fprintf(fp, " 0x95de,0x91df,0x91e0,0x95e1,0x95e2,0x91e3,0x95e4,0x91e5,\n");\r
6917 fprintf(fp, " 0x91e6,0x95e7,0x95e8,0x91e9,0x91ea,0x95eb,0x91ec,0x95ed,\n");\r
6918 fprintf(fp, " 0x95ee,0x91ef,0x95f0,0x91f1,0x91f2,0x95f3,0x91f4,0x95f5,\n");\r
6919 fprintf(fp, " 0x95f6,0x91f7,0x91f8,0x95f9,0x95fa,0x91fb,0x95fc,0x91fd,\n");\r
6920 fprintf(fp, " 0x91fe,0x95ff,0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,\n");\r
6921 fprintf(fp, " 0x1506,0x1107,0x1108,0x1509,0x150a,0x110b,0x150c,0x110d,\n");\r
6922 fprintf(fp, " 0x110e,0x150f,0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,\n");\r
6923 fprintf(fp, " 0x1116,0x1517,0x1518,0x1119,0x111a,0x151b,0x111c,0x151d,\n");\r
6924 fprintf(fp, " 0x151e,0x111f,0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,\n");\r
6925 fprintf(fp, " 0x1126,0x1527,0x1528,0x1129,0x112a,0x152b,0x112c,0x152d,\n");\r
6926 fprintf(fp, " 0x152e,0x112f,0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,\n");\r
6927 fprintf(fp, " 0x1536,0x1137,0x1138,0x1539,0x153a,0x113b,0x153c,0x113d,\n");\r
6928 fprintf(fp, " 0x113e,0x153f,0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,\n");\r
6929 fprintf(fp, " 0x1146,0x1547,0x1548,0x1149,0x114a,0x154b,0x114c,0x154d,\n");\r
6930 fprintf(fp, " 0x154e,0x114f,0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,\n");\r
6931 fprintf(fp, " 0x1556,0x1157,0x1158,0x1559,0x155a,0x115b,0x155c,0x115d,\n");\r
6932 fprintf(fp, " 0x115e,0x155f,0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,\n");\r
6933 fprintf(fp, " 0x5600,0x1201,0x1202,0x1603,0x1204,0x1605,0x1606,0x1207,\n");\r
6934 fprintf(fp, " 0x1208,0x1609,0x1204,0x1605,0x1606,0x1207,0x1208,0x1609,\n");\r
6935 fprintf(fp, " 0x1210,0x1611,0x1612,0x1213,0x1614,0x1215,0x1216,0x1617,\n");\r
6936 fprintf(fp, " 0x1618,0x1219,0x1614,0x1215,0x1216,0x1617,0x1618,0x1219,\n");\r
6937 fprintf(fp, " 0x1220,0x1621,0x1622,0x1223,0x1624,0x1225,0x1226,0x1627,\n");\r
6938 fprintf(fp, " 0x1628,0x1229,0x1624,0x1225,0x1226,0x1627,0x1628,0x1229,\n");\r
6939 fprintf(fp, " 0x1630,0x1231,0x1232,0x1633,0x1234,0x1635,0x1636,0x1237,\n");\r
6940 fprintf(fp, " 0x1238,0x1639,0x1234,0x1635,0x1636,0x1237,0x1238,0x1639,\n");\r
6941 fprintf(fp, " 0x1240,0x1641,0x1642,0x1243,0x1644,0x1245,0x1246,0x1647,\n");\r
6942 fprintf(fp, " 0x1648,0x1249,0x1644,0x1245,0x1246,0x1647,0x1648,0x1249,\n");\r
6943 fprintf(fp, " 0x1650,0x1251,0x1252,0x1653,0x1254,0x1655,0x1656,0x1257,\n");\r
6944 fprintf(fp, " 0x1258,0x1659,0x1254,0x1655,0x1656,0x1257,0x1258,0x1659,\n");\r
6945 fprintf(fp, " 0x1660,0x1261,0x1262,0x1663,0x1264,0x1665,0x1666,0x1267,\n");\r
6946 fprintf(fp, " 0x1268,0x1669,0x1264,0x1665,0x1666,0x1267,0x1268,0x1669,\n");\r
6947 fprintf(fp, " 0x1270,0x1671,0x1672,0x1273,0x1674,0x1275,0x1276,0x1677,\n");\r
6948 fprintf(fp, " 0x1678,0x1279,0x1674,0x1275,0x1276,0x1677,0x1678,0x1279,\n");\r
6949 fprintf(fp, " 0x9280,0x9681,0x9682,0x9283,0x9684,0x9285,0x9286,0x9687,\n");\r
6950 fprintf(fp, " 0x9688,0x9289,0x9684,0x9285,0x9286,0x9687,0x9688,0x9289,\n");\r
6951 fprintf(fp, " 0x9690,0x9291,0x9292,0x9693,0x9294,0x9695,0x9696,0x9297,\n");\r
6952 fprintf(fp, " 0x9298,0x9699,0x1334,0x1735,0x1736,0x1337,0x1338,0x1739,\n");\r
6953 fprintf(fp, " 0x1340,0x1741,0x1742,0x1343,0x1744,0x1345,0x1346,0x1747,\n");\r
6954 fprintf(fp, " 0x1748,0x1349,0x1744,0x1345,0x1346,0x1747,0x1748,0x1349,\n");\r
6955 fprintf(fp, " 0x1750,0x1351,0x1352,0x1753,0x1354,0x1755,0x1756,0x1357,\n");\r
6956 fprintf(fp, " 0x1358,0x1759,0x1354,0x1755,0x1756,0x1357,0x1358,0x1759,\n");\r
6957 fprintf(fp, " 0x1760,0x1361,0x1362,0x1763,0x1364,0x1765,0x1766,0x1367,\n");\r
6958 fprintf(fp, " 0x1368,0x1769,0x1364,0x1765,0x1766,0x1367,0x1368,0x1769,\n");\r
6959 fprintf(fp, " 0x1370,0x1771,0x1772,0x1373,0x1774,0x1375,0x1376,0x1777,\n");\r
6960 fprintf(fp, " 0x1778,0x1379,0x1774,0x1375,0x1376,0x1777,0x1778,0x1379,\n");\r
6961 fprintf(fp, " 0x9380,0x9781,0x9782,0x9383,0x9784,0x9385,0x9386,0x9787,\n");\r
6962 fprintf(fp, " 0x9788,0x9389,0x9784,0x9385,0x9386,0x9787,0x9788,0x9389,\n");\r
6963 fprintf(fp, " 0x9790,0x9391,0x9392,0x9793,0x9394,0x9795,0x9796,0x9397,\n");\r
6964 fprintf(fp, " 0x9398,0x9799,0x9394,0x9795,0x9796,0x9397,0x9398,0x9799,\n");\r
6965 fprintf(fp, " 0x97a0,0x93a1,0x93a2,0x97a3,0x93a4,0x97a5,0x97a6,0x93a7,\n");\r
6966 fprintf(fp, " 0x93a8,0x97a9,0x93a4,0x97a5,0x97a6,0x93a7,0x93a8,0x97a9,\n");\r
6967 fprintf(fp, " 0x93b0,0x97b1,0x97b2,0x93b3,0x97b4,0x93b5,0x93b6,0x97b7,\n");\r
6968 fprintf(fp, " 0x97b8,0x93b9,0x97b4,0x93b5,0x93b6,0x97b7,0x97b8,0x93b9,\n");\r
6969 fprintf(fp, " 0x97c0,0x93c1,0x93c2,0x97c3,0x93c4,0x97c5,0x97c6,0x93c7,\n");\r
6970 fprintf(fp, " 0x93c8,0x97c9,0x93c4,0x97c5,0x97c6,0x93c7,0x93c8,0x97c9,\n");\r
6971 fprintf(fp, " 0x93d0,0x97d1,0x97d2,0x93d3,0x97d4,0x93d5,0x93d6,0x97d7,\n");\r
6972 fprintf(fp, " 0x97d8,0x93d9,0x97d4,0x93d5,0x93d6,0x97d7,0x97d8,0x93d9,\n");\r
6973 fprintf(fp, " 0x93e0,0x97e1,0x97e2,0x93e3,0x97e4,0x93e5,0x93e6,0x97e7,\n");\r
6974 fprintf(fp, " 0x97e8,0x93e9,0x97e4,0x93e5,0x93e6,0x97e7,0x97e8,0x93e9,\n");\r
6975 fprintf(fp, " 0x97f0,0x93f1,0x93f2,0x97f3,0x93f4,0x97f5,0x97f6,0x93f7,\n");\r
6976 fprintf(fp, " 0x93f8,0x97f9,0x93f4,0x97f5,0x97f6,0x93f7,0x93f8,0x97f9,\n");\r
6977 fprintf(fp, " 0x5700,0x1301,0x1302,0x1703,0x1304,0x1705,0x1706,0x1307,\n");\r
6978 fprintf(fp, " 0x1308,0x1709,0x1304,0x1705,0x1706,0x1307,0x1308,0x1709,\n");\r
6979 fprintf(fp, " 0x1310,0x1711,0x1712,0x1313,0x1714,0x1315,0x1316,0x1717,\n");\r
6980 fprintf(fp, " 0x1718,0x1319,0x1714,0x1315,0x1316,0x1717,0x1718,0x1319,\n");\r
6981 fprintf(fp, " 0x1320,0x1721,0x1722,0x1323,0x1724,0x1325,0x1326,0x1727,\n");\r
6982 fprintf(fp, " 0x1728,0x1329,0x1724,0x1325,0x1326,0x1727,0x1728,0x1329,\n");\r
6983 fprintf(fp, " 0x1730,0x1331,0x1332,0x1733,0x1334,0x1735,0x1736,0x1337,\n");\r
6984 fprintf(fp, " 0x1338,0x1739,0x1334,0x1735,0x1736,0x1337,0x1338,0x1739,\n");\r
6985 fprintf(fp, " 0x1340,0x1741,0x1742,0x1343,0x1744,0x1345,0x1346,0x1747,\n");\r
6986 fprintf(fp, " 0x1748,0x1349,0x1744,0x1345,0x1346,0x1747,0x1748,0x1349,\n");\r
6987 fprintf(fp, " 0x1750,0x1351,0x1352,0x1753,0x1354,0x1755,0x1756,0x1357,\n");\r
6988 fprintf(fp, " 0x1358,0x1759,0x1354,0x1755,0x1756,0x1357,0x1358,0x1759,\n");\r
6989 fprintf(fp, " 0x1760,0x1361,0x1362,0x1763,0x1364,0x1765,0x1766,0x1367,\n");\r
6990 fprintf(fp, " 0x1368,0x1769,0x1364,0x1765,0x1766,0x1367,0x1368,0x1769,\n");\r
6991 fprintf(fp, " 0x1370,0x1771,0x1772,0x1373,0x1774,0x1375,0x1376,0x1777,\n");\r
6992 fprintf(fp, " 0x1778,0x1379,0x1774,0x1375,0x1376,0x1777,0x1778,0x1379,\n");\r
6993 fprintf(fp, " 0x9380,0x9781,0x9782,0x9383,0x9784,0x9385,0x9386,0x9787,\n");\r
6994 fprintf(fp, " 0x9788,0x9389,0x9784,0x9385,0x9386,0x9787,0x9788,0x9389,\n");\r
6995 fprintf(fp, " 0x9790,0x9391,0x9392,0x9793,0x9394,0x9795,0x9796,0x9397,\n");\r
6996 fprintf(fp, " 0x9398,0x9799,0x9394,0x9795,0x9796,0x9397,0x9398,0x9799,\n");\r
6997 fprintf(fp, " 0x97fa,0x93fb,0x97fc,0x93fd,0x93fe,0x97ff,0x5600,0x1201,\n");\r
6998 fprintf(fp, " 0x1202,0x1603,0x1204,0x1605,0x1606,0x1207,0x1208,0x1609,\n");\r
6999 fprintf(fp, " 0x160a,0x120b,0x160c,0x120d,0x120e,0x160f,0x1210,0x1611,\n");\r
7000 fprintf(fp, " 0x1612,0x1213,0x1614,0x1215,0x1216,0x1617,0x1618,0x1219,\n");\r
7001 fprintf(fp, " 0x121a,0x161b,0x121c,0x161d,0x161e,0x121f,0x1220,0x1621,\n");\r
7002 fprintf(fp, " 0x1622,0x1223,0x1624,0x1225,0x1226,0x1627,0x1628,0x1229,\n");\r
7003 fprintf(fp, " 0x122a,0x162b,0x122c,0x162d,0x162e,0x122f,0x1630,0x1231,\n");\r
7004 fprintf(fp, " 0x1232,0x1633,0x1234,0x1635,0x1636,0x1237,0x1238,0x1639,\n");\r
7005 fprintf(fp, " 0x163a,0x123b,0x163c,0x123d,0x123e,0x163f,0x1240,0x1641,\n");\r
7006 fprintf(fp, " 0x1642,0x1243,0x1644,0x1245,0x1246,0x1647,0x1648,0x1249,\n");\r
7007 fprintf(fp, " 0x124a,0x164b,0x124c,0x164d,0x164e,0x124f,0x1650,0x1251,\n");\r
7008 fprintf(fp, " 0x1252,0x1653,0x1254,0x1655,0x1656,0x1257,0x1258,0x1659,\n");\r
7009 fprintf(fp, " 0x165a,0x125b,0x165c,0x125d,0x125e,0x165f,0x1660,0x1261,\n");\r
7010 fprintf(fp, " 0x1262,0x1663,0x1264,0x1665,0x1666,0x1267,0x1268,0x1669,\n");\r
7011 fprintf(fp, " 0x166a,0x126b,0x166c,0x126d,0x126e,0x166f,0x1270,0x1671,\n");\r
7012 fprintf(fp, " 0x1672,0x1273,0x1674,0x1275,0x1276,0x1677,0x1678,0x1279,\n");\r
7013 fprintf(fp, " 0x127a,0x167b,0x127c,0x167d,0x167e,0x127f,0x9280,0x9681,\n");\r
7014 fprintf(fp, " 0x9682,0x9283,0x9684,0x9285,0x9286,0x9687,0x9688,0x9289,\n");\r
7015 fprintf(fp, " 0x928a,0x968b,0x928c,0x968d,0x968e,0x928f,0x9690,0x9291,\n");\r
7016 fprintf(fp, " 0x9292,0x9693,0x1334,0x1735,0x1736,0x1337,0x1338,0x1739,\n");\r
7017 fprintf(fp, " 0x173a,0x133b,0x173c,0x133d,0x133e,0x173f,0x1340,0x1741,\n");\r
7018 fprintf(fp, " 0x1742,0x1343,0x1744,0x1345,0x1346,0x1747,0x1748,0x1349,\n");\r
7019 fprintf(fp, " 0x134a,0x174b,0x134c,0x174d,0x174e,0x134f,0x1750,0x1351,\n");\r
7020 fprintf(fp, " 0x1352,0x1753,0x1354,0x1755,0x1756,0x1357,0x1358,0x1759,\n");\r
7021 fprintf(fp, " 0x175a,0x135b,0x175c,0x135d,0x135e,0x175f,0x1760,0x1361,\n");\r
7022 fprintf(fp, " 0x1362,0x1763,0x1364,0x1765,0x1766,0x1367,0x1368,0x1769,\n");\r
7023 fprintf(fp, " 0x176a,0x136b,0x176c,0x136d,0x136e,0x176f,0x1370,0x1771,\n");\r
7024 fprintf(fp, " 0x1772,0x1373,0x1774,0x1375,0x1376,0x1777,0x1778,0x1379,\n");\r
7025 fprintf(fp, " 0x137a,0x177b,0x137c,0x177d,0x177e,0x137f,0x9380,0x9781,\n");\r
7026 fprintf(fp, " 0x9782,0x9383,0x9784,0x9385,0x9386,0x9787,0x9788,0x9389,\n");\r
7027 fprintf(fp, " 0x938a,0x978b,0x938c,0x978d,0x978e,0x938f,0x9790,0x9391,\n");\r
7028 fprintf(fp, " 0x9392,0x9793,0x9394,0x9795,0x9796,0x9397,0x9398,0x9799,\n");\r
7029 fprintf(fp, " 0x979a,0x939b,0x979c,0x939d,0x939e,0x979f,0x97a0,0x93a1,\n");\r
7030 fprintf(fp, " 0x93a2,0x97a3,0x93a4,0x97a5,0x97a6,0x93a7,0x93a8,0x97a9,\n");\r
7031 fprintf(fp, " 0x97aa,0x93ab,0x97ac,0x93ad,0x93ae,0x97af,0x93b0,0x97b1,\n");\r
7032 fprintf(fp, " 0x97b2,0x93b3,0x97b4,0x93b5,0x93b6,0x97b7,0x97b8,0x93b9,\n");\r
7033 fprintf(fp, " 0x93ba,0x97bb,0x93bc,0x97bd,0x97be,0x93bf,0x97c0,0x93c1,\n");\r
7034 fprintf(fp, " 0x93c2,0x97c3,0x93c4,0x97c5,0x97c6,0x93c7,0x93c8,0x97c9,\n");\r
7035 fprintf(fp, " 0x97ca,0x93cb,0x97cc,0x93cd,0x93ce,0x97cf,0x93d0,0x97d1,\n");\r
7036 fprintf(fp, " 0x97d2,0x93d3,0x97d4,0x93d5,0x93d6,0x97d7,0x97d8,0x93d9,\n");\r
7037 fprintf(fp, " 0x93da,0x97db,0x93dc,0x97dd,0x97de,0x93df,0x93e0,0x97e1,\n");\r
7038 fprintf(fp, " 0x97e2,0x93e3,0x97e4,0x93e5,0x93e6,0x97e7,0x97e8,0x93e9,\n");\r
7039 fprintf(fp, " 0x93ea,0x97eb,0x93ec,0x97ed,0x97ee,0x93ef,0x97f0,0x93f1,\n");\r
7040 fprintf(fp, " 0x93f2,0x97f3,0x93f4,0x97f5,0x97f6,0x93f7,0x93f8,0x97f9,\n");\r
7041 fprintf(fp, " 0x97fa,0x93fb,0x97fc,0x93fd,0x93fe,0x97ff,0x5700,0x1301,\n");\r
7042 fprintf(fp, " 0x1302,0x1703,0x1304,0x1705,0x1706,0x1307,0x1308,0x1709,\n");\r
7043 fprintf(fp, " 0x170a,0x130b,0x170c,0x130d,0x130e,0x170f,0x1310,0x1711,\n");\r
7044 fprintf(fp, " 0x1712,0x1313,0x1714,0x1315,0x1316,0x1717,0x1718,0x1319,\n");\r
7045 fprintf(fp, " 0x131a,0x171b,0x131c,0x171d,0x171e,0x131f,0x1320,0x1721,\n");\r
7046 fprintf(fp, " 0x1722,0x1323,0x1724,0x1325,0x1326,0x1727,0x1728,0x1329,\n");\r
7047 fprintf(fp, " 0x132a,0x172b,0x132c,0x172d,0x172e,0x132f,0x1730,0x1331,\n");\r
7048 fprintf(fp, " 0x1332,0x1733,0x1334,0x1735,0x1736,0x1337,0x1338,0x1739,\n");\r
7049 fprintf(fp, " 0x173a,0x133b,0x173c,0x133d,0x133e,0x173f,0x1340,0x1741,\n");\r
7050 fprintf(fp, " 0x1742,0x1343,0x1744,0x1345,0x1346,0x1747,0x1748,0x1349,\n");\r
7051 fprintf(fp, " 0x134a,0x174b,0x134c,0x174d,0x174e,0x134f,0x1750,0x1351,\n");\r
7052 fprintf(fp, " 0x1352,0x1753,0x1354,0x1755,0x1756,0x1357,0x1358,0x1759,\n");\r
7053 fprintf(fp, " 0x175a,0x135b,0x175c,0x135d,0x135e,0x175f,0x1760,0x1361,\n");\r
7054 fprintf(fp, " 0x1362,0x1763,0x1364,0x1765,0x1766,0x1367,0x1368,0x1769,\n");\r
7055 fprintf(fp, " 0x176a,0x136b,0x176c,0x136d,0x136e,0x176f,0x1370,0x1771,\n");\r
7056 fprintf(fp, " 0x1772,0x1373,0x1774,0x1375,0x1376,0x1777,0x1778,0x1379,\n");\r
7057 fprintf(fp, " 0x137a,0x177b,0x137c,0x177d,0x177e,0x137f,0x9380,0x9781,\n");\r
7058 fprintf(fp, " 0x9782,0x9383,0x9784,0x9385,0x9386,0x9787,0x9788,0x9389,\n");\r
7059 fprintf(fp, " 0x938a,0x978b,0x938c,0x978d,0x978e,0x938f,0x9790,0x9391,\n");\r
7060 fprintf(fp, " 0x9392,0x9793,0x9394,0x9795,0x9796,0x9397,0x9398,0x9799 \n");\r
7061 fprintf(fp, "};\n\n");\r
7062\r
7063 fprintf(fp, "void DDFDCBHandler(UINT32 dwWhich);\n\n");\r
7064\r
7065 fprintf(fp, "\n");\r
7066 }\r
7067 else\r
7068 {\r
7069 assert(0);\r
7070 }\r
7071}\r
7072 \r
7073CodeSegmentBegin()\r
7074{\r
7075 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7076 {\r
7077 fprintf(fp, " section .text use32 flat class=code\n");\r
7078 }\r
7079 else\r
7080 if (MZ80_C == bWhat)\r
7081 {\r
7082 fprintf(fp, "static void InvalidInstruction(UINT32 dwCount)\n");\r
7083 fprintf(fp, "{\n");\r
7084\r
7085 fprintf(fp, " pbPC -= dwCount; /* Invalid instruction - back up */\n");\r
7086 fprintf(fp, " dwReturnCode = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
7087 fprintf(fp, " dwOriginalCycles -= sdwCyclesRemaining;\n");\r
7088 fprintf(fp, " sdwCyclesRemaining = 0;\n");\r
7089\r
7090 fprintf(fp, "}\n\n");\r
7091 }\r
7092 else\r
7093 {\r
7094 assert(0);\r
7095 }\r
7096}\r
7097\r
7098CodeSegmentEnd()\r
7099{\r
7100}\r
7101\r
7102ProgramEnd()\r
7103{\r
7104 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7105 {\r
7106 fprintf(fp, " end\n");\r
7107 }\r
7108 else\r
7109 if (MZ80_C == bWhat)\r
7110 {\r
7111 }\r
7112 else\r
7113 {\r
7114 assert(0);\r
7115 }\r
7116}\r
7117\r
7118EmitRegularInstructions()\r
7119{\r
7120 UINT32 dwLoop = 0;\r
7121 UINT32 dwLoop2 = 0;\r
7122\r
7123 bCurrentMode = TIMING_REGULAR;\r
7124\r
7125 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7126 {\r
7127 while (dwLoop < 0x100)\r
7128 {\r
7129 dwLoop2 = 0;\r
7130 sprintf(procname, "RegInst%.2x", dwLoop);\r
7131\r
7132 while (StandardOps[dwLoop2].bOpCode != dwLoop && StandardOps[dwLoop2].bOpCode != 0xffffffff)\r
7133 dwLoop2++;\r
7134\r
7135 assert(dwLoop2 < 0x100);\r
7136 if (StandardOps[dwLoop2].Emitter\r
7137 && StandardOps[dwLoop2].bOpCode != 0xffffffff)\r
7138 StandardOps[dwLoop2].Emitter((UINT32) dwLoop);\r
7139\r
7140 dwLoop++;\r
7141 }\r
7142 }\r
7143 else\r
7144 if (MZ80_C == bWhat)\r
7145 {\r
7146 fprintf(fp, "/* Main execution entry point */\n\n");\r
7147\r
7148 fprintf(fp, "UINT32 %sexec(UINT32 dwCycles)\n", cpubasename);\r
7149 fprintf(fp, "{\n");\r
7150 fprintf(fp, " UINT8 bOpcode;\n\n");\r
7151\r
7152 fprintf(fp, " dwReturnCode = 0x80000000; /* Assume it'll work */\n");\r
7153\r
7154 fprintf(fp, " sdwCyclesRemaining = dwCycles;\n");\r
7155 fprintf(fp, " dwOriginalCycles = dwCycles;\n");\r
7156\r
7157 fprintf(fp, " if (cpu.z80halted)\n");\r
7158 fprintf(fp, " {\n");\r
7159\r
7160 fprintf(fp, " dwElapsedTicks += dwCycles;\n");\r
7161 fprintf(fp, " return(0x80000000);\n");\r
7162\r
7163 fprintf(fp, " }\n\n");\r
7164 \r
7165\r
7166 fprintf(fp, " pbPC = cpu.z80Base + cpu.z80pc;\n\n");\r
7167\r
7168 fprintf(fp, " while (sdwCyclesRemaining > 0)\n");\r
7169\r
7170 fprintf(fp, " {\n");\r
7171 fprintf(fp, " bOpcode = *pbPC++;\n");\r
7172 fprintf(fp, " switch (bOpcode)\n");\r
7173 fprintf(fp, " {\n");\r
7174\r
7175 while (dwLoop < 0x100)\r
7176 {\r
7177 dwLoop2 = 0;\r
7178\r
7179 fprintf(fp, " case 0x%.2x:\n", dwLoop);\r
7180 fprintf(fp, " {\n");\r
7181\r
7182 while (StandardOps[dwLoop2].bOpCode != dwLoop && StandardOps[dwLoop2].bOpCode != 0xffffffff)\r
7183 dwLoop2++;\r
7184\r
7185 if (bTimingRegular[dwLoop])\r
7186 {\r
7187 fprintf(fp, " sdwCyclesRemaining -= %ld;\n", bTimingRegular[dwLoop]);\r
7188 }\r
7189\r
7190 if (StandardOps[dwLoop2].Emitter)\r
7191 {\r
7192 StandardOps[dwLoop2].Emitter(dwLoop);\r
7193 }\r
7194\r
7195 fprintf(fp, " break;\n");\r
7196 fprintf(fp, " }\n");\r
7197 ++dwLoop;\r
7198 }\r
7199\r
7200 fprintf(fp, " }\n");\r
7201 fprintf(fp, " }\n\n");\r
7202\r
7203 fprintf(fp, " dwElapsedTicks += (dwOriginalCycles - sdwCyclesRemaining);\n\n");\r
7204\r
7205 fprintf(fp, " cpu.z80pc = (UINT32) pbPC - (UINT32) cpu.z80Base;\n");\r
7206\r
7207 fprintf(fp, " return(dwReturnCode); /* Indicate success */\n");\r
7208 fprintf(fp, "}\n\n");\r
7209 }\r
7210 else\r
7211 {\r
7212 assert(0);\r
7213 }\r
7214}\r
7215\r
7216EmitCBInstructions()\r
7217{\r
7218 UINT32 dwLoop = 0;\r
7219 UINT32 dwLoop2 = 0;\r
7220\r
7221 bCurrentMode = TIMING_CB;\r
7222\r
7223 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7224 {\r
7225 while (dwLoop < 0x100)\r
7226 {\r
7227 sprintf(procname, "CBInst%.2x", dwLoop);\r
7228 dwLoop2 = 0;\r
7229\r
7230 while (CBOps[dwLoop2].bOpCode != dwLoop && CBOps[dwLoop2].bOpCode != 0xffffffff)\r
7231 dwLoop2++;\r
7232\r
7233 assert(dwLoop2 < 0x100);\r
7234 if (CBOps[dwLoop2].Emitter && CBOps[dwLoop2].bOpCode != 0xffffffff)\r
7235 CBOps[dwLoop2].Emitter((UINT32) dwLoop);\r
7236\r
7237 dwLoop++;\r
7238 }\r
7239 }\r
7240 else\r
7241 if (MZ80_C == bWhat)\r
7242 {\r
7243 fprintf(fp, "void CBHandler(void)\n");\r
7244 fprintf(fp, "{\n");\r
7245 fprintf(fp, " switch (*pbPC++)\n");\r
7246 fprintf(fp, " {\n");\r
7247\r
7248 while (dwLoop < 0x100)\r
7249 {\r
7250 dwLoop2 = 0;\r
7251\r
7252 fprintf(fp, " case 0x%.2x:\n", dwLoop);\r
7253 fprintf(fp, " {\n");\r
7254\r
7255 while (CBOps[dwLoop2].bOpCode != dwLoop && CBOps[dwLoop2].bOpCode != 0xffffffff)\r
7256 dwLoop2++;\r
7257\r
7258 if (bTimingCB[dwLoop])\r
7259 {\r
7260 fprintf(fp, " sdwCyclesRemaining -= %ld;\n", bTimingCB[dwLoop]);\r
7261 }\r
7262\r
7263 if (CBOps[dwLoop2].Emitter)\r
7264 {\r
7265 CBOps[dwLoop2].Emitter(dwLoop);\r
7266 }\r
7267 else\r
7268 {\r
7269 InvalidInstructionC(2);\r
7270 }\r
7271\r
7272 fprintf(fp, " break;\n");\r
7273 fprintf(fp, " }\n");\r
7274 ++dwLoop;\r
7275 }\r
7276\r
7277 fprintf(fp, " }\n");\r
7278 fprintf(fp, "}\n");\r
7279 }\r
7280 else\r
7281 {\r
7282 assert(0);\r
7283 }\r
7284}\r
7285\r
7286EmitEDInstructions()\r
7287{\r
7288 UINT32 dwLoop = 0;\r
7289 UINT32 dwLoop2 = 0;\r
7290\r
7291 bCurrentMode = TIMING_ED;\r
7292\r
7293 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7294 {\r
7295 while (dwLoop < 0x100)\r
7296 {\r
7297 sprintf(procname, "EDInst%.2x", dwLoop);\r
7298 dwLoop2 = 0;\r
7299\r
7300 while (EDOps[dwLoop2].bOpCode != dwLoop && EDOps[dwLoop2].bOpCode != 0xffffffff)\r
7301 dwLoop2++;\r
7302\r
7303 assert(dwLoop2 < 0x100);\r
7304 if (EDOps[dwLoop2].Emitter && EDOps[dwLoop2].bOpCode != 0xffffffff)\r
7305 EDOps[dwLoop2].Emitter((UINT32) dwLoop);\r
7306\r
7307 dwLoop++;\r
7308 }\r
7309 }\r
7310 else\r
7311 if (MZ80_C == bWhat)\r
7312 {\r
7313 fprintf(fp, "void EDHandler(void)\n");\r
7314 fprintf(fp, "{\n");\r
7315 fprintf(fp, " switch (*pbPC++)\n");\r
7316 fprintf(fp, " {\n");\r
7317\r
7318 while (dwLoop < 0x100)\r
7319 {\r
7320 dwLoop2 = 0;\r
7321\r
7322 fprintf(fp, " case 0x%.2x:\n", dwLoop);\r
7323 fprintf(fp, " {\n");\r
7324\r
7325 while (EDOps[dwLoop2].bOpCode != dwLoop && EDOps[dwLoop2].bOpCode != 0xffffffff)\r
7326 dwLoop2++;\r
7327\r
7328 if (bTimingED[dwLoop])\r
7329 {\r
7330 fprintf(fp, " sdwCyclesRemaining -= %ld;\n", bTimingED[dwLoop]);\r
7331 }\r
7332\r
7333 if (EDOps[dwLoop2].Emitter)\r
7334 {\r
7335 EDOps[dwLoop2].Emitter(dwLoop);\r
7336 }\r
7337 else\r
7338 {\r
7339 InvalidInstructionC(2);\r
7340 }\r
7341\r
7342 fprintf(fp, " break;\n");\r
7343 fprintf(fp, " }\n");\r
7344 ++dwLoop;\r
7345 }\r
7346\r
7347 fprintf(fp, " }\n");\r
7348 fprintf(fp, "}\n");\r
7349 }\r
7350 else\r
7351 {\r
7352 assert(0);\r
7353 }\r
7354\r
7355 fprintf(fp, "\n");\r
7356}\r
7357\r
7358EmitDDInstructions()\r
7359{\r
7360 UINT32 dwLoop = 0;\r
7361 UINT32 dwLoop2 = 0;\r
7362\r
7363 bCurrentMode = TIMING_DDFD;\r
7364\r
7365 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7366 {\r
7367 while (dwLoop < 0x100)\r
7368 {\r
7369 sprintf(procname, "DDInst%.2x", dwLoop);\r
7370 dwLoop2 = 0;\r
7371 \r
7372 while (DDFDOps[dwLoop2].bOpCode != dwLoop && DDFDOps[dwLoop2].bOpCode != 0xffffffff)\r
7373 dwLoop2++;\r
7374 \r
7375 assert(dwLoop2 < 0x100);\r
7376 if (DDFDOps[dwLoop2].Emitter && DDFDOps[dwLoop2].bOpCode != 0xffffffff)\r
7377 DDFDOps[dwLoop2].Emitter((UINT32) dwLoop);\r
7378 \r
7379 dwLoop++;\r
7380 }\r
7381\r
7382 bCurrentMode = TIMING_XXCB;\r
7383\r
7384 dwLoop = 0;\r
7385\r
7386 while (dwLoop < 0x100)\r
7387 {\r
7388 sprintf(procname, "DDFDCBInst%.2x", dwLoop);\r
7389 dwLoop2 = 0;\r
7390\r
7391 while (DDFDCBOps[dwLoop2].bOpCode != dwLoop && DDFDCBOps[dwLoop2].bOpCode != 0xffffffff)\r
7392 dwLoop2++;\r
7393\r
7394 assert(dwLoop2 < 0x100);\r
7395 if (DDFDCBOps[dwLoop2].Emitter && DDFDCBOps[dwLoop2].bOpCode != 0xffffffff)\r
7396 DDFDCBOps[dwLoop2].Emitter((UINT32) dwLoop);\r
7397\r
7398 dwLoop++;\r
7399 }\r
7400 }\r
7401 else\r
7402 if (MZ80_C == bWhat)\r
7403 {\r
7404 fprintf(fp, "void DDHandler(void)\n");\r
7405 fprintf(fp, "{\n");\r
7406 fprintf(fp, " switch (*pbPC++)\n");\r
7407 fprintf(fp, " {\n");\r
7408\r
7409 while (dwLoop < 0x100)\r
7410 {\r
7411 dwLoop2 = 0;\r
7412\r
7413 fprintf(fp, " case 0x%.2x:\n", dwLoop);\r
7414 fprintf(fp, " {\n");\r
7415\r
7416 while (DDFDOps[dwLoop2].bOpCode != dwLoop && DDFDOps[dwLoop2].bOpCode != 0xffffffff)\r
7417 dwLoop2++;\r
7418\r
7419 if (bTimingDDFD[dwLoop])\r
7420 {\r
7421 fprintf(fp, " sdwCyclesRemaining -= %ld;\n", bTimingDDFD[dwLoop]);\r
7422 }\r
7423\r
7424 if (DDFDOps[dwLoop2].Emitter)\r
7425 {\r
7426 DDFDOps[dwLoop2].Emitter(dwLoop);\r
7427 }\r
7428 else\r
7429 {\r
7430 InvalidInstructionC(2);\r
7431 }\r
7432\r
7433 fprintf(fp, " break;\n");\r
7434 fprintf(fp, " }\n");\r
7435 ++dwLoop;\r
7436 }\r
7437\r
7438 fprintf(fp, " }\n");\r
7439 fprintf(fp, "}\n");\r
7440\r
7441 // DDFD Handler\r
7442\r
7443 bCurrentMode = TIMING_XXCB;\r
7444\r
7445 dwLoop = 0;\r
7446\r
7447 fprintf(fp, "void DDFDCBHandler(UINT32 dwWhich)\n");\r
7448 fprintf(fp, "{\n");\r
7449 fprintf(fp, " if (dwWhich)\n");\r
7450 fprintf(fp, " {\n");\r
7451 fprintf(fp, " dwAddr = (UINT32) ((INT32) cpu.z80IY + ((INT32) *pbPC++)) & 0xffff;\n");\r
7452 fprintf(fp, " }\n");\r
7453 fprintf(fp, " else\n");\r
7454 fprintf(fp, " {\n");\r
7455 fprintf(fp, " dwAddr = (UINT32) ((INT32) cpu.z80IX + ((INT32) *pbPC++)) & 0xffff;\n");\r
7456 fprintf(fp, " }\n\n");\r
7457\r
7458 ReadValueFromMemory("dwAddr", "bTemp");\r
7459\r
7460 fprintf(fp, " switch (*pbPC++)\n");\r
7461 fprintf(fp, " {\n");\r
7462\r
7463 while (dwLoop < 0x100)\r
7464 {\r
7465 dwLoop2 = 0;\r
7466\r
7467 fprintf(fp, " case 0x%.2x:\n", dwLoop);\r
7468 fprintf(fp, " {\n");\r
7469\r
7470 while (DDFDCBOps[dwLoop2].bOpCode != dwLoop && DDFDCBOps[dwLoop2].bOpCode != 0xffffffff)\r
7471 dwLoop2++;\r
7472\r
7473 if (bTimingXXCB[dwLoop])\r
7474 {\r
7475 fprintf(fp, " sdwCyclesRemaining -= %ld;\n", bTimingXXCB[dwLoop]);\r
7476 }\r
7477\r
7478 if (DDFDCBOps[dwLoop2].Emitter)\r
7479 {\r
7480 DDFDCBOps[dwLoop2].Emitter(dwLoop);\r
7481 }\r
7482 else\r
7483 {\r
7484 InvalidInstructionC(4);\r
7485 }\r
7486\r
7487 fprintf(fp, " break;\n");\r
7488 fprintf(fp, " }\n");\r
7489 ++dwLoop;\r
7490 }\r
7491\r
7492 fprintf(fp, " }\n");\r
7493 fprintf(fp, "}\n");\r
7494 }\r
7495 else\r
7496 {\r
7497 assert(0);\r
7498 }\r
7499}\r
7500\r
7501EmitFDInstructions()\r
7502{\r
7503 UINT32 dwLoop = 0;\r
7504 UINT32 dwLoop2 = 0;\r
7505\r
7506 bCurrentMode = TIMING_DDFD;\r
7507\r
7508 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7509 {\r
7510 while (dwLoop < 0x100)\r
7511 {\r
7512 sprintf(procname, "FDInst%.2x", dwLoop);\r
7513 dwLoop2 = 0;\r
7514\r
7515 while (DDFDOps[dwLoop2].bOpCode != dwLoop && DDFDOps[dwLoop2].bOpCode != 0xffffffff)\r
7516 dwLoop2++;\r
7517\r
7518 assert(dwLoop2 < 0x100);\r
7519 if (DDFDOps[dwLoop2].Emitter && DDFDOps[dwLoop2].bOpCode != 0xffffffff)\r
7520 DDFDOps[dwLoop2].Emitter((UINT32) dwLoop);\r
7521\r
7522 dwLoop++;\r
7523 }\r
7524 }\r
7525 else\r
7526 if (MZ80_C == bWhat)\r
7527 {\r
7528 fprintf(fp, "void FDHandler(void)\n");\r
7529 fprintf(fp, "{\n");\r
7530 fprintf(fp, " switch (*pbPC++)\n");\r
7531 fprintf(fp, " {\n");\r
7532\r
7533 while (dwLoop < 0x100)\r
7534 {\r
7535 dwLoop2 = 0;\r
7536\r
7537 fprintf(fp, " case 0x%.2x:\n", dwLoop);\r
7538 fprintf(fp, " {\n");\r
7539\r
7540 while (DDFDOps[dwLoop2].bOpCode != dwLoop && DDFDOps[dwLoop2].bOpCode != 0xffffffff)\r
7541 dwLoop2++;\r
7542\r
7543 if (bTimingDDFD[dwLoop])\r
7544 {\r
7545 fprintf(fp, " sdwCyclesRemaining -= %ld;\n", bTimingDDFD[dwLoop]);\r
7546 }\r
7547\r
7548 if (DDFDOps[dwLoop2].Emitter)\r
7549 {\r
7550 DDFDOps[dwLoop2].Emitter(dwLoop);\r
7551 }\r
7552 else\r
7553 {\r
7554 InvalidInstructionC(2);\r
7555 }\r
7556\r
7557 fprintf(fp, " break;\n");\r
7558 fprintf(fp, " }\n");\r
7559 ++dwLoop;\r
7560 }\r
7561\r
7562 fprintf(fp, " }\n");\r
7563 fprintf(fp, "}\n");\r
7564 }\r
7565 else\r
7566 {\r
7567 assert(0);\r
7568 }\r
7569}\r
7570\r
7571/* These are the meta routines */\r
7572\r
7573void ReadMemoryByteHandler()\r
7574{\r
7575 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7576 {\r
7577 Alignment();\r
7578 fprintf(fp, "; This is a generic read memory byte handler when a foreign\n");\r
7579 fprintf(fp, "; handler is to be called\n\n");\r
7580 fprintf(fp, "; EDI=Handler address, EDX=Address\n");\r
7581 fprintf(fp, "; On return, EDX & EDI are undisturbed and AL=Byte read\n\n");\r
7582 fprintf(fp, "ReadMemoryByte:\n");\r
7583 \r
7584 fprintf(fp, " mov [_z80af], ax ; Save AF\n");\r
7585 fprintf(fp, " cmp [edi+8], dword 0 ; Null handler?\n");\r
7586 fprintf(fp, " je directReadHandler ; Yep! It's a direct read!\n\n");\r
7587\r
7588 fprintf(fp, " mov [_z80hl], bx ; Save HL\n");\r
7589 fprintf(fp, " mov [_z80bc], cx ; Save BC\n");\r
7590\r
7591 fprintf(fp, " sub esi, ebp ; Our program counter\n", cpubasename);\r
7592 fprintf(fp, " mov [_z80pc], si ; Save our program counter\n", cpubasename);\r
7593\r
7594 // Now adjust the proper timing\r
7595\r
7596 fprintf(fp, " mov esi, [dwOriginalExec] \n");\r
7597 fprintf(fp, " sub esi, [cyclesRemaining]\n");\r
7598 fprintf(fp, " add [dwElapsedTicks], esi\n");\r
7599 fprintf(fp, " add [_z80rCounter], esi\n");\r
7600 fprintf(fp, " sub [dwOriginalExec], esi\n");\r
7601 \r
7602 fprintf(fp, " push edi ; Save our structure address\n");\r
7603 fprintf(fp, " push edx ; And our desired address\n");\r
7604\r
7605 if (FALSE == bUseStack)\r
7606 {\r
7607 fprintf(fp, " mov eax, edx ; Get our desired address reg\n");\r
7608 fprintf(fp, " mov edx, edi ; Pointer to the structure\n");\r
7609 }\r
7610 \r
7611 fprintf(fp, " call dword [edi + 8] ; Go call our handler\n");\r
7612 \r
7613 fprintf(fp, " pop edx ; Restore our address\n");\r
7614 fprintf(fp, " pop edi ; Restore our handler's address\n");\r
7615 \r
7616 fprintf(fp, " xor ebx, ebx ; Zero our future HL\n");\r
7617 fprintf(fp, " xor esi, esi ; Zero it!\n");\r
7618 fprintf(fp, " mov ebp, [_z80Base] ; Base pointer comes back\n", cpubasename);\r
7619 fprintf(fp, " mov si, [_z80pc] ; Get our program counter back\n", cpubasename);\r
7620 fprintf(fp, " xor ecx, ecx ; Zero our future BC\n");\r
7621 fprintf(fp, " add esi, ebp ; Rebase it properly\n");\r
7622 \r
7623 fprintf(fp, " mov bx, [_z80hl] ; Get HL back\n");\r
7624 fprintf(fp, " mov cx, [_z80bc] ; Get BC back\n");\r
7625 \r
7626 // Note: the callee must restore AF!\r
7627\r
7628 fprintf(fp, " ret\n\n");\r
7629 fprintf(fp, "directReadHandler:\n");\r
7630 fprintf(fp, " mov eax, [edi+12] ; Get our base address\n");\r
7631 fprintf(fp, " sub edx, [edi] ; Subtract our base (low) address\n");\r
7632 fprintf(fp, " mov al, [edx+eax] ; Get our data byte\n");\r
7633 fprintf(fp, " and eax, 0ffh ; Only the lower byte matters!\n");\r
7634 fprintf(fp, " add edx, [edi] ; Add our base back\n");\r
7635 fprintf(fp, " ret ; Return to caller!\n\n");\r
7636 }\r
7637 else\r
7638 if (MZ80_C == bWhat)\r
7639 {\r
7640 }\r
7641 else\r
7642 {\r
7643 assert(0);\r
7644 }\r
7645}\r
7646\r
7647void WriteMemoryByteHandler()\r
7648{\r
7649 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7650 {\r
7651 Alignment();\r
7652 fprintf(fp, "; This is a generic read memory byte handler when a foreign\n");\r
7653 fprintf(fp, "; handler is to be called.\n");\r
7654 fprintf(fp, "; EDI=Handler address, AL=Byte to write, EDX=Address\n");\r
7655 fprintf(fp, "; EDI and EDX Are undisturbed on exit\n\n");\r
7656 fprintf(fp, "WriteMemoryByte:\n");\r
7657\r
7658 fprintf(fp, " cmp [edi+8], dword 0 ; Null handler?\n");\r
7659 fprintf(fp, " je directWriteHandler\n\n");\r
7660 \r
7661 \r
7662 fprintf(fp, " mov [_z80hl], bx ; Save HL\n");\r
7663 fprintf(fp, " mov [_z80bc], cx ; Save BX\n");\r
7664 \r
7665 fprintf(fp, " sub esi, ebp ; Our program counter\n", cpubasename);\r
7666 fprintf(fp, " mov [_z80pc], si ; Save our program counter\n", cpubasename);\r
7667 \r
7668 // Now adjust the proper timing\r
7669 \r
7670 fprintf(fp, " mov esi, [dwOriginalExec] \n");\r
7671 fprintf(fp, " sub esi, [cyclesRemaining]\n");\r
7672 fprintf(fp, " add [dwElapsedTicks], esi\n");\r
7673 fprintf(fp, " add [_z80rCounter], esi\n");\r
7674 fprintf(fp, " sub [dwOriginalExec], esi\n");\r
7675 \r
7676 fprintf(fp, " push edi ; Save our structure address\n");\r
7677 \r
7678 if (bUseStack)\r
7679 fprintf(fp, " push eax ; Data to write\n");\r
7680 \r
7681 fprintf(fp, " push edx ; And our desired address\n");\r
7682 \r
7683 if (FALSE == bUseStack)\r
7684 {\r
7685 fprintf(fp, " xchg eax, edx ; Swap address/data around\n");\r
7686 fprintf(fp, " mov ebx, edi ; Our MemoryWriteByte structure address\n");\r
7687 }\r
7688 \r
7689 fprintf(fp, " call dword [edi + 8] ; Go call our handler\n");\r
7690 \r
7691 fprintf(fp, " pop edx ; Restore our address\n");\r
7692 \r
7693 if (bUseStack)\r
7694 fprintf(fp, " pop eax ; Restore our data written\n");\r
7695 \r
7696 fprintf(fp, " pop edi ; Save our structure address\n");\r
7697 \r
7698 fprintf(fp, " xor ebx, ebx ; Zero our future HL\n");\r
7699 fprintf(fp, " xor ecx, ecx ; Zero our future BC\n");\r
7700 fprintf(fp, " mov bx, [_z80hl] ; Get HL back\n");\r
7701 fprintf(fp, " mov cx, [_z80bc] ; Get BC back\n");\r
7702 fprintf(fp, " mov ax, [_z80af] ; Get AF back\n");\r
7703 fprintf(fp, " xor esi, esi ; Zero it!\n");\r
7704 fprintf(fp, " mov si, [_z80pc] ; Get our program counter back\n", cpubasename);\r
7705 fprintf(fp, " mov ebp, [_z80Base] ; Base pointer comes back\n", cpubasename);\r
7706 fprintf(fp, " add esi, ebp ; Rebase it properly\n");\r
7707\r
7708 fprintf(fp, " ret\n\n");\r
7709\r
7710 fprintf(fp, "directWriteHandler:\n");\r
7711 fprintf(fp, " sub edx, [edi] ; Subtract our offset\n");\r
7712 fprintf(fp, " add edx, [edi+12] ; Add in the base address\n");\r
7713 fprintf(fp, " mov [edx], al ; Store our byte\n");\r
7714 fprintf(fp, " sub edx, [edi+12] ; Restore our base address\n");\r
7715 fprintf(fp, " add edx, [edi] ; And put our offset back\n");\r
7716 fprintf(fp, " ret\n\n");\r
7717 }\r
7718 else\r
7719 if (MZ80_C == bWhat)\r
7720 {\r
7721 }\r
7722 else\r
7723 {\r
7724 assert(0);\r
7725 }\r
7726}\r
7727\r
7728void PushWordHandler()\r
7729{\r
7730 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7731 {\r
7732 Alignment();\r
7733 \r
7734 fprintf(fp, ";\n");\r
7735 fprintf(fp, "; DX=Top of SP, [_wordval]=word value to push\n");\r
7736 fprintf(fp, ";\n\n");\r
7737 fprintf(fp, "PushWord:\n");\r
7738 fprintf(fp, " mov dx, [_z80sp]\n");\r
7739 fprintf(fp, " dec dx\n");\r
7740 WriteValueToMemory("dx", "byte [_wordval+1]");\r
7741 fprintf(fp, " dec dx\n");\r
7742 WriteValueToMemory("dx", "byte [_wordval]");\r
7743 fprintf(fp, " sub [_z80sp], word 2\n");\r
7744 fprintf(fp, " xor edx, edx\n");\r
7745 fprintf(fp, " ret\n\n");\r
7746 }\r
7747}\r
7748\r
7749void PopWordHandler()\r
7750{\r
7751 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7752 {\r
7753 Alignment();\r
7754 \r
7755 fprintf(fp, ";\n");\r
7756 fprintf(fp, "; [_z80sp]=Top of SP, DX=Word value read\n");\r
7757 fprintf(fp, ";\n\n");\r
7758 fprintf(fp, "PopWord:\n");\r
7759 fprintf(fp, " mov dx, [_z80sp]\n");\r
7760 \r
7761 ReadWordFromMemory("dx", "dx");\r
7762 fprintf(fp, " ret\n\n");\r
7763 }\r
7764}\r
7765\r
7766void ReadIoHandler()\r
7767{\r
7768 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7769 {\r
7770 Alignment();\r
7771\r
7772 fprintf(fp, "; This is a generic I/O read byte handler for when a foreign\n");\r
7773 fprintf(fp, "; handler is to be called\n");\r
7774\r
7775 fprintf(fp, "; EDI=Handler address, EDX=I/O Address\n");\r
7776 fprintf(fp, "; On return, EDX & EDI are undisturbed and AL=Byte read\n\n");\r
7777 fprintf(fp, "ReadIOByte:\n");\r
7778 \r
7779 fprintf(fp, " mov [_z80af], ax ; Save AF\n");\r
7780 fprintf(fp, " mov [_z80hl], bx ; Save HL\n");\r
7781 fprintf(fp, " mov [_z80bc], cx ; Save BC\n");\r
7782\r
7783 fprintf(fp, " sub esi, ebp ; Our program counter\n", cpubasename);\r
7784 fprintf(fp, " mov [_z80pc], si ; Save our program counter\n", cpubasename);\r
7785\r
7786 // Now adjust the proper timing\r
7787\r
7788 fprintf(fp, " mov esi, [dwOriginalExec] \n");\r
7789 fprintf(fp, " sub esi, [cyclesRemaining]\n");\r
7790 fprintf(fp, " add [dwElapsedTicks], esi\n");\r
7791 fprintf(fp, " add [_z80rCounter], esi\n");\r
7792 fprintf(fp, " sub [dwOriginalExec], esi\n");\r
7793\r
7794 fprintf(fp, " push edi ; Save our structure address\n");\r
7795 fprintf(fp, " push edx ; And our desired I/O port\n");\r
7796\r
7797 if (FALSE == bUseStack)\r
7798 {\r
7799 fprintf(fp, " mov eax, edx ; Get our desired address reg\n");\r
7800 fprintf(fp, " mov edx, edi ; Pointer to the structure\n");\r
7801 }\r
7802\r
7803 fprintf(fp, " call dword [edi + 4] ; Go call our handler\n");\r
7804\r
7805 fprintf(fp, " pop edx ; Restore our address\n");\r
7806 fprintf(fp, " pop edi ; Restore our handler's address\n");\r
7807\r
7808 fprintf(fp, " xor ebx, ebx ; Zero our future HL\n");\r
7809 fprintf(fp, " xor ecx, ecx ; Zero our future BC\n");\r
7810 fprintf(fp, " xor esi, esi ; Zero it!\n");\r
7811 fprintf(fp, " mov si, [_z80pc] ; Get our program counter back\n", cpubasename);\r
7812 fprintf(fp, " mov ebp, [_z80Base] ; Base pointer comes back\n", cpubasename);\r
7813 fprintf(fp, " add esi, ebp ; Rebase it properly\n");\r
7814\r
7815 fprintf(fp, " mov bx, [_z80hl] ; Get HL back\n");\r
7816 fprintf(fp, " mov cx, [_z80bc] ; Get BC back\n");\r
7817\r
7818 // Note: the callee must restore AF!\r
7819\r
7820 fprintf(fp, " ret\n\n");\r
7821 }\r
7822 else\r
7823 if (MZ80_C == bWhat)\r
7824 {\r
7825 }\r
7826 else\r
7827 {\r
7828 assert(0);\r
7829 }\r
7830}\r
7831\r
7832void WriteIoHandler()\r
7833{\r
7834 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7835 {\r
7836 Alignment();\r
7837\r
7838 fprintf(fp, "; This is a generic write I/O byte handler when a foreign handler is to\n");\r
7839 fprintf(fp, "; be called\n");\r
7840 fprintf(fp, "; EDI=Handler address, AL=Byte to write, EDX=I/O Address\n");\r
7841 fprintf(fp, "; EDI and EDX Are undisturbed on exit\n\n");\r
7842 fprintf(fp, "WriteIOByte:\n");\r
7843 \r
7844 fprintf(fp, " mov [_z80hl], bx ; Save HL\n");\r
7845 fprintf(fp, " mov [_z80bc], cx ; Save BX\n");\r
7846\r
7847 fprintf(fp, " sub esi, ebp ; Our program counter\n", cpubasename);\r
7848 fprintf(fp, " mov [_z80pc], si ; Save our program counter\n", cpubasename);\r
7849\r
7850 // Now adjust the proper timing\r
7851\r
7852 fprintf(fp, " mov esi, [dwOriginalExec] \n");\r
7853 fprintf(fp, " sub esi, [cyclesRemaining]\n");\r
7854 fprintf(fp, " add [dwElapsedTicks], esi\n");\r
7855 fprintf(fp, " add [_z80rCounter], esi\n");\r
7856 fprintf(fp, " sub [dwOriginalExec], esi\n");\r
7857\r
7858 fprintf(fp, " push edi ; Save our structure address\n");\r
7859\r
7860 if (bUseStack)\r
7861 fprintf(fp, " push eax ; Data to write\n");\r
7862\r
7863 fprintf(fp, " push edx ; And our desired I/O address\n");\r
7864\r
7865 if (FALSE == bUseStack)\r
7866 {\r
7867 fprintf(fp, " xchg eax, edx ; Swap address/data around\n");\r
7868 fprintf(fp, " mov ebx, edi ; Our z80IoWrite structure address\n");\r
7869 }\r
7870\r
7871 fprintf(fp, " call dword [edi + 4] ; Go call our handler\n");\r
7872\r
7873 fprintf(fp, " pop edx ; Restore our address\n");\r
7874 \r
7875 if (bUseStack)\r
7876 fprintf(fp, " pop eax ; Restore our data written\n");\r
7877 \r
7878 fprintf(fp, " pop edi ; Save our structure address\n");\r
7879\r
7880 fprintf(fp, " xor ebx, ebx ; Zero our future HL\n");\r
7881 fprintf(fp, " xor ecx, ecx ; Zero our future BC\n");\r
7882 fprintf(fp, " mov bx, [_z80hl] ; Get HL back\n");\r
7883 fprintf(fp, " mov cx, [_z80bc] ; Get BC back\n");\r
7884 fprintf(fp, " mov ax, [_z80af] ; Get AF back\n");\r
7885 fprintf(fp, " xor esi, esi ; Zero it!\n");\r
7886 fprintf(fp, " mov si, [_z80pc] ; Get our program counter back\n", cpubasename);\r
7887 fprintf(fp, " mov ebp, [_z80Base] ; Base pointer comes back\n", cpubasename);\r
7888 fprintf(fp, " add esi, ebp ; Rebase it properly\n");\r
7889\r
7890 fprintf(fp, " ret\n\n");\r
7891 }\r
7892 else\r
7893 if (MZ80_C == bWhat)\r
7894 {\r
7895 }\r
7896 else\r
7897 {\r
7898 assert(0);\r
7899 }\r
7900}\r
7901\r
7902ExecCode()\r
7903{\r
7904 if (MZ80_ASSEMBLY_X86 == bWhat)\r
7905 {\r
7906 fprintf(fp, " global _%sexec\n", cpubasename);\r
7907 fprintf(fp, " global %sexec_\n", cpubasename);\r
7908 \r
7909 if (bPlain)\r
7910 fprintf(fp, " global %sexec\n", cpubasename);\r
7911 \r
7912 sprintf(procname, "%sexec_", cpubasename);\r
7913 ProcBegin(0xffffffff);\r
7914 \r
7915 fprintf(fp, "_%sexec:\n", cpubasename);\r
7916 \r
7917 if (bPlain)\r
7918 fprintf(fp, "%sexec:\n", cpubasename);\r
7919 \r
7920 if (bUseStack)\r
7921 fprintf(fp, " mov eax, [esp+4] ; Get our execution cycle count\n");\r
7922 \r
7923 fprintf(fp, " push ebx ; Save all registers we use\n");\r
7924 fprintf(fp, " push ecx\n");\r
7925 fprintf(fp, " push edx\n");\r
7926 fprintf(fp, " push ebp\n");\r
7927 fprintf(fp, " push esi\n");\r
7928 fprintf(fp, " push edi\n");\r
7929 fprintf(fp, "\n");\r
7930\r
7931 fprintf(fp, " mov edi, eax\n"); \r
7932 fprintf(fp, " mov dword [cyclesRemaining], eax ; Store # of instructions to\n");\r
7933 fprintf(fp, " mov [dwLastRSample], eax\n");\r
7934 fprintf(fp, " mov [dwOriginalExec], eax ; Store this!\n");\r
7935\r
7936 fprintf(fp, " cmp dword [_z80halted], 0\n");\r
7937 fprintf(fp, " je goCpu\n");\r
7938 fprintf(fp, " add [_z80rCounter], eax\n");\r
7939 \r
7940 if (FALSE == bNoTiming)\r
7941 {\r
7942 fprintf(fp, " add dword [dwElapsedTicks], eax\n");\r
7943 }\r
7944 \r
7945 fprintf(fp, " mov dword [cyclesRemaining], 0 ; Nothing left!\n");\r
7946 fprintf(fp, " mov eax, 80000000h ; Successful exection\n");\r
7947 fprintf(fp, " jmp popReg\n");\r
7948 fprintf(fp, "goCpu:\n");\r
7949 fprintf(fp, " cld ; Go forward!\n");\r
7950 fprintf(fp, "\n");\r
7951 fprintf(fp, " xor eax, eax ; Zero EAX 'cause we use it!\n");\r
7952 fprintf(fp, " xor ebx, ebx ; Zero EBX, too\n");\r
7953 fprintf(fp, " xor ecx, ecx ; Zero ECX\n");\r
7954 fprintf(fp, " xor edx, edx ; And EDX\n");\r
7955 fprintf(fp, " xor esi, esi ; Zero our source address\n");\r
7956 fprintf(fp, "\n");\r
7957 fprintf(fp, " mov ax, [_z80af] ; Accumulator & flags\n");\r
7958 fprintf(fp, " xchg ah, al ; Swap these for later\n");\r
7959 fprintf(fp, " mov bx, [_z80hl] ; Get our HL value\n");\r
7960 fprintf(fp, " mov cx, [_z80bc] ; And our BC value\n");\r
7961 fprintf(fp, " mov ebp, [_z80Base] ; Get the base address\n");\r
7962 fprintf(fp, " mov si, [_z80pc] ; Get our program counter\n");\r
7963 fprintf(fp, " add esi, ebp ; Add in our base address\n");\r
7964\r
7965 fprintf(fp, " cmp [_z80intPending], byte 0 ; Interrupt pending?\n");\r
7966 fprintf(fp, " jz masterExecTarget\n\n");\r
7967 fprintf(fp, " call causeInternalInterrupt\n\n");\r
7968 fprintf(fp, "masterExecTarget:\n");\r
7969 fprintf(fp, " mov dl, [esi]\n");\r
7970 fprintf(fp, " inc esi\n");\r
7971 fprintf(fp, " jmp dword [z80regular+edx*4]\n\n");\r
7972 fprintf(fp, "; We get to invalidInsWord if it's a double byte invalid opcode\n");\r
7973 fprintf(fp, "\n");\r
7974 fprintf(fp, "invalidInsWord:\n");\r
7975 \r
7976 fprintf(fp, " dec esi\n");\r
7977 fprintf(fp, "\n");\r
7978 fprintf(fp, "; We get to invalidInsByte if it's a single byte invalid opcode\n");\r
7979 fprintf(fp, "\n");\r
7980 \r
7981 fprintf(fp, "invalidInsByte:\n");\r
7982 fprintf(fp, " xchg ah, al ; Swap them back so they look good\n");\r
7983 fprintf(fp, " mov [_z80af], ax ; Store A & flags\n");\r
7984 fprintf(fp, " dec esi ; Back up one instruction...\n");\r
7985 fprintf(fp, " mov edx, esi ; Get our address in EAX\n");\r
7986 fprintf(fp, " sub edx, ebp ; And subtract our base for\n");\r
7987 fprintf(fp, " ; an invalid instruction\n");\r
7988 fprintf(fp, " jmp short emulateEnd\n");\r
7989 fprintf(fp, "\n");\r
7990 fprintf(fp, "noMoreExec:\n");\r
7991 fprintf(fp, " cmp [bEIExit], byte 0 ; Are we exiting because of an EI?\n");\r
7992 fprintf(fp, " jne checkEI\n");\r
7993 fprintf(fp, "noMoreExecNoEI:\n");\r
7994 fprintf(fp, " xchg ah, al ; Swap these for later\n");\r
7995 fprintf(fp, " mov [_z80af], ax ; Store A & flags\n");\r
7996 \r
7997 fprintf(fp, " mov edx, [dwOriginalExec] ; Original exec time\n");\r
7998 fprintf(fp, " sub edx, edi ; Subtract # of cycles remaining\n");\r
7999 fprintf(fp, " add [_z80rCounter], edx\n");\r
8000 fprintf(fp, " add [dwElapsedTicks], edx ; Add our executed time\n");\r
8001 \r
8002 fprintf(fp, " mov edx, 80000000h ; Indicate successful exec\n");\r
8003 fprintf(fp, " jmp short emulateEnd ; All finished!\n");\r
8004 fprintf(fp, "\n");\r
8005 fprintf(fp, "; Now let's tuck away the virtual registers for next time\n");\r
8006 fprintf(fp, "\n");\r
8007 fprintf(fp, "storeFlags:\n");\r
8008 fprintf(fp, " xchg ah, al ; Swap these for later\n");\r
8009 fprintf(fp, " mov [_z80af], ax ; Store A & flags\n");\r
8010 fprintf(fp, "emulateEnd:\n");\r
8011 fprintf(fp, " mov [_z80hl], bx ; Store HL\n");\r
8012 fprintf(fp, " mov [_z80bc], cx ; Store BC\n");\r
8013 fprintf(fp, " sub esi, [_z80Base] ; Knock off physical address\n");\r
8014 fprintf(fp, " mov [_z80pc], si ; And store virtual address\n");\r
8015 fprintf(fp, " mov eax, edx ; Result code return\n");\r
8016 fprintf(fp, "\n");\r
8017 fprintf(fp, "popReg:\n");\r
8018 fprintf(fp, " pop edi ; Restore registers\n");\r
8019 fprintf(fp, " pop esi\n");\r
8020 fprintf(fp, " pop ebp\n");\r
8021 fprintf(fp, " pop edx\n");\r
8022 fprintf(fp, " pop ecx\n");\r
8023 fprintf(fp, " pop ebx\n");\r
8024 fprintf(fp, "\n");\r
8025 fprintf(fp, " ret\n");\r
8026 fprintf(fp, "\n");\r
8027 Alignment();\r
8028 fprintf(fp, "checkEI:\n");\r
8029 fprintf(fp, " xor edx, edx\n");\r
8030 fprintf(fp, " mov [bEIExit], byte 0\n");\r
8031 fprintf(fp, " sub edx, edi ; Find out how much time has passed\n");\r
8032 fprintf(fp, " mov edi, [dwEITiming]\n");\r
8033 fprintf(fp, " sub edi, edx\n");\r
8034 fprintf(fp, " js noMoreExecNoEI\n");\r
8035 fprintf(fp, " xor edx, edx\n");\r
8036\r
8037 fprintf(fp, " cmp [_z80intPending], byte 0\n");\r
8038 fprintf(fp, " je near masterExecTarget\n");\r
8039 fprintf(fp, " call causeInternalInterrupt\n");\r
8040 fprintf(fp, " jmp masterExecTarget\n\n");\r
8041\r
8042 Alignment();\r
8043 fprintf(fp, "causeInternalInterrupt:\n");\r
8044 fprintf(fp, " mov dword [_z80halted], 0 ; We're not halted anymore!\n");\r
8045 fprintf(fp, " test [_z80iff], byte IFF1 ; Interrupt enabled yet?\n");\r
8046 fprintf(fp, " jz near internalInterruptsDisabled\n");\r
8047\r
8048 fprintf(fp, "\n; Interrupts enabled. Clear IFF1 and IFF2\n\n");\r
8049\r
8050 fprintf(fp, " mov [_z80intPending], byte 0\n");\r
8051\r
8052 fprintf(fp, "\n; Save off our active register sets\n\n");\r
8053\r
8054 fprintf(fp, " xchg ah, al ; Swap these for later\n");\r
8055 fprintf(fp, " mov [_z80af], ax ; Store A & flags\n");\r
8056 fprintf(fp, " mov [_z80hl], bx ; Store HL\n");\r
8057 fprintf(fp, " mov [_z80bc], cx ; Store BC\n");\r
8058 fprintf(fp, " sub esi, ebp ; Knock off physical address\n");\r
8059 fprintf(fp, " mov [_z80pc], si ; And store virtual address\n");\r
8060\r
8061 fprintf(fp, " xor eax, eax\n");\r
8062 fprintf(fp, " mov al, [_intData]\n\n");\r
8063\r
8064 fprintf(fp, "\n");\r
8065 fprintf(fp, " push edi\n");\r
8066 fprintf(fp, "\n");\r
8067 \r
8068 if (bThroughCallHandler)\r
8069 {\r
8070 fprintf(fp, " pushad\n" );\r
8071 fprintf(fp, " xor edx, edx\n" );\r
8072 fprintf(fp, " mov ax, [_z80pc]\n");\r
8073 fprintf(fp, " mov [_wordval], ax\n");\r
8074 fprintf(fp, " push ecx\n");\r
8075 fprintf(fp, " push ebx\n");\r
8076 fprintf(fp, " push esi\n");\r
8077 \r
8078 fprintf(fp, " mov ax, [_z80af]\n"); // Get AF\r
8079 fprintf(fp, " mov bx, [_z80hl]\n"); // Get HL\r
8080 fprintf(fp, " mov cx, [_z80bc]\n"); // Get BC\r
8081 fprintf(fp, " call PushWord\n");\r
8082 \r
8083 fprintf(fp, " pop esi\n");\r
8084 fprintf(fp, " pop ebx\n");\r
8085 fprintf(fp, " pop ecx\n");\r
8086 fprintf(fp, " popad\n" );\r
8087 }\r
8088 else\r
8089 {\r
8090 fprintf(fp, " mov dx, [_z80pc]\n");\r
8091 fprintf(fp, " xor edi, edi\n");\r
8092 fprintf(fp, " mov di, word [_z80sp]\n");\r
8093 fprintf(fp, " sub di, 2\n");\r
8094 fprintf(fp, " mov word [_z80sp], di\n");\r
8095 fprintf(fp, " mov [ebp+edi], dx\n");\r
8096 }\r
8097 \r
8098 fprintf(fp, " cmp dword [_z80interruptMode], 2 ; Are we lower than mode 2?\n");\r
8099 fprintf(fp, " jb internalJustModeTwo\n");\r
8100 fprintf(fp, " mov ah, [_z80i] ; Get our high address here\n");\r
8101 fprintf(fp, " and eax, 0ffffh ; Only the lower part\n");\r
8102 fprintf(fp, " mov ax, [eax+ebp] ; Get our vector\n");\r
8103 fprintf(fp, " jmp short internalSetNewVector ; Go set it!\n");\r
8104 fprintf(fp, "internalJustModeTwo:\n");\r
8105 fprintf(fp, " mov ax, word [_z80intAddr]\n");\r
8106 fprintf(fp, "internalSetNewVector:\n");\r
8107 fprintf(fp, " mov [_z80pc], ax\n");\r
8108 fprintf(fp, "\n");\r
8109 fprintf(fp, " pop edi\n");\r
8110 fprintf(fp, "\n");\r
8111 fprintf(fp, " xor eax, eax ; Zero this so we can use it as an index\n");\r
8112\r
8113 fprintf(fp, " mov al, [_z80interruptMode]\n");\r
8114 fprintf(fp, " mov al, [intModeTStates+eax]\n");\r
8115 fprintf(fp, " sub edi, eax\n");\r
8116 fprintf(fp, " add [_z80rCounter], eax\n");\r
8117\r
8118 fprintf(fp, "\n; Restore all the registers and whatnot\n\n");\r
8119\r
8120 fprintf(fp, " mov ax, [_z80af] ; Accumulator & flags\n");\r
8121 fprintf(fp, " xchg ah, al ; Swap these for later\n");\r
8122 fprintf(fp, " mov bx, [_z80hl] ; Get our HL value\n");\r
8123 fprintf(fp, " mov cx, [_z80bc] ; And our BC value\n");\r
8124 fprintf(fp, " mov ebp, [_z80Base] ; Get the base address\n");\r
8125 fprintf(fp, " mov si, [_z80pc] ; Get our program counter\n");\r
8126 fprintf(fp, " add esi, ebp ; Add in our base address\n");\r
8127\r
8128 fprintf(fp, "internalInterruptsDisabled:\n");\r
8129 fprintf(fp, " xor edx, edx\n");\r
8130 fprintf(fp, " ret\n");\r
8131 }\r
8132 else\r
8133 if (MZ80_C == bWhat)\r
8134 {\r
8135 }\r
8136 else\r
8137 {\r
8138 assert(0);\r
8139 }\r
8140}\r
8141\r
8142NmiCode()\r
8143{\r
8144 if (MZ80_ASSEMBLY_X86 == bWhat)\r
8145 {\r
8146 fprintf(fp, " global _%snmi\n", cpubasename);\r
8147 fprintf(fp, " global %snmi_\n", cpubasename);\r
8148\r
8149 if (bPlain)\r
8150 fprintf(fp, " global %snmi\n", cpubasename);\r
8151 \r
8152 sprintf(procname, "%snmi_", cpubasename);\r
8153 ProcBegin(0xffffffff);\r
8154 fprintf(fp, "_%snmi:\n", cpubasename);\r
8155 \r
8156 if (bPlain)\r
8157 fprintf(fp, "%snmi:\n", cpubasename);\r
8158\r
8159 fprintf(fp, " mov dword [_z80halted], 0 ; We're not halted anymore!\n");\r
8160 fprintf(fp, " mov al, [_z80iff] ; Get our IFF setting\n");\r
8161 fprintf(fp, " and al, IFF1 ; Just IFF 1\n");\r
8162 fprintf(fp, " shl al, 1 ; Makes IFF1->IFF2 and zeros IFF1\n");\r
8163 fprintf(fp, " mov [_z80iff], al ; Store it back to the interrupt state!\n");\r
8164 fprintf(fp, "\n");\r
8165 fprintf(fp, " push ebp\n");\r
8166 fprintf(fp, " push edi\n");\r
8167 fprintf(fp, " mov ebp, [_z80Base]\n");\r
8168 fprintf(fp, "\n");\r
8169\r
8170 fprintf(fp, " xor eax, eax\n");\r
8171 fprintf(fp, " mov ax, [_z80pc]\n");\r
8172\r
8173 if (bThroughCallHandler)\r
8174 {\r
8175 fprintf(fp, " push esi\n");\r
8176 fprintf(fp, " push ebx\n");\r
8177 fprintf(fp, " push ecx\n");\r
8178\r
8179 fprintf(fp, " mov [_wordval], ax\n");\r
8180 fprintf(fp, " mov esi, ebp\n");\r
8181 fprintf(fp, " add esi, eax\n");\r
8182 fprintf(fp, " mov ax, [_z80af]\n"); // Get AF\r
8183 fprintf(fp, " mov bx, [_z80hl]\n"); // Get HL\r
8184 fprintf(fp, " mov cx, [_z80bc]\n"); // Get BC\r
8185 fprintf(fp, " push ebx\n");\r
8186 fprintf(fp, " push ecx\n");\r
8187 fprintf(fp, " push edx\n");\r
8188 fprintf(fp, " push esi\n");\r
8189 fprintf(fp, " push eax\n");\r
8190 fprintf(fp, " call PushWord\n");\r
8191 fprintf(fp, " pop eax\n");\r
8192 fprintf(fp, " pop esi\n");\r
8193 fprintf(fp, " pop edx\n");\r
8194 fprintf(fp, " pop ecx\n");\r
8195 fprintf(fp, " pop ebx\n");\r
8196\r
8197 fprintf(fp, " pop ecx\n");\r
8198 fprintf(fp, " pop ebx\n");\r
8199 fprintf(fp, " pop esi\n");\r
8200 } \r
8201 else \r
8202 { \r
8203 fprintf(fp, " xor edi, edi\n");\r
8204 fprintf(fp, " mov di, word [_z80sp]\n");\r
8205 fprintf(fp, " sub di, 2\n");\r
8206 fprintf(fp, " mov word [_z80sp], di\n");\r
8207 fprintf(fp, " mov [ebp+edi], ax\n");\r
8208 }\r
8209\r
8210 fprintf(fp, " mov ax, [_z80nmiAddr]\n");\r
8211 fprintf(fp, " mov [_z80pc], ax\n");\r
8212 fprintf(fp, "\n");\r
8213 fprintf(fp, " add [dwElapsedTicks], dword 11 ; 11 T-States for NMI\n");\r
8214 fprintf(fp, " add [_z80rCounter], dword 11\n");\r
8215 fprintf(fp, " pop edi\n");\r
8216 fprintf(fp, " pop ebp\n");\r
8217 fprintf(fp, "\n");\r
8218 fprintf(fp, " xor eax, eax ; Indicate we took the interrupt\n");\r
8219 fprintf(fp, " ret\n");\r
8220 }\r
8221 else\r
8222 if (MZ80_C == bWhat)\r
8223 {\r
8224 fprintf(fp, "/* NMI Handler */\n\n");\r
8225 fprintf(fp, "UINT32 %snmi(void)\n", cpubasename);\r
8226 fprintf(fp, "{\n");\r
8227\r
8228 fprintf(fp, " cpu.z80halted = 0;\n");\r
8229 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp - 1); /* Normalize the stack pointer */\n");\r
8230 fprintf(fp, " *pbSP-- = cpu.z80pc >> 8; /* LSB */\n");\r
8231 fprintf(fp, " *pbSP = (UINT8) cpu.z80pc; /* MSB */\n");\r
8232 fprintf(fp, " cpu.z80sp -= 2; /* Back our stack up */\n");\r
8233 fprintf(fp, " cpu.z80pc = cpu.z80nmiAddr; /* Our NMI */\n");\r
8234\r
8235 fprintf(fp, " return(0);\n");\r
8236 fprintf(fp, "}\n\n");\r
8237 }\r
8238 else\r
8239 {\r
8240 assert(0);\r
8241 }\r
8242}\r
8243\r
8244IntCode()\r
8245{\r
8246 if (MZ80_ASSEMBLY_X86 == bWhat)\r
8247 {\r
8248 fprintf(fp, " global _%sint\n", cpubasename);\r
8249 fprintf(fp, " global %sint_\n", cpubasename);\r
8250\r
8251 if (bPlain)\r
8252 fprintf(fp, " global %sint\n", cpubasename);\r
8253\r
8254 sprintf(procname, "%sint_", cpubasename);\r
8255 ProcBegin(0xffffffff);\r
8256 fprintf(fp, "_%sint:\n", cpubasename);\r
8257\r
8258 if (bPlain)\r
8259 fprintf(fp, "%sint:\n", cpubasename);\r
8260\r
8261 if (bUseStack)\r
8262 fprintf(fp, " mov eax, [esp+4] ; Get our (potential) lower interrupt address\n");\r
8263 \r
8264 fprintf(fp, " mov dword [_z80halted], 0 ; We're not halted anymore!\n");\r
8265\r
8266 fprintf(fp, " mov ah, IFF1 ; Is IFF1 enabled?\n");\r
8267 fprintf(fp, " and ah, [_z80iff] ; Well, is it?\n");\r
8268 fprintf(fp, " jz near interruptsDisabled\n");\r
8269\r
8270 fprintf(fp, "\n; Interrupts enabled. Clear IFF1 and IFF2\n\n");\r
8271\r
8272 fprintf(fp, " and dword [_z80iff], ~(IFF1 | IFF2);\n\n");\r
8273 fprintf(fp, " mov [_z80intPending], byte 0\n");\r
8274\r
8275 fprintf(fp, "\n");\r
8276 fprintf(fp, " push ebp\n");\r
8277 fprintf(fp, " push edi\n");\r
8278 fprintf(fp, " push edx\n");\r
8279 fprintf(fp, " mov ebp, [_z80Base]\n");\r
8280 fprintf(fp, "\n");\r
8281 \r
8282 \r
8283 if (bThroughCallHandler)\r
8284 {\r
8285 fprintf(fp, " pushad\n" );\r
8286 fprintf(fp, " xor edx, edx\n" );\r
8287 fprintf(fp, " mov ax, [_z80pc]\n");\r
8288 fprintf(fp, " mov [_wordval], ax\n");\r
8289 fprintf(fp, " push ecx\n");\r
8290 fprintf(fp, " push ebx\n");\r
8291 fprintf(fp, " push esi\n");\r
8292 \r
8293 fprintf(fp, " mov ax, [_z80af]\n"); // Get AF\r
8294 fprintf(fp, " mov bx, [_z80hl]\n"); // Get HL\r
8295 fprintf(fp, " mov cx, [_z80bc]\n"); // Get BC\r
8296 fprintf(fp, " call PushWord\n");\r
8297 \r
8298 fprintf(fp, " pop esi\n");\r
8299 fprintf(fp, " pop ebx\n");\r
8300 fprintf(fp, " pop ecx\n");\r
8301 fprintf(fp, " popad\n" );\r
8302 }\r
8303 else\r
8304 {\r
8305 fprintf(fp, " mov dx, [_z80pc]\n");\r
8306 fprintf(fp, " xor edi, edi\n");\r
8307 fprintf(fp, " mov di, word [_z80sp]\n");\r
8308 fprintf(fp, " sub di, 2\n");\r
8309 fprintf(fp, " mov word [_z80sp], di\n");\r
8310 fprintf(fp, " mov [ebp+edi], dx\n");\r
8311 }\r
8312 \r
8313 fprintf(fp, " cmp dword [_z80interruptMode], 2 ; Are we lower than mode 2?\n");\r
8314 fprintf(fp, " jb justModeTwo\n");\r
8315 fprintf(fp, " mov ah, [_z80i] ; Get our high address here\n");\r
8316 fprintf(fp, " and eax, 0ffffh ; Only the lower part\n");\r
8317 fprintf(fp, " mov ax, [eax+ebp] ; Get our vector\n");\r
8318 fprintf(fp, " jmp short setNewVector ; Go set it!\n");\r
8319 fprintf(fp, "justModeTwo:\n");\r
8320 fprintf(fp, " mov ax, word [_z80intAddr]\n");\r
8321 fprintf(fp, "setNewVector:\n");\r
8322 fprintf(fp, " mov [_z80pc], ax\n");\r
8323 fprintf(fp, "\n");\r
8324 fprintf(fp, " pop edx\n");\r
8325 fprintf(fp, " pop edi\n");\r
8326 fprintf(fp, " pop ebp\n");\r
8327 fprintf(fp, "\n");\r
8328 fprintf(fp, " xor eax, eax ; Zero this so we can use it as an index\n");\r
8329\r
8330 fprintf(fp, " mov al, [_z80interruptMode]\n");\r
8331 fprintf(fp, " mov al, [intModeTStates+eax]\n");\r
8332 fprintf(fp, " add [dwElapsedTicks], eax\n");\r
8333 fprintf(fp, " add [_z80rCounter], eax\n");\r
8334 fprintf(fp, " xor eax, eax ; Indicate we took the interrupt\n");\r
8335\r
8336 fprintf(fp, " jmp short z80intExit\n");\r
8337 fprintf(fp, "\n");\r
8338 fprintf(fp, "interruptsDisabled:\n");\r
8339 fprintf(fp, " mov [_z80intPending], byte 1\n");\r
8340 fprintf(fp, " mov [_intData], al ; Save this info for later\n");\r
8341 fprintf(fp, " mov eax, 0ffffffffh ; Indicate we didn't take it\n");\r
8342 fprintf(fp, "\n");\r
8343 fprintf(fp, "z80intExit:\n");\r
8344 fprintf(fp, " ret\n\n");\r
8345\r
8346\r
8347 fprintf(fp, " global _%sClearPendingInterrupt\n", cpubasename);\r
8348 fprintf(fp, " global %sClearPendingInterrupt_\n", cpubasename);\r
8349\r
8350 if (bPlain)\r
8351 fprintf(fp, " global %sClearPendingInterrupt\n", cpubasename);\r
8352\r
8353 sprintf(procname, "%sClearPendingInterrupt_", cpubasename);\r
8354 ProcBegin(0xffffffff);\r
8355 fprintf(fp, "_%sClearPendingInterrupt:\n", cpubasename);\r
8356\r
8357 if (bPlain)\r
8358 fprintf(fp, "%sClearPendingInterrupt:\n", cpubasename);\r
8359\r
8360 fprintf(fp, " mov [_z80intPending], byte 0\n");\r
8361 fprintf(fp, " ret\n\n");\r
8362 }\r
8363 else\r
8364 if (MZ80_C == bWhat)\r
8365 {\r
8366 fprintf(fp, "/* Interrupt handler */\n\n");\r
8367 fprintf(fp, "UINT32 %sint(UINT32 dwLowAddr)\n", cpubasename);\r
8368 fprintf(fp, "{\n");\r
8369 fprintf(fp, " cpu.z80halted = 0;\n");\r
8370\r
8371 fprintf(fp, " if (0 == (cpu.z80iff & IFF1))\n");\r
8372 fprintf(fp, " return(0xffffffff);\n");\r
8373\r
8374 fprintf(fp, " cpu.z80iff &= ~(IFF1 | IFF2);\n");\r
8375 fprintf(fp, " pbSP = (cpu.z80Base + cpu.z80sp - 1); /* Normalize the stack pointer */\n");\r
8376 fprintf(fp, " *pbSP-- = cpu.z80pc >> 8; /* LSB */\n");\r
8377 fprintf(fp, " *pbSP = (UINT8) cpu.z80pc; /* MSB */\n");\r
8378 fprintf(fp, " cpu.z80sp -= 2; /* Back our stack up */\n");\r
8379\r
8380 fprintf(fp, " if (2 == cpu.z80interruptMode)\n");\r
8381 fprintf(fp, " {\n");\r
8382 fprintf(fp, " cpu.z80pc = ((UINT16) cpu.z80i << 8) | (dwLowAddr & 0xff);\n");\r
8383 fprintf(fp, " cpu.z80pc = ((UINT16) cpu.z80Base[cpu.z80pc + 1] << 8) | (cpu.z80Base[cpu.z80pc]);\n");\r
8384 fprintf(fp, " }\n");\r
8385 fprintf(fp, " else\n");\r
8386 fprintf(fp, " {\n");\r
8387 fprintf(fp, " cpu.z80pc = cpu.z80intAddr;\n");\r
8388 fprintf(fp, " }\n");\r
8389\r
8390 fprintf(fp, " pbPC = cpu.z80Base + cpu.z80pc; /* Normalize the address */\n");\r
8391\r
8392 fprintf(fp, " return(0);\n");\r
8393 fprintf(fp, "}\n\n");\r
8394 }\r
8395 else\r
8396 {\r
8397 assert(0);\r
8398 }\r
8399}\r
8400\r
8401ResetCode()\r
8402{\r
8403 if (MZ80_ASSEMBLY_X86 == bWhat)\r
8404 {\r
8405 fprintf(fp, " global _%sreset\n", cpubasename);\r
8406 fprintf(fp, " global %sreset_\n", cpubasename);\r
8407\r
8408 if (bPlain)\r
8409 fprintf(fp, " global %sreset\n", cpubasename);\r
8410 sprintf(procname, "%sreset_", cpubasename);\r
8411 ProcBegin(0xffffffff);\r
8412\r
8413 fprintf(fp, "_%sreset:\n", cpubasename);\r
8414\r
8415 if (bPlain)\r
8416 fprintf(fp, "%sreset:\n", cpubasename);\r
8417\r
8418 fprintf(fp, " xor eax, eax ; Zero AX\n");\r
8419 fprintf(fp, "\n");\r
8420 fprintf(fp, " mov dword [_z80halted], eax ; We're not halted anymore!\n");\r
8421 fprintf(fp, " mov word [_z80af], 0040h ; Zero A & flags - zero flag set\n");\r
8422 fprintf(fp, " mov word [_z80bc], ax ; Zero BC\n");\r
8423 fprintf(fp, " mov word [_z80de], ax ; Zero DE\n");\r
8424 fprintf(fp, " mov word [_z80hl], ax ; Zero HL\n");\r
8425 fprintf(fp, " mov word [_z80afprime], ax ; Zero AF Prime\n");\r
8426 fprintf(fp, " mov word [_z80bcprime], ax ; Zero BC prime\n");\r
8427 fprintf(fp, " mov word [_z80deprime], ax ; Zero DE prime\n");\r
8428 fprintf(fp, " mov word [_z80hlprime], ax ; Zero HL prime\n");\r
8429 fprintf(fp, " mov byte [_z80i], al ; Zero Interrupt register\n");\r
8430 fprintf(fp, " mov byte [_z80r], al ; Zero refresh register\n");\r
8431 fprintf(fp, " mov word [_z80ix], 0ffffh ; Default mz80Index register\n");\r
8432 fprintf(fp, " mov word [_z80iy], 0ffffh ; Default mz80Index register\n");\r
8433 fprintf(fp, " mov word [_z80pc], ax ; Zero program counter\n");\r
8434 fprintf(fp, " mov word [_z80sp], ax ; And the stack pointer\n");\r
8435 fprintf(fp, " mov dword [_z80iff], eax ; IFF1/IFF2 disabled!\n");\r
8436 fprintf(fp, " mov dword [_z80interruptMode], eax ; Clear our interrupt mode (0)\n");\r
8437 fprintf(fp, " mov word [_z80intAddr], 38h ; Set default interrupt address\n");\r
8438 fprintf(fp, " mov word [_z80nmiAddr], 66h ; Set default nmi addr\n");\r
8439 fprintf(fp, "\n");\r
8440 fprintf(fp, " ret\n");\r
8441 fprintf(fp, "\n");\r
8442 }\r
8443 else\r
8444 if (MZ80_C == bWhat)\r
8445 {\r
8446 fprintf(fp, "/* This routine is mz80's reset handler */\n\n");\r
8447 fprintf(fp, "void %sreset(void)\n", cpubasename);\r
8448 fprintf(fp, "{\n");\r
8449 fprintf(fp, " cpu.z80halted = 0;\n");\r
8450 fprintf(fp, " cpu.z80AF = 0;\n");\r
8451 fprintf(fp, " cpu.z80F = Z80_FLAG_ZERO;\n");\r
8452 fprintf(fp, " cpu.z80BC = 0;\n");\r
8453 fprintf(fp, " cpu.z80DE = 0;\n");\r
8454 fprintf(fp, " cpu.z80HL = 0;\n");\r
8455 fprintf(fp, " cpu.z80afprime = 0;\n");\r
8456 fprintf(fp, " cpu.z80bcprime = 0;\n");\r
8457 fprintf(fp, " cpu.z80deprime = 0;\n");\r
8458 fprintf(fp, " cpu.z80hlprime = 0;\n");\r
8459 fprintf(fp, " cpu.z80i = 0;\n");\r
8460 fprintf(fp, " cpu.z80r = 0;\n");\r
8461 fprintf(fp, " cpu.z80IX = 0xffff; /* Yes, this is intentional */\n");\r
8462 fprintf(fp, " cpu.z80IY = 0xffff; /* Yes, this is intentional */\n");\r
8463 fprintf(fp, " cpu.z80pc = 0;\n");\r
8464 fprintf(fp, " cpu.z80sp = 0;\n");\r
8465 fprintf(fp, " cpu.z80interruptMode = 0;\n");\r
8466 fprintf(fp, " cpu.z80intAddr = 0x38;\n");\r
8467 fprintf(fp, " cpu.z80nmiAddr = 0x66;\n");\r
8468 fprintf(fp, "}\n\n");\r
8469 }\r
8470 else\r
8471 {\r
8472 assert(0);\r
8473 }\r
8474}\r
8475\r
8476SetContextCode()\r
8477{\r
8478 if (MZ80_ASSEMBLY_X86 == bWhat)\r
8479 {\r
8480 fprintf(fp, " global _%sSetContext\n", cpubasename);\r
8481 fprintf(fp, " global %sSetContext_\n", cpubasename);\r
8482 \r
8483 if (bPlain)\r
8484 fprintf(fp, " global %sSetContext\n", cpubasename);\r
8485 \r
8486 sprintf(procname, "%sSetContext_", cpubasename);\r
8487 ProcBegin(0xffffffff);\r
8488 fprintf(fp, "_%sSetContext:\n", cpubasename);\r
8489 \r
8490 if (bPlain)\r
8491 fprintf(fp, "%sSetContext:\n", cpubasename);\r
8492 \r
8493 if (bUseStack)\r
8494 fprintf(fp, " mov eax, [esp+4] ; Get our context address\n");\r
8495 \r
8496 fprintf(fp, " push esi ; Save registers we use\n");\r
8497 fprintf(fp, " push edi\n");\r
8498 fprintf(fp, " push ecx\n");\r
8499 fprintf(fp, " push es\n");\r
8500 fprintf(fp, " mov di, ds\n");\r
8501 fprintf(fp, " mov es, di\n");\r
8502 fprintf(fp, " mov edi, _%scontextBegin\n", cpubasename);\r
8503 fprintf(fp, " mov esi, eax ; Source address in ESI\n");\r
8504 fprintf(fp, " mov ecx, (_%scontextEnd - _%scontextBegin) >> 2\n", cpubasename, cpubasename);\r
8505 fprintf(fp, " rep movsd\n");\r
8506 fprintf(fp, " mov ecx, (_%scontextEnd - _%scontextBegin) & 0x03\n", cpubasename, cpubasename);\r
8507 fprintf(fp, " rep movsb\n");\r
8508 fprintf(fp, " pop es\n");\r
8509 fprintf(fp, " pop ecx\n");\r
8510 fprintf(fp, " pop edi\n");\r
8511 fprintf(fp, " pop esi\n");\r
8512 fprintf(fp, " ret ; No return code\n");\r
8513 }\r
8514 else\r
8515 if (MZ80_C == bWhat)\r
8516 {\r
8517 fprintf(fp, "/* Set mz80's context */\n\n");\r
8518 fprintf(fp, "void %sSetContext(void *pData)\n", cpubasename);\r
8519 fprintf(fp, "{\n");\r
8520 fprintf(fp, " memcpy(&cpu, pData, sizeof(CONTEXTMZ80));\n");\r
8521 fprintf(fp, "}\n\n");\r
8522 }\r
8523 else\r
8524 {\r
8525 assert(0);\r
8526 }\r
8527}\r
8528\r
8529GetContextCode()\r
8530{\r
8531 if (MZ80_ASSEMBLY_X86 == bWhat)\r
8532 {\r
8533 fprintf(fp, " global _%sGetContext\n", cpubasename);\r
8534 fprintf(fp, " global %sGetContext_\n", cpubasename);\r
8535\r
8536 if (bPlain)\r
8537 fprintf(fp, " global %sGetContext\n", cpubasename);\r
8538 \r
8539 sprintf(procname, "%sGetContext_", cpubasename);\r
8540 ProcBegin(0xffffffff);\r
8541 fprintf(fp, "_%sGetContext:\n", cpubasename);\r
8542\r
8543 if (bPlain)\r
8544 fprintf(fp, "%sGetContext:\n", cpubasename);\r
8545\r
8546 if (bUseStack)\r
8547 fprintf(fp, " mov eax, [esp+4] ; Get our context address\n");\r
8548\r
8549 fprintf(fp, " push esi ; Save registers we use\n");\r
8550 fprintf(fp, " push edi\n");\r
8551 fprintf(fp, " push ecx\n");\r
8552 fprintf(fp, " push es\n");\r
8553 fprintf(fp, " mov di, ds\n");\r
8554 fprintf(fp, " mov es, di\n");\r
8555\r
8556 fprintf(fp, " mov esi, _%scontextBegin\n", cpubasename);\r
8557 fprintf(fp, " mov edi, eax ; Source address in ESI\n");\r
8558\r
8559 fprintf(fp, " mov ecx, (_%scontextEnd - _%scontextBegin) >> 2\n", cpubasename, cpubasename);\r
8560 fprintf(fp, " rep movsd\n");\r
8561 fprintf(fp, " mov ecx, (_%scontextEnd - _%scontextBegin) & 0x03\n", cpubasename, cpubasename);\r
8562 fprintf(fp, " rep movsb\n");\r
8563\r
8564 fprintf(fp, " pop es\n");\r
8565 fprintf(fp, " pop ecx\n");\r
8566 fprintf(fp, " pop edi\n");\r
8567 fprintf(fp, " pop esi\n");\r
8568 fprintf(fp, " ret ; No return code\n");\r
8569 }\r
8570 else\r
8571 if (MZ80_C == bWhat)\r
8572 {\r
8573 fprintf(fp, "/* Get mz80's context */\n\n");\r
8574 fprintf(fp, "void %sGetContext(void *pData)\n", cpubasename);\r
8575 fprintf(fp, "{\n");\r
8576 fprintf(fp, " memcpy(pData, &cpu, sizeof(CONTEXTMZ80));\n");\r
8577 fprintf(fp, "}\n\n");\r
8578 }\r
8579 else\r
8580 {\r
8581 assert(0);\r
8582 }\r
8583}\r
8584\r
8585GetContextSizeCode()\r
8586{\r
8587 if (MZ80_ASSEMBLY_X86 == bWhat)\r
8588 {\r
8589 fprintf(fp, " global _%sGetContextSize\n", cpubasename);\r
8590 fprintf(fp, " global %sGetContextSize_\n", cpubasename);\r
8591\r
8592 if (bPlain)\r
8593 fprintf(fp, " global %sGetContextSize\n", cpubasename);\r
8594\r
8595 sprintf(procname, "%sGetContextSize_", cpubasename);\r
8596 ProcBegin(0xffffffff);\r
8597\r
8598 fprintf(fp, "_%sGetContextSize:\n", cpubasename);\r
8599 \r
8600 if (bPlain)\r
8601 fprintf(fp, "%sGetContextSize:\n", cpubasename);\r
8602\r
8603 fprintf(fp, " mov eax, _%scontextEnd - _%scontextBegin\n", cpubasename, cpubasename);\r
8604 fprintf(fp, " ret\n\n");\r
8605 }\r
8606 else\r
8607 if (MZ80_C == bWhat)\r
8608 {\r
8609 fprintf(fp, "/* Get mz80's context size */\n\n");\r
8610 fprintf(fp, "UINT32 %sGetContextSize(void)\n", cpubasename);\r
8611 fprintf(fp, "{\n");\r
8612 fprintf(fp, " return(sizeof(CONTEXTMZ80));\n");\r
8613 fprintf(fp, "}\n\n");\r
8614 }\r
8615 else\r
8616 {\r
8617 assert(0);\r
8618 }\r
8619}\r
8620\r
8621void InitCode(void)\r
8622{\r
8623 if (MZ80_ASSEMBLY_X86 == bWhat)\r
8624 {\r
8625 fprintf(fp, " global _%sinit\n", cpubasename);\r
8626 fprintf(fp, " global %sinit_\n", cpubasename);\r
8627\r
8628 if (bPlain)\r
8629 fprintf(fp, " global %sinit\n", cpubasename);\r
8630\r
8631 sprintf(procname, "%sinit_", cpubasename);\r
8632 ProcBegin(0xffffffff);\r
8633\r
8634 fprintf(fp, "_%sinit:\n", cpubasename);\r
8635 \r
8636 if (bPlain)\r
8637 fprintf(fp, "%sinit:\n", cpubasename);\r
8638\r
8639 fprintf(fp, " ret\n\n");\r
8640 }\r
8641 else\r
8642 if (MZ80_C == bWhat)\r
8643 {\r
8644 fprintf(fp, "/* Initialize MZ80 for action */\n\n");\r
8645 fprintf(fp, "void %sinit(void)\n", cpubasename);\r
8646 fprintf(fp, "{\n");\r
8647\r
8648 fprintf(fp, " UINT32 dwLoop;\n");\r
8649 fprintf(fp, " UINT8 *pbTempPtr;\n");\r
8650 fprintf(fp, " UINT8 *pbTempPtr2;\n");\r
8651 fprintf(fp, " UINT8 bNewAdd;\n");\r
8652 fprintf(fp, " UINT8 bNewSub;\n");\r
8653 fprintf(fp, " UINT8 bFlag;\n");\r
8654 fprintf(fp, " UINT8 bLow;\n");\r
8655 fprintf(fp, " UINT8 bHigh;\n");\r
8656 fprintf(fp, " UINT8 bCarry;\n");\r
8657 fprintf(fp, "\n");\r
8658 fprintf(fp, " if (NULL == pbAddAdcTable)\n");\r
8659 fprintf(fp, " {\n");\r
8660 fprintf(fp, " pbAddAdcTable = malloc(256*256*2);\n");\r
8661 fprintf(fp, "\n");\r
8662 fprintf(fp, " if (NULL == pbAddAdcTable)\n");\r
8663 fprintf(fp, " {\n");\r
8664 fprintf(fp, " return;\n");\r
8665 fprintf(fp, " }\n");\r
8666 fprintf(fp, "\n");\r
8667 fprintf(fp, " pbTempPtr = pbAddAdcTable;\n\n");\r
8668 fprintf(fp, " pbSubSbcTable = malloc(256*256*2);\n");\r
8669 fprintf(fp, "\n");\r
8670 fprintf(fp, " if (NULL == pbSubSbcTable)\n");\r
8671 fprintf(fp, " {\n");\r
8672 fprintf(fp, " return;\n");\r
8673 fprintf(fp, " }\n");\r
8674 fprintf(fp, "\n");\r
8675 fprintf(fp, " pbTempPtr2 = pbSubSbcTable;\n");\r
8676 fprintf(fp, "\n");\r
8677 fprintf(fp, " for (dwLoop = 0; dwLoop < (256*256*2); dwLoop++)\n");\r
8678 fprintf(fp, " {\n");\r
8679 fprintf(fp, " bLow = dwLoop & 0xff;\n");\r
8680 fprintf(fp, " bHigh = (dwLoop >> 8) & 0xff;\n");\r
8681 fprintf(fp, " bCarry = (dwLoop >> 16);\n");\r
8682 fprintf(fp, "\n");\r
8683 fprintf(fp, " bFlag = 0;\n");\r
8684 fprintf(fp, " bNewAdd = bHigh + bLow + bCarry;\n");\r
8685 fprintf(fp, "\n");\r
8686 fprintf(fp, " if (0 == bNewAdd)\n");\r
8687 fprintf(fp, " {\n");\r
8688 fprintf(fp, " bFlag |= Z80_FLAG_ZERO;\n");\r
8689 fprintf(fp, " }\n");\r
8690 fprintf(fp, " else\n");\r
8691 fprintf(fp, " {\n");\r
8692 fprintf(fp, " bFlag = bNewAdd & 0x80; /* Sign flag */\n");\r
8693 fprintf(fp, " }\n");\r
8694 fprintf(fp, "\n");\r
8695 fprintf(fp, " if (((UINT32) bLow + (UINT32) bHigh + (UINT32) bCarry) >= 0x100)\n");\r
8696 fprintf(fp, " {\n");\r
8697 fprintf(fp, " bFlag |= Z80_FLAG_CARRY;\n");\r
8698 fprintf(fp, " }\n");\r
8699 fprintf(fp, "\n");\r
8700 fprintf(fp, " if ( ((bLow ^ bHigh ^ 0x80) & (bLow ^ (bNewAdd & 0x80))) & 0x80)\n");\r
8701 fprintf(fp, " {\n");\r
8702 fprintf(fp, " bFlag |= Z80_FLAG_OVERFLOW_PARITY;\n");\r
8703 fprintf(fp, " }\n");\r
8704 fprintf(fp, "\n");\r
8705 fprintf(fp, " if (((bLow & 0x0f) + (bHigh & 0x0f) + bCarry) >= 0x10)\n");\r
8706 fprintf(fp, " {\n");\r
8707 fprintf(fp, " bFlag |= Z80_FLAG_HALF_CARRY;\n");\r
8708 fprintf(fp, " }\n");\r
8709 fprintf(fp, "\n");\r
8710 fprintf(fp, " *pbTempPtr++ = bFlag; /* Store our new flag */\n\n");\r
8711\r
8712 fprintf(fp, " // Now do subtract - Zero\n");\r
8713 fprintf(fp, "\n");\r
8714 fprintf(fp, " bFlag = Z80_FLAG_NEGATIVE;\n");\r
8715 fprintf(fp, " bNewSub = bHigh - bLow - bCarry;\n");\r
8716 fprintf(fp, "\n");\r
8717 fprintf(fp, " if (0 == bNewSub)\n");\r
8718 fprintf(fp, " {\n");\r
8719 fprintf(fp, " bFlag |= Z80_FLAG_ZERO;\n");\r
8720 fprintf(fp, " }\n");\r
8721 fprintf(fp, " else\n");\r
8722 fprintf(fp, " {\n");\r
8723 fprintf(fp, " bFlag |= bNewSub & 0x80; /* Sign flag */\n");\r
8724 fprintf(fp, " }\n");\r
8725 fprintf(fp, "\n");\r
8726 fprintf(fp, " if ( ((INT32) bHigh - (INT32) bLow - (INT32) bCarry) < 0)\n");\r
8727 fprintf(fp, " {\n");\r
8728 fprintf(fp, " bFlag |= Z80_FLAG_CARRY;\n");\r
8729 fprintf(fp, " }\n");\r
8730 fprintf(fp, "\n");\r
8731 fprintf(fp, " if ( ((INT32) (bHigh & 0xf) - (INT32) (bLow & 0x0f) - (INT32) bCarry) < 0)\n");\r
8732 fprintf(fp, " {\n");\r
8733 fprintf(fp, " bFlag |= Z80_FLAG_HALF_CARRY;\n");\r
8734 fprintf(fp, " }\n");\r
8735 fprintf(fp, "\n");\r
8736 fprintf(fp, " if ( ((bLow ^ bHigh) & (bHigh ^ bNewSub) & 0x80) )\n");\r
8737 fprintf(fp, " {\n");\r
8738 fprintf(fp, " bFlag |= Z80_FLAG_OVERFLOW_PARITY;\n");\r
8739 fprintf(fp, " }\n");\r
8740 fprintf(fp, "\n");\r
8741 fprintf(fp, " *pbTempPtr2++ = bFlag; /* Store our sub flag */\n");\r
8742 fprintf(fp, "\n");\r
8743 fprintf(fp, " }\n");\r
8744 fprintf(fp, " }\n");\r
8745 fprintf(fp, "}\n");\r
8746 }\r
8747 else\r
8748 {\r
8749 assert(0);\r
8750 }\r
8751}\r
8752\r
8753void ShutdownCode(void)\r
8754{\r
8755 if (MZ80_ASSEMBLY_X86 == bWhat)\r
8756 {\r
8757 fprintf(fp, " global _%sshutdown\n", cpubasename);\r
8758 fprintf(fp, " global %sshutdown_\n", cpubasename);\r
8759\r
8760 if (bPlain)\r
8761 fprintf(fp, " global %sshutdown\n", cpubasename);\r
8762\r
8763 sprintf(procname, "%sshutdown_", cpubasename);\r
8764 ProcBegin(0xffffffff);\r
8765\r
8766 fprintf(fp, "_%sshutdown:\n", cpubasename);\r
8767 \r
8768 if (bPlain)\r
8769 fprintf(fp, "%sshutdown:\n", cpubasename);\r
8770\r
8771 fprintf(fp, " ret\n\n");\r
8772 }\r
8773 else\r
8774 if (MZ80_C == bWhat)\r
8775 {\r
8776 fprintf(fp, "/* Shut down MZ80 */\n\n");\r
8777 fprintf(fp, "void %sshutdown(void)\n", cpubasename);\r
8778 fprintf(fp, "{\n");\r
8779\r
8780 fprintf(fp, "}\n\n");\r
8781 }\r
8782 else\r
8783 {\r
8784 assert(0);\r
8785 }\r
8786}\r
8787\r
8788void DebuggerCode(void)\r
8789{\r
8790 if (MZ80_ASSEMBLY_X86 == bWhat)\r
8791 {\r
8792 Alignment();\r
8793\r
8794 fprintf(fp, ";\n");\r
8795 fprintf(fp, "; In : EAX=Reg #, ESI=Context address\n");\r
8796 fprintf(fp, "; Out: EAX=Value of register\n");\r
8797 fprintf(fp, ";\n");\r
8798\r
8799 fprintf(fp, "getRegValueInternal:\n");\r
8800\r
8801 fprintf(fp, " push ecx\n");\r
8802 fprintf(fp, " push edx\n\n");\r
8803\r
8804 fprintf(fp, " cmp eax, CPUREG_MAXINDEX\n");\r
8805 fprintf(fp, " jae badIndex2\n\n");\r
8806\r
8807 fprintf(fp, " shl eax, 4 ; Times 16 for table entry size\n");\r
8808 fprintf(fp, " add eax, RegTable ; Now it's the memory location\n");\r
8809\r
8810 fprintf(fp, " mov edx, [eax+4] ; Get the offset of the register\n");\r
8811 fprintf(fp, " mov edx, [edx + esi] ; Get our value\n");\r
8812\r
8813 fprintf(fp, " mov ecx, [eax+8] ; Get our shift value\n");\r
8814 fprintf(fp, " shr edx, cl ; Shift it right by a value\n");\r
8815\r
8816 fprintf(fp, " and edx, [eax+12] ; Mask off any unneeded bits\n");\r
8817 fprintf(fp, " mov eax, edx ; Put our value in EAX\n");\r
8818 fprintf(fp, " jmp short indexExit ; Index's exit!\n");\r
8819\r
8820 fprintf(fp, "badIndex2:\n");\r
8821 fprintf(fp, " mov eax, 0ffffffffh\n\n");\r
8822 fprintf(fp, "indexExit:\n");\r
8823 fprintf(fp, " pop edx\n");\r
8824 fprintf(fp, " pop ecx\n");\r
8825 fprintf(fp, " ret\n\n");\r
8826\r
8827 Alignment();\r
8828\r
8829 fprintf(fp, ";\n");\r
8830 fprintf(fp, "; In : EAX=Value, EDX=Reg #, ESI=Context address\n");\r
8831 fprintf(fp, "; Out: EAX=Value of register\n");\r
8832 fprintf(fp, ";\n");\r
8833\r
8834 fprintf(fp, "convertValueToText:\n");\r
8835\r
8836 fprintf(fp, " push ecx\n");\r
8837 fprintf(fp, " push edx\n\n");\r
8838\r
8839 fprintf(fp, " cmp edx, CPUREG_MAXINDEX\n");\r
8840 fprintf(fp, " jae badIndex3\n\n");\r
8841\r
8842 fprintf(fp, " shl edx, 4 ; Times 16 for table entry size\n");\r
8843 fprintf(fp, " add edx, RegTable ; Now it's the memory location\n");\r
8844 fprintf(fp, " mov edx, [edx + 12] ; Shift mask\n");\r
8845 fprintf(fp, " xor ecx, ecx ; Zero our shift\n");\r
8846\r
8847 fprintf(fp, "shiftLoop:\n");\r
8848 fprintf(fp, " test edx, 0f0000000h ; High nibble nonzero yet?\n");\r
8849 fprintf(fp, " jnz convertLoop ; Yup!\n");\r
8850 fprintf(fp, " shl edx, 4 ; Move over, bacon\n");\r
8851 fprintf(fp, " shl eax, 4 ; Move the value over, too\n");\r
8852 fprintf(fp, " jmp short shiftLoop ; Keep shiftin'\n\n");\r
8853\r
8854 fprintf(fp, "convertLoop:\n");\r
8855 fprintf(fp, " mov ecx, eax ; Get our value\n");\r
8856 fprintf(fp, " shr ecx, 28 ; Only the top nibble\n");\r
8857 fprintf(fp, " add cl, '0' ; Convert to ASCII\n");\r
8858 fprintf(fp, " cmp cl, '9' ; Greater than 9?\n");\r
8859 fprintf(fp, " jbe noAdd ; Nope! Don't add it\n");\r
8860 fprintf(fp, " add cl, 32+7 ; Convert from lowercase a-f\n");\r
8861 fprintf(fp, "noAdd:\n");\r
8862 fprintf(fp, " mov [edi], cl ; New value storage\n");\r
8863 fprintf(fp, " inc edi ; Next byte, please\n");\r
8864 fprintf(fp, " shl eax, 4 ; Move the mask over\n");\r
8865 fprintf(fp, " shl edx, 4 ; Move the mask over\n");\r
8866 fprintf(fp, " jnz convertLoop ; Keep convertin'\n\n");\r
8867\r
8868\r
8869 fprintf(fp, "badIndex3:\n");\r
8870 fprintf(fp, " mov [edi], byte 0 ; Null terminate the sucker!\n");\r
8871 fprintf(fp, " pop edx\n");\r
8872 fprintf(fp, " pop ecx\n");\r
8873 fprintf(fp, " ret\n\n");\r
8874\r
8875 fprintf(fp, " global _%sSetRegisterValue\n", cpubasename);\r
8876 fprintf(fp, " global %sSetRegisterValue_\n", cpubasename);\r
8877\r
8878 if (bPlain)\r
8879 fprintf(fp, " global %sSetRegisterValue\n", cpubasename);\r
8880\r
8881 sprintf(procname, "%sSetRegisterValue_", cpubasename);\r
8882 ProcBegin(0xffffffff);\r
8883\r
8884 fprintf(fp, "_%sSetRegisterValue:\n", cpubasename);\r
8885 if (bPlain)\r
8886 fprintf(fp, "%sSetRegisterValue:\n", cpubasename);\r
8887\r
8888 fprintf(fp, " push esi\n");\r
8889 fprintf(fp, " push edi\n");\r
8890 fprintf(fp, " push edx\n");\r
8891 fprintf(fp, " push ecx\n");\r
8892\r
8893 if (bUseStack)\r
8894 {\r
8895 fprintf(fp, " mov eax, [esp+20] ; Get our register #\n");\r
8896 fprintf(fp, " mov esi, [esp+24] ; Get our context address\n");\r
8897 fprintf(fp, " mov edi, [esp+28] ; Value to assign\n");\r
8898 }\r
8899 else\r
8900 {\r
8901 fprintf(fp, " mov esi, eax ; Get context\n");\r
8902 fprintf(fp, " mov eax, edx ; Get register # in EAX\n");\r
8903 fprintf(fp, " mov edi, ebx ; Get value to assign\n");\r
8904 }\r
8905\r
8906 fprintf(fp, " or esi, esi ; Are we NULL?\n");\r
8907 fprintf(fp, " jnz userDefined\n");\r
8908\r
8909 fprintf(fp, " mov esi, _%scontextBegin\n", cpubasename);\r
8910 fprintf(fp, "userDefined:\n\n");\r
8911 fprintf(fp, " shl eax, 4 ; Times 16 for reg entry size\n");\r
8912 fprintf(fp, " add eax, RegTable\n");\r
8913 fprintf(fp, " mov edx, [eax+12] ; Our mask\n");\r
8914 fprintf(fp, " not edx ; Invert EDX!\n");\r
8915 fprintf(fp, " test edi, edx ; Did we set any invalid bits?\n");\r
8916 fprintf(fp, " jnz rangeViolation\n\n");\r
8917\r
8918 fprintf(fp, " not edx ; Toggle it back to normal\n");\r
8919 fprintf(fp, " mov ecx, [eax+8] ; Get our shift value\n");\r
8920 fprintf(fp, " shl edx, cl ; Shift our mask\n");\r
8921 fprintf(fp, " shl eax, cl ; And our value to OR in\n");\r
8922 \r
8923 fprintf(fp, " not edx ; Make it the inverse of what we want\n");\r
8924 fprintf(fp, " mov eax, [eax+4] ; Get our offset into the context\n");\r
8925 fprintf(fp, " and [esi+eax], edx ; Mask off the bits we're changin\n");\r
8926 fprintf(fp, " or [esi+eax], edi ; Or in our new value\n\n");\r
8927 fprintf(fp, " xor eax, eax\n");\r
8928 fprintf(fp, " jmp short setExit\n\n");\r
8929\r
8930 fprintf(fp, "rangeViolation:\n");\r
8931 fprintf(fp, " mov eax, 0ffffffffh\n\n");\r
8932\r
8933 fprintf(fp, "setExit:\n");\r
8934 fprintf(fp, " pop ecx\n");\r
8935 fprintf(fp, " pop edx\n");\r
8936 fprintf(fp, " pop edi\n");\r
8937 fprintf(fp, " pop esi\n\n");\r
8938\r
8939 fprintf(fp, " ret\n\n");\r
8940\r
8941 Alignment();\r
8942\r
8943 fprintf(fp, " global _%sGetRegisterValue\n", cpubasename);\r
8944 fprintf(fp, " global %sGetRegisterValue_\n", cpubasename);\r
8945\r
8946 if (bPlain)\r
8947 fprintf(fp, " global %sGetRegisterValue\n", cpubasename);\r
8948\r
8949 sprintf(procname, "%sGetRegisterValue_", cpubasename);\r
8950 ProcBegin(0xffffffff);\r
8951\r
8952 fprintf(fp, "_%sGetRegisterValue:\n", cpubasename);\r
8953 if (bPlain)\r
8954 fprintf(fp, "%sGetRegisterValue:\n", cpubasename);\r
8955\r
8956 fprintf(fp, " push esi\n");\r
8957\r
8958 if (bUseStack)\r
8959 {\r
8960 fprintf(fp, " mov eax, [esp+8] ; Get our register #\n");\r
8961 fprintf(fp, " mov esi, [esp+12] ; Get our context address\n");\r
8962 }\r
8963 else\r
8964 {\r
8965 fprintf(fp, " mov esi, eax ; Get context\n");\r
8966 fprintf(fp, " mov eax, edx ; Get register # in EAX\n");\r
8967 }\r
8968\r
8969 fprintf(fp, " or esi, esi ; Is context NULL?\n");\r
8970 fprintf(fp, " jnz getVal ; Nope - use it!\n");\r
8971 fprintf(fp, " mov esi, _%scontextBegin\n\n", cpubasename);\r
8972\r
8973 fprintf(fp, "getVal:\n");\r
8974 fprintf(fp, " call getRegValueInternal\n\n");\r
8975\r
8976 fprintf(fp, " pop esi\n");\r
8977\r
8978 fprintf(fp, " ret\n\n");\r
8979\r
8980 Alignment();\r
8981\r
8982 fprintf(fp, " global _%sGetRegisterName\n", cpubasename);\r
8983 fprintf(fp, " global %sGetRegisterName_\n", cpubasename);\r
8984\r
8985 if (bPlain)\r
8986 fprintf(fp, " global %sGetRegisterName\n", cpubasename);\r
8987\r
8988 sprintf(procname, "%sGetRegisterName_", cpubasename);\r
8989 ProcBegin(0xffffffff);\r
8990\r
8991 fprintf(fp, "_%sGetRegisterName:\n", cpubasename);\r
8992 if (bPlain)\r
8993 fprintf(fp, "%sGetRegisterName:\n", cpubasename);\r
8994\r
8995 if (bUseStack)\r
8996 {\r
8997 fprintf(fp, " mov eax, [esp+4] ; Get our register #\n");\r
8998 }\r
8999\r
9000 fprintf(fp, " cmp eax, CPUREG_MAXINDEX\n");\r
9001 fprintf(fp, " jae badIndex\n");\r
9002\r
9003 fprintf(fp, " shl eax, 4 ; Times 16 bytes for each entry\n");\r
9004 fprintf(fp, " mov eax, [eax+RegTable]\n");\r
9005 fprintf(fp, " jmp nameExit\n\n");\r
9006\r
9007 fprintf(fp, "badIndex:\n");\r
9008 fprintf(fp, " xor eax, eax\n\n");\r
9009\r
9010 fprintf(fp, "nameExit:\n");\r
9011 fprintf(fp, " ret\n\n");\r
9012\r
9013 Alignment();\r
9014\r
9015 fprintf(fp, " global _%sGetRegisterTextValue\n", cpubasename);\r
9016 fprintf(fp, " global %sGetRegisterTextValue_\n", cpubasename);\r
9017\r
9018 if (bPlain)\r
9019 fprintf(fp, " global %sGetRegisterTextValue\n", cpubasename);\r
9020\r
9021 sprintf(procname, "%sGetRegisterTextValue_", cpubasename);\r
9022 ProcBegin(0xffffffff);\r
9023\r
9024 fprintf(fp, "_%sGetRegisterTextValue:\n", cpubasename);\r
9025 if (bPlain)\r
9026 fprintf(fp, "%sGetRegisterTextValue:\n", cpubasename);\r
9027\r
9028 fprintf(fp, " push esi\n");\r
9029 fprintf(fp, " push edi\n");\r
9030 fprintf(fp, " push edx\n");\r
9031\r
9032 if (bUseStack)\r
9033 {\r
9034 fprintf(fp, " mov eax, [esp+16] ; Get our register #\n");\r
9035 fprintf(fp, " mov esi, [esp+20] ; Get our context address\n");\r
9036 fprintf(fp, " mov edi, [esp+24] ; Address to place text\n");\r
9037 }\r
9038 else\r
9039 {\r
9040 fprintf(fp, " mov esi, eax ; Get context\n");\r
9041 fprintf(fp, " mov eax, edx ; Get register # in EAX\n");\r
9042 fprintf(fp, " mov edi, ebx ; Address to place text\n");\r
9043 }\r
9044\r
9045 fprintf(fp, " or esi, esi ; Is context NULL?\n");\r
9046 fprintf(fp, " jnz getVal2 ; Nope - use it!\n");\r
9047 fprintf(fp, " mov esi, _%scontextBegin\n\n", cpubasename);\r
9048\r
9049 fprintf(fp, "getVal2:\n");\r
9050 fprintf(fp, " mov edx, eax ; Save off our index for later\n");\r
9051 fprintf(fp, " call getRegValueInternal\n\n");\r
9052\r
9053 fprintf(fp, "; EAX Holds the value, EDX=Register #, and EDI=Destination!\n\n");\r
9054\r
9055 fprintf(fp, " call convertValueToText\n\n");\r
9056\r
9057 fprintf(fp, " pop edx\n");\r
9058 fprintf(fp, " pop esi\n");\r
9059 fprintf(fp, " pop edi\n");\r
9060\r
9061 fprintf(fp, " ret\n\n");\r
9062\r
9063 Alignment();\r
9064\r
9065 fprintf(fp, " global _%sWriteValue\n", cpubasename);\r
9066 fprintf(fp, " global %sWriteValue_\n", cpubasename);\r
9067\r
9068 if (bPlain)\r
9069 fprintf(fp, " global %sWriteValue\n", cpubasename);\r
9070\r
9071 sprintf(procname, "%sWriteValue_", cpubasename);\r
9072 ProcBegin(0xffffffff);\r
9073\r
9074 fprintf(fp, "_%sWriteValue:\n", cpubasename);\r
9075 if (bPlain)\r
9076 fprintf(fp, "%sWriteValue:\n", cpubasename);\r
9077\r
9078 fprintf(fp, " push esi\n");\r
9079 fprintf(fp, " push edi\n");\r
9080 fprintf(fp, " push edx\n");\r
9081 fprintf(fp, " push ebx\n");\r
9082 fprintf(fp, " push ecx\n");\r
9083 fprintf(fp, " push ebp\n");\r
9084\r
9085 if (bUseStack)\r
9086 {\r
9087 fprintf(fp, " mov eax, [esp+28] ; What kind of write is this?\n");\r
9088 fprintf(fp, " mov ebx, [esp+32] ; Address\n");\r
9089 fprintf(fp, " mov edx, [esp+36] ; Value\n");\r
9090 }\r
9091 else\r
9092 {\r
9093 fprintf(fp, " xchg edx, ebx ; Addr=EBX, value=EDX\n");\r
9094 }\r
9095\r
9096 fprintf(fp, " cmp eax, 1 ; Is it a word write?\n");\r
9097 fprintf(fp, " je near invalidWrite ; Yep - it's not valid\n");\r
9098 fprintf(fp, " cmp eax, 2 ; Is it a dword write?\n");\r
9099 fprintf(fp, " je near invalidWrite ; Yep - it's not valid\n\n");\r
9100 fprintf(fp, " or eax, eax ; Is it a byte write?\n");\r
9101 fprintf(fp, " jnz itsIoDummy ; Nope... it's an I/O write\n\n");\r
9102\r
9103 // Here we do a write memory byte\r
9104\r
9105 fprintf(fp, " mov ebp, [_z80Base] ; Base pointer comes back\n");\r
9106 fprintf(fp, " mov edi, [_z80MemWrite] ; Point to the write array\n");\r
9107\r
9108 fprintf(fp, "checkLoop:\n");\r
9109 fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n");\r
9110 fprintf(fp, " je memoryWrite ; Yes - go write it!\n");\r
9111 fprintf(fp, " cmp bx, [edi] ; Are we smaller?\n");\r
9112 fprintf(fp, " jb nextAddr ; Yes... go to the next addr\n");\r
9113 fprintf(fp, " cmp bx, [edi+4] ; Are we smaller?\n");\r
9114 fprintf(fp, " jbe callRoutine ; If not, go call it!\n");\r
9115\r
9116 fprintf(fp, "nextAddr:\n");\r
9117 fprintf(fp, " add edi, 10h ; Next structure, please\n");\r
9118 fprintf(fp, " jmp short checkLoop\n");\r
9119\r
9120 fprintf(fp, "callRoutine:\n");\r
9121\r
9122 fprintf(fp, "\n;\n; EBX=Address to target, DL=Byte to write \n;\n\n");\r
9123\r
9124 fprintf(fp, " cmp [edi+8], dword 0 ; Null handler?\n");\r
9125 fprintf(fp, " je directWriteHandler2\n\n");\r
9126 \r
9127 if (FALSE == bUseStack)\r
9128 {\r
9129 fprintf(fp, " mov eax, ebx ; Address\n");\r
9130 fprintf(fp, " mov ebx, edi ; Pointer to struct (EDX Already has the byte to write)\n");\r
9131 }\r
9132 else\r
9133 {\r
9134 fprintf(fp, " push edi ; Handler\n");\r
9135 fprintf(fp, " push edx ; Byte\n");\r
9136 fprintf(fp, " push ebx ; Address\n");\r
9137 }\r
9138 \r
9139 fprintf(fp, " call dword [edi + 8] ; Go call our handler\n");\r
9140\r
9141 if (bUseStack)\r
9142 {\r
9143 fprintf(fp, " add esp, 12\n");\r
9144 }\r
9145\r
9146 fprintf(fp, " jmp short itsGood\n");\r
9147\r
9148 fprintf(fp, "directWriteHandler2:\n");\r
9149 fprintf(fp, " sub ebx, [edi] ; Subtract our offset\n");\r
9150 fprintf(fp, " add ebx, [edi+12] ; Add in the base address\n");\r
9151 fprintf(fp, " mov [ebx], dl ; Store our byte\n");\r
9152 fprintf(fp, " jmp short itsGood\n");\r
9153 fprintf(fp, "memoryWrite:\n");\r
9154 fprintf(fp, " mov [ebp + ebx], dl\n\n");\r
9155 fprintf(fp, " jmp short itsGood\n");\r
9156\r
9157 // Here we do an "out"\r
9158\r
9159 fprintf(fp, "itsIoDummy:\n");\r
9160\r
9161 fprintf(fp, " mov edi, [_z80IoWrite] ; Point to the I/O write array\n");\r
9162\r
9163 fprintf(fp, "IOCheck:\n");\r
9164 fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n");\r
9165 fprintf(fp, " je itsGood ; Yes - ignore it!\n");\r
9166 fprintf(fp, " cmp bx, [edi] ; Are we smaller?\n");\r
9167 fprintf(fp, " jb nextIOAddr ; Yes... go to the next addr\n");\r
9168 fprintf(fp, " cmp bx, [edi+2] ; Are we bigger?\n");\r
9169 fprintf(fp, " jbe callIOHandler ; If not, go call it!\n");\r
9170\r
9171 fprintf(fp, "nextIOAddr:\n");\r
9172 fprintf(fp, " add edi, 0ch ; Next structure, please\n");\r
9173 fprintf(fp, " jmp short IOCheck\n");\r
9174\r
9175 fprintf(fp, "callIOHandler:\n");\r
9176\r
9177 if (FALSE == bUseStack)\r
9178 {\r
9179 fprintf(fp, " mov eax, ebx ; Address\n");\r
9180 fprintf(fp, " mov ebx, edi ; Pointer to struct (EDX Already has the byte to write)\n");\r
9181 }\r
9182 else\r
9183 {\r
9184 fprintf(fp, " push edi ; Handler\n");\r
9185 fprintf(fp, " push edx ; Byte\n");\r
9186 fprintf(fp, " push ebx ; Address\n");\r
9187 }\r
9188\r
9189 fprintf(fp, " call dword [edi+4] ; Call the handler!\n");\r
9190\r
9191 if (bUseStack)\r
9192 fprintf(fp, " add esp, 12\n");\r
9193\r
9194 fprintf(fp, " jmp short itsGood\n\n");\r
9195\r
9196 // Errors and whatnot\r
9197\r
9198 fprintf(fp, "invalidWrite:\n");\r
9199 fprintf(fp, " mov eax, 0ffffffffh\n");\r
9200 fprintf(fp, " jmp short writeValueExit\n\n");\r
9201\r
9202 fprintf(fp, "itsGood:\n");\r
9203 fprintf(fp, " xor eax, eax\n\n");\r
9204\r
9205 fprintf(fp, "writeValueExit:\n");\r
9206\r
9207 fprintf(fp, " pop ebp\n");\r
9208 fprintf(fp, " pop ecx\n");\r
9209 fprintf(fp, " pop ebx\n");\r
9210 fprintf(fp, " pop edx\n");\r
9211 fprintf(fp, " pop esi\n");\r
9212 fprintf(fp, " pop edi\n");\r
9213\r
9214 fprintf(fp, " ret\n\n");\r
9215\r
9216 Alignment();\r
9217\r
9218 fprintf(fp, " global _%sReadValue\n", cpubasename);\r
9219 fprintf(fp, " global %sReadValue_\n", cpubasename);\r
9220\r
9221 if (bPlain)\r
9222 fprintf(fp, " global %sReadValue\n", cpubasename);\r
9223\r
9224 sprintf(procname, "%sReadValue_", cpubasename);\r
9225 ProcBegin(0xffffffff);\r
9226\r
9227 fprintf(fp, "_%sReadValue:\n", cpubasename);\r
9228 if (bPlain)\r
9229 fprintf(fp, "%sReadValue:\n", cpubasename);\r
9230\r
9231 fprintf(fp, " push esi\n");\r
9232 fprintf(fp, " push edi\n");\r
9233 fprintf(fp, " push edx\n");\r
9234 fprintf(fp, " push ebx\n");\r
9235 fprintf(fp, " push ecx\n");\r
9236 fprintf(fp, " push ebp\n");\r
9237\r
9238 if (bUseStack)\r
9239 {\r
9240 fprintf(fp, " mov eax, [esp+28] ; What kind of read is this?\n");\r
9241 fprintf(fp, " mov ebx, [esp+32] ; Address\n");\r
9242 }\r
9243 else\r
9244 {\r
9245 fprintf(fp, " xchg edx, ebx ; Addr=EBX\n");\r
9246 }\r
9247\r
9248 fprintf(fp, " cmp eax, 1 ; Is it a word read?\n");\r
9249 fprintf(fp, " je near invalidRead ; Yep - it's not valid\n");\r
9250 fprintf(fp, " cmp eax, 2 ; Is it a dword read?\n");\r
9251 fprintf(fp, " je near invalidRead ; Yep - it's not valid\n\n");\r
9252 fprintf(fp, " or eax, eax ; Is it a byte read?\n");\r
9253 fprintf(fp, " jnz itsIoDummyRead ; Nope... it's an I/O read\n\n");\r
9254\r
9255 // Here we do a read memory byte\r
9256\r
9257 fprintf(fp, " mov ebp, [_z80Base] ; Base pointer comes back\n");\r
9258 fprintf(fp, " mov edi, [_z80MemRead] ; Point to the read array\n");\r
9259\r
9260 fprintf(fp, "checkLoopRead:\n");\r
9261 fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n");\r
9262 fprintf(fp, " je memoryRead ; Yes - go read it!\n");\r
9263 fprintf(fp, " cmp bx, [edi] ; Are we smaller?\n");\r
9264 fprintf(fp, " jb nextAddrRead ; Yes... go to the next addr\n");\r
9265 fprintf(fp, " cmp bx, [edi+4] ; Are we smaller?\n");\r
9266 fprintf(fp, " jbe callRoutineRead ; If not, go call it!\n");\r
9267\r
9268 fprintf(fp, "nextAddrRead:\n");\r
9269 fprintf(fp, " add edi, 10h ; Next structure, please\n");\r
9270 fprintf(fp, " jmp short checkLoopRead\n");\r
9271\r
9272 fprintf(fp, "callRoutineRead:\n");\r
9273\r
9274 fprintf(fp, "\n;\n; EBX=Address to target\n;\n\n");\r
9275\r
9276 fprintf(fp, " cmp [edi+8], dword 0 ; NULL HAndler?\n");\r
9277 fprintf(fp, " je handleSharedRead\n\n");\r
9278\r
9279 if (FALSE == bUseStack)\r
9280 {\r
9281 fprintf(fp, " mov eax, ebx ; Address\n");\r
9282 fprintf(fp, " mov edx, edi ; Pointer to struct\n");\r
9283 }\r
9284 else\r
9285 {\r
9286 fprintf(fp, " push edi ; Handler\n");\r
9287 fprintf(fp, " push ebx ; Address\n");\r
9288 }\r
9289 \r
9290 fprintf(fp, " call dword [edi + 8] ; Go call our handler\n");\r
9291 fprintf(fp, " mov dl, al ; Get our byte read\n");\r
9292\r
9293 if (bUseStack)\r
9294 {\r
9295 fprintf(fp, " add esp, 8\n");\r
9296 }\r
9297\r
9298 fprintf(fp, " jmp short itsGoodRead\n\n");\r
9299\r
9300 fprintf(fp, "memoryRead:\n");\r
9301 fprintf(fp, " mov dl, [ebp+ebx]\n\n");\r
9302 fprintf(fp, " jmp short itsGoodRead\n\n");\r
9303\r
9304 fprintf(fp, "handleSharedRead:\n");\r
9305 fprintf(fp, " sub ebx, [edi]\n");\r
9306 fprintf(fp, " add ebx, [edi+12]\n");\r
9307 fprintf(fp, " mov dl, [ebx]\n");\r
9308 fprintf(fp, " jmp short itsGoodRead\n\n");\r
9309\r
9310 // Here we do an "out"\r
9311\r
9312 fprintf(fp, "itsIoDummyRead:\n");\r
9313\r
9314 fprintf(fp, " mov edi, [_z80IoRead] ; Point to the I/O read array\n");\r
9315 fprintf(fp, " mov dl, 0ffh ; Assume no handler\n");\r
9316\r
9317 fprintf(fp, "IOCheckRead:\n");\r
9318 fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n");\r
9319 fprintf(fp, " je itsGoodRead ; Yes - ignore it!\n");\r
9320 fprintf(fp, " cmp bx, [edi] ; Are we smaller?\n");\r
9321 fprintf(fp, " jb nextIOAddrRead ; Yes... go to the next addr\n");\r
9322 fprintf(fp, " cmp bx, [edi+2] ; Are we bigger?\n");\r
9323 fprintf(fp, " jbe callIOHandlerRead ; If not, go call it!\n");\r
9324\r
9325 fprintf(fp, "nextIOAddrRead:\n");\r
9326 fprintf(fp, " add edi, 0ch ; Next structure, please\n");\r
9327 fprintf(fp, " jmp short IOCheckRead\n");\r
9328\r
9329 fprintf(fp, "callIOHandlerRead:\n");\r
9330\r
9331 if (FALSE == bUseStack)\r
9332 {\r
9333 fprintf(fp, " mov eax, ebx ; Address\n");\r
9334 fprintf(fp, " mov edx, edi ; Pointer to struct (EDX Already has the byte to write)\n");\r
9335 }\r
9336 else\r
9337 {\r
9338 fprintf(fp, " push edi ; Handler\n");\r
9339 fprintf(fp, " push ebx ; Address\n");\r
9340 }\r
9341\r
9342 fprintf(fp, " call dword [edi+4] ; Call the handler!\n");\r
9343 fprintf(fp, " mov dl, al ; Get our byte read\n");\r
9344\r
9345 if (bUseStack)\r
9346 fprintf(fp, " add esp, 8\n");\r
9347\r
9348 fprintf(fp, " jmp short itsGoodRead\n\n");\r
9349\r
9350 // Errors and whatnot\r
9351\r
9352 fprintf(fp, "invalidRead:\n");\r
9353 fprintf(fp, " mov eax, 0ffffffffh\n");\r
9354 fprintf(fp, " jmp short ReadValueExit\n\n");\r
9355\r
9356 fprintf(fp, "itsGoodRead:\n");\r
9357 fprintf(fp, " xor eax, eax\n");\r
9358 fprintf(fp, " mov al, dl\n\n");\r
9359\r
9360 fprintf(fp, "ReadValueExit:\n");\r
9361\r
9362 fprintf(fp, " pop ebp\n");\r
9363 fprintf(fp, " pop ecx\n");\r
9364 fprintf(fp, " pop ebx\n");\r
9365 fprintf(fp, " pop edx\n");\r
9366 fprintf(fp, " pop esi\n");\r
9367 fprintf(fp, " pop edi\n");\r
9368\r
9369 fprintf(fp, " ret\n\n");\r
9370\r
9371\r
9372\r
9373 }\r
9374 else\r
9375 if (MZ80_C == bWhat)\r
9376 {\r
9377 }\r
9378}\r
9379\r
9380\r
9381EmitCode()\r
9382{\r
9383 CodeSegmentBegin();\r
9384 EmitCBInstructions();\r
9385 EmitEDInstructions();\r
9386\r
9387 if (MZ80_ASSEMBLY_X86 == bWhat)\r
9388 strcpy(mz80Index, "ix");\r
9389 \r
9390 else\r
9391 {\r
9392 strcpy(mz80Index, "cpu.z80IX");\r
9393 strcpy(mz80IndexHalfHigh, "cpu.z80XH");\r
9394 strcpy(mz80IndexHalfLow, "cpu.z80XL");\r
9395 }\r
9396\r
9397 strcpy(majorOp, "DD");\r
9398 EmitDDInstructions();\r
9399\r
9400 if (MZ80_ASSEMBLY_X86 == bWhat)\r
9401 strcpy(mz80Index, "iy");\r
9402 else\r
9403 {\r
9404 strcpy(mz80Index, "cpu.z80IY");\r
9405 strcpy(mz80IndexHalfHigh, "cpu.z80YH");\r
9406 strcpy(mz80IndexHalfLow, "cpu.z80YL");\r
9407 }\r
9408\r
9409 strcpy(majorOp, "FD");\r
9410 EmitFDInstructions();\r
9411 majorOp[0] = '\0';\r
9412 EmitRegularInstructions();\r
9413 ReadMemoryByteHandler();\r
9414 WriteMemoryByteHandler();\r
9415\r
9416 if (bThroughCallHandler)\r
9417 {\r
9418 PushWordHandler();\r
9419 PopWordHandler();\r
9420 }\r
9421\r
9422 ReadIoHandler();\r
9423 WriteIoHandler();\r
9424 GetContextCode();\r
9425 SetContextCode();\r
9426 GetContextSizeCode();\r
9427 GetTicksCode();\r
9428 ReleaseTimesliceCode();\r
9429 ResetCode();\r
9430 IntCode();\r
9431 NmiCode();\r
9432 ExecCode();\r
9433 InitCode();\r
9434 ShutdownCode();\r
9435 DebuggerCode();\r
9436 CodeSegmentEnd();\r
9437}\r
9438\r
9439main(int argc, char **argv)\r
9440{\r
9441 UINT32 dwLoop = 0;\r
9442\r
9443 printf("MakeZ80 - V%s - Copyright 1996-2000 Neil Bradley (neil@synthcom.com)\n", VERSION);\r
9444\r
9445 if (argc < 2)\r
9446 {\r
9447 printf("Usage: %s outfile [option1] [option2] ....\n", argv[0]);\r
9448 printf("\n -s - Stack calling conventions (DJGPP, MSVC, Borland)\n");\r
9449 printf(" -x86 - Emit an assembly version of mz80\n");\r
9450 printf(" -c - Emit a C version of mz80\n");\r
9451 printf(" -cs - All stack operations go through handlers\n");\r
9452 printf(" -16 - Treat all I/O input and output as 16 bit (BC) instead of (C)\n");\r
9453 printf(" -l - Create 'plain' labels - ones without leading or trailing _'s\n");\r
9454 printf(" -nt - No timing additions occur\n");\r
9455 printf(" -os2 - Emit OS/2 compatible segmentation pragmas\n");\r
9456 exit(1);\r
9457 }\r
9458\r
9459 dwLoop = 1;\r
9460\r
9461 while (dwLoop < argc)\r
9462 {\r
9463 if (strcmp("-x86", argv[dwLoop]) == 0 || strcmp("-X86", argv[dwLoop]) == 0)\r
9464 bWhat = MZ80_ASSEMBLY_X86;\r
9465 if (strcmp("-c", argv[dwLoop]) == 0 || strcmp("-C", argv[dwLoop]) == 0)\r
9466 bWhat = MZ80_C;\r
9467 if (strcmp("-cs", argv[dwLoop]) == 0 || strcmp("-cs", argv[dwLoop]) == 0)\r
9468 bThroughCallHandler = TRUE;\r
9469 if (strcmp("-s", argv[dwLoop]) == 0 || strcmp("-S", argv[dwLoop]) == 0)\r
9470 bUseStack = 1;\r
9471 if (strcmp("-l", argv[dwLoop]) == 0 || strcmp("-L", argv[dwLoop]) == 0)\r
9472 bPlain = TRUE;\r
9473 if (strcmp("-16", argv[dwLoop]) == 0)\r
9474 b16BitIo = TRUE;\r
9475 if (strcmp("-os2", argv[dwLoop]) == 0 || strcmp("-OS2", argv[dwLoop]) == 0)\r
9476 bOS2 = TRUE;\r
9477 if (strcmp("-nt", argv[dwLoop]) == 0)\r
9478 {\r
9479 bNoTiming = TRUE;\r
9480 }\r
9481\r
9482 dwLoop++;\r
9483 }\r
9484\r
9485 if (bWhat == MZ80_UNKNOWN)\r
9486 {\r
9487 fprintf(stderr, "Need emitted type qualifier\n");\r
9488 exit(1);\r
9489 }\r
9490\r
9491 for (dwLoop = 1; dwLoop < argc; dwLoop++)\r
9492 if (argv[dwLoop][0] != '-')\r
9493 {\r
9494 fp = fopen(argv[dwLoop], "w");\r
9495 break;\r
9496 }\r
9497\r
9498 if (NULL == fp)\r
9499 {\r
9500 fprintf(stderr, "Can't open %s for writing\n", argv[1]);\r
9501 exit(1);\r
9502 }\r
9503\r
9504 strcpy(cpubasename, "mz80");\r
9505\r
9506 StandardHeader();\r
9507 DataSegment();\r
9508 EmitCode();\r
9509 ProgramEnd();\r
9510\r
9511 fclose(fp);\r
9512}\r