2 /* Z80 instruction set simulator.
3 Copyright (C) 1995 Frank D. Cringle.
5 This file is part of yaze - yet another Z80 emulator.
7 Yaze is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 # This perl script generates the z80 instruction set simulator simz80().
26 # Because simz80() is the function which determines the speed of the
27 # emulator, it can be interesting to experiment with different coding
28 # styles. Using perl to generate the final C code helps to separate
29 # the logic of the emulator from implementation details, such as whether
30 # to use sub-functions or inline code for handling extended opcodes.
32 # Set $combine = 1 to insert goto's where possible to combine
33 # identical instruction sequences at the end of switch branches.
34 # If $combine is not set (or set = 0), the generated code will be
35 # larger but there will be fewer jump instructions during execution.
36 # Thus the code may execute faster on a machine with slow branches and
37 # no cache or one with a large instruction cache. The compiler and
38 # optimizer will also play a role, so the best choice for a particular
39 # environment must by found empirically.
43 # Set $optab = 1 to use an array of labels instead of a switch for the
44 # main op-code dispatch function. This only works with gcc, and
45 # actually produces worse code with gcc-2.6.1 on a sparc.
49 # Set $xx_inline = 1 to generate inline code for the instruction prefix xx.
50 # If $xx_inline is undefined or 0, prefix xx will be handled by a separate
51 # function which does not have access to the local variables of the main
59 ##### end of configuration options ####
63 /* This file was generated from $f
64 with the following choice of options */
68 "cb_inline=$cb_inline,"
69 "dfd_inline=$dfd_inline,"
70 "ed_inline=$ed_inline";
77 &preamble
; # generate the function header and switch
80 &case
(0x01, "LD BC,nnnn"); &LDddnn
(BC
);
81 &case
(0x02, "LD (BC),A"); print "\t\tPutBYTE(BC, hreg(AF));\n";
82 &case
(0x03, "INC BC"); print "\t\t++BC;\n";
83 &case
(0x04, "INC B"); &INCr
(BC
, "h");
84 &case
(0x05, "DEC B"); &DECr
(BC
, "h");
85 &case
(0x06, "LD B,nn"); print "\t\tSethreg(BC, GetBYTE(PC)); ++PC;\n";
86 &case
(0x07, "RLCA"); print <<"EOT";
87 AF = ((AF >> 7) & 0x0128) | ((AF << 1) & ~0x1ff) |
88 (AF & 0xc4) | ((AF >> 15) & 1);
90 &case
(0x08, "EX AF,AF'"); print <<"EOT";
95 &case
(0x09, "ADD HL,BC"); &ADDdd
(HL
, BC
);
96 &case
(0x0A, "LD A,(BC)"); print "\t\tSethreg(AF, GetBYTE(BC));\n";
97 &case
(0x0B, "DEC BC"); print "\t\t--BC;\n";
98 &case
(0x0C, "INC C"); &INCr
(BC
, "l");
99 &case
(0x0D, "DEC C"); &DECr
(BC
, "l");
100 &case
(0x0E, "LD C,nn"); print "\t\tSetlreg(BC, GetBYTE(PC)); ++PC;\n";
101 &case
(0x0F, "RRCA"); print <<"EOT";
104 AF = ((temp & 1) << 15) | (sum << 8) |
105 (sum & 0x28) | (AF & 0xc4) | (temp & 1);
107 &case
(0x10, "DJNZ dd"); &JRcond
("(BC -= 0x100) & 0xff00");
108 &case
(0x11, "LD DE,nnnn"); &LDddnn
(DE
);
109 &case
(0x12, "LD (DE),A"); print "\t\tPutBYTE(DE, hreg(AF));\n";
110 &case
(0x13, "INC DE"); print "\t\t++DE;\n";
111 &case
(0x14, "INC D"); &INCr
(DE
, "h");
112 &case
(0x15, "DEC D"); &DECr
(DE
, "h");
113 &case
(0x16, "LD D,nn"); print "\t\tSethreg(DE, GetBYTE(PC)); ++PC;\n";
114 &case
(0x17, "RLA"); print <<"EOT";
115 AF = ((AF << 8) & 0x0100) | ((AF >> 7) & 0x28) | ((AF << 1) & ~0x01ff) |
116 (AF & 0xc4) | ((AF >> 15) & 1);
118 &case
(0x18, "JR dd"); &JRcond
(1);
119 &case
(0x19, "ADD HL,DE"); &ADDdd
(HL
, DE
);
120 &case
(0x1A, "LD A,(DE)"); print "\t\tSethreg(AF, GetBYTE(DE));\n";
121 &case
(0x1B, "DEC DE"); print "\t\t--DE;\n";
122 &case
(0x1C, "INC E"); &INCr
(DE
, "l");
123 &case
(0x1D, "DEC E"); &DECr
(DE
, "l");
124 &case
(0x1E, "LD E,nn"); print "\t\tSetlreg(DE, GetBYTE(PC)); ++PC;\n";
125 &case
(0x1F, "RRA"); print <<"EOT";
128 AF = ((AF & 1) << 15) | (sum << 8) |
129 (sum & 0x28) | (AF & 0xc4) | (temp & 1);
131 &case
(0x20, "JR NZ,dd"); &JRcond
("!TSTFLAG(Z)");
132 &case
(0x21, "LD HL,nnnn"); &LDddnn
(HL
);
133 &case
(0x22, "LD (nnnn),HL"); &LDmemdd
(HL
);
134 &case
(0x23, "INC HL"); print "\t\t++HL;\n";
135 &case
(0x24, "INC H"); &INCr
(HL
, "h");
136 &case
(0x25, "DEC H"); &DECr
(HL
, "h");
137 &case
(0x26, "LD H,nn"); print "\t\tSethreg(HL, GetBYTE(PC)); ++PC;\n";
138 &case
(0x27, "DAA"); print <<"EOT";
142 if (TSTFLAG(N)) { /* last operation was a subtract */
143 int hd = cbits || acu > 0x99;
144 if (TSTFLAG(H) || (temp > 9)) { /* adjust low digit */
150 if (hd) /* adjust high digit */
153 else { /* last operation was an add */
154 if (TSTFLAG(H) || (temp > 9)) { /* adjust low digit */
155 SETFLAG(H, (temp > 9));
158 if (cbits || ((acu & 0x1f0) > 0x90)) /* adjust high digit */
161 cbits |= (acu >> 8) & 1;
163 AF = (acu << 8) | (acu & 0xa8) | ((acu == 0) << 6) |
164 (AF & 0x12) | partab[acu] | cbits;
166 &case
(0x28, "JR Z,dd"); &JRcond
("TSTFLAG(Z)");
167 &case
(0x29, "ADD HL,HL"); &ADDdd
(HL
, HL
);
168 &case
(0x2A, "LD HL,(nnnn)"); &LDddmem
(HL
);
169 &case
(0x2B, "DEC HL"); print "\t\t--HL;\n";
170 &case
(0x2C, "INC L"); &INCr
(HL
, "l");
171 &case
(0x2D, "DEC L"); &DECr
(HL
, "l");
172 &case
(0x2E, "LD L,nn"); print "\t\tSetlreg(HL, GetBYTE(PC)); ++PC;\n";
173 &case
(0x2F, "CPL"); print <<"EOT";
174 AF = (~AF & ~0xff) | (AF & 0xc5) | ((~AF >> 8) & 0x28) | 0x12;
176 &case
(0x30, "JR NC,dd"); &JRcond
("!TSTFLAG(C)");
177 &case
(0x31, "LD SP,nnnn"); &LDddnn
(SP
);
178 &case
(0x32, "LD (nnnn),A"); &LDmemr
(AF
, "h");
179 &case
(0x33, "INC SP"); print "\t\t++SP;\n";
180 &case
(0x34, "INC (HL)"); &INCm
(HL
);
181 &case
(0x35, "DEC (HL)"); &DECm
(HL
);
182 &case
(0x36, "LD (HL),nn"); print "\t\tPutBYTE(HL, GetBYTE(PC)); ++PC;\n";
183 &case
(0x37, "SCF"); print "\t\tAF = (AF&~0x3b)|((AF>>8)&0x28)|1;\n";
184 &case
(0x38, "JR C,dd"); &JRcond
("TSTFLAG(C)");
185 &case
(0x39, "ADD HL,SP"); &ADDdd
(HL
, SP
);
186 &case
(0x3A, "LD A,(nnnn)"); &LDrmem
(AF
, "h");
187 &case
(0x3B, "DEC SP"); print "\t\t--SP;\n";
188 &case
(0x3C, "INC A"); &INCr
(AF
, "h");
189 &case
(0x3D, "DEC A"); &DECr
(AF
, "h");
190 &case
(0x3E, "LD A,nn"); print "\t\tSethreg(AF, GetBYTE(PC)); ++PC;\n";
192 print "\t\tAF = (AF&~0x3b)|((AF>>8)&0x28)|((AF&1)<<4)|(~AF&1);\n";
193 &case
(0x40, "LD B,B"); print "\t\t/* nop */\n";
194 &case
(0x41, "LD B,C"); print "\t\tBC = (BC & 255) | ((BC & 255) << 8);\n";
195 &case
(0x42, "LD B,D"); print "\t\tBC = (BC & 255) | (DE & ~255);\n";
196 &case
(0x43, "LD B,E"); print "\t\tBC = (BC & 255) | ((DE & 255) << 8);\n";
197 &case
(0x44, "LD B,H"); print "\t\tBC = (BC & 255) | (HL & ~255);\n";
198 &case
(0x45, "LD B,L"); print "\t\tBC = (BC & 255) | ((HL & 255) << 8);\n";
199 &case
(0x46, "LD B,(HL)"); print "\t\tSethreg(BC, GetBYTE(HL));\n";
200 &case
(0x47, "LD B,A"); print "\t\tBC = (BC & 255) | (AF & ~255);\n";
201 &case
(0x48, "LD C,B"); print "\t\tBC = (BC & ~255) | ((BC >> 8) & 255);\n";
202 &case
(0x49, "LD C,C"); print "\t\t/* nop */\n";
203 &case
(0x4A, "LD C,D"); print "\t\tBC = (BC & ~255) | ((DE >> 8) & 255);\n";
204 &case
(0x4B, "LD C,E"); print "\t\tBC = (BC & ~255) | (DE & 255);\n";
205 &case
(0x4C, "LD C,H"); print "\t\tBC = (BC & ~255) | ((HL >> 8) & 255);\n";
206 &case
(0x4D, "LD C,L"); print "\t\tBC = (BC & ~255) | (HL & 255);\n";
207 &case
(0x4E, "LD C,(HL)"); print "\t\tSetlreg(BC, GetBYTE(HL));\n";
208 &case
(0x4F, "LD C,A"); print "\t\tBC = (BC & ~255) | ((AF >> 8) & 255);\n";
209 &case
(0x50, "LD D,B"); print "\t\tDE = (DE & 255) | (BC & ~255);\n";
210 &case
(0x51, "LD D,C"); print "\t\tDE = (DE & 255) | ((BC & 255) << 8);\n";
211 &case
(0x52, "LD D,D"); print "\t\t/* nop */\n";
212 &case
(0x53, "LD D,E"); print "\t\tDE = (DE & 255) | ((DE & 255) << 8);\n";
213 &case
(0x54, "LD D,H"); print "\t\tDE = (DE & 255) | (HL & ~255);\n";
214 &case
(0x55, "LD D,L"); print "\t\tDE = (DE & 255) | ((HL & 255) << 8);\n";
215 &case
(0x56, "LD D,(HL)"); print "\t\tSethreg(DE, GetBYTE(HL));\n";
216 &case
(0x57, "LD D,A"); print "\t\tDE = (DE & 255) | (AF & ~255);\n";
217 &case
(0x58, "LD E,B"); print "\t\tDE = (DE & ~255) | ((BC >> 8) & 255);\n";
218 &case
(0x59, "LD E,C"); print "\t\tDE = (DE & ~255) | (BC & 255);\n";
219 &case
(0x5A, "LD E,D"); print "\t\tDE = (DE & ~255) | ((DE >> 8) & 255);\n";
220 &case
(0x5B, "LD E,E"); print "\t\t/* nop */\n";
221 &case
(0x5C, "LD E,H"); print "\t\tDE = (DE & ~255) | ((HL >> 8) & 255);\n";
222 &case
(0x5D, "LD E,L"); print "\t\tDE = (DE & ~255) | (HL & 255);\n";
223 &case
(0x5E, "LD E,(HL)"); print "\t\tSetlreg(DE, GetBYTE(HL));\n";
224 &case
(0x5F, "LD E,A"); print "\t\tDE = (DE & ~255) | ((AF >> 8) & 255);\n";
225 &case
(0x60, "LD H,B"); print "\t\tHL = (HL & 255) | (BC & ~255);\n";
226 &case
(0x61, "LD H,C"); print "\t\tHL = (HL & 255) | ((BC & 255) << 8);\n";
227 &case
(0x62, "LD H,D"); print "\t\tHL = (HL & 255) | (DE & ~255);\n";
228 &case
(0x63, "LD H,E"); print "\t\tHL = (HL & 255) | ((DE & 255) << 8);\n";
229 &case
(0x64, "LD H,H"); print "\t\t/* nop */\n";
230 &case
(0x65, "LD H,L"); print "\t\tHL = (HL & 255) | ((HL & 255) << 8);\n";
231 &case
(0x66, "LD H,(HL)"); print "\t\tSethreg(HL, GetBYTE(HL));\n";
232 &case
(0x67, "LD H,A"); print "\t\tHL = (HL & 255) | (AF & ~255);\n";
233 &case
(0x68, "LD L,B"); print "\t\tHL = (HL & ~255) | ((BC >> 8) & 255);\n";
234 &case
(0x69, "LD L,C"); print "\t\tHL = (HL & ~255) | (BC & 255);\n";
235 &case
(0x6A, "LD L,D"); print "\t\tHL = (HL & ~255) | ((DE >> 8) & 255);\n";
236 &case
(0x6B, "LD L,E"); print "\t\tHL = (HL & ~255) | (DE & 255);\n";
237 &case
(0x6C, "LD L,H"); print "\t\tHL = (HL & ~255) | ((HL >> 8) & 255);\n";
238 &case
(0x6D, "LD L,L"); print "\t\t/* nop */\n";
239 &case
(0x6E, "LD L,(HL)"); print "\t\tSetlreg(HL, GetBYTE(HL));\n";
240 &case
(0x6F, "LD L,A"); print "\t\tHL = (HL & ~255) | ((AF >> 8) & 255);\n";
241 &case
(0x70, "LD (HL),B"); print "\t\tPutBYTE(HL, hreg(BC));\n";
242 &case
(0x71, "LD (HL),C"); print "\t\tPutBYTE(HL, lreg(BC));\n";
243 &case
(0x72, "LD (HL),D"); print "\t\tPutBYTE(HL, hreg(DE));\n";
244 &case
(0x73, "LD (HL),E"); print "\t\tPutBYTE(HL, lreg(DE));\n";
245 &case
(0x74, "LD (HL),H"); print "\t\tPutBYTE(HL, hreg(HL));\n";
246 &case
(0x75, "LD (HL),L"); print "\t\tPutBYTE(HL, lreg(HL));\n";
247 &case
(0x76, "HALT"); print "\t\tSAVE_STATE();\n\t\treturn PC&0xffff;\n"; $needbreak = 0;
248 &case
(0x77, "LD (HL),A"); print "\t\tPutBYTE(HL, hreg(AF));\n";
249 &case
(0x78, "LD A,B"); print "\t\tAF = (AF & 255) | (BC & ~255);\n";
250 &case
(0x79, "LD A,C"); print "\t\tAF = (AF & 255) | ((BC & 255) << 8);\n";
251 &case
(0x7A, "LD A,D"); print "\t\tAF = (AF & 255) | (DE & ~255);\n";
252 &case
(0x7B, "LD A,E"); print "\t\tAF = (AF & 255) | ((DE & 255) << 8);\n";
253 &case
(0x7C, "LD A,H"); print "\t\tAF = (AF & 255) | (HL & ~255);\n";
254 &case
(0x7D, "LD A,L"); print "\t\tAF = (AF & 255) | ((HL & 255) << 8);\n";
255 &case
(0x7E, "LD A,(HL)"); print "\t\tSethreg(AF, GetBYTE(HL));\n";
256 &case
(0x7F, "LD A,A"); print "\t\t/* nop */\n";
257 &case
(0x80, "ADD A,B"); &ADDAr
("hreg(BC)");
258 &case
(0x81, "ADD A,C"); &ADDAr
("lreg(BC)");
259 &case
(0x82, "ADD A,D"); &ADDAr
("hreg(DE)");
260 &case
(0x83, "ADD A,E"); &ADDAr
("lreg(DE)");
261 &case
(0x84, "ADD A,H"); &ADDAr
("hreg(HL)");
262 &case
(0x85, "ADD A,L"); &ADDAr
("lreg(HL)");
263 &case
(0x86, "ADD A,(HL)"); &ADDAr
("GetBYTE(HL)");
264 &case
(0x87, "ADD A,A"); &ADDAr
("hreg(AF)");
265 &case
(0x88, "ADC A,B"); &ADCAr
("hreg(BC)");
266 &case
(0x89, "ADC A,C"); &ADCAr
("lreg(BC)");
267 &case
(0x8A, "ADC A,D"); &ADCAr
("hreg(DE)");
268 &case
(0x8B, "ADC A,E"); &ADCAr
("lreg(DE)");
269 &case
(0x8C, "ADC A,H"); &ADCAr
("hreg(HL)");
270 &case
(0x8D, "ADC A,L"); &ADCAr
("lreg(HL)");
271 &case
(0x8E, "ADC A,(HL)"); &ADCAr
("GetBYTE(HL)");
272 &case
(0x8F, "ADC A,A"); &ADCAr
("hreg(AF)");
273 &case
(0x90, "SUB B"); &SUBAr
("hreg(BC)");
274 &case
(0x91, "SUB C"); &SUBAr
("lreg(BC)");
275 &case
(0x92, "SUB D"); &SUBAr
("hreg(DE)");
276 &case
(0x93, "SUB E"); &SUBAr
("lreg(DE)");
277 &case
(0x94, "SUB H"); &SUBAr
("hreg(HL)");
278 &case
(0x95, "SUB L"); &SUBAr
("lreg(HL)");
279 &case
(0x96, "SUB (HL)"); &SUBAr
("GetBYTE(HL)");
280 &case
(0x97, "SUB A"); &SUBAr
("hreg(AF)");
281 &case
(0x98, "SBC A,B"); &SBCAr
("hreg(BC)");
282 &case
(0x99, "SBC A,C"); &SBCAr
("lreg(BC)");
283 &case
(0x9A, "SBC A,D"); &SBCAr
("hreg(DE)");
284 &case
(0x9B, "SBC A,E"); &SBCAr
("lreg(DE)");
285 &case
(0x9C, "SBC A,H"); &SBCAr
("hreg(HL)");
286 &case
(0x9D, "SBC A,L"); &SBCAr
("lreg(HL)");
287 &case
(0x9E, "SBC A,(HL)"); &SBCAr
("GetBYTE(HL)");
288 &case
(0x9F, "SBC A,A"); &SBCAr
("hreg(AF)");
289 &case
(0xA0, "AND B"); &ANDAh
("&", "BC");
290 &case
(0xA1, "AND C"); &ANDAl
("&", "BC");
291 &case
(0xA2, "AND D"); &ANDAh
("&", "DE");
292 &case
(0xA3, "AND E"); &ANDAl
("&", "DE");
293 &case
(0xA4, "AND H"); &ANDAh
("&", "HL");
294 &case
(0xA5, "AND L"); &ANDAl
("&", "HL");
295 &case
(0xA6, "AND (HL)"); &ANDAl
("&", "GetBYTE(HL)");
296 &case
(0xA7, "AND A"); &ANDAh
("&", "AF");
297 &case
(0xA8, "XOR B"); &LOGAh
("^", "BC");
298 &case
(0xA9, "XOR C"); &LOGAl
("^", "BC");
299 &case
(0xAA, "XOR D"); &LOGAh
("^", "DE");
300 &case
(0xAB, "XOR E"); &LOGAl
("^", "DE");
301 &case
(0xAC, "XOR H"); &LOGAh
("^", "HL");
302 &case
(0xAD, "XOR L"); &LOGAl
("^", "HL");
303 &case
(0xAE, "XOR (HL)"); &LOGAl
("^", "GetBYTE(HL)");
304 &case
(0xAF, "XOR A"); &LOGAh
("^", "AF");
305 &case
(0xB0, "OR B"); &LOGAh
("|", "BC");
306 &case
(0xB1, "OR C"); &LOGAl
("|", "BC");
307 &case
(0xB2, "OR D"); &LOGAh
("|", "DE");
308 &case
(0xB3, "OR E"); &LOGAl
("|", "DE");
309 &case
(0xB4, "OR H"); &LOGAh
("|", "HL");
310 &case
(0xB5, "OR L"); &LOGAl
("|", "HL");
311 &case
(0xB6, "OR (HL)"); &LOGAl
("|", "GetBYTE(HL)");
312 &case
(0xB7, "OR A"); &LOGAh
("|", "AF");
313 &case
(0xB8, "CP B"); &CPAr
("hreg(BC)");
314 &case
(0xB9, "CP C"); &CPAr
("lreg(BC)");
315 &case
(0xBA, "CP D"); &CPAr
("hreg(DE)");
316 &case
(0xBB, "CP E"); &CPAr
("lreg(DE)");
317 &case
(0xBC, "CP H"); &CPAr
("hreg(HL)");
318 &case
(0xBD, "CP L"); &CPAr
("lreg(HL)");
319 &case
(0xBE, "CP (HL)"); &CPAr
("GetBYTE(HL)");
320 &case
(0xBF, "CP A"); &CPAr
("hreg(AF)");
321 &case
(0xC0, "RET NZ"); print "\t\tif (!TSTFLAG(Z)) POP(PC);\n";
322 &case
(0xC1, "POP BC"); print "\t\tPOP(BC);\n";
323 &case
(0xC2, "JP NZ,nnnn"); print "\t\tJPC(!TSTFLAG(Z));\n";
324 &case
(0xC3, "JP nnnn"); print "\t\tJPC(1);\n";
325 &case
(0xC4, "CALL NZ,nnnn"); print "\t\tCALLC(!TSTFLAG(Z));\n";
326 &case
(0xC5, "PUSH BC"); print "\t\tPUSH(BC);\n";
327 &case
(0xC6, "ADD A,nn"); &ADDAr
("GetBYTE(PC)"); print "\t\t++PC;\n";
328 &case
(0xC7, "RST 0"); print "\t\tPUSH(PC); PC = 0;\n";
329 &case
(0xC8, "RET Z"); print "\t\tif (TSTFLAG(Z)) POP(PC);\n";
330 &case
(0xC9, "RET"); print "\t\tPOP(PC);\n";
331 &case
(0xCA, "JP Z,nnnn"); print "\t\tJPC(TSTFLAG(Z));\n";
332 &case
(0xCB, "CB prefix"); &CB
("HL");
333 &case
(0xCC, "CALL Z,nnnn"); print "\t\tCALLC(TSTFLAG(Z));\n";
334 &case
(0xCD, "CALL nnnn"); print "\t\tCALLC(1);\n";
335 &case
(0xCE, "ADC A,nn"); &ADCAr
("GetBYTE(PC)"); print "\t\t++PC;\n";
336 &case
(0xCF, "RST 8"); print "\t\tPUSH(PC); PC = 8;\n";
337 &case
(0xD0, "RET NC"); print "\t\tif (!TSTFLAG(C)) POP(PC);\n";
338 &case
(0xD1, "POP DE"); print "\t\tPOP(DE);\n";
339 &case
(0xD2, "JP NC,nnnn"); print "\t\tJPC(!TSTFLAG(C));\n";
340 &case
(0xD3, "OUT (nn),A"); print "\t\tOutput(GetBYTE(PC), hreg(AF)); ++PC;\n";
341 &case
(0xD4, "CALL NC,nnnn"); print "\t\tCALLC(!TSTFLAG(C));\n";
342 &case
(0xD5, "PUSH DE"); print "\t\tPUSH(DE);\n";
343 &case
(0xD6, "SUB nn"); &SUBAr
("GetBYTE(PC)"); print "\t\t++PC;\n";
344 &case
(0xD7, "RST 10H"); print "\t\tPUSH(PC); PC = 0x10;\n";
345 &case
(0xD8, "RET C"); print "\t\tif (TSTFLAG(C)) POP(PC);\n";
346 &case
(0xD9, "EXX"); print <<"EOT";
347 regs[regs_sel].bc = BC;
348 regs[regs_sel].de = DE;
349 regs[regs_sel].hl = HL;
350 regs_sel = 1 - regs_sel;
351 BC = regs[regs_sel].bc;
352 DE = regs[regs_sel].de;
353 HL = regs[regs_sel].hl;
355 &case
(0xDA, "JP C,nnnn"); print "\t\tJPC(TSTFLAG(C));\n";
356 &case
(0xDB, "IN A,(nn)"); print "\t\tSethreg(AF, Input(GetBYTE(PC))); ++PC;\n";
357 &case
(0xDC, "CALL C,nnnn"); print "\t\tCALLC(TSTFLAG(C));\n";
358 &case
(0xDD, "DD prefix"); $dfd_inline ?
&DFD
("IX") : &DFD
("ix");
359 &case
(0xDE, "SBC A,nn"); &SBCAr
("GetBYTE(PC)"); print "\t\t++PC;\n";
360 &case
(0xDF, "RST 18H"); print "\t\tPUSH(PC); PC = 0x18;\n";
361 &case
(0xE0, "RET PO"); print "\t\tif (!TSTFLAG(P)) POP(PC);\n";
362 &case
(0xE1, "POP HL"); print "\t\tPOP(HL);\n";
363 &case
(0xE2, "JP PO,nnnn"); print "\t\tJPC(!TSTFLAG(P));\n";
364 &case
(0xE3, "EX (SP),HL"); print "\t\ttemp = HL; POP(HL); PUSH(temp);\n";
365 &case
(0xE4, "CALL PO,nnnn"); print "\t\tCALLC(!TSTFLAG(P));\n";
366 &case
(0xE5, "PUSH HL"); print "\t\tPUSH(HL);\n";
367 &case
(0xE6, "AND nn"); &ANDAl
("&", "GetBYTE(PC)"); print "\t\t++PC;\n";
368 &case
(0xE7, "RST 20H"); print "\t\tPUSH(PC); PC = 0x20;\n";
369 &case
(0xE8, "RET PE"); print "\t\tif (TSTFLAG(P)) POP(PC);\n";
370 &case
(0xE9, "JP (HL)"); print "\t\tPC = HL;\n";
371 &case
(0xEA, "JP PE,nnnn"); print "\t\tJPC(TSTFLAG(P));\n";
372 &case
(0xEB, "EX DE,HL"); print "\t\ttemp = HL; HL = DE; DE = temp;\n";
373 &case
(0xEC, "CALL PE,nnnn"); print "\t\tCALLC(TSTFLAG(P));\n";
374 &case
(0xED, "ED prefix"); &ED
("HL");
375 &case
(0xEE, "XOR nn"); &LOGAl
("^", "GetBYTE(PC)"); print "\t\t++PC;\n";
376 &case
(0xEF, "RST 28H"); print "\t\tPUSH(PC); PC = 0x28;\n";
377 &case
(0xF0, "RET P"); print "\t\tif (!TSTFLAG(S)) POP(PC);\n";
378 &case
(0xF1, "POP AF"); print "\t\tPOP(AF);\n";
379 &case
(0xF2, "JP P,nnnn"); print "\t\tJPC(!TSTFLAG(S));\n";
380 &case
(0xF3, "DI"); print "\t\tIFF = 0;\n";
381 &case
(0xF4, "CALL P,nnnn"); print "\t\tCALLC(!TSTFLAG(S));\n";
382 &case
(0xF5, "PUSH AF"); print "\t\tPUSH(AF);\n";
383 &case
(0xF6, "OR nn"); &LOGAl
("|", "GetBYTE(PC)"); print "\t\t++PC;\n";
384 &case
(0xF7, "RST 30H"); print "\t\tPUSH(PC); PC = 0x30;\n";
385 &case
(0xF8, "RET M"); print "\t\tif (TSTFLAG(S)) POP(PC);\n";
386 &case
(0xF9, "LD SP,HL"); print "\t\tSP = HL;\n";
387 &case
(0xFA, "JP M,nnnn"); print "\t\tJPC(TSTFLAG(S));\n";
388 &case
(0xFB, "EI"); print "\t\tIFF = 3;\n";
389 &case
(0xFC, "CALL M,nnnn"); print "\t\tCALLC(TSTFLAG(S));\n";
390 &case
(0xFD, "FD prefix"); $dfd_inline ?
&DFD
("IY") : &DFD
("iy");
391 &case
(0xFE, "CP nn"); &CPAr
("GetBYTE(PC)"); print "\t\t++PC;\n";
392 &case
(0xFF, "RST 38H"); print "\t\tPUSH(PC); PC = 0x38;\n";
397 local($op,$cmnt) = @_;
399 print $optab ?
"${tab}\tcontinue;\n" : "${tab}\tbreak;\n";
402 printf("${tab}case 0x%02X:\t\t\t/* $cmnt */\n", $op) if !$optab;
403 printf("${tab}op_%02x:\t\t\t/* $cmnt */\n", $op) if $optab;
408 print "${tab}\tPC += ($cond) ? (signed char) GetBYTE(PC) + 1 : 1;\n";
412 local($reg,$which) = @_;
413 print "${tab}\ttemp = GetWORD(PC);\n";
414 print "${tab}\tPutBYTE(temp, ${which}reg($reg));\n";
415 if ($combine && $labpcp2) {
416 print "${tab}\tgoto labpcp2;\n";
421 print "${tab}labpcp2:\n" if $combine;
422 print "${tab}\tPC += 2;\n";
427 local($reg,$which) = @_;
428 print "${tab}\ttemp = GetWORD(PC);\n";
429 print "${tab}\tSet${which}reg($reg, GetBYTE(temp));\n";
430 if ($combine && $labpcp2) {
431 print "${tab}\tgoto labpcp2;\n";
436 print "${tab}labpcp2:\n" if $combine;
437 print "${tab}\tPC += 2;\n";
443 print "${tab}\ttemp = GetWORD(PC);\n";
444 print "${tab}\t$reg = GetWORD(temp);\n";
445 if ($combine && $labpcp2) {
446 print "${tab}\tgoto labpcp2;\n";
451 print "${tab}labpcp2:\n" if $combine;
452 print "${tab}\tPC += 2;\n";
458 print "${tab}\ttemp = GetWORD(PC);\n";
459 print "${tab}\tPutWORD(temp, $reg);\n";
460 if ($combine && $labpcp2) {
461 print "${tab}\tgoto labpcp2;\n";
466 print "${tab}labpcp2:\n" if $combine;
467 print "${tab}\tPC += 2;\n";
473 print "${tab}\t$reg = GetWORD(PC);\n";
474 if ($combine && $labpcp2) {
475 print "${tab}\tgoto labpcp2;\n";
480 print "${tab}labpcp2:\n" if $combine;
481 print "${tab}\tPC += 2;\n";
486 local($reg,$which) = @_;
488 print "${tab}\t$reg += 0x100;\n${tab}\ttemp = hreg($reg);\n";
491 print "${tab}\ttemp = ${which}reg($reg)+1;\n${tab}\tSet${which}reg($reg, temp);\n";
493 if ($combine && $labincr) {
494 print "${tab}\tgoto labincr;\n";
499 print "${tab}labincr:\n" if $combine;
501 $tab AF = (AF & ~0xfe) | (temp & 0xa8) |
502 $tab (((temp & 0xff) == 0) << 6) |
503 $tab (((temp & 0xf) == 0) << 4) |
504 $tab ((temp == 0x80) << 2);
511 print "${tab}\ttemp = GetBYTE($reg)+1;\n${tab}\tPutBYTE($reg, temp);\n";
512 if ($combine && $labincr) {
513 print "${tab}\tgoto labincr;\n";
518 print "${tab}labincr:\n" if $combine;
520 $tab AF = (AF & ~0xfe) | (temp & 0xa8) |
521 $tab (((temp & 0xff) == 0) << 6) |
522 $tab (((temp & 0xf) == 0) << 4) |
523 $tab ((temp == 0x80) << 2);
529 local($reg,$which) = @_;
531 print "${tab}\t$reg -= 0x100;\n${tab}\ttemp = hreg($reg);\n";
534 print "${tab}\ttemp = ${which}reg($reg)-1;\n${tab}\tSet${which}reg($reg, temp);\n";
536 if ($combine && $labdecr) {
537 print "${tab}\tgoto labdecr;\n";
542 print "${tab}labdecr:\n" if $combine;
544 $tab AF = (AF & ~0xfe) | (temp & 0xa8) |
545 $tab (((temp & 0xff) == 0) << 6) |
546 $tab (((temp & 0xf) == 0xf) << 4) |
547 $tab ((temp == 0x7f) << 2) | 2;
554 print "${tab}\ttemp = GetBYTE($reg)-1;\n${tab}\tPutBYTE($reg, temp);\n";
555 if ($combine && $labdecr) {
556 print "${tab}\tgoto labdecr;\n";
561 print "${tab}labdecr:\n" if $combine;
563 $tab AF = (AF & ~0xfe) | (temp & 0xa8) |
564 $tab (((temp & 0xff) == 0) << 6) |
565 $tab (((temp & 0xf) == 0xf) << 4) |
566 $tab ((temp == 0x7f) << 2) | 2;
573 print "${tab}\ttemp = $val;\n";
574 if ($combine && $labaddar) {
575 print "${tab}\tgoto labaddar;\n";
580 print "${tab}labaddar:\n" if $combine;
583 $tab sum = acu + temp;
584 $tab cbits = acu ^ temp ^ sum;
585 $tab AF = ((sum & 0xff) << 8) | (sum & 0xa8) |
586 $tab (((sum & 0xff) == 0) << 6) | (cbits & 0x10) |
587 $tab (((cbits >> 6) ^ (cbits >> 5)) & 4) |
588 $tab ((cbits >> 8) & 1);
595 print "${tab}\ttemp = $val;\n";
596 if ($combine && $labadcar) {
597 print "${tab}\tgoto labadcar;\n";
602 print "${tab}labadcar:\n" if $combine;
605 $tab sum = acu + temp + TSTFLAG(C);
606 $tab cbits = acu ^ temp ^ sum;
607 $tab AF = ((sum & 0xff) << 8) | (sum & 0xa8) |
608 $tab (((sum & 0xff) == 0) << 6) | (cbits & 0x10) |
609 $tab (((cbits >> 6) ^ (cbits >> 5)) & 4) |
610 $tab ((cbits >> 8) & 1);
617 print "${tab}\ttemp = $val;\n";
618 if ($combine && $labsubar) {
619 print "${tab}\tgoto labsubar;\n";
624 print "${tab}labsubar:\n" if $combine;
627 $tab sum = acu - temp;
628 $tab cbits = acu ^ temp ^ sum;
629 $tab AF = ((sum & 0xff) << 8) | (sum & 0xa8) |
630 $tab (((sum & 0xff) == 0) << 6) | (cbits & 0x10) |
631 $tab (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 |
632 $tab ((cbits >> 8) & 1);
639 print "${tab}\ttemp = $val;\n";
640 if ($combine && $labsbcar) {
641 print "${tab}\tgoto labsbcar;\n";
646 print "${tab}labsbcar:\n" if $combine;
649 $tab sum = acu - temp - TSTFLAG(C);
650 $tab cbits = acu ^ temp ^ sum;
651 $tab AF = ((sum & 0xff) << 8) | (sum & 0xa8) |
652 $tab (((sum & 0xff) == 0) << 6) | (cbits & 0x10) |
653 $tab (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 |
654 $tab ((cbits >> 8) & 1);
660 local($op, $reg) = @_;
661 print "${tab}\tsum = ((AF $op ($reg)) >> 8) & 0xff;\n";
662 if ($combine && $labandar) {
663 print "${tab}\tgoto labandar;\n";
668 print "${tab}labandar:\n" if $combine;
669 print "${tab}\tAF = (sum << 8) | (sum & 0xa8) |\n";
670 print "${tab}\t\t((sum == 0) << 6) | 0x10 | partab[sum];\n";
675 local($op, $reg) = @_;
676 print "${tab}\tsum = ((AF >> 8) $op $reg) & 0xff;\n";
677 if ($combine && $labandar) {
678 print "${tab}\tgoto labandar;\n";
683 print "${tab}labandar:\n" if $combine;
684 print "${tab}\tAF = (sum << 8) | (sum & 0xa8) | 0x10 |\n";
685 print "${tab}\t\t((sum == 0) << 6) | partab[sum];\n";
690 local($op, $reg) = @_;
691 print "${tab}\tsum = ((AF $op ($reg)) >> 8) & 0xff;\n";
692 if ($combine && $lablogar) {
693 print "${tab}\tgoto lablogar;\n";
698 print "${tab}lablogar:\n" if $combine;
700 "${tab}\tAF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum];\n";
705 local($op, $reg) = @_;
706 print "${tab}\tsum = ((AF >> 8) $op $reg) & 0xff;\n";
707 if ($combine && $lablogar) {
708 print "${tab}\tgoto lablogar;\n";
713 print "${tab}lablogar:\n" if $combine;
715 "${tab}\tAF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum];\n";
721 print "${tab}\ttemp = $reg;\n";
722 print "${tab}\tAF = (AF & ~0x28) | (temp & 0x28);\n";
723 if ($combine && $labcpar) {
724 print "${tab}\tgoto labcpar;\n";
729 print "${tab}labcpar:\n" if $combine;
732 $tab sum = acu - temp;
733 $tab cbits = acu ^ temp ^ sum;
734 $tab AF = (AF & ~0xff) | (sum & 0x80) |
735 $tab (((sum & 0xff) == 0) << 6) | (temp & 0x28) |
736 $tab (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 |
737 $tab (cbits & 0x10) | ((cbits >> 8) & 1);
744 print "${tab}\t$r1 &= 0xffff;\n" if ($r1 ne $r2);
747 $tab sum = $r1 + $r2;
748 $tab cbits = ($r1 ^ $r2 ^ sum) >> 8;
751 if ($combine && $labadddd) {
752 print "${tab}\tgoto labadddd;\n";
757 print "${tab}labadddd:\n" if $combine;
759 $tab AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) |
760 $tab (cbits & 0x10) | ((cbits >> 8) & 1);
767 print "${tab}\t$r1 &= 0xffff;\n" if ($r1 ne $r2);
770 $tab sum = $r1 + $r2 + TSTFLAG(C);
771 $tab cbits = ($r1 ^ $r2 ^ sum) >> 8;
774 if ($combine && $labadcdd) {
775 print "${tab}\tgoto labadcdd;\n";
780 print "${tab}labadcdd:\n" if $combine;
782 $tab AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) |
783 $tab (((sum & 0xffff) == 0) << 6) |
784 $tab (((cbits >> 6) ^ (cbits >> 5)) & 4) |
785 $tab (cbits & 0x10) | ((cbits >> 8) & 1);
792 print "${tab}\t$r1 &= 0xffff;\n" if ($r1 ne $r2);
795 $tab sum = $r1 - $r2 - TSTFLAG(C);
796 $tab cbits = ($r1 ^ $r2 ^ sum) >> 8;
799 if ($combine && $labsbcdd) {
800 print "${tab}\tgoto labsbcdd;\n";
805 print "${tab}labsbcdd:\n" if $combine;
807 $tab AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) |
808 $tab (((sum & 0xffff) == 0) << 6) |
809 $tab (((cbits >> 6) ^ (cbits >> 5)) & 4) |
810 $tab (cbits & 0x10) | 2 | ((cbits >> 8) & 1);
816 local($reg,$which) = @_;
818 $tab temp = Input(lreg(BC));
819 $tab Set${which}reg($reg, temp);
820 $tab AF = (AF & ~0xfe) | (temp & 0xa8) |
821 $tab (((temp & 0xff) == 0) << 6) |
827 local($reg,$which) = @_;
829 $tab Output(lreg(BC), $reg);
836 print "${tab}\tadr = $reg;\n";
842 $tab cb_prefix($reg);
849 local($optabsav) = $optab;
853 $tab switch ((op = GetBYTE(PC)) & 7) {
854 $tab case 0: ++PC; acu = hreg(BC); break;
855 $tab case 1: ++PC; acu = lreg(BC); break;
856 $tab case 2: ++PC; acu = hreg(DE); break;
857 $tab case 3: ++PC; acu = lreg(DE); break;
858 $tab case 4: ++PC; acu = hreg(HL); break;
859 $tab case 5: ++PC; acu = lreg(HL); break;
860 $tab case 6: ++PC; acu = GetBYTE(adr); break;
861 $tab case 7: ++PC; acu = hreg(AF); break;
863 $tab switch (op & 0xc0) {
864 $tab case 0x00: /* shift/rotate */
865 $tab switch (op & 0x38) {
866 $tab case 0x00: /* RLC */
867 $tab temp = (acu << 1) | (acu >> 7);
868 $tab cbits = temp & 1;
869 $tab goto cbshflg$cblabno;
870 $tab case 0x08: /* RRC */
871 $tab temp = (acu >> 1) | (acu << 7);
872 $tab cbits = temp & 0x80;
873 $tab goto cbshflg$cblabno;
874 $tab case 0x10: /* RL */
875 $tab temp = (acu << 1) | TSTFLAG(C);
876 $tab cbits = acu & 0x80;
877 $tab goto cbshflg$cblabno;
878 $tab case 0x18: /* RR */
879 $tab temp = (acu >> 1) | (TSTFLAG(C) << 7);
880 $tab cbits = acu & 1;
881 $tab goto cbshflg$cblabno;
882 $tab case 0x20: /* SLA */
883 $tab temp = acu << 1;
884 $tab cbits = acu & 0x80;
885 $tab goto cbshflg$cblabno;
886 $tab case 0x28: /* SRA */
887 $tab temp = (acu >> 1) | (acu & 0x80);
888 $tab cbits = acu & 1;
889 $tab goto cbshflg$cblabno;
890 $tab case 0x30: /* SLIA */
891 $tab temp = (acu << 1) | 1;
892 $tab cbits = acu & 0x80;
893 $tab goto cbshflg$cblabno;
894 $tab case 0x38: /* SRL */
895 $tab temp = acu >> 1;
896 $tab cbits = acu & 1;
897 $tab cbshflg$cblabno:
898 $tab AF = (AF & ~0xff) | (temp & 0xa8) |
899 $tab (((temp & 0xff) == 0) << 6) |
900 $tab parity(temp) | !!cbits;
903 $tab case 0x40: /* BIT */
904 $tab if (acu & (1 << ((op >> 3) & 7)))
905 $tab AF = (AF & ~0xfe) | 0x10 |
906 $tab (((op & 0x38) == 0x38) << 7);
908 $tab AF = (AF & ~0xfe) | 0x54;
909 $tab if ((op&7) != 6)
910 $tab AF |= (acu & 0x28);
913 $tab case 0x80: /* RES */
914 $tab temp = acu & ~(1 << ((op >> 3) & 7));
916 $tab case 0xc0: /* SET */
917 $tab temp = acu | (1 << ((op >> 3) & 7));
920 $tab switch (op & 7) {
921 $tab case 0: Sethreg(BC, temp); break;
922 $tab case 1: Setlreg(BC, temp); break;
923 $tab case 2: Sethreg(DE, temp); break;
924 $tab case 3: Setlreg(DE, temp); break;
925 $tab case 4: Sethreg(HL, temp); break;
926 $tab case 5: Setlreg(HL, temp); break;
927 $tab case 6: PutBYTE(adr, temp); break;
928 $tab case 7: Sethreg(AF, temp); break;
943 $tab $reg = dfd_prefix($reg);
951 print "${tab}\tadr = $reg + (signed char) GetBYTE(PC); ++PC;\n";
956 local($optabsav) = $optab;
958 print "${tab}\tswitch (++PC, op = GetBYTE(PC-1)) {\n";
961 &case
(0x09, "ADD $reg,BC"); &ADDdd
($reg, BC
);
962 &case
(0x19, "ADD $reg,DE"); &ADDdd
($reg, DE
);
963 &case
(0x21, "LD $reg,nnnn"); &LDddnn
($reg);
964 &case
(0x22, "LD (nnnn),$reg"); &LDmemdd
($reg);
965 &case
(0x23, "INC $reg"); print "${tab}\t++$reg;\n";
966 &case
(0x24, "INC ${reg}H"); &INCr
($reg, "h");
967 &case
(0x25, "DEC ${reg}H"); &DECr
($reg, "h");
968 &case
(0x26, "LD ${reg}H,nn"); print "${tab}\tSethreg($reg, GetBYTE(PC)); ++PC;\n";
969 &case
(0x29, "ADD $reg,$reg"); &ADDdd
($reg, $reg);
970 &case
(0x2A, "LD $reg,(nnnn)"); &LDddmem
($reg);
971 &case
(0x2B, "DEC $reg"); print "${tab}\t--$reg;\n";
972 &case
(0x2C, "INC ${reg}L"); &INCr
($reg, "l");
973 &case
(0x2D, "DEC ${reg}L"); &DECr
($reg, "l");
974 &case
(0x2E, "LD ${reg}L,nn"); print "${tab}\tSetlreg($reg, GetBYTE(PC)); ++PC;\n";
975 &case
(0x34, "INC ($reg+dd)"); &Offsadr
($reg); &INCm
("adr");
976 &case
(0x35, "DEC ($reg+dd)"); &Offsadr
($reg); &DECm
("adr");
977 &case
(0x36, "LD ($reg+dd),nn"); &Offsadr
($reg); print "${tab}\tPutBYTE(adr, GetBYTE(PC)); ++PC;\n";
978 &case
(0x39, "ADD $reg,SP"); &ADDdd
($reg, SP
);
979 &case
(0x44, "LD B,${reg}H"); print "${tab}\tSethreg(BC, hreg($reg));\n";
980 &case
(0x45, "LD B,${reg}L"); print "${tab}\tSethreg(BC, lreg($reg));\n";
981 &case
(0x46, "LD B,($reg+dd)"); &Offsadr
($reg); print "${tab}\tSethreg(BC, GetBYTE(adr));\n";
982 &case
(0x4C, "LD C,${reg}H"); print "${tab}\tSetlreg(BC, hreg($reg));\n";
983 &case
(0x4D, "LD C,${reg}L"); print "${tab}\tSetlreg(BC, lreg($reg));\n";
984 &case
(0x4E, "LD C,($reg+dd)"); &Offsadr
($reg); print "${tab}\tSetlreg(BC, GetBYTE(adr));\n";
985 &case
(0x54, "LD D,${reg}H"); print "${tab}\tSethreg(DE, hreg($reg));\n";
986 &case
(0x55, "LD D,${reg}L"); print "${tab}\tSethreg(DE, lreg($reg));\n";
987 &case
(0x56, "LD D,($reg+dd)"); &Offsadr
($reg); print "${tab}\tSethreg(DE, GetBYTE(adr));\n";
988 &case
(0x5C, "LD E,H"); print "${tab}\tSetlreg(DE, hreg($reg));\n";
989 &case
(0x5D, "LD E,L"); print "${tab}\tSetlreg(DE, lreg($reg));\n";
990 &case
(0x5E, "LD E,($reg+dd)"); &Offsadr
($reg); print "${tab}\tSetlreg(DE, GetBYTE(adr));\n";
991 &case
(0x60, "LD ${reg}H,B"); print "${tab}\tSethreg($reg, hreg(BC));\n";
992 &case
(0x61, "LD ${reg}H,C"); print "${tab}\tSethreg($reg, lreg(BC));\n";
993 &case
(0x62, "LD ${reg}H,D"); print "${tab}\tSethreg($reg, hreg(DE));\n";
994 &case
(0x63, "LD ${reg}H,E"); print "${tab}\tSethreg($reg, lreg(DE));\n";
995 &case
(0x64, "LD ${reg}H,${reg}H"); print "${tab}\t/* nop */\n";
996 &case
(0x65, "LD ${reg}H,${reg}L"); print "${tab}\tSethreg($reg, lreg($reg));\n";
997 &case
(0x66, "LD H,($reg+dd)"); &Offsadr
($reg); print "${tab}\tSethreg(HL, GetBYTE(adr));\n";
998 &case
(0x67, "LD ${reg}H,A"); print "${tab}\tSethreg($reg, hreg(AF));\n";
999 &case
(0x68, "LD ${reg}L,B"); print "${tab}\tSetlreg($reg, hreg(BC));\n";
1000 &case
(0x69, "LD ${reg}L,C"); print "${tab}\tSetlreg($reg, lreg(BC));\n";
1001 &case
(0x6A, "LD ${reg}L,D"); print "${tab}\tSetlreg($reg, hreg(DE));\n";
1002 &case
(0x6B, "LD ${reg}L,E"); print "${tab}\tSetlreg($reg, lreg(DE));\n";
1003 &case
(0x6C, "LD ${reg}L,${reg}H"); print "${tab}\tSetlreg($reg, hreg($reg));\n";
1004 &case
(0x6D, "LD ${reg}L,${reg}L"); print "${tab}\t/* nop */\n";
1005 &case
(0x6E, "LD L,($reg+dd)"); &Offsadr
($reg); print "${tab}\tSetlreg(HL, GetBYTE(adr));\n";
1006 &case
(0x6F, "LD ${reg}L,A"); print "${tab}\tSetlreg($reg, hreg(AF));\n";
1007 &case
(0x70, "LD ($reg+dd),B"); &Offsadr
($reg); print "${tab}\tPutBYTE(adr, hreg(BC));\n";
1008 &case
(0x71, "LD ($reg+dd),C"); &Offsadr
($reg); print "${tab}\tPutBYTE(adr, lreg(BC));\n";
1009 &case
(0x72, "LD ($reg+dd),D"); &Offsadr
($reg); print "${tab}\tPutBYTE(adr, hreg(DE));\n";
1010 &case
(0x73, "LD ($reg+dd),E"); &Offsadr
($reg); print "${tab}\tPutBYTE(adr, lreg(DE));\n";
1011 &case
(0x74, "LD ($reg+dd),H"); &Offsadr
($reg); print "${tab}\tPutBYTE(adr, hreg(HL));\n";
1012 &case
(0x75, "LD ($reg+dd),L"); &Offsadr
($reg); print "${tab}\tPutBYTE(adr, lreg(HL));\n";
1013 &case
(0x77, "LD ($reg+dd),A"); &Offsadr
($reg); print "${tab}\tPutBYTE(adr, hreg(AF));\n";
1014 &case
(0x7C, "LD A,${reg}H"); print "${tab}\tSethreg(AF, hreg($reg));\n";
1015 &case
(0x7D, "LD A,${reg}L"); print "${tab}\tSethreg(AF, lreg($reg));\n";
1016 &case
(0x7E, "LD A,($reg+dd)"); &Offsadr
($reg); print "${tab}\tSethreg(AF, GetBYTE(adr));\n";
1017 &case
(0x84, "ADD A,${reg}H"); &ADDAr
("hreg($reg)");
1018 &case
(0x85, "ADD A,${reg}L"); &ADDAr
("lreg($reg)");
1019 &case
(0x86, "ADD A,($reg+dd)"); &Offsadr
($reg); &ADDAr
("GetBYTE(adr)");
1020 &case
(0x8C, "ADC A,${reg}H"); &ADCAr
("hreg($reg)");
1021 &case
(0x8D, "ADC A,${reg}L"); &ADCAr
("lreg($reg)");
1022 &case
(0x8E, "ADC A,($reg+dd)"); &Offsadr
($reg); &ADCAr
("GetBYTE(adr)");
1023 &case
(0x94, "SUB ${reg}H"); &SUBAr
("hreg($reg)");
1024 &case
(0x95, "SUB ${reg}L"); &SUBAr
("lreg($reg)");
1025 &case
(0x96, "SUB ($reg+dd)"); &Offsadr
($reg); &SUBAr
("GetBYTE(adr)");
1026 &case
(0x9C, "SBC A,${reg}H"); &SBCAr
("hreg($reg)");
1027 &case
(0x9D, "SBC A,${reg}L"); &SBCAr
("lreg($reg)");
1028 &case
(0x9E, "SBC A,($reg+dd)"); &Offsadr
($reg); &SBCAr
("GetBYTE(adr)");
1029 &case
(0xA4, "AND ${reg}H"); &ANDAh
("&", "$reg");
1030 &case
(0xA5, "AND ${reg}L"); &ANDAl
("&", "$reg");
1031 &case
(0xA6, "AND ($reg+dd)"); &Offsadr
($reg); &ANDAl
("&", "GetBYTE(adr)");
1032 &case
(0xAC, "XOR ${reg}H"); &LOGAh
("^", "$reg");
1033 &case
(0xAD, "XOR ${reg}L"); &LOGAl
("^", "$reg");
1034 &case
(0xAE, "XOR ($reg+dd)"); &Offsadr
($reg); &LOGAl
("^", "GetBYTE(adr)");
1035 &case
(0xB4, "OR ${reg}H"); &LOGAh
("|", "$reg");
1036 &case
(0xB5, "OR ${reg}L"); &LOGAl
("|", "$reg");
1037 &case
(0xB6, "OR ($reg+dd)"); &Offsadr
($reg); &LOGAl
("|", "GetBYTE(adr)");
1038 &case
(0xBC, "CP ${reg}H"); &CPAr
("hreg($reg)");
1039 &case
(0xBD, "CP ${reg}L"); &CPAr
("lreg($reg)");
1040 &case
(0xBE, "CP ($reg+dd)"); &Offsadr
($reg); &CPAr
("GetBYTE(adr)");
1041 &case
(0xCB, "CB prefix"); &Offsadr
($reg); &CB
("adr");
1042 &case
(0xE1, "POP $reg"); print "${tab}\tPOP($reg);\n";
1043 &case
(0xE3, "EX (SP),$reg"); print "${tab}\ttemp = $reg; POP($reg); PUSH(temp);\n";
1044 &case
(0xE5, "PUSH $reg"); print "${tab}\tPUSH($reg);\n";
1045 &case
(0xE9, "JP ($reg)"); print "${tab}\tPC = $reg;\n";
1046 &case
(0xF9, "LD SP,$reg"); print "${tab}\tSP = $reg;\n";
1047 print "${tab}\tbreak;\n${tab}default: PC--;\t\t/* ignore DD */\n";
1068 local($optabsav) = $optab;
1070 print "${tab}\tswitch (++PC, op = GetBYTE(PC-1)) {\n";
1073 &case
(0x40, "IN B,(C)"); &INP
(BC
, "h");
1074 &case
(0x41, "OUT (C),B"); &OUTP
(BC
, "h");
1075 &case
(0x42, "SBC HL,BC"); &SBCdd
(HL
, BC
);
1076 &case
(0x43, "LD (nnnn),BC"); &LDmemdd
(BC
);
1077 &case
(0x44, "NEG"); print <<"EOT";
1079 AF = (-(AF & 0xff00) & 0xff00);
1080 AF |= ((AF >> 8) & 0xa8) | (((AF & 0xff00) == 0) << 6) |
1081 (((temp & 0x0f) != 0) << 4) | ((temp == 0x80) << 2) |
1084 &case
(0x45, "RETN"); print "\t\t\tIFF |= IFF >> 1;\n\t\t\tPOP(PC);\n";
1085 &case
(0x46, "IM 0"); print "\t\t\t/* interrupt mode 0 */\n";
1086 &case
(0x47, "LD I,A"); print "\t\t\tir = (ir & 255) | (AF & ~255);\n";
1087 &case
(0x48, "IN C,(C)"); &INP
(BC
, "l");
1088 &case
(0x49, "OUT (C),C"); &OUTP
(BC
, "l");
1089 &case
(0x4A, "ADC HL,BC"); &ADCdd
(HL
, BC
);
1090 &case
(0x4B, "LD BC,(nnnn)"); &LDddmem
(BC
);
1091 &case
(0x4D, "RETI"); print "\t\t\tIFF |= IFF >> 1;\n\t\t\tPOP(PC);\n";
1092 &case
(0x4F, "LD R,A"); print "\t\t\tir = (ir & ~255) | ((AF >> 8) & 255);\n";
1093 &case
(0x50, "IN D,(C)"); &INP
(DE
, "h");
1094 &case
(0x51, "OUT (C),D"); &OUTP
(DE
, "h");
1095 &case
(0x52, "SBC HL,DE"); &SBCdd
(HL
, DE
);
1096 &case
(0x53, "LD (nnnn),DE"); &LDmemdd
(DE
);
1097 &case
(0x56, "IM 1"); print "\t\t\t/* interrupt mode 1 */\n";
1098 &case
(0x57, "LD A,I"); print "\t\t\tAF = (AF & 0x29) | (ir & ~255) | ",
1099 "((ir >> 8) & 0x80) | (((ir & ~255) == 0) << 6)",
1100 " | ((IFF & 2) << 1);\n";
1101 &case
(0x58, "IN E,(C)"); &INP
(DE
, "l");
1102 &case
(0x59, "OUT (C),E"); &OUTP
(DE
, "l");
1103 &case
(0x5A, "ADC HL,DE"); &ADCdd
(HL
, DE
);
1104 &case
(0x5B, "LD DE,(nnnn)"); &LDddmem
(DE
);
1105 &case
(0x5E, "IM 2"); print "\t\t\t/* interrupt mode 2 */\n";
1106 &case
(0x5F, "LD A,R"); print "\t\t\tAF = (AF & 0x29) | ((ir & 255) << 8) | ",
1107 "(ir & 0x80) | (((ir & 255) == 0) << 6)",
1108 " | ((IFF & 2) << 1);\n";
1109 &case
(0x60, "IN H,(C)"); &INP
(HL
, "h");
1110 &case
(0x61, "OUT (C),H"); &OUTP
(HL
, "h");
1111 &case
(0x62, "SBC HL,HL"); &SBCdd
(HL
, HL
);
1112 &case
(0x63, "LD (nnnn),HL"); &LDmemdd
(HL
);
1113 &case
(0x67, "RRD"); print <<"EOT";
1116 PutBYTE(HL, hdig(temp) | (ldig(acu) << 4));
1117 acu = (acu & 0xf0) | ldig(temp);
1118 AF = (acu << 8) | (acu & 0xa8) | (((acu & 0xff) == 0) << 6) |
1119 partab[acu] | (AF & 1);
1121 &case
(0x68, "IN L,(C)"); &INP
(HL
, "l");
1122 &case
(0x69, "OUT (C),L"); &OUTP
(HL
, "l");
1123 &case
(0x6A, "ADC HL,HL"); &ADCdd
(HL
, HL
);
1124 &case
(0x6B, "LD HL,(nnnn)"); &LDddmem
(HL
);
1125 &case
(0x6F, "RLD"); print <<"EOT";
1128 PutBYTE(HL, (ldig(temp) << 4) | ldig(acu));
1129 acu = (acu & 0xf0) | hdig(temp);
1130 AF = (acu << 8) | (acu & 0xa8) | (((acu & 0xff) == 0) << 6) |
1131 partab[acu] | (AF & 1);
1133 &case
(0x70, "IN (C)"); &INP
("temp", "l");
1134 &case
(0x71, "OUT (C),0"); &OUTP
(0, "l");
1135 &case
(0x72, "SBC HL,SP"); &SBCdd
(HL
, SP
);
1136 &case
(0x73, "LD (nnnn),SP"); &LDmemdd
(SP
);
1137 &case
(0x78, "IN A,(C)"); &INP
(AF
, "h");
1138 &case
(0x79, "OUT (C),A"); &OUTP
(AF
, "h");
1139 &case
(0x7A, "ADC HL,SP"); &ADCdd
(HL
, SP
);
1140 &case
(0x7B, "LD SP,(nnnn)"); &LDddmem
(SP
);
1141 &case
(0xA0, "LDI"); print <<"EOT";
1142 acu = GetBYTE(HL); ++HL;
1143 PutBYTE(DE, acu); ++DE;
1145 AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) |
1146 (((--BC & 0xffff) != 0) << 2);
1148 &case
(0xA1, "CPI"); print <<"EOT";
1150 temp = GetBYTE(HL); ++HL;
1152 cbits = acu ^ temp ^ sum;
1153 AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
1154 (((sum - ((cbits&16)>>4))&2) << 4) | (cbits & 16) |
1155 ((sum - ((cbits >> 4) & 1)) & 8) |
1156 ((--BC & 0xffff) != 0) << 2 | 2;
1157 if ((sum & 15) == 8 && (cbits & 16) != 0)
1160 &case
(0xA2, "INI"); print <<"EOT";
1161 PutBYTE(HL, Input(lreg(BC))); ++HL;
1163 SETFLAG(P, (--BC & 0xffff) != 0);
1165 &case
(0xA3, "OUTI"); print <<"EOT";
1166 Output(lreg(BC), GetBYTE(HL)); ++HL;
1168 Sethreg(BC, lreg(BC) - 1);
1169 SETFLAG(Z, lreg(BC) == 0);
1171 &case
(0xA8, "LDD"); print <<"EOT";
1172 acu = GetBYTE(HL); --HL;
1173 PutBYTE(DE, acu); --DE;
1175 AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) |
1176 (((--BC & 0xffff) != 0) << 2);
1178 &case
(0xA9, "CPD"); print <<"EOT";
1180 temp = GetBYTE(HL); --HL;
1182 cbits = acu ^ temp ^ sum;
1183 AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
1184 (((sum - ((cbits&16)>>4))&2) << 4) | (cbits & 16) |
1185 ((sum - ((cbits >> 4) & 1)) & 8) |
1186 ((--BC & 0xffff) != 0) << 2 | 2;
1187 if ((sum & 15) == 8 && (cbits & 16) != 0)
1190 &case
(0xAA, "IND"); print <<"EOT";
1191 PutBYTE(HL, Input(lreg(BC))); --HL;
1193 Sethreg(BC, lreg(BC) - 1);
1194 SETFLAG(Z, lreg(BC) == 0);
1196 &case
(0xAB, "OUTD"); print <<"EOT";
1197 Output(lreg(BC), GetBYTE(HL)); --HL;
1199 Sethreg(BC, lreg(BC) - 1);
1200 SETFLAG(Z, lreg(BC) == 0);
1202 &case
(0xB0, "LDIR"); print <<"EOT";
1206 acu = GetBYTE(HL); ++HL;
1207 PutBYTE(DE, acu); ++DE;
1210 AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4);
1212 &case
(0xB1, "CPIR"); print <<"EOT";
1216 temp = GetBYTE(HL); ++HL;
1219 } while (op && sum != 0);
1220 cbits = acu ^ temp ^ sum;
1221 AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
1222 (((sum - ((cbits&16)>>4))&2) << 4) |
1223 (cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) |
1225 if ((sum & 15) == 8 && (cbits & 16) != 0)
1228 &case
(0xB2, "INIR"); print <<"EOT";
1231 PutBYTE(HL, Input(lreg(BC))); ++HL;
1237 &case
(0xB3, "OTIR"); print <<"EOT";
1240 Output(lreg(BC), GetBYTE(HL)); ++HL;
1246 &case
(0xB8, "LDDR"); print <<"EOT";
1249 acu = GetBYTE(HL); --HL;
1250 PutBYTE(DE, acu); --DE;
1253 AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4);
1255 &case
(0xB9, "CPDR"); print <<"EOT";
1259 temp = GetBYTE(HL); --HL;
1262 } while (op && sum != 0);
1263 cbits = acu ^ temp ^ sum;
1264 AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
1265 (((sum - ((cbits&16)>>4))&2) << 4) |
1266 (cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) |
1268 if ((sum & 15) == 8 && (cbits & 16) != 0)
1271 &case
(0xBA, "INDR"); print <<"EOT";
1274 PutBYTE(HL, Input(lreg(BC))); --HL;
1280 &case
(0xBB, "OTDR"); print <<"EOT";
1283 Output(lreg(BC), GetBYTE(HL)); --HL;
1289 print "${tab}\tbreak;\n${tab}default: if (0x40 <= op && op <= 0x7f) PC--;\t\t/* ignore ED */\n";
1311 print "#include \"simz80.h\"\n\n";
1313 print "static const unsigned char partab[256] = {\n";
1315 print "\t" if (($_ & 15) == 0);
1316 $x = ($_>>4) ^ ($_&15);
1317 $x = ($x>>2) ^ ($x&3);
1318 $x = ($x>>1) ^ ($x&1);
1319 print $x ?
"0," : "4,";
1320 print "\n" if (($_ & 15) == 15);
1325 #define parity(x) partab[(x)&0xff]
1328 volatile int stopsim;
1331 #define POP(x) do { \
1332 FASTREG y = RAM(SP); SP++; \
1333 x = y + (RAM(SP) << 8); SP++; \
1336 #define PUSH(x) do { \
1337 --SP; RAM(SP) = (x) >> 8; \
1338 --SP; RAM(SP) = x; \
1341 #define JPC(cond) PC = cond ? GetWORD(PC) : PC+2
1343 #define CALLC(cond) { \
1345 FASTREG adrr = GetWORD(PC); \
1353 /* load Z80 registers into (we hope) host registers */
1354 #define LOAD_STATE() \
1357 BC = regs[regs_sel].bc; \
1358 DE = regs[regs_sel].de; \
1359 HL = regs[regs_sel].hl; \
1370 /* load Z80 registers into (we hope) host registers */
1371 #define DECLARE_STATE() \
1373 FASTREG AF = af[af_sel]; \
1374 FASTREG BC = regs[regs_sel].bc; \
1375 FASTREG DE = regs[regs_sel].de; \
1376 FASTREG HL = regs[regs_sel].hl; \
1387 /* save Z80 registers back into memory */
1388 #define SAVE_STATE() \
1391 regs[regs_sel].bc = BC; \
1392 regs[regs_sel].de = DE; \
1393 regs[regs_sel].hl = HL; \
1409 cb_prefix(FASTREG adr)
1412 FASTWORK temp, acu, op, cbits;
1426 dfd_prefix(FASTREG IXY)
1429 FASTWORK temp, adr, acu, op, sum, cbits;
1432 local(@labs) = ($labpcp2, $labcpar, $lablogar,
1433 $labandar, $labsbcar, $labsubar,
1434 $labadcar, $labaddar, $labadddd,
1435 $labdecr, $labincr);
1437 ($labpcp2, $labcpar, $lablogar,
1438 $labandar, $labsbcar, $labsubar,
1439 $labadcar, $labaddar, $labadddd,
1440 $labdecr, $labincr) = @labs;
1455 FASTWORK temp, acu, op, sum, cbits;
1458 local(@labs) = ($labpcp2, $labcpar, $lablogar,
1459 $labandar, $labsbcar, $labsubar,
1460 $labadcar, $labaddar, $labadddd,
1461 $labdecr, $labincr);
1463 ($labpcp2, $labcpar, $lablogar,
1464 $labandar, $labsbcar, $labsubar,
1465 $labadcar, $labaddar, $labadddd,
1466 $labdecr, $labincr) = @labs;
1478 FASTREG AF = af[af_sel];
1479 FASTREG BC = regs[regs_sel].bc;
1480 FASTREG DE = regs[regs_sel].de;
1481 FASTREG HL = regs[regs_sel].hl;
1490 print " FASTWORK temp, acu, sum, cbits;\n";
1491 print " FASTWORK op, adr;\n" if ($cb_inline + $dfd_inline +
1495 print "static void *optab[256] = {\n";
1497 print "\t" if (($_ & 7) == 0);
1498 printf("&&op_%02x,", $_);
1499 print "\n" if (($_ & 7) == 7);
1512 print " goto *optab[++PC,RAM(PC-1)]; {\n";
1515 print " switch(++PC,RAM(PC-1)) {\n";
1524 /* make registers visible for debugging if interrupted */
1526 return (PC&0xffff)|0x10000; /* flag non-bios stop */