initial import
[picodrive.git] / cpu / mz80 / makez80.c
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
70 FILE *fp = NULL;\r
71 char string[150];\r
72 char cpubasename[150];\r
73 static char mz80Index[50];\r
74 static char mz80IndexHalfHigh[50];\r
75 static char mz80IndexHalfLow[50];\r
76 char majorOp[50];\r
77 char procname[150];\r
78 UINT32 dwGlobalLabel = 0;\r
79 \r
80 enum\r
81 {\r
82         MZ80_ASSEMBLY_X86,\r
83         MZ80_C,\r
84         MZ80_UNKNOWN\r
85 };\r
86 \r
87 UINT8 bPlain = FALSE;\r
88 UINT8 bNoTiming = FALSE;\r
89 UINT8 bUseStack = 0;\r
90 UINT8 bCurrentMode = TIMING_REGULAR;    // Current timing mode\r
91 UINT8 b16BitIo = FALSE;\r
92 UINT8 bThroughCallHandler = FALSE;\r
93 UINT8 bOS2 = FALSE;\r
94 UINT8 bWhat = MZ80_UNKNOWN;\r
95 \r
96 void ProcBegin(UINT32 dwOpcode);\r
97 \r
98 UINT8 *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
110 UINT8 *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
122 UINT8 *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
134 UINT8 *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
146 UINT8 *pbRegPairC[] =\r
147 {\r
148         "cpu.z80BC",\r
149         "cpu.z80DE",\r
150         "cpu.z80HL",\r
151         "cpu.z80sp"\r
152 };\r
153 \r
154 UINT8 *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
166 UINT8 *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
178 UINT8 *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
190 UINT8 *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
198 UINT8 *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
206 UINT8 *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
214 UINT8 *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
222 UINT8 *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
232 UINT8 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
255 UINT8 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
276 UINT8 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
296 UINT8 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
318 UINT8 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
341 void EDHandler(UINT32 dwOpcode);\r
342 void DDHandler(UINT32 dwOpcode);\r
343 void FDHandler(UINT32 dwOpcode);\r
344 void CBHandler(UINT32 dwOpcode);\r
345 \r
346 void PushPopOperations(UINT32 dwOpcode);\r
347 void AddRegpairOperations(UINT32 dwOpcode);\r
348 void CallHandler(UINT32 dwOpcode);\r
349 void MiscHandler(UINT32 dwOpcode);\r
350 void IMHandler(UINT32 dwOpcode);\r
351 void IRHandler(UINT32 dwOpcode);\r
352 void LdRegPairImmediate(UINT32 dwOpcode);\r
353 void LoadImmediate(UINT32 dwOpcode);\r
354 void LdRegpairPtrByte(UINT32 dwOpcode);\r
355 void MathOperation(UINT32 dwOpcode);\r
356 void RegIntoMemory(UINT32 dwOpcode);\r
357 void JpHandler(UINT32 dwOpcode);\r
358 void LdRegImmediate(UINT32 dwOpcode);\r
359 void IncRegister(UINT32 dwOpcode);\r
360 void DecRegister(UINT32 dwOpcode);\r
361 void IncDecRegpair(UINT32 dwOpcode);\r
362 void LdRegReg(UINT32 dwOpcode);\r
363 void MathOperationDirect(UINT32 dwOpcode);\r
364 void JrHandler(UINT32 dwOpcode);\r
365 void RetHandler(UINT32 dwOpcode);\r
366 void RestartHandler(UINT32 dwOpcode);\r
367 void ToRegFromHl(UINT32);\r
368 void RraRlaHandler(UINT32);\r
369 void LdByteRegpair(UINT32);\r
370 void IncDecHLPtr(UINT32 dwOpcode);\r
371 void InOutHandler(UINT32 dwOpcode);\r
372 void RLCRRCRLRRSLASRASRLHandler(UINT32 dwOpcode);\r
373 void BITHandler(UINT32 dwOpcode);\r
374 void RESSETHandler(UINT32 dwOpcode);\r
375 void PushPopOperationsIndexed(UINT32 dwOpcode);\r
376 void LDILDRLDIRLDDRHandler(UINT32);\r
377 void LdRegpair(UINT32 dwOpcode);\r
378 void ExtendedRegIntoMemory(UINT32 dwOpcode);\r
379 void NegHandler(UINT32 dwOpcode);\r
380 void ExtendedInHandler(UINT32 dwOpcode);\r
381 void ExtendedOutHandler(UINT32 dwOpcode);\r
382 void RetIRetNHandler(UINT32 dwOcode);\r
383 void AdcSbcRegpair(UINT32 dwOpcode);\r
384 void CPICPDCPIRCPDRHandler(UINT32 dwOpcode);\r
385 void RRDRLDHandler(UINT32 dwOpcode);\r
386 void UndocRegToIndex(UINT32 dwOpcode);\r
387 void UndocIndexToReg(UINT32 dwOpcode);\r
388 void MathOperationIndexed(UINT32 dwOpcode);\r
389 void IncDecIndexed(UINT32 dwOpcode);\r
390 void DDFDCBHandler(UINT32 dwOpcode);\r
391 void JPIXIYHandler(UINT32 dwOpcode);\r
392 void AddIndexHandler(UINT32 dwOpcode);\r
393 void SPToIndex(UINT32 dwOpcode);\r
394 void LdByteToIndex(UINT32 dwOpcode);\r
395 void LdRegIndexOffset(UINT32 dwOpcode);\r
396 void IncDecIndexReg(UINT32 dwOpcode);\r
397 void ExIndexed(UINT32 dwOpcode);\r
398 void UndocIncDecIndexReg(UINT32 dwOpcode);\r
399 void UndocLoadHalfIndexReg(UINT32 dwOpcode);\r
400 void UndocMathIndex(UINT32 dwOpcode);\r
401 void ddcbBitWise(UINT32 dwOpcode);\r
402 void LdIndexPtrReg(UINT32 dwOpcode);\r
403 void StoreIndexReg(UINT32 dwOpcode);\r
404 void LoadIndexReg(UINT32 dwOpcode);\r
405 void OTIROTDROUTIOUTDHandler(UINT32 dwOpcode);\r
406 void INIRINDRINIINDHandler(UINT32 dwOpcode);\r
407 \r
408 struct sOp\r
409 {\r
410         UINT32 bOpCode;\r
411         void (*Emitter)(UINT32);\r
412 };\r
413 \r
414 struct 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
705 struct 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
989 struct 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
1056 struct 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
1162 struct 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
1201 void InvalidInstructionC(UINT32 dwCount)\r
1202 {\r
1203         fprintf(fp, "                           InvalidInstruction(%ld);\n", dwCount);\r
1204 }\r
1205 \r
1206 UINT32 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
1242 void 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
1254 void 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
1279 void 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
1304 void 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
1329 void 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
1354 StandardHeader()\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
1484 Alignment()\r
1485 {\r
1486         fprintf(fp, "\ntimes ($$-$) & 3 nop     ; pad with NOPs to 4-byte boundary\n\n");\r
1487 }\r
1488 \r
1489 void ProcBegin(UINT32 dwOpcode)\r
1490 {\r
1491         Alignment();\r
1492         fprintf(fp, "%s:\n", procname);\r
1493 }\r
1494 \r
1495 void 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
1502 void 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
1509 void 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
1516 void 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
1523 UINT32 dwOverflowCount = 0;\r
1524 \r
1525 SetOverflow()\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
1533 void 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
1550 void 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
1680 void 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
1797 void 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
1856 void 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
1947 void 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
2063 void 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
2151 void 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
2484 void 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
2529 void 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
2571 void 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
2757 void 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
2796 void 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
2849 void 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
2883 void 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
2913 void 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
2943 void 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
2973 void 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
3021 void 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
3143 void 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
3223 void 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
3306 void 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
3376 void 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
3425 void 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
3457 void 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
3503 void 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
3557 void 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
3596 void 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
3627 void 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
3689 void 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
3733 void 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
3791 void 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
3843 void 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
3997 void 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
4085 void 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
4202 void 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
4316 void 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
4426 void 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
4513 void 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
4579 void 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
4609 void 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
4662 void 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
4689 void 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
4741 void 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
4787 void 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
4924 void 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
4964 void 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
5060 void 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
5101 void 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
5129 void 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
5161 void 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
5188 void 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
5338 void 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
5366 void 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
5418 void 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
5459 void 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
5490 void 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
5520 void 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
5560 void 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
5581 void 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
5634 void 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
5655 void 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
5723 void 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
5843 void 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
5890 void 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
5919 void 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
5942 void 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
6001 void 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
6183 GetTicksCode()\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
6229 ReleaseTimesliceCode()\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
6265 DataSegment()\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
7073 CodeSegmentBegin()\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
7098 CodeSegmentEnd()\r
7099 {\r
7100 }\r
7101 \r
7102 ProgramEnd()\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
7118 EmitRegularInstructions()\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
7216 EmitCBInstructions()\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
7286 EmitEDInstructions()\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
7358 EmitDDInstructions()\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
7501 EmitFDInstructions()\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
7573 void 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
7647 void 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
7728 void 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
7749 void 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
7766 void 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
7832 void 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
7902 ExecCode()\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
8142 NmiCode()\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
8244 IntCode()\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
8401 ResetCode()\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
8476 SetContextCode()\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
8529 GetContextCode()\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
8585 GetContextSizeCode()\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
8621 void 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
8753 void 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
8788 void 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
9381 EmitCode()\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
9439 main(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