1 /* altairz80_cpu_opt.c: MITS Altair CPU (8080 and Z80)
2
3 Copyright (c) 2002-2011, Peter Schorn
4
5 Permission is hereby granted, free of charge, to any person obtaining a
6 copy of this software and associated documentation files (the "Software"),
7 to deal in the Software without restriction, including without limitation
8 the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 and/or sell copies of the Software, and to permit persons to whom the
10 Software is furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 PETER SCHORN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of Peter Schorn shall not
23 be used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from Peter Schorn.
25
26 Based on work by Charles E Owen (c) 1997
27 Code for Z80 CPU from Frank D. Cringle ((c) 1995 under GNU license)
28 */
29
30 #include "altairz80_defs.h"
31
32 #define FLAG_C 1
33 #define FLAG_N 2
34 #define FLAG_P 4
35 #define FLAG_H 16
36 #define FLAG_Z 64
37 #define FLAG_S 128
38
39 #define SETFLAG(f,c) AF = (c) ? AF | FLAG_ ## f : AF & ~FLAG_ ## f
40 #define TSTFLAG(f) ((AF & FLAG_ ## f) != 0)
41
42 #define LOW_DIGIT(x) ((x) & 0xf)
43 #define HIGH_DIGIT(x) (((x) >> 4) & 0xf)
44 #define LOW_REGISTER(x) ((x) & 0xff)
45 #define HIGH_REGISTER(x) (((x) >> 8) & 0xff)
46
47 #define SET_LOW_REGISTER(x, v) x = (((x) & 0xff00) | ((v) & 0xff))
48 #define SET_HIGH_REGISTER(x, v) x = (((x) & 0xff) | (((v) & 0xff) << 8))
49
50 #define PARITY(x) parityTable[(x) & 0xff]
51 /* SET_PV and SET_PV2 are used to provide correct PARITY flag semantics for the 8080 in cases
52 where the Z80 uses the overflow flag
53 */
54 #define SET_PVS(s) ((chiptype == CHIP_TYPE_Z80) ? (((cbits >> 6) ^ (cbits >> 5)) & 4) : (PARITY(s)))
55 #define SET_PV (SET_PVS(sum))
56 #define SET_PV2(x) ((chiptype == CHIP_TYPE_Z80) ? (((temp == (x)) << 2)) : (PARITY(temp)))
57
58 /* CHECK_CPU_8080 must be invoked whenever a Z80 only instruction is executed
59 In case a Z80 instruction is executed on an 8080 the following two cases exist:
60 1) Trapping is enabled: execution stops
61 2) Trapping is not enabled: decoding continues with the next byte
62 */
63 #define CHECK_CPU_8080 \
64 if (chiptype == CHIP_TYPE_8080) { \
65 if (cpu_unit.flags & UNIT_CPU_OPSTOP) { \
66 reason = STOP_OPCODE; \
67 goto end_decode; \
68 } \
69 else continue; \
70 }
71
72 /* CHECK_CPU_Z80 must be invoked whenever a non Z80 instruction is executed */
73 #define CHECK_CPU_Z80 \
74 if (cpu_unit.flags & UNIT_CPU_OPSTOP) { \
75 reason = STOP_OPCODE; \
76 goto end_decode; \
77 }
78
79 #define POP(x) { \
80 register uint32 y = RAM_PP(SP); \
81 x = y + (RAM_PP(SP) << 8); \
82 }
83
84 #define JPC(cond) { \
85 if (cond) { \
86 PC = GET_WORD(PC); \
87 } \
88 else { \
89 PC += 2; \
90 } \
91 }
92
93 #define CALLC(cond) { \
94 if (cond) { \
95 register uint32 adrr = GET_WORD(PC); \
96 PUSH(PC + 2); \
97 PC = adrr; \
98 } \
99 else { \
100 PC += 2; \
101 } \
102 }
103
104 /* function prototypes */
105 t_stat sim_instr_nommu(void);
106
107 extern void out(const uint32 Port, const uint32 Value);
108 extern uint32 in(const uint32 Port);
109 extern UNIT cpu_unit;
110 extern uint32 PCX; /* external view of PC */
111 extern int32 AF_S; /* AF register */
112 extern int32 BC_S; /* BC register */
113 extern int32 DE_S; /* DE register */
114 extern int32 HL_S; /* HL register */
115 extern int32 IX_S; /* IX register */
116 extern int32 IY_S; /* IY register */
117 extern int32 PC_S; /* program counter */
118 extern int32 SP_S; /* SP register */
119 extern int32 AF1_S; /* alternate AF register */
120 extern int32 BC1_S; /* alternate BC register */
121 extern int32 DE1_S; /* alternate DE register */
122 extern int32 HL1_S; /* alternate HL register */
123 extern int32 IFF_S; /* Interrupt Flip Flop */
124 extern int32 IR_S; /* Interrupt (upper) / Refresh (lower) register */
125 extern int32 chiptype;
126
127 /* the following tables precompute some common subexpressions
128 parityTable[i] 0..255 (number of 1's in i is odd) ? 0 : 4
129 incTable[i] 0..256! (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4)
130 decTable[i] 0..255 (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | 2
131 cbitsTable[i] 0..511 (i & 0x10) | ((i >> 8) & 1)
132 cbitsDup8Table[i] 0..511 (i & 0x10) | ((i >> 8) & 1) | ((i & 0xff) << 8) | (i & 0xa8) |
133 (((i & 0xff) == 0) << 6)
134 cbitsDup16Table[i] 0..511 (i & 0x10) | ((i >> 8) & 1) | (i & 0x28)
135 cbits2Table[i] 0..511 (i & 0x10) | ((i >> 8) & 1) | 2
136 rrcaTable[i] 0..255 ((i & 1) << 15) | ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1)
137 rraTable[i] 0..255 ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1)
138 addTable[i] 0..511 ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6)
139 subTable[i] 0..255 ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | 2
140 andTable[i] 0..255 (i << 8) | (i & 0xa8) | ((i == 0) << 6) | 0x10 | parityTable[i]
141 xororTable[i] 0..255 (i << 8) | (i & 0xa8) | ((i == 0) << 6) | parityTable[i]
142 rotateShiftTable[i] 0..255 (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i & 0xff]
143 incZ80Table[i] 0..256! (i & 0xa8) | (((i & 0xff) == 0) << 6) |
144 (((i & 0xf) == 0) << 4) | ((i == 0x80) << 2)
145 decZ80Table[i] 0..255 (i & 0xa8) | (((i & 0xff) == 0) << 6) |
146 (((i & 0xf) == 0xf) << 4) | ((i == 0x7f) << 2) | 2
147 cbitsZ80Table[i] 0..511 (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1)
148 cbitsZ80DupTable[i] 0..511 (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) |
149 ((i >> 8) & 1) | (i & 0xa8)
150 cbits2Z80Table[i] 0..511 (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2
151 cbits2Z80DupTable[i] 0..511 (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2 |
152 (i & 0xa8)
153 negTable[i] 0..255 (((i & 0x0f) != 0) << 4) | ((i == 0x80) << 2) | 2 | (i != 0)
154 rrdrldTable[i] 0..255 (i << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i]
155 cpTable[i] 0..255 (i & 0x80) | (((i & 0xff) == 0) << 6)
156 */
157
158 /* parityTable[i] = (number of 1's in i is odd) ? 0 : 4, i = 0..255 */
159 static const uint8 parityTable[256] = {
160 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
161 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
162 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
163 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
164 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
165 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
166 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
167 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
168 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
169 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
170 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
171 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
172 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
173 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
174 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
175 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
176 };
177
178 /* incTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4), i = 0..256 */
179 static const uint8 incTable[257] = {
180 80, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
181 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
182 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
183 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
184 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
185 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
186 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
187 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
188 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
189 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
190 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
191 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
192 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
193 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
194 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
195 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, 80
196 };
197
198 /* decTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | 2, i = 0..255 */
199 static const uint8 decTable[256] = {
200 66, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
201 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
202 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
203 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
204 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
205 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
206 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
207 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
208 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
209 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
210 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
211 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
212 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
213 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
214 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
215 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
216 };
217
218 /* cbitsTable[i] = (i & 0x10) | ((i >> 8) & 1), i = 0..511 */
219 static const uint8 cbitsTable[512] = {
220 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
222 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
223 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
224 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
225 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
226 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
227 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
228 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
229 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
230 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
231 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
232 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
233 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
234 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
235 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
236 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
237 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
238 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
239 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
240 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
241 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
242 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
243 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
244 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
245 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
246 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
247 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
248 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
249 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
250 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
251 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
252 };
253
254 /* cbitsDup8Table[i] = (i & 0x10) | ((i >> 8) & 1) | ((i & 0xff) << 8) | (i & 0xa8) |
255 (((i & 0xff) == 0) << 6), i = 0..511 */
256 static const uint16 cbitsDup8Table[512] = {
257 0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700,
258 0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08,
259 0x1010,0x1110,0x1210,0x1310,0x1410,0x1510,0x1610,0x1710,
260 0x1818,0x1918,0x1a18,0x1b18,0x1c18,0x1d18,0x1e18,0x1f18,
261 0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720,
262 0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28,
263 0x3030,0x3130,0x3230,0x3330,0x3430,0x3530,0x3630,0x3730,
264 0x3838,0x3938,0x3a38,0x3b38,0x3c38,0x3d38,0x3e38,0x3f38,
265 0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700,
266 0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08,
267 0x5010,0x5110,0x5210,0x5310,0x5410,0x5510,0x5610,0x5710,
268 0x5818,0x5918,0x5a18,0x5b18,0x5c18,0x5d18,0x5e18,0x5f18,
269 0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720,
270 0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28,
271 0x7030,0x7130,0x7230,0x7330,0x7430,0x7530,0x7630,0x7730,
272 0x7838,0x7938,0x7a38,0x7b38,0x7c38,0x7d38,0x7e38,0x7f38,
273 0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780,
274 0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88,
275 0x9090,0x9190,0x9290,0x9390,0x9490,0x9590,0x9690,0x9790,
276 0x9898,0x9998,0x9a98,0x9b98,0x9c98,0x9d98,0x9e98,0x9f98,
277 0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0,
278 0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8,
279 0xb0b0,0xb1b0,0xb2b0,0xb3b0,0xb4b0,0xb5b0,0xb6b0,0xb7b0,
280 0xb8b8,0xb9b8,0xbab8,0xbbb8,0xbcb8,0xbdb8,0xbeb8,0xbfb8,
281 0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780,
282 0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88,
283 0xd090,0xd190,0xd290,0xd390,0xd490,0xd590,0xd690,0xd790,
284 0xd898,0xd998,0xda98,0xdb98,0xdc98,0xdd98,0xde98,0xdf98,
285 0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0,
286 0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8,
287 0xf0b0,0xf1b0,0xf2b0,0xf3b0,0xf4b0,0xf5b0,0xf6b0,0xf7b0,
288 0xf8b8,0xf9b8,0xfab8,0xfbb8,0xfcb8,0xfdb8,0xfeb8,0xffb8,
289 0x0041,0x0101,0x0201,0x0301,0x0401,0x0501,0x0601,0x0701,
290 0x0809,0x0909,0x0a09,0x0b09,0x0c09,0x0d09,0x0e09,0x0f09,
291 0x1011,0x1111,0x1211,0x1311,0x1411,0x1511,0x1611,0x1711,
292 0x1819,0x1919,0x1a19,0x1b19,0x1c19,0x1d19,0x1e19,0x1f19,
293 0x2021,0x2121,0x2221,0x2321,0x2421,0x2521,0x2621,0x2721,
294 0x2829,0x2929,0x2a29,0x2b29,0x2c29,0x2d29,0x2e29,0x2f29,
295 0x3031,0x3131,0x3231,0x3331,0x3431,0x3531,0x3631,0x3731,
296 0x3839,0x3939,0x3a39,0x3b39,0x3c39,0x3d39,0x3e39,0x3f39,
297 0x4001,0x4101,0x4201,0x4301,0x4401,0x4501,0x4601,0x4701,
298 0x4809,0x4909,0x4a09,0x4b09,0x4c09,0x4d09,0x4e09,0x4f09,
299 0x5011,0x5111,0x5211,0x5311,0x5411,0x5511,0x5611,0x5711,
300 0x5819,0x5919,0x5a19,0x5b19,0x5c19,0x5d19,0x5e19,0x5f19,
301 0x6021,0x6121,0x6221,0x6321,0x6421,0x6521,0x6621,0x6721,
302 0x6829,0x6929,0x6a29,0x6b29,0x6c29,0x6d29,0x6e29,0x6f29,
303 0x7031,0x7131,0x7231,0x7331,0x7431,0x7531,0x7631,0x7731,
304 0x7839,0x7939,0x7a39,0x7b39,0x7c39,0x7d39,0x7e39,0x7f39,
305 0x8081,0x8181,0x8281,0x8381,0x8481,0x8581,0x8681,0x8781,
306 0x8889,0x8989,0x8a89,0x8b89,0x8c89,0x8d89,0x8e89,0x8f89,
307 0x9091,0x9191,0x9291,0x9391,0x9491,0x9591,0x9691,0x9791,
308 0x9899,0x9999,0x9a99,0x9b99,0x9c99,0x9d99,0x9e99,0x9f99,
309 0xa0a1,0xa1a1,0xa2a1,0xa3a1,0xa4a1,0xa5a1,0xa6a1,0xa7a1,
310 0xa8a9,0xa9a9,0xaaa9,0xaba9,0xaca9,0xada9,0xaea9,0xafa9,
311 0xb0b1,0xb1b1,0xb2b1,0xb3b1,0xb4b1,0xb5b1,0xb6b1,0xb7b1,
312 0xb8b9,0xb9b9,0xbab9,0xbbb9,0xbcb9,0xbdb9,0xbeb9,0xbfb9,
313 0xc081,0xc181,0xc281,0xc381,0xc481,0xc581,0xc681,0xc781,
314 0xc889,0xc989,0xca89,0xcb89,0xcc89,0xcd89,0xce89,0xcf89,
315 0xd091,0xd191,0xd291,0xd391,0xd491,0xd591,0xd691,0xd791,
316 0xd899,0xd999,0xda99,0xdb99,0xdc99,0xdd99,0xde99,0xdf99,
317 0xe0a1,0xe1a1,0xe2a1,0xe3a1,0xe4a1,0xe5a1,0xe6a1,0xe7a1,
318 0xe8a9,0xe9a9,0xeaa9,0xeba9,0xeca9,0xeda9,0xeea9,0xefa9,
319 0xf0b1,0xf1b1,0xf2b1,0xf3b1,0xf4b1,0xf5b1,0xf6b1,0xf7b1,
320 0xf8b9,0xf9b9,0xfab9,0xfbb9,0xfcb9,0xfdb9,0xfeb9,0xffb9,
321 };
322
323 /* cbitsDup16Table[i] = (i & 0x10) | ((i >> 8) & 1) | (i & 0x28), i = 0..511 */
324 static const uint8 cbitsDup16Table[512] = {
325 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
326 16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,
327 32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,
328 48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56,
329 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
330 16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,
331 32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,
332 48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56,
333 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
334 16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,
335 32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,
336 48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56,
337 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
338 16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,
339 32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,
340 48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56,
341 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9,
342 17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25,
343 33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41,
344 49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57,
345 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9,
346 17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25,
347 33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41,
348 49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57,
349 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9,
350 17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25,
351 33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41,
352 49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57,
353 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9,
354 17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25,
355 33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41,
356 49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57,
357 };
358
359 /* cbits2Table[i] = (i & 0x10) | ((i >> 8) & 1) | 2, i = 0..511 */
360 static const uint8 cbits2Table[512] = {
361 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
362 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
363 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
364 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
365 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
366 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
367 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
368 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
369 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
370 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
371 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
372 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
373 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
374 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
375 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
376 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
377 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
378 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
379 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
380 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
381 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
382 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
383 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
384 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
385 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
386 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
387 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
388 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
389 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
390 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
391 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
392 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
393 };
394
395 /* rrcaTable[i] = ((i & 1) << 15) | ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1), i = 0..255 */
396 static const uint16 rrcaTable[256] = {
397 0x0000,0x8001,0x0100,0x8101,0x0200,0x8201,0x0300,0x8301,
398 0x0400,0x8401,0x0500,0x8501,0x0600,0x8601,0x0700,0x8701,
399 0x0808,0x8809,0x0908,0x8909,0x0a08,0x8a09,0x0b08,0x8b09,
400 0x0c08,0x8c09,0x0d08,0x8d09,0x0e08,0x8e09,0x0f08,0x8f09,
401 0x1000,0x9001,0x1100,0x9101,0x1200,0x9201,0x1300,0x9301,
402 0x1400,0x9401,0x1500,0x9501,0x1600,0x9601,0x1700,0x9701,
403 0x1808,0x9809,0x1908,0x9909,0x1a08,0x9a09,0x1b08,0x9b09,
404 0x1c08,0x9c09,0x1d08,0x9d09,0x1e08,0x9e09,0x1f08,0x9f09,
405 0x2020,0xa021,0x2120,0xa121,0x2220,0xa221,0x2320,0xa321,
406 0x2420,0xa421,0x2520,0xa521,0x2620,0xa621,0x2720,0xa721,
407 0x2828,0xa829,0x2928,0xa929,0x2a28,0xaa29,0x2b28,0xab29,
408 0x2c28,0xac29,0x2d28,0xad29,0x2e28,0xae29,0x2f28,0xaf29,
409 0x3020,0xb021,0x3120,0xb121,0x3220,0xb221,0x3320,0xb321,
410 0x3420,0xb421,0x3520,0xb521,0x3620,0xb621,0x3720,0xb721,
411 0x3828,0xb829,0x3928,0xb929,0x3a28,0xba29,0x3b28,0xbb29,
412 0x3c28,0xbc29,0x3d28,0xbd29,0x3e28,0xbe29,0x3f28,0xbf29,
413 0x4000,0xc001,0x4100,0xc101,0x4200,0xc201,0x4300,0xc301,
414 0x4400,0xc401,0x4500,0xc501,0x4600,0xc601,0x4700,0xc701,
415 0x4808,0xc809,0x4908,0xc909,0x4a08,0xca09,0x4b08,0xcb09,
416 0x4c08,0xcc09,0x4d08,0xcd09,0x4e08,0xce09,0x4f08,0xcf09,
417 0x5000,0xd001,0x5100,0xd101,0x5200,0xd201,0x5300,0xd301,
418 0x5400,0xd401,0x5500,0xd501,0x5600,0xd601,0x5700,0xd701,
419 0x5808,0xd809,0x5908,0xd909,0x5a08,0xda09,0x5b08,0xdb09,
420 0x5c08,0xdc09,0x5d08,0xdd09,0x5e08,0xde09,0x5f08,0xdf09,
421 0x6020,0xe021,0x6120,0xe121,0x6220,0xe221,0x6320,0xe321,
422 0x6420,0xe421,0x6520,0xe521,0x6620,0xe621,0x6720,0xe721,
423 0x6828,0xe829,0x6928,0xe929,0x6a28,0xea29,0x6b28,0xeb29,
424 0x6c28,0xec29,0x6d28,0xed29,0x6e28,0xee29,0x6f28,0xef29,
425 0x7020,0xf021,0x7120,0xf121,0x7220,0xf221,0x7320,0xf321,
426 0x7420,0xf421,0x7520,0xf521,0x7620,0xf621,0x7720,0xf721,
427 0x7828,0xf829,0x7928,0xf929,0x7a28,0xfa29,0x7b28,0xfb29,
428 0x7c28,0xfc29,0x7d28,0xfd29,0x7e28,0xfe29,0x7f28,0xff29,
429 };
430
431 /* rraTable[i] = ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1), i = 0..255 */
432 static const uint16 rraTable[256] = {
433 0x0000,0x0001,0x0100,0x0101,0x0200,0x0201,0x0300,0x0301,
434 0x0400,0x0401,0x0500,0x0501,0x0600,0x0601,0x0700,0x0701,
435 0x0808,0x0809,0x0908,0x0909,0x0a08,0x0a09,0x0b08,0x0b09,
436 0x0c08,0x0c09,0x0d08,0x0d09,0x0e08,0x0e09,0x0f08,0x0f09,
437 0x1000,0x1001,0x1100,0x1101,0x1200,0x1201,0x1300,0x1301,
438 0x1400,0x1401,0x1500,0x1501,0x1600,0x1601,0x1700,0x1701,
439 0x1808,0x1809,0x1908,0x1909,0x1a08,0x1a09,0x1b08,0x1b09,
440 0x1c08,0x1c09,0x1d08,0x1d09,0x1e08,0x1e09,0x1f08,0x1f09,
441 0x2020,0x2021,0x2120,0x2121,0x2220,0x2221,0x2320,0x2321,
442 0x2420,0x2421,0x2520,0x2521,0x2620,0x2621,0x2720,0x2721,
443 0x2828,0x2829,0x2928,0x2929,0x2a28,0x2a29,0x2b28,0x2b29,
444 0x2c28,0x2c29,0x2d28,0x2d29,0x2e28,0x2e29,0x2f28,0x2f29,
445 0x3020,0x3021,0x3120,0x3121,0x3220,0x3221,0x3320,0x3321,
446 0x3420,0x3421,0x3520,0x3521,0x3620,0x3621,0x3720,0x3721,
447 0x3828,0x3829,0x3928,0x3929,0x3a28,0x3a29,0x3b28,0x3b29,
448 0x3c28,0x3c29,0x3d28,0x3d29,0x3e28,0x3e29,0x3f28,0x3f29,
449 0x4000,0x4001,0x4100,0x4101,0x4200,0x4201,0x4300,0x4301,
450 0x4400,0x4401,0x4500,0x4501,0x4600,0x4601,0x4700,0x4701,
451 0x4808,0x4809,0x4908,0x4909,0x4a08,0x4a09,0x4b08,0x4b09,
452 0x4c08,0x4c09,0x4d08,0x4d09,0x4e08,0x4e09,0x4f08,0x4f09,
453 0x5000,0x5001,0x5100,0x5101,0x5200,0x5201,0x5300,0x5301,
454 0x5400,0x5401,0x5500,0x5501,0x5600,0x5601,0x5700,0x5701,
455 0x5808,0x5809,0x5908,0x5909,0x5a08,0x5a09,0x5b08,0x5b09,
456 0x5c08,0x5c09,0x5d08,0x5d09,0x5e08,0x5e09,0x5f08,0x5f09,
457 0x6020,0x6021,0x6120,0x6121,0x6220,0x6221,0x6320,0x6321,
458 0x6420,0x6421,0x6520,0x6521,0x6620,0x6621,0x6720,0x6721,
459 0x6828,0x6829,0x6928,0x6929,0x6a28,0x6a29,0x6b28,0x6b29,
460 0x6c28,0x6c29,0x6d28,0x6d29,0x6e28,0x6e29,0x6f28,0x6f29,
461 0x7020,0x7021,0x7120,0x7121,0x7220,0x7221,0x7320,0x7321,
462 0x7420,0x7421,0x7520,0x7521,0x7620,0x7621,0x7720,0x7721,
463 0x7828,0x7829,0x7928,0x7929,0x7a28,0x7a29,0x7b28,0x7b29,
464 0x7c28,0x7c29,0x7d28,0x7d29,0x7e28,0x7e29,0x7f28,0x7f29,
465 };
466
467 /* addTable[i] = ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6), i = 0..511 */
468 static const uint16 addTable[512] = {
469 0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700,
470 0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08,
471 0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700,
472 0x1808,0x1908,0x1a08,0x1b08,0x1c08,0x1d08,0x1e08,0x1f08,
473 0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720,
474 0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28,
475 0x3020,0x3120,0x3220,0x3320,0x3420,0x3520,0x3620,0x3720,
476 0x3828,0x3928,0x3a28,0x3b28,0x3c28,0x3d28,0x3e28,0x3f28,
477 0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700,
478 0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08,
479 0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,0x5700,
480 0x5808,0x5908,0x5a08,0x5b08,0x5c08,0x5d08,0x5e08,0x5f08,
481 0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720,
482 0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28,
483 0x7020,0x7120,0x7220,0x7320,0x7420,0x7520,0x7620,0x7720,
484 0x7828,0x7928,0x7a28,0x7b28,0x7c28,0x7d28,0x7e28,0x7f28,
485 0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780,
486 0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88,
487 0x9080,0x9180,0x9280,0x9380,0x9480,0x9580,0x9680,0x9780,
488 0x9888,0x9988,0x9a88,0x9b88,0x9c88,0x9d88,0x9e88,0x9f88,
489 0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0,
490 0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8,
491 0xb0a0,0xb1a0,0xb2a0,0xb3a0,0xb4a0,0xb5a0,0xb6a0,0xb7a0,
492 0xb8a8,0xb9a8,0xbaa8,0xbba8,0xbca8,0xbda8,0xbea8,0xbfa8,
493 0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780,
494 0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88,
495 0xd080,0xd180,0xd280,0xd380,0xd480,0xd580,0xd680,0xd780,
496 0xd888,0xd988,0xda88,0xdb88,0xdc88,0xdd88,0xde88,0xdf88,
497 0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0,
498 0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8,
499 0xf0a0,0xf1a0,0xf2a0,0xf3a0,0xf4a0,0xf5a0,0xf6a0,0xf7a0,
500 0xf8a8,0xf9a8,0xfaa8,0xfba8,0xfca8,0xfda8,0xfea8,0xffa8,
501 0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700,
502 0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08,
503 0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700,
504 0x1808,0x1908,0x1a08,0x1b08,0x1c08,0x1d08,0x1e08,0x1f08,
505 0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720,
506 0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28,
507 0x3020,0x3120,0x3220,0x3320,0x3420,0x3520,0x3620,0x3720,
508 0x3828,0x3928,0x3a28,0x3b28,0x3c28,0x3d28,0x3e28,0x3f28,
509 0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700,
510 0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08,
511 0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,0x5700,
512 0x5808,0x5908,0x5a08,0x5b08,0x5c08,0x5d08,0x5e08,0x5f08,
513 0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720,
514 0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28,
515 0x7020,0x7120,0x7220,0x7320,0x7420,0x7520,0x7620,0x7720,
516 0x7828,0x7928,0x7a28,0x7b28,0x7c28,0x7d28,0x7e28,0x7f28,
517 0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780,
518 0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88,
519 0x9080,0x9180,0x9280,0x9380,0x9480,0x9580,0x9680,0x9780,
520 0x9888,0x9988,0x9a88,0x9b88,0x9c88,0x9d88,0x9e88,0x9f88,
521 0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0,
522 0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8,
523 0xb0a0,0xb1a0,0xb2a0,0xb3a0,0xb4a0,0xb5a0,0xb6a0,0xb7a0,
524 0xb8a8,0xb9a8,0xbaa8,0xbba8,0xbca8,0xbda8,0xbea8,0xbfa8,
525 0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780,
526 0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88,
527 0xd080,0xd180,0xd280,0xd380,0xd480,0xd580,0xd680,0xd780,
528 0xd888,0xd988,0xda88,0xdb88,0xdc88,0xdd88,0xde88,0xdf88,
529 0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0,
530 0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8,
531 0xf0a0,0xf1a0,0xf2a0,0xf3a0,0xf4a0,0xf5a0,0xf6a0,0xf7a0,
532 0xf8a8,0xf9a8,0xfaa8,0xfba8,0xfca8,0xfda8,0xfea8,0xffa8,
533 };
534
535 /* subTable[i] = ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | 2, i = 0..255 */
536 static const uint16 subTable[256] = {
537 0x0042,0x0102,0x0202,0x0302,0x0402,0x0502,0x0602,0x0702,
538 0x080a,0x090a,0x0a0a,0x0b0a,0x0c0a,0x0d0a,0x0e0a,0x0f0a,
539 0x1002,0x1102,0x1202,0x1302,0x1402,0x1502,0x1602,0x1702,
540 0x180a,0x190a,0x1a0a,0x1b0a,0x1c0a,0x1d0a,0x1e0a,0x1f0a,
541 0x2022,0x2122,0x2222,0x2322,0x2422,0x2522,0x2622,0x2722,
542 0x282a,0x292a,0x2a2a,0x2b2a,0x2c2a,0x2d2a,0x2e2a,0x2f2a,
543 0x3022,0x3122,0x3222,0x3322,0x3422,0x3522,0x3622,0x3722,
544 0x382a,0x392a,0x3a2a,0x3b2a,0x3c2a,0x3d2a,0x3e2a,0x3f2a,
545 0x4002,0x4102,0x4202,0x4302,0x4402,0x4502,0x4602,0x4702,
546 0x480a,0x490a,0x4a0a,0x4b0a,0x4c0a,0x4d0a,0x4e0a,0x4f0a,
547 0x5002,0x5102,0x5202,0x5302,0x5402,0x5502,0x5602,0x5702,
548 0x580a,0x590a,0x5a0a,0x5b0a,0x5c0a,0x5d0a,0x5e0a,0x5f0a,
549 0x6022,0x6122,0x6222,0x6322,0x6422,0x6522,0x6622,0x6722,
550 0x682a,0x692a,0x6a2a,0x6b2a,0x6c2a,0x6d2a,0x6e2a,0x6f2a,
551 0x7022,0x7122,0x7222,0x7322,0x7422,0x7522,0x7622,0x7722,
552 0x782a,0x792a,0x7a2a,0x7b2a,0x7c2a,0x7d2a,0x7e2a,0x7f2a,
553 0x8082,0x8182,0x8282,0x8382,0x8482,0x8582,0x8682,0x8782,
554 0x888a,0x898a,0x8a8a,0x8b8a,0x8c8a,0x8d8a,0x8e8a,0x8f8a,
555 0x9082,0x9182,0x9282,0x9382,0x9482,0x9582,0x9682,0x9782,
556 0x988a,0x998a,0x9a8a,0x9b8a,0x9c8a,0x9d8a,0x9e8a,0x9f8a,
557 0xa0a2,0xa1a2,0xa2a2,0xa3a2,0xa4a2,0xa5a2,0xa6a2,0xa7a2,
558 0xa8aa,0xa9aa,0xaaaa,0xabaa,0xacaa,0xadaa,0xaeaa,0xafaa,
559 0xb0a2,0xb1a2,0xb2a2,0xb3a2,0xb4a2,0xb5a2,0xb6a2,0xb7a2,
560 0xb8aa,0xb9aa,0xbaaa,0xbbaa,0xbcaa,0xbdaa,0xbeaa,0xbfaa,
561 0xc082,0xc182,0xc282,0xc382,0xc482,0xc582,0xc682,0xc782,
562 0xc88a,0xc98a,0xca8a,0xcb8a,0xcc8a,0xcd8a,0xce8a,0xcf8a,
563 0xd082,0xd182,0xd282,0xd382,0xd482,0xd582,0xd682,0xd782,
564 0xd88a,0xd98a,0xda8a,0xdb8a,0xdc8a,0xdd8a,0xde8a,0xdf8a,
565 0xe0a2,0xe1a2,0xe2a2,0xe3a2,0xe4a2,0xe5a2,0xe6a2,0xe7a2,
566 0xe8aa,0xe9aa,0xeaaa,0xebaa,0xecaa,0xedaa,0xeeaa,0xefaa,
567 0xf0a2,0xf1a2,0xf2a2,0xf3a2,0xf4a2,0xf5a2,0xf6a2,0xf7a2,
568 0xf8aa,0xf9aa,0xfaaa,0xfbaa,0xfcaa,0xfdaa,0xfeaa,0xffaa,
569 };
570
571 /* andTable[i] = (i << 8) | (i & 0xa8) | ((i == 0) << 6) | 0x10 | parityTable[i], i = 0..255 */
572 static const uint16 andTable[256] = {
573 0x0054,0x0110,0x0210,0x0314,0x0410,0x0514,0x0614,0x0710,
574 0x0818,0x091c,0x0a1c,0x0b18,0x0c1c,0x0d18,0x0e18,0x0f1c,
575 0x1010,0x1114,0x1214,0x1310,0x1414,0x1510,0x1610,0x1714,
576 0x181c,0x1918,0x1a18,0x1b1c,0x1c18,0x1d1c,0x1e1c,0x1f18,
577 0x2030,0x2134,0x2234,0x2330,0x2434,0x2530,0x2630,0x2734,
578 0x283c,0x2938,0x2a38,0x2b3c,0x2c38,0x2d3c,0x2e3c,0x2f38,
579 0x3034,0x3130,0x3230,0x3334,0x3430,0x3534,0x3634,0x3730,
580 0x3838,0x393c,0x3a3c,0x3b38,0x3c3c,0x3d38,0x3e38,0x3f3c,
581 0x4010,0x4114,0x4214,0x4310,0x4414,0x4510,0x4610,0x4714,
582 0x481c,0x4918,0x4a18,0x4b1c,0x4c18,0x4d1c,0x4e1c,0x4f18,
583 0x5014,0x5110,0x5210,0x5314,0x5410,0x5514,0x5614,0x5710,
584 0x5818,0x591c,0x5a1c,0x5b18,0x5c1c,0x5d18,0x5e18,0x5f1c,
585 0x6034,0x6130,0x6230,0x6334,0x6430,0x6534,0x6634,0x6730,
586 0x6838,0x693c,0x6a3c,0x6b38,0x6c3c,0x6d38,0x6e38,0x6f3c,
587 0x7030,0x7134,0x7234,0x7330,0x7434,0x7530,0x7630,0x7734,
588 0x783c,0x7938,0x7a38,0x7b3c,0x7c38,0x7d3c,0x7e3c,0x7f38,
589 0x8090,0x8194,0x8294,0x8390,0x8494,0x8590,0x8690,0x8794,
590 0x889c,0x8998,0x8a98,0x8b9c,0x8c98,0x8d9c,0x8e9c,0x8f98,
591 0x9094,0x9190,0x9290,0x9394,0x9490,0x9594,0x9694,0x9790,
592 0x9898,0x999c,0x9a9c,0x9b98,0x9c9c,0x9d98,0x9e98,0x9f9c,
593 0xa0b4,0xa1b0,0xa2b0,0xa3b4,0xa4b0,0xa5b4,0xa6b4,0xa7b0,
594 0xa8b8,0xa9bc,0xaabc,0xabb8,0xacbc,0xadb8,0xaeb8,0xafbc,
595 0xb0b0,0xb1b4,0xb2b4,0xb3b0,0xb4b4,0xb5b0,0xb6b0,0xb7b4,
596 0xb8bc,0xb9b8,0xbab8,0xbbbc,0xbcb8,0xbdbc,0xbebc,0xbfb8,
597 0xc094,0xc190,0xc290,0xc394,0xc490,0xc594,0xc694,0xc790,
598 0xc898,0xc99c,0xca9c,0xcb98,0xcc9c,0xcd98,0xce98,0xcf9c,
599 0xd090,0xd194,0xd294,0xd390,0xd494,0xd590,0xd690,0xd794,
600 0xd89c,0xd998,0xda98,0xdb9c,0xdc98,0xdd9c,0xde9c,0xdf98,
601 0xe0b0,0xe1b4,0xe2b4,0xe3b0,0xe4b4,0xe5b0,0xe6b0,0xe7b4,
602 0xe8bc,0xe9b8,0xeab8,0xebbc,0xecb8,0xedbc,0xeebc,0xefb8,
603 0xf0b4,0xf1b0,0xf2b0,0xf3b4,0xf4b0,0xf5b4,0xf6b4,0xf7b0,
604 0xf8b8,0xf9bc,0xfabc,0xfbb8,0xfcbc,0xfdb8,0xfeb8,0xffbc,
605 };
606
607 /* xororTable[i] = (i << 8) | (i & 0xa8) | ((i == 0) << 6) | parityTable[i], i = 0..255 */
608 static const uint16 xororTable[256] = {
609 0x0044,0x0100,0x0200,0x0304,0x0400,0x0504,0x0604,0x0700,
610 0x0808,0x090c,0x0a0c,0x0b08,0x0c0c,0x0d08,0x0e08,0x0f0c,
611 0x1000,0x1104,0x1204,0x1300,0x1404,0x1500,0x1600,0x1704,
612 0x180c,0x1908,0x1a08,0x1b0c,0x1c08,0x1d0c,0x1e0c,0x1f08,
613 0x2020,0x2124,0x2224,0x2320,0x2424,0x2520,0x2620,0x2724,
614 0x282c,0x2928,0x2a28,0x2b2c,0x2c28,0x2d2c,0x2e2c,0x2f28,
615 0x3024,0x3120,0x3220,0x3324,0x3420,0x3524,0x3624,0x3720,
616 0x3828,0x392c,0x3a2c,0x3b28,0x3c2c,0x3d28,0x3e28,0x3f2c,
617 0x4000,0x4104,0x4204,0x4300,0x4404,0x4500,0x4600,0x4704,
618 0x480c,0x4908,0x4a08,0x4b0c,0x4c08,0x4d0c,0x4e0c,0x4f08,
619 0x5004,0x5100,0x5200,0x5304,0x5400,0x5504,0x5604,0x5700,
620 0x5808,0x590c,0x5a0c,0x5b08,0x5c0c,0x5d08,0x5e08,0x5f0c,
621 0x6024,0x6120,0x6220,0x6324,0x6420,0x6524,0x6624,0x6720,
622 0x6828,0x692c,0x6a2c,0x6b28,0x6c2c,0x6d28,0x6e28,0x6f2c,
623 0x7020,0x7124,0x7224,0x7320,0x7424,0x7520,0x7620,0x7724,
624 0x782c,0x7928,0x7a28,0x7b2c,0x7c28,0x7d2c,0x7e2c,0x7f28,
625 0x8080,0x8184,0x8284,0x8380,0x8484,0x8580,0x8680,0x8784,
626 0x888c,0x8988,0x8a88,0x8b8c,0x8c88,0x8d8c,0x8e8c,0x8f88,
627 0x9084,0x9180,0x9280,0x9384,0x9480,0x9584,0x9684,0x9780,
628 0x9888,0x998c,0x9a8c,0x9b88,0x9c8c,0x9d88,0x9e88,0x9f8c,
629 0xa0a4,0xa1a0,0xa2a0,0xa3a4,0xa4a0,0xa5a4,0xa6a4,0xa7a0,
630 0xa8a8,0xa9ac,0xaaac,0xaba8,0xacac,0xada8,0xaea8,0xafac,
631 0xb0a0,0xb1a4,0xb2a4,0xb3a0,0xb4a4,0xb5a0,0xb6a0,0xb7a4,
632 0xb8ac,0xb9a8,0xbaa8,0xbbac,0xbca8,0xbdac,0xbeac,0xbfa8,
633 0xc084,0xc180,0xc280,0xc384,0xc480,0xc584,0xc684,0xc780,
634 0xc888,0xc98c,0xca8c,0xcb88,0xcc8c,0xcd88,0xce88,0xcf8c,
635 0xd080,0xd184,0xd284,0xd380,0xd484,0xd580,0xd680,0xd784,
636 0xd88c,0xd988,0xda88,0xdb8c,0xdc88,0xdd8c,0xde8c,0xdf88,
637 0xe0a0,0xe1a4,0xe2a4,0xe3a0,0xe4a4,0xe5a0,0xe6a0,0xe7a4,
638 0xe8ac,0xe9a8,0xeaa8,0xebac,0xeca8,0xedac,0xeeac,0xefa8,
639 0xf0a4,0xf1a0,0xf2a0,0xf3a4,0xf4a0,0xf5a4,0xf6a4,0xf7a0,
640 0xf8a8,0xf9ac,0xfaac,0xfba8,0xfcac,0xfda8,0xfea8,0xffac,
641 };
642
643 /* rotateShiftTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i & 0xff], i = 0..255 */
644 static const uint8 rotateShiftTable[256] = {
645 68, 0, 0, 4, 0, 4, 4, 0, 8, 12, 12, 8, 12, 8, 8, 12,
646 0, 4, 4, 0, 4, 0, 0, 4, 12, 8, 8, 12, 8, 12, 12, 8,
647 32, 36, 36, 32, 36, 32, 32, 36, 44, 40, 40, 44, 40, 44, 44, 40,
648 36, 32, 32, 36, 32, 36, 36, 32, 40, 44, 44, 40, 44, 40, 40, 44,
649 0, 4, 4, 0, 4, 0, 0, 4, 12, 8, 8, 12, 8, 12, 12, 8,
650 4, 0, 0, 4, 0, 4, 4, 0, 8, 12, 12, 8, 12, 8, 8, 12,
651 36, 32, 32, 36, 32, 36, 36, 32, 40, 44, 44, 40, 44, 40, 40, 44,
652 32, 36, 36, 32, 36, 32, 32, 36, 44, 40, 40, 44, 40, 44, 44, 40,
653 128,132,132,128,132,128,128,132,140,136,136,140,136,140,140,136,
654 132,128,128,132,128,132,132,128,136,140,140,136,140,136,136,140,
655 164,160,160,164,160,164,164,160,168,172,172,168,172,168,168,172,
656 160,164,164,160,164,160,160,164,172,168,168,172,168,172,172,168,
657 132,128,128,132,128,132,132,128,136,140,140,136,140,136,136,140,
658 128,132,132,128,132,128,128,132,140,136,136,140,136,140,140,136,
659 160,164,164,160,164,160,160,164,172,168,168,172,168,172,172,168,
660 164,160,160,164,160,164,164,160,168,172,172,168,172,168,168,172,
661 };
662
663 /* incZ80Table[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) |
664 (((i & 0xf) == 0) << 4) | ((i == 0x80) << 2), i = 0..256 */
665 static const uint8 incZ80Table[257] = {
666 80, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
667 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
668 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
669 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
670 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
671 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
672 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
673 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
674 148,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
675 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
676 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
677 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
678 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
679 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
680 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
681 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, 80,
682 };
683
684 /* decZ80Table[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) |
685 (((i & 0xf) == 0xf) << 4) | ((i == 0x7f) << 2) | 2, i = 0..255 */
686 static const uint8 decZ80Table[256] = {
687 66, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
688 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
689 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
690 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
691 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
692 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
693 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
694 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 62,
695 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
696 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
697 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
698 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
699 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
700 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
701 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
702 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
703 };
704
705 /* cbitsZ80Table[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1), i = 0..511 */
706 static const uint8 cbitsZ80Table[512] = {
707 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
708 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
709 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
710 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
711 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
712 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
713 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
714 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
715 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
716 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
717 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
718 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
719 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
720 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
721 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
722 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
723 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
724 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
725 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
726 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
727 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
728 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
729 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
730 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
731 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
732 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
733 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
734 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
735 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
736 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
737 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
738 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
739 };
740
741 /* cbitsZ80DupTable[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) |
742 ((i >> 8) & 1) | (i & 0xa8), i = 0..511 */
743 static const uint8 cbitsZ80DupTable[512] = {
744 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
745 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24,
746 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
747 48, 48, 48, 48, 48, 48, 48, 48, 56, 56, 56, 56, 56, 56, 56, 56,
748 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
749 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24,
750 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
751 48, 48, 48, 48, 48, 48, 48, 48, 56, 56, 56, 56, 56, 56, 56, 56,
752 132,132,132,132,132,132,132,132,140,140,140,140,140,140,140,140,
753 148,148,148,148,148,148,148,148,156,156,156,156,156,156,156,156,
754 164,164,164,164,164,164,164,164,172,172,172,172,172,172,172,172,
755 180,180,180,180,180,180,180,180,188,188,188,188,188,188,188,188,
756 132,132,132,132,132,132,132,132,140,140,140,140,140,140,140,140,
757 148,148,148,148,148,148,148,148,156,156,156,156,156,156,156,156,
758 164,164,164,164,164,164,164,164,172,172,172,172,172,172,172,172,
759 180,180,180,180,180,180,180,180,188,188,188,188,188,188,188,188,
760 5, 5, 5, 5, 5, 5, 5, 5, 13, 13, 13, 13, 13, 13, 13, 13,
761 21, 21, 21, 21, 21, 21, 21, 21, 29, 29, 29, 29, 29, 29, 29, 29,
762 37, 37, 37, 37, 37, 37, 37, 37, 45, 45, 45, 45, 45, 45, 45, 45,
763 53, 53, 53, 53, 53, 53, 53, 53, 61, 61, 61, 61, 61, 61, 61, 61,
764 5, 5, 5, 5, 5, 5, 5, 5, 13, 13, 13, 13, 13, 13, 13, 13,
765 21, 21, 21, 21, 21, 21, 21, 21, 29, 29, 29, 29, 29, 29, 29, 29,
766 37, 37, 37, 37, 37, 37, 37, 37, 45, 45, 45, 45, 45, 45, 45, 45,
767 53, 53, 53, 53, 53, 53, 53, 53, 61, 61, 61, 61, 61, 61, 61, 61,
768 129,129,129,129,129,129,129,129,137,137,137,137,137,137,137,137,
769 145,145,145,145,145,145,145,145,153,153,153,153,153,153,153,153,
770 161,161,161,161,161,161,161,161,169,169,169,169,169,169,169,169,
771 177,177,177,177,177,177,177,177,185,185,185,185,185,185,185,185,
772 129,129,129,129,129,129,129,129,137,137,137,137,137,137,137,137,
773 145,145,145,145,145,145,145,145,153,153,153,153,153,153,153,153,
774 161,161,161,161,161,161,161,161,169,169,169,169,169,169,169,169,
775 177,177,177,177,177,177,177,177,185,185,185,185,185,185,185,185,
776 };
777
778 /* cbits2Z80Table[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2, i = 0..511 */
779 static const uint8 cbits2Z80Table[512] = {
780 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
781 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
782 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
783 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
784 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
785 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
786 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
787 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
788 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
789 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
790 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
791 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
792 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
793 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
794 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
795 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
796 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
797 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
798 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
799 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
800 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
801 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
802 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
803 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
804 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
805 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
806 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
807 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
808 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
809 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
810 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
811 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
812 };
813
814 /* cbits2Z80DupTable[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2 |
815 (i & 0xa8), i = 0..511 */
816 static const uint8 cbits2Z80DupTable[512] = {
817 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10,
818 18, 18, 18, 18, 18, 18, 18, 18, 26, 26, 26, 26, 26, 26, 26, 26,
819 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 42,
820 50, 50, 50, 50, 50, 50, 50, 50, 58, 58, 58, 58, 58, 58, 58, 58,
821 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10,
822 18, 18, 18, 18, 18, 18, 18, 18, 26, 26, 26, 26, 26, 26, 26, 26,
823 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 42,
824 50, 50, 50, 50, 50, 50, 50, 50, 58, 58, 58, 58, 58, 58, 58, 58,
825 134,134,134,134,134,134,134,134,142,142,142,142,142,142,142,142,
826 150,150,150,150,150,150,150,150,158,158,158,158,158,158,158,158,
827 166,166,166,166,166,166,166,166,174,174,174,174,174,174,174,174,
828 182,182,182,182,182,182,182,182,190,190,190,190,190,190,190,190,
829 134,134,134,134,134,134,134,134,142,142,142,142,142,142,142,142,
830 150,150,150,150,150,150,150,150,158,158,158,158,158,158,158,158,
831 166,166,166,166,166,166,166,166,174,174,174,174,174,174,174,174,
832 182,182,182,182,182,182,182,182,190,190,190,190,190,190,190,190,
833 7, 7, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15,
834 23, 23, 23, 23, 23, 23, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31,
835 39, 39, 39, 39, 39, 39, 39, 39, 47, 47, 47, 47, 47, 47, 47, 47,
836 55, 55, 55, 55, 55, 55, 55, 55, 63, 63, 63, 63, 63, 63, 63, 63,
837 7, 7, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15,
838 23, 23, 23, 23, 23, 23, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31,
839 39, 39, 39, 39, 39, 39, 39, 39, 47, 47, 47, 47, 47, 47, 47, 47,
840 55, 55, 55, 55, 55, 55, 55, 55, 63, 63, 63, 63, 63, 63, 63, 63,
841 131,131,131,131,131,131,131,131,139,139,139,139,139,139,139,139,
842 147,147,147,147,147,147,147,147,155,155,155,155,155,155,155,155,
843 163,163,163,163,163,163,163,163,171,171,171,171,171,171,171,171,
844 179,179,179,179,179,179,179,179,187,187,187,187,187,187,187,187,
845 131,131,131,131,131,131,131,131,139,139,139,139,139,139,139,139,
846 147,147,147,147,147,147,147,147,155,155,155,155,155,155,155,155,
847 163,163,163,163,163,163,163,163,171,171,171,171,171,171,171,171,
848 179,179,179,179,179,179,179,179,187,187,187,187,187,187,187,187,
849 };
850
851 /* negTable[i] = (((i & 0x0f) != 0) << 4) | ((i == 0x80) << 2) | 2 | (i != 0), i = 0..255 */
852 static const uint8 negTable[256] = {
853 2,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
854 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
855 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
856 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
857 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
858 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
859 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
860 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
861 7,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
862 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
863 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
864 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
865 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
866 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
867 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
868 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
869 };
870
871 /* rrdrldTable[i] = (i << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i], i = 0..255 */
872 static const uint16 rrdrldTable[256] = {
873 0x0044,0x0100,0x0200,0x0304,0x0400,0x0504,0x0604,0x0700,
874 0x0808,0x090c,0x0a0c,0x0b08,0x0c0c,0x0d08,0x0e08,0x0f0c,
875 0x1000,0x1104,0x1204,0x1300,0x1404,0x1500,0x1600,0x1704,
876 0x180c,0x1908,0x1a08,0x1b0c,0x1c08,0x1d0c,0x1e0c,0x1f08,
877 0x2020,0x2124,0x2224,0x2320,0x2424,0x2520,0x2620,0x2724,
878 0x282c,0x2928,0x2a28,0x2b2c,0x2c28,0x2d2c,0x2e2c,0x2f28,
879 0x3024,0x3120,0x3220,0x3324,0x3420,0x3524,0x3624,0x3720,
880 0x3828,0x392c,0x3a2c,0x3b28,0x3c2c,0x3d28,0x3e28,0x3f2c,
881 0x4000,0x4104,0x4204,0x4300,0x4404,0x4500,0x4600,0x4704,
882 0x480c,0x4908,0x4a08,0x4b0c,0x4c08,0x4d0c,0x4e0c,0x4f08,
883 0x5004,0x5100,0x5200,0x5304,0x5400,0x5504,0x5604,0x5700,
884 0x5808,0x590c,0x5a0c,0x5b08,0x5c0c,0x5d08,0x5e08,0x5f0c,
885 0x6024,0x6120,0x6220,0x6324,0x6420,0x6524,0x6624,0x6720,
886 0x6828,0x692c,0x6a2c,0x6b28,0x6c2c,0x6d28,0x6e28,0x6f2c,
887 0x7020,0x7124,0x7224,0x7320,0x7424,0x7520,0x7620,0x7724,
888 0x782c,0x7928,0x7a28,0x7b2c,0x7c28,0x7d2c,0x7e2c,0x7f28,
889 0x8080,0x8184,0x8284,0x8380,0x8484,0x8580,0x8680,0x8784,
890 0x888c,0x8988,0x8a88,0x8b8c,0x8c88,0x8d8c,0x8e8c,0x8f88,
891 0x9084,0x9180,0x9280,0x9384,0x9480,0x9584,0x9684,0x9780,
892 0x9888,0x998c,0x9a8c,0x9b88,0x9c8c,0x9d88,0x9e88,0x9f8c,
893 0xa0a4,0xa1a0,0xa2a0,0xa3a4,0xa4a0,0xa5a4,0xa6a4,0xa7a0,
894 0xa8a8,0xa9ac,0xaaac,0xaba8,0xacac,0xada8,0xaea8,0xafac,
895 0xb0a0,0xb1a4,0xb2a4,0xb3a0,0xb4a4,0xb5a0,0xb6a0,0xb7a4,
896 0xb8ac,0xb9a8,0xbaa8,0xbbac,0xbca8,0xbdac,0xbeac,0xbfa8,
897 0xc084,0xc180,0xc280,0xc384,0xc480,0xc584,0xc684,0xc780,
898 0xc888,0xc98c,0xca8c,0xcb88,0xcc8c,0xcd88,0xce88,0xcf8c,
899 0xd080,0xd184,0xd284,0xd380,0xd484,0xd580,0xd680,0xd784,
900 0xd88c,0xd988,0xda88,0xdb8c,0xdc88,0xdd8c,0xde8c,0xdf88,
901 0xe0a0,0xe1a4,0xe2a4,0xe3a0,0xe4a4,0xe5a0,0xe6a0,0xe7a4,
902 0xe8ac,0xe9a8,0xeaa8,0xebac,0xeca8,0xedac,0xeeac,0xefa8,
903 0xf0a4,0xf1a0,0xf2a0,0xf3a4,0xf4a0,0xf5a4,0xf6a4,0xf7a0,
904 0xf8a8,0xf9ac,0xfaac,0xfba8,0xfcac,0xfda8,0xfea8,0xffac,
905 };
906
907 /* cpTable[i] = (i & 0x80) | (((i & 0xff) == 0) << 6), i = 0..255 */
908 static const uint8 cpTable[256] = {
909 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
910 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
911 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
912 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
913 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
914 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
915 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
916 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
917 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
918 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
919 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
920 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
921 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
922 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
923 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
924 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
925 };
926
927 /* Memory management */
928
929 uint8 MOPT[MAXBANKSIZE]; /* RAM which is present */
930
GET_BYTE(register uint32 Addr)931 static uint8 GET_BYTE(register uint32 Addr) {
932 return MOPT[Addr & ADDRMASK];
933 }
934
PUT_BYTE(register uint32 Addr,register uint32 Value)935 static void PUT_BYTE(register uint32 Addr, register uint32 Value) {
936 MOPT[Addr & ADDRMASK] = Value;
937 }
938
PUT_WORD(register uint32 Addr,register uint32 Value)939 static void PUT_WORD(register uint32 Addr, register uint32 Value) {
940 MOPT[Addr & ADDRMASK] = Value;
941 MOPT[(Addr + 1) & ADDRMASK] = Value >> 8;
942 }
943
GET_WORD(register uint32 a)944 static uint16 GET_WORD(register uint32 a) {
945 return GET_BYTE(a) | (GET_BYTE(a + 1) << 8);
946 }
947
948 #define RAM_MM(a) GET_BYTE(a--)
949 #define RAM_PP(a) GET_BYTE(a++)
950
951 #define PUT_BYTE_PP(a,v) PUT_BYTE(a++, v)
952 #define PUT_BYTE_MM(a,v) PUT_BYTE(a--, v)
953 #define MM_PUT_BYTE(a,v) PUT_BYTE(--a, v)
954
955 #define PUSH(x) do { \
956 MM_PUT_BYTE(SP, (x) >> 8); \
957 MM_PUT_BYTE(SP, x); \
958 } while (0)
959
960 /* Macros for the IN/OUT instructions INI/INIR/IND/INDR/OUTI/OTIR/OUTD/OTDR
961
962 Pre condition
963 temp == value of register B at entry of the instruction
964 acu == value of transferred byte (IN or OUT)
965 Post condition
966 F is set correctly
967
968 Use INOUTFLAGS_ZERO(x) for INIR/INDR/OTIR/OTDR where
969 x == (C + 1) & 0xff for INIR
970 x == L for OTIR and OTDR
971 x == (C - 1) & 0xff for INDR
972 Use INOUTFLAGS_NONZERO(x) for INI/IND/OUTI/OUTD where
973 x == (C + 1) & 0xff for INI
974 x == L for OUTI and OUTD
975 x == (C - 1) & 0xff for IND
976 */
977 #define INOUTFLAGS(syxz, x) \
978 AF = (AF & 0xff00) | (syxz) | /* SF, YF, XF, ZF */ \
979 ((acu & 0x80) >> 6) | /* NF */ \
980 ((acu + (x)) > 0xff ? (FLAG_C | FLAG_H) : 0) | /* CF, HF */ \
981 parityTable[((acu + (x)) & 7) ^ temp] /* PF */
982
983 #define INOUTFLAGS_ZERO(x) INOUTFLAGS(FLAG_Z, x)
984 #define INOUTFLAGS_NONZERO(x) \
985 INOUTFLAGS((HIGH_REGISTER(BC) & 0xa8) | ((HIGH_REGISTER(BC) == 0) << 6), x)
986
sim_instr_nommu(void)987 t_stat sim_instr_nommu(void) {
988 extern int32 sim_interval;
989 extern uint32 sim_brk_summ;
990 int32 reason = SCPE_OK;
991 register uint32 AF;
992 register uint32 BC;
993 register uint32 DE;
994 register uint32 HL;
995 register uint32 PC;
996 register uint32 SP;
997 register uint32 IX;
998 register uint32 IY;
999 register uint32 temp = 0;
1000 register uint32 acu = 0;
1001 register uint32 sum;
1002 register uint32 cbits;
1003 register uint32 op;
1004 register uint32 adr;
1005 register int32 l_sim_brk_summ;
1006
1007 AF = AF_S;
1008 BC = BC_S;
1009 DE = DE_S;
1010 HL = HL_S;
1011 PC = PC_S & ADDRMASK;
1012 SP = SP_S;
1013 IX = IX_S;
1014 IY = IY_S;
1015 l_sim_brk_summ = sim_brk_summ;
1016
1017 /* main instruction fetch/decode loop */
1018 while (TRUE) { /* loop until halted */
1019 if (sim_interval <= 0) { /* check clock queue */
1020 #if !UNIX_PLATFORM
1021 if ((reason = sim_poll_kbd()) == SCPE_STOP)
1022 break; /* poll on platforms without reliable signalling */
1023 #endif
1024 if ((reason = sim_process_event()))
1025 break;
1026 }
1027
1028 if (l_sim_brk_summ && sim_brk_test(PC, SWMASK('E'))) {/* breakpoint? */
1029 reason = STOP_IBKPT; /* stop simulation */
1030 break;
1031 }
1032
1033 PCX = PC;
1034 sim_interval--;
1035
1036 switch(RAM_PP(PC)) {
1037
1038 case 0x00: /* NOP */
1039 break;
1040
1041 case 0x01: /* LD BC,nnnn */
1042 BC = GET_WORD(PC);
1043 PC += 2;
1044 break;
1045
1046 case 0x02: /* LD (BC),A */
1047 PUT_BYTE(BC, HIGH_REGISTER(AF));
1048 break;
1049
1050 case 0x03: /* INC BC */
1051 ++BC;
1052 break;
1053
1054 case 0x04: /* INC B */
1055 BC += 0x100;
1056 temp = HIGH_REGISTER(BC);
1057 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80); /* SET_PV2 uses temp */
1058 break;
1059
1060 case 0x05: /* DEC B */
1061 BC -= 0x100;
1062 temp = HIGH_REGISTER(BC);
1063 AF = (AF & ~0xfe) | decTable[temp] | SET_PV2(0x7f); /* SET_PV2 uses temp */
1064 break;
1065
1066 case 0x06: /* LD B,nn */
1067 SET_HIGH_REGISTER(BC, RAM_PP(PC));
1068 break;
1069
1070 case 0x07: /* RLCA */
1071 AF = ((AF >> 7) & 0x0128) | ((AF << 1) & ~0x1ff) |
1072 (AF & 0xc4) | ((AF >> 15) & 1);
1073 break;
1074
1075 case 0x08: /* EX AF,AF' */
1076 CHECK_CPU_8080;
1077 temp = AF;
1078 AF = AF1_S;
1079 AF1_S = temp;
1080 break;
1081
1082 case 0x09: /* ADD HL,BC */
1083 HL &= ADDRMASK;
1084 BC &= ADDRMASK;
1085 sum = HL + BC;
1086 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(HL ^ BC ^ sum) >> 8];
1087 HL = sum;
1088 break;
1089
1090 case 0x0a: /* LD A,(BC) */
1091 SET_HIGH_REGISTER(AF, GET_BYTE(BC));
1092 break;
1093
1094 case 0x0b: /* DEC BC */
1095 --BC;
1096 break;
1097
1098 case 0x0c: /* INC C */
1099 temp = LOW_REGISTER(BC) + 1;
1100 SET_LOW_REGISTER(BC, temp);
1101 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80);
1102 break;
1103
1104 case 0x0d: /* DEC C */
1105 temp = LOW_REGISTER(BC) - 1;
1106 SET_LOW_REGISTER(BC, temp);
1107 AF = (AF & ~0xfe) | decTable[temp & 0xff] | SET_PV2(0x7f);
1108 break;
1109
1110 case 0x0e: /* LD C,nn */
1111 SET_LOW_REGISTER(BC, RAM_PP(PC));
1112 break;
1113
1114 case 0x0f: /* RRCA */
1115 AF = (AF & 0xc4) | rrcaTable[HIGH_REGISTER(AF)];
1116 break;
1117
1118 case 0x10: /* DJNZ dd */
1119 CHECK_CPU_8080;
1120 if ((BC -= 0x100) & 0xff00)
1121 PC += (int8) GET_BYTE(PC) + 1;
1122 else
1123 PC++;
1124 break;
1125
1126 case 0x11: /* LD DE,nnnn */
1127 DE = GET_WORD(PC);
1128 PC += 2;
1129 break;
1130
1131 case 0x12: /* LD (DE),A */
1132 PUT_BYTE(DE, HIGH_REGISTER(AF));
1133 break;
1134
1135 case 0x13: /* INC DE */
1136 ++DE;
1137 break;
1138
1139 case 0x14: /* INC D */
1140 DE += 0x100;
1141 temp = HIGH_REGISTER(DE);
1142 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80); /* SET_PV2 uses temp */
1143 break;
1144
1145 case 0x15: /* DEC D */
1146 DE -= 0x100;
1147 temp = HIGH_REGISTER(DE);
1148 AF = (AF & ~0xfe) | decTable[temp] | SET_PV2(0x7f); /* SET_PV2 uses temp */
1149 break;
1150
1151 case 0x16: /* LD D,nn */
1152 SET_HIGH_REGISTER(DE, RAM_PP(PC));
1153 break;
1154
1155 case 0x17: /* RLA */
1156 AF = ((AF << 8) & 0x0100) | ((AF >> 7) & 0x28) | ((AF << 1) & ~0x01ff) |
1157 (AF & 0xc4) | ((AF >> 15) & 1);
1158 break;
1159
1160 case 0x18: /* JR dd */
1161 CHECK_CPU_8080;
1162 PC += (int8) GET_BYTE(PC) + 1;
1163 break;
1164
1165 case 0x19: /* ADD HL,DE */
1166 HL &= ADDRMASK;
1167 DE &= ADDRMASK;
1168 sum = HL + DE;
1169 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(HL ^ DE ^ sum) >> 8];
1170 HL = sum;
1171 break;
1172
1173 case 0x1a: /* LD A,(DE) */
1174 SET_HIGH_REGISTER(AF, GET_BYTE(DE));
1175 break;
1176
1177 case 0x1b: /* DEC DE */
1178 --DE;
1179 break;
1180
1181 case 0x1c: /* INC E */
1182 temp = LOW_REGISTER(DE) + 1;
1183 SET_LOW_REGISTER(DE, temp);
1184 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80);
1185 break;
1186
1187 case 0x1d: /* DEC E */
1188 temp = LOW_REGISTER(DE) - 1;
1189 SET_LOW_REGISTER(DE, temp);
1190 AF = (AF & ~0xfe) | decTable[temp & 0xff] | SET_PV2(0x7f);
1191 break;
1192
1193 case 0x1e: /* LD E,nn */
1194 SET_LOW_REGISTER(DE, RAM_PP(PC));
1195 break;
1196
1197 case 0x1f: /* RRA */
1198 AF = ((AF & 1) << 15) | (AF & 0xc4) | rraTable[HIGH_REGISTER(AF)];
1199 break;
1200
1201 case 0x20: /* JR NZ,dd */
1202 CHECK_CPU_8080;
1203 if (TSTFLAG(Z))
1204 PC++;
1205 else
1206 PC += (int8) GET_BYTE(PC) + 1;
1207 break;
1208
1209 case 0x21: /* LD HL,nnnn */
1210 HL = GET_WORD(PC);
1211 PC += 2;
1212 break;
1213
1214 case 0x22: /* LD (nnnn),HL */
1215 temp = GET_WORD(PC);
1216 PUT_WORD(temp, HL);
1217 PC += 2;
1218 break;
1219
1220 case 0x23: /* INC HL */
1221 ++HL;
1222 break;
1223
1224 case 0x24: /* INC H */
1225 HL += 0x100;
1226 temp = HIGH_REGISTER(HL);
1227 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80); /* SET_PV2 uses temp */
1228 break;
1229
1230 case 0x25: /* DEC H */
1231 HL -= 0x100;
1232 temp = HIGH_REGISTER(HL);
1233 AF = (AF & ~0xfe) | decTable[temp] | SET_PV2(0x7f); /* SET_PV2 uses temp */
1234 break;
1235
1236 case 0x26: /* LD H,nn */
1237 SET_HIGH_REGISTER(HL, RAM_PP(PC));
1238 break;
1239
1240 case 0x27: /* DAA */
1241 acu = HIGH_REGISTER(AF);
1242 temp = LOW_DIGIT(acu);
1243 cbits = TSTFLAG(C);
1244 if (TSTFLAG(N)) { /* last operation was a subtract */
1245 int hd = cbits || acu > 0x99;
1246 if (TSTFLAG(H) || (temp > 9)) { /* adjust low digit */
1247 if (temp > 5)
1248 SETFLAG(H, 0);
1249 acu -= 6;
1250 acu &= 0xff;
1251 }
1252 if (hd)
1253 acu -= 0x160; /* adjust high digit */
1254 }
1255 else { /* last operation was an add */
1256 if (TSTFLAG(H) || (temp > 9)) { /* adjust low digit */
1257 SETFLAG(H, (temp > 9));
1258 acu += 6;
1259 }
1260 if (cbits || ((acu & 0x1f0) > 0x90))
1261 acu += 0x60; /* adjust high digit */
1262 }
1263 AF = (AF & 0x12) | rrdrldTable[acu & 0xff] | ((acu >> 8) & 1) | cbits;
1264 break;
1265
1266 case 0x28: /* JR Z,dd */
1267 CHECK_CPU_8080;
1268 if (TSTFLAG(Z))
1269 PC += (int8) GET_BYTE(PC) + 1;
1270 else
1271 PC++;
1272 break;
1273
1274 case 0x29: /* ADD HL,HL */
1275 HL &= ADDRMASK;
1276 sum = HL + HL;
1277 AF = (AF & ~0x3b) | cbitsDup16Table[sum >> 8];
1278 HL = sum;
1279 break;
1280
1281 case 0x2a: /* LD HL,(nnnn) */
1282 temp = GET_WORD(PC);
1283 HL = GET_WORD(temp);
1284 PC += 2;
1285 break;
1286
1287 case 0x2b: /* DEC HL */
1288 --HL;
1289 break;
1290
1291 case 0x2c: /* INC L */
1292 temp = LOW_REGISTER(HL) + 1;
1293 SET_LOW_REGISTER(HL, temp);
1294 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80);
1295 break;
1296
1297 case 0x2d: /* DEC L */
1298 temp = LOW_REGISTER(HL) - 1;
1299 SET_LOW_REGISTER(HL, temp);
1300 AF = (AF & ~0xfe) | decTable[temp & 0xff] | SET_PV2(0x7f);
1301 break;
1302
1303 case 0x2e: /* LD L,nn */
1304 SET_LOW_REGISTER(HL, RAM_PP(PC));
1305 break;
1306
1307 case 0x2f: /* CPL */
1308 AF = (~AF & ~0xff) | (AF & 0xc5) | ((~AF >> 8) & 0x28) | 0x12;
1309 break;
1310
1311 case 0x30: /* JR NC,dd */
1312 CHECK_CPU_8080;
1313 if (TSTFLAG(C))
1314 PC++;
1315 else
1316 PC += (int8) GET_BYTE(PC) + 1;
1317 break;
1318
1319 case 0x31: /* LD SP,nnnn */
1320 SP = GET_WORD(PC);
1321 PC += 2;
1322 break;
1323
1324 case 0x32: /* LD (nnnn),A */
1325 temp = GET_WORD(PC);
1326 PUT_BYTE(temp, HIGH_REGISTER(AF));
1327 PC += 2;
1328 break;
1329
1330 case 0x33: /* INC SP */
1331 ++SP;
1332 break;
1333
1334 case 0x34: /* INC (HL) */
1335 temp = GET_BYTE(HL) + 1;
1336 PUT_BYTE(HL, temp);
1337 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80);
1338 break;
1339
1340 case 0x35: /* DEC (HL) */
1341 temp = GET_BYTE(HL) - 1;
1342 PUT_BYTE(HL, temp);
1343 AF = (AF & ~0xfe) | decTable[temp & 0xff] | SET_PV2(0x7f);
1344 break;
1345
1346 case 0x36: /* LD (HL),nn */
1347 PUT_BYTE(HL, RAM_PP(PC));
1348 break;
1349
1350 case 0x37: /* SCF */
1351 AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | 1;
1352 break;
1353
1354 case 0x38: /* JR C,dd */
1355 CHECK_CPU_8080;
1356 if (TSTFLAG(C))
1357 PC += (int8) GET_BYTE(PC) + 1;
1358 else
1359 PC++;
1360 break;
1361
1362 case 0x39: /* ADD HL,SP */
1363 HL &= ADDRMASK;
1364 SP &= ADDRMASK;
1365 sum = HL + SP;
1366 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(HL ^ SP ^ sum) >> 8];
1367 HL = sum;
1368 break;
1369
1370 case 0x3a: /* LD A,(nnnn) */
1371 temp = GET_WORD(PC);
1372 SET_HIGH_REGISTER(AF, GET_BYTE(temp));
1373 PC += 2;
1374 break;
1375
1376 case 0x3b: /* DEC SP */
1377 --SP;
1378 break;
1379
1380 case 0x3c: /* INC A */
1381 AF += 0x100;
1382 temp = HIGH_REGISTER(AF);
1383 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80); /* SET_PV2 uses temp */
1384 break;
1385
1386 case 0x3d: /* DEC A */
1387 AF -= 0x100;
1388 temp = HIGH_REGISTER(AF);
1389 AF = (AF & ~0xfe) | decTable[temp] | SET_PV2(0x7f); /* SET_PV2 uses temp */
1390 break;
1391
1392 case 0x3e: /* LD A,nn */
1393 SET_HIGH_REGISTER(AF, RAM_PP(PC));
1394 break;
1395
1396 case 0x3f: /* CCF */
1397 AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | ((AF & 1) << 4) | (~AF & 1);
1398 break;
1399
1400 case 0x40: /* LD B,B */
1401 break;
1402
1403 case 0x41: /* LD B,C */
1404 BC = (BC & 0xff) | ((BC & 0xff) << 8);
1405 break;
1406
1407 case 0x42: /* LD B,D */
1408 BC = (BC & 0xff) | (DE & ~0xff);
1409 break;
1410
1411 case 0x43: /* LD B,E */
1412 BC = (BC & 0xff) | ((DE & 0xff) << 8);
1413 break;
1414
1415 case 0x44: /* LD B,H */
1416 BC = (BC & 0xff) | (HL & ~0xff);
1417 break;
1418
1419 case 0x45: /* LD B,L */
1420 BC = (BC & 0xff) | ((HL & 0xff) << 8);
1421 break;
1422
1423 case 0x46: /* LD B,(HL) */
1424 SET_HIGH_REGISTER(BC, GET_BYTE(HL));
1425 break;
1426
1427 case 0x47: /* LD B,A */
1428 BC = (BC & 0xff) | (AF & ~0xff);
1429 break;
1430
1431 case 0x48: /* LD C,B */
1432 BC = (BC & ~0xff) | ((BC >> 8) & 0xff);
1433 break;
1434
1435 case 0x49: /* LD C,C */
1436 break;
1437
1438 case 0x4a: /* LD C,D */
1439 BC = (BC & ~0xff) | ((DE >> 8) & 0xff);
1440 break;
1441
1442 case 0x4b: /* LD C,E */
1443 BC = (BC & ~0xff) | (DE & 0xff);
1444 break;
1445
1446 case 0x4c: /* LD C,H */
1447 BC = (BC & ~0xff) | ((HL >> 8) & 0xff);
1448 break;
1449
1450 case 0x4d: /* LD C,L */
1451 BC = (BC & ~0xff) | (HL & 0xff);
1452 break;
1453
1454 case 0x4e: /* LD C,(HL) */
1455 SET_LOW_REGISTER(BC, GET_BYTE(HL));
1456 break;
1457
1458 case 0x4f: /* LD C,A */
1459 BC = (BC & ~0xff) | ((AF >> 8) & 0xff);
1460 break;
1461
1462 case 0x50: /* LD D,B */
1463 DE = (DE & 0xff) | (BC & ~0xff);
1464 break;
1465
1466 case 0x51: /* LD D,C */
1467 DE = (DE & 0xff) | ((BC & 0xff) << 8);
1468 break;
1469
1470 case 0x52: /* LD D,D */
1471 break;
1472
1473 case 0x53: /* LD D,E */
1474 DE = (DE & 0xff) | ((DE & 0xff) << 8);
1475 break;
1476
1477 case 0x54: /* LD D,H */
1478 DE = (DE & 0xff) | (HL & ~0xff);
1479 break;
1480
1481 case 0x55: /* LD D,L */
1482 DE = (DE & 0xff) | ((HL & 0xff) << 8);
1483 break;
1484
1485 case 0x56: /* LD D,(HL) */
1486 SET_HIGH_REGISTER(DE, GET_BYTE(HL));
1487 break;
1488
1489 case 0x57: /* LD D,A */
1490 DE = (DE & 0xff) | (AF & ~0xff);
1491 break;
1492
1493 case 0x58: /* LD E,B */
1494 DE = (DE & ~0xff) | ((BC >> 8) & 0xff);
1495 break;
1496
1497 case 0x59: /* LD E,C */
1498 DE = (DE & ~0xff) | (BC & 0xff);
1499 break;
1500
1501 case 0x5a: /* LD E,D */
1502 DE = (DE & ~0xff) | ((DE >> 8) & 0xff);
1503 break;
1504
1505 case 0x5b: /* LD E,E */
1506 break;
1507
1508 case 0x5c: /* LD E,H */
1509 DE = (DE & ~0xff) | ((HL >> 8) & 0xff);
1510 break;
1511
1512 case 0x5d: /* LD E,L */
1513 DE = (DE & ~0xff) | (HL & 0xff);
1514 break;
1515
1516 case 0x5e: /* LD E,(HL) */
1517 SET_LOW_REGISTER(DE, GET_BYTE(HL));
1518 break;
1519
1520 case 0x5f: /* LD E,A */
1521 DE = (DE & ~0xff) | ((AF >> 8) & 0xff);
1522 break;
1523
1524 case 0x60: /* LD H,B */
1525 HL = (HL & 0xff) | (BC & ~0xff);
1526 break;
1527
1528 case 0x61: /* LD H,C */
1529 HL = (HL & 0xff) | ((BC & 0xff) << 8);
1530 break;
1531
1532 case 0x62: /* LD H,D */
1533 HL = (HL & 0xff) | (DE & ~0xff);
1534 break;
1535
1536 case 0x63: /* LD H,E */
1537 HL = (HL & 0xff) | ((DE & 0xff) << 8);
1538 break;
1539
1540 case 0x64: /* LD H,H */
1541 break;
1542
1543 case 0x65: /* LD H,L */
1544 HL = (HL & 0xff) | ((HL & 0xff) << 8);
1545 break;
1546
1547 case 0x66: /* LD H,(HL) */
1548 SET_HIGH_REGISTER(HL, GET_BYTE(HL));
1549 break;
1550
1551 case 0x67: /* LD H,A */
1552 HL = (HL & 0xff) | (AF & ~0xff);
1553 break;
1554
1555 case 0x68: /* LD L,B */
1556 HL = (HL & ~0xff) | ((BC >> 8) & 0xff);
1557 break;
1558
1559 case 0x69: /* LD L,C */
1560 HL = (HL & ~0xff) | (BC & 0xff);
1561 break;
1562
1563 case 0x6a: /* LD L,D */
1564 HL = (HL & ~0xff) | ((DE >> 8) & 0xff);
1565 break;
1566
1567 case 0x6b: /* LD L,E */
1568 HL = (HL & ~0xff) | (DE & 0xff);
1569 break;
1570
1571 case 0x6c: /* LD L,H */
1572 HL = (HL & ~0xff) | ((HL >> 8) & 0xff);
1573 break;
1574
1575 case 0x6d: /* LD L,L */
1576 break;
1577
1578 case 0x6e: /* LD L,(HL) */
1579 SET_LOW_REGISTER(HL, GET_BYTE(HL));
1580 break;
1581
1582 case 0x6f: /* LD L,A */
1583 HL = (HL & ~0xff) | ((AF >> 8) & 0xff);
1584 break;
1585
1586 case 0x70: /* LD (HL),B */
1587 PUT_BYTE(HL, HIGH_REGISTER(BC));
1588 break;
1589
1590 case 0x71: /* LD (HL),C */
1591 PUT_BYTE(HL, LOW_REGISTER(BC));
1592 break;
1593
1594 case 0x72: /* LD (HL),D */
1595 PUT_BYTE(HL, HIGH_REGISTER(DE));
1596 break;
1597
1598 case 0x73: /* LD (HL),E */
1599 PUT_BYTE(HL, LOW_REGISTER(DE));
1600 break;
1601
1602 case 0x74: /* LD (HL),H */
1603 PUT_BYTE(HL, HIGH_REGISTER(HL));
1604 break;
1605
1606 case 0x75: /* LD (HL),L */
1607 PUT_BYTE(HL, LOW_REGISTER(HL));
1608 break;
1609
1610 case 0x76: /* HALT */
1611 PC--;
1612 if (cpu_unit.flags & UNIT_CPU_STOPONHALT) {
1613 reason = STOP_HALT;
1614 goto end_decode;
1615 }
1616 sim_interval = 0;
1617 break;
1618
1619 case 0x77: /* LD (HL),A */
1620 PUT_BYTE(HL, HIGH_REGISTER(AF));
1621 break;
1622
1623 case 0x78: /* LD A,B */
1624 AF = (AF & 0xff) | (BC & ~0xff);
1625 break;
1626
1627 case 0x79: /* LD A,C */
1628 AF = (AF & 0xff) | ((BC & 0xff) << 8);
1629 break;
1630
1631 case 0x7a: /* LD A,D */
1632 AF = (AF & 0xff) | (DE & ~0xff);
1633 break;
1634
1635 case 0x7b: /* LD A,E */
1636 AF = (AF & 0xff) | ((DE & 0xff) << 8);
1637 break;
1638
1639 case 0x7c: /* LD A,H */
1640 AF = (AF & 0xff) | (HL & ~0xff);
1641 break;
1642
1643 case 0x7d: /* LD A,L */
1644 AF = (AF & 0xff) | ((HL & 0xff) << 8);
1645 break;
1646
1647 case 0x7e: /* LD A,(HL) */
1648 SET_HIGH_REGISTER(AF, GET_BYTE(HL));
1649 break;
1650
1651 case 0x7f: /* LD A,A */
1652 break;
1653
1654 case 0x80: /* ADD A,B */
1655 temp = HIGH_REGISTER(BC);
1656 acu = HIGH_REGISTER(AF);
1657 sum = acu + temp;
1658 cbits = acu ^ temp ^ sum;
1659 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1660 break;
1661
1662 case 0x81: /* ADD A,C */
1663 temp = LOW_REGISTER(BC);
1664 acu = HIGH_REGISTER(AF);
1665 sum = acu + temp;
1666 cbits = acu ^ temp ^ sum;
1667 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1668 break;
1669
1670 case 0x82: /* ADD A,D */
1671 temp = HIGH_REGISTER(DE);
1672 acu = HIGH_REGISTER(AF);
1673 sum = acu + temp;
1674 cbits = acu ^ temp ^ sum;
1675 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1676 break;
1677
1678 case 0x83: /* ADD A,E */
1679 temp = LOW_REGISTER(DE);
1680 acu = HIGH_REGISTER(AF);
1681 sum = acu + temp;
1682 cbits = acu ^ temp ^ sum;
1683 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1684 break;
1685
1686 case 0x84: /* ADD A,H */
1687 temp = HIGH_REGISTER(HL);
1688 acu = HIGH_REGISTER(AF);
1689 sum = acu + temp;
1690 cbits = acu ^ temp ^ sum;
1691 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1692 break;
1693
1694 case 0x85: /* ADD A,L */
1695 temp = LOW_REGISTER(HL);
1696 acu = HIGH_REGISTER(AF);
1697 sum = acu + temp;
1698 cbits = acu ^ temp ^ sum;
1699 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1700 break;
1701
1702 case 0x86: /* ADD A,(HL) */
1703 temp = GET_BYTE(HL);
1704 acu = HIGH_REGISTER(AF);
1705 sum = acu + temp;
1706 cbits = acu ^ temp ^ sum;
1707 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1708 break;
1709
1710 case 0x87: /* ADD A,A */
1711 cbits = 2 * HIGH_REGISTER(AF);
1712 AF = cbitsDup8Table[cbits] | (SET_PVS(cbits));
1713 break;
1714
1715 case 0x88: /* ADC A,B */
1716 temp = HIGH_REGISTER(BC);
1717 acu = HIGH_REGISTER(AF);
1718 sum = acu + temp + TSTFLAG(C);
1719 cbits = acu ^ temp ^ sum;
1720 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1721 break;
1722
1723 case 0x89: /* ADC A,C */
1724 temp = LOW_REGISTER(BC);
1725 acu = HIGH_REGISTER(AF);
1726 sum = acu + temp + TSTFLAG(C);
1727 cbits = acu ^ temp ^ sum;
1728 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1729 break;
1730
1731 case 0x8a: /* ADC A,D */
1732 temp = HIGH_REGISTER(DE);
1733 acu = HIGH_REGISTER(AF);
1734 sum = acu + temp + TSTFLAG(C);
1735 cbits = acu ^ temp ^ sum;
1736 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1737 break;
1738
1739 case 0x8b: /* ADC A,E */
1740 temp = LOW_REGISTER(DE);
1741 acu = HIGH_REGISTER(AF);
1742 sum = acu + temp + TSTFLAG(C);
1743 cbits = acu ^ temp ^ sum;
1744 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1745 break;
1746
1747 case 0x8c: /* ADC A,H */
1748 temp = HIGH_REGISTER(HL);
1749 acu = HIGH_REGISTER(AF);
1750 sum = acu + temp + TSTFLAG(C);
1751 cbits = acu ^ temp ^ sum;
1752 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1753 break;
1754
1755 case 0x8d: /* ADC A,L */
1756 temp = LOW_REGISTER(HL);
1757 acu = HIGH_REGISTER(AF);
1758 sum = acu + temp + TSTFLAG(C);
1759 cbits = acu ^ temp ^ sum;
1760 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1761 break;
1762
1763 case 0x8e: /* ADC A,(HL) */
1764 temp = GET_BYTE(HL);
1765 acu = HIGH_REGISTER(AF);
1766 sum = acu + temp + TSTFLAG(C);
1767 cbits = acu ^ temp ^ sum;
1768 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
1769 break;
1770
1771 case 0x8f: /* ADC A,A */
1772 cbits = 2 * HIGH_REGISTER(AF) + TSTFLAG(C);
1773 AF = cbitsDup8Table[cbits] | (SET_PVS(cbits));
1774 break;
1775
1776 case 0x90: /* SUB B */
1777 temp = HIGH_REGISTER(BC);
1778 acu = HIGH_REGISTER(AF);
1779 sum = acu - temp;
1780 cbits = acu ^ temp ^ sum;
1781 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1782 break;
1783
1784 case 0x91: /* SUB C */
1785 temp = LOW_REGISTER(BC);
1786 acu = HIGH_REGISTER(AF);
1787 sum = acu - temp;
1788 cbits = acu ^ temp ^ sum;
1789 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1790 break;
1791
1792 case 0x92: /* SUB D */
1793 temp = HIGH_REGISTER(DE);
1794 acu = HIGH_REGISTER(AF);
1795 sum = acu - temp;
1796 cbits = acu ^ temp ^ sum;
1797 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1798 break;
1799
1800 case 0x93: /* SUB E */
1801 temp = LOW_REGISTER(DE);
1802 acu = HIGH_REGISTER(AF);
1803 sum = acu - temp;
1804 cbits = acu ^ temp ^ sum;
1805 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1806 break;
1807
1808 case 0x94: /* SUB H */
1809 temp = HIGH_REGISTER(HL);
1810 acu = HIGH_REGISTER(AF);
1811 sum = acu - temp;
1812 cbits = acu ^ temp ^ sum;
1813 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1814 break;
1815
1816 case 0x95: /* SUB L */
1817 temp = LOW_REGISTER(HL);
1818 acu = HIGH_REGISTER(AF);
1819 sum = acu - temp;
1820 cbits = acu ^ temp ^ sum;
1821 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1822 break;
1823
1824 case 0x96: /* SUB (HL) */
1825 temp = GET_BYTE(HL);
1826 acu = HIGH_REGISTER(AF);
1827 sum = acu - temp;
1828 cbits = acu ^ temp ^ sum;
1829 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1830 break;
1831
1832 case 0x97: /* SUB A */
1833 AF = (chiptype == CHIP_TYPE_Z80) ? 0x42 : 0x46;
1834 break;
1835
1836 case 0x98: /* SBC A,B */
1837 temp = HIGH_REGISTER(BC);
1838 acu = HIGH_REGISTER(AF);
1839 sum = acu - temp - TSTFLAG(C);
1840 cbits = acu ^ temp ^ sum;
1841 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1842 break;
1843
1844 case 0x99: /* SBC A,C */
1845 temp = LOW_REGISTER(BC);
1846 acu = HIGH_REGISTER(AF);
1847 sum = acu - temp - TSTFLAG(C);
1848 cbits = acu ^ temp ^ sum;
1849 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1850 break;
1851
1852 case 0x9a: /* SBC A,D */
1853 temp = HIGH_REGISTER(DE);
1854 acu = HIGH_REGISTER(AF);
1855 sum = acu - temp - TSTFLAG(C);
1856 cbits = acu ^ temp ^ sum;
1857 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1858 break;
1859
1860 case 0x9b: /* SBC A,E */
1861 temp = LOW_REGISTER(DE);
1862 acu = HIGH_REGISTER(AF);
1863 sum = acu - temp - TSTFLAG(C);
1864 cbits = acu ^ temp ^ sum;
1865 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1866 break;
1867
1868 case 0x9c: /* SBC A,H */
1869 temp = HIGH_REGISTER(HL);
1870 acu = HIGH_REGISTER(AF);
1871 sum = acu - temp - TSTFLAG(C);
1872 cbits = acu ^ temp ^ sum;
1873 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1874 break;
1875
1876 case 0x9d: /* SBC A,L */
1877 temp = LOW_REGISTER(HL);
1878 acu = HIGH_REGISTER(AF);
1879 sum = acu - temp - TSTFLAG(C);
1880 cbits = acu ^ temp ^ sum;
1881 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1882 break;
1883
1884 case 0x9e: /* SBC A,(HL) */
1885 temp = GET_BYTE(HL);
1886 acu = HIGH_REGISTER(AF);
1887 sum = acu - temp - TSTFLAG(C);
1888 cbits = acu ^ temp ^ sum;
1889 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
1890 break;
1891
1892 case 0x9f: /* SBC A,A */
1893 cbits = -TSTFLAG(C);
1894 AF = subTable[cbits & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PVS(cbits));
1895 break;
1896
1897 case 0xa0: /* AND B */
1898 AF = andTable[((AF & BC) >> 8) & 0xff];
1899 break;
1900
1901 case 0xa1: /* AND C */
1902 AF = andTable[((AF >> 8) & BC) & 0xff];
1903 break;
1904
1905 case 0xa2: /* AND D */
1906 AF = andTable[((AF & DE) >> 8) & 0xff];
1907 break;
1908
1909 case 0xa3: /* AND E */
1910 AF = andTable[((AF >> 8) & DE) & 0xff];
1911 break;
1912
1913 case 0xa4: /* AND H */
1914 AF = andTable[((AF & HL) >> 8) & 0xff];
1915 break;
1916
1917 case 0xa5: /* AND L */
1918 AF = andTable[((AF >> 8) & HL) & 0xff];
1919 break;
1920
1921 case 0xa6: /* AND (HL) */
1922 AF = andTable[((AF >> 8) & GET_BYTE(HL)) & 0xff];
1923 break;
1924
1925 case 0xa7: /* AND A */
1926 AF = andTable[(AF >> 8) & 0xff];
1927 break;
1928
1929 case 0xa8: /* XOR B */
1930 AF = xororTable[((AF ^ BC) >> 8) & 0xff];
1931 break;
1932
1933 case 0xa9: /* XOR C */
1934 AF = xororTable[((AF >> 8) ^ BC) & 0xff];
1935 break;
1936
1937 case 0xaa: /* XOR D */
1938 AF = xororTable[((AF ^ DE) >> 8) & 0xff];
1939 break;
1940
1941 case 0xab: /* XOR E */
1942 AF = xororTable[((AF >> 8) ^ DE) & 0xff];
1943 break;
1944
1945 case 0xac: /* XOR H */
1946 AF = xororTable[((AF ^ HL) >> 8) & 0xff];
1947 break;
1948
1949 case 0xad: /* XOR L */
1950 AF = xororTable[((AF >> 8) ^ HL) & 0xff];
1951 break;
1952
1953 case 0xae: /* XOR (HL) */
1954 AF = xororTable[((AF >> 8) ^ GET_BYTE(HL)) & 0xff];
1955 break;
1956
1957 case 0xaf: /* XOR A */
1958 AF = 0x44;
1959 break;
1960
1961 case 0xb0: /* OR B */
1962 AF = xororTable[((AF | BC) >> 8) & 0xff];
1963 break;
1964
1965 case 0xb1: /* OR C */
1966 AF = xororTable[((AF >> 8) | BC) & 0xff];
1967 break;
1968
1969 case 0xb2: /* OR D */
1970 AF = xororTable[((AF | DE) >> 8) & 0xff];
1971 break;
1972
1973 case 0xb3: /* OR E */
1974 AF = xororTable[((AF >> 8) | DE) & 0xff];
1975 break;
1976
1977 case 0xb4: /* OR H */
1978 AF = xororTable[((AF | HL) >> 8) & 0xff];
1979 break;
1980
1981 case 0xb5: /* OR L */
1982 AF = xororTable[((AF >> 8) | HL) & 0xff];
1983 break;
1984
1985 case 0xb6: /* OR (HL) */
1986 AF = xororTable[((AF >> 8) | GET_BYTE(HL)) & 0xff];
1987 break;
1988
1989 case 0xb7: /* OR A */
1990 AF = xororTable[(AF >> 8) & 0xff];
1991 break;
1992
1993 case 0xb8: /* CP B */
1994 temp = HIGH_REGISTER(BC);
1995 AF = (AF & ~0x28) | (temp & 0x28);
1996 acu = HIGH_REGISTER(AF);
1997 sum = acu - temp;
1998 cbits = acu ^ temp ^ sum;
1999 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
2000 (SET_PV) | cbits2Table[cbits & 0x1ff];
2001 break;
2002
2003 case 0xb9: /* CP C */
2004 temp = LOW_REGISTER(BC);
2005 AF = (AF & ~0x28) | (temp & 0x28);
2006 acu = HIGH_REGISTER(AF);
2007 sum = acu - temp;
2008 cbits = acu ^ temp ^ sum;
2009 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
2010 (SET_PV) | cbits2Table[cbits & 0x1ff];
2011 break;
2012
2013 case 0xba: /* CP D */
2014 temp = HIGH_REGISTER(DE);
2015 AF = (AF & ~0x28) | (temp & 0x28);
2016 acu = HIGH_REGISTER(AF);
2017 sum = acu - temp;
2018 cbits = acu ^ temp ^ sum;
2019 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
2020 (SET_PV) | cbits2Table[cbits & 0x1ff];
2021 break;
2022
2023 case 0xbb: /* CP E */
2024 temp = LOW_REGISTER(DE);
2025 AF = (AF & ~0x28) | (temp & 0x28);
2026 acu = HIGH_REGISTER(AF);
2027 sum = acu - temp;
2028 cbits = acu ^ temp ^ sum;
2029 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
2030 (SET_PV) | cbits2Table[cbits & 0x1ff];
2031 break;
2032
2033 case 0xbc: /* CP H */
2034 temp = HIGH_REGISTER(HL);
2035 AF = (AF & ~0x28) | (temp & 0x28);
2036 acu = HIGH_REGISTER(AF);
2037 sum = acu - temp;
2038 cbits = acu ^ temp ^ sum;
2039 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
2040 (SET_PV) | cbits2Table[cbits & 0x1ff];
2041 break;
2042
2043 case 0xbd: /* CP L */
2044 temp = LOW_REGISTER(HL);
2045 AF = (AF & ~0x28) | (temp & 0x28);
2046 acu = HIGH_REGISTER(AF);
2047 sum = acu - temp;
2048 cbits = acu ^ temp ^ sum;
2049 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
2050 (SET_PV) | cbits2Table[cbits & 0x1ff];
2051 break;
2052
2053 case 0xbe: /* CP (HL) */
2054 temp = GET_BYTE(HL);
2055 AF = (AF & ~0x28) | (temp & 0x28);
2056 acu = HIGH_REGISTER(AF);
2057 sum = acu - temp;
2058 cbits = acu ^ temp ^ sum;
2059 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
2060 (SET_PV) | cbits2Table[cbits & 0x1ff];
2061 break;
2062
2063 case 0xbf: /* CP A */
2064 SET_LOW_REGISTER(AF, (HIGH_REGISTER(AF) & 0x28) | (chiptype == CHIP_TYPE_Z80 ? 0x42 : 0x46));
2065 break;
2066
2067 case 0xc0: /* RET NZ */
2068 if (!(TSTFLAG(Z)))
2069 POP(PC);
2070 break;
2071
2072 case 0xc1: /* POP BC */
2073 POP(BC);
2074 break;
2075
2076 case 0xc2: /* JP NZ,nnnn */
2077 JPC(!TSTFLAG(Z));
2078 break;
2079
2080 case 0xc3: /* JP nnnn */
2081 JPC(1);
2082 break;
2083
2084 case 0xc4: /* CALL NZ,nnnn */
2085 CALLC(!TSTFLAG(Z));
2086 break;
2087
2088 case 0xc5: /* PUSH BC */
2089 PUSH(BC);
2090 break;
2091
2092 case 0xc6: /* ADD A,nn */
2093 temp = RAM_PP(PC);
2094 acu = HIGH_REGISTER(AF);
2095 sum = acu + temp;
2096 cbits = acu ^ temp ^ sum;
2097 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
2098 break;
2099
2100 case 0xc7: /* RST 0 */
2101 PUSH(PC);
2102 PC = 0;
2103 break;
2104
2105 case 0xc8: /* RET Z */
2106 if (TSTFLAG(Z))
2107 POP(PC);
2108 break;
2109
2110 case 0xc9: /* RET */
2111 POP(PC);
2112 break;
2113
2114 case 0xca: /* JP Z,nnnn */
2115 JPC(TSTFLAG(Z));
2116 break;
2117
2118 case 0xcb: /* CB prefix */
2119 CHECK_CPU_8080;
2120 adr = HL;
2121 switch ((op = GET_BYTE(PC)) & 7) {
2122
2123 case 0:
2124 ++PC;
2125 acu = HIGH_REGISTER(BC);
2126 break;
2127
2128 case 1:
2129 ++PC;
2130 acu = LOW_REGISTER(BC);
2131 break;
2132
2133 case 2:
2134 ++PC;
2135 acu = HIGH_REGISTER(DE);
2136 break;
2137
2138 case 3:
2139 ++PC;
2140 acu = LOW_REGISTER(DE);
2141 break;
2142
2143 case 4:
2144 ++PC;
2145 acu = HIGH_REGISTER(HL);
2146 break;
2147
2148 case 5:
2149 ++PC;
2150 acu = LOW_REGISTER(HL);
2151 break;
2152
2153 case 6:
2154 ++PC;
2155 acu = GET_BYTE(adr);
2156 break;
2157
2158 case 7:
2159 ++PC;
2160 acu = HIGH_REGISTER(AF);
2161 break;
2162 }
2163 switch (op & 0xc0) {
2164
2165 case 0x00: /* shift/rotate */
2166 switch (op & 0x38) {
2167
2168 case 0x00:/* RLC */
2169 temp = (acu << 1) | (acu >> 7);
2170 cbits = temp & 1;
2171 goto cbshflg1;
2172
2173 case 0x08:/* RRC */
2174 temp = (acu >> 1) | (acu << 7);
2175 cbits = temp & 0x80;
2176 goto cbshflg1;
2177
2178 case 0x10:/* RL */
2179 temp = (acu << 1) | TSTFLAG(C);
2180 cbits = acu & 0x80;
2181 goto cbshflg1;
2182
2183 case 0x18:/* RR */
2184 temp = (acu >> 1) | (TSTFLAG(C) << 7);
2185 cbits = acu & 1;
2186 goto cbshflg1;
2187
2188 case 0x20:/* SLA */
2189 temp = acu << 1;
2190 cbits = acu & 0x80;
2191 goto cbshflg1;
2192
2193 case 0x28:/* SRA */
2194 temp = (acu >> 1) | (acu & 0x80);
2195 cbits = acu & 1;
2196 goto cbshflg1;
2197
2198 case 0x30:/* SLIA */
2199 temp = (acu << 1) | 1;
2200 cbits = acu & 0x80;
2201 goto cbshflg1;
2202
2203 case 0x38:/* SRL */
2204 temp = acu >> 1;
2205 cbits = acu & 1;
2206 cbshflg1:
2207 AF = (AF & ~0xff) | rotateShiftTable[temp & 0xff] | !!cbits;
2208 }
2209 break;
2210
2211 case 0x40: /* BIT */
2212 if (acu & (1 << ((op >> 3) & 7)))
2213 AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7);
2214 else
2215 AF = (AF & ~0xfe) | 0x54;
2216 if ((op & 7) != 6)
2217 AF |= (acu & 0x28);
2218 temp = acu;
2219 break;
2220
2221 case 0x80: /* RES */
2222 temp = acu & ~(1 << ((op >> 3) & 7));
2223 break;
2224
2225 case 0xc0: /* SET */
2226 temp = acu | (1 << ((op >> 3) & 7));
2227 break;
2228 }
2229 switch (op & 7) {
2230
2231 case 0:
2232 SET_HIGH_REGISTER(BC, temp);
2233 break;
2234
2235 case 1:
2236 SET_LOW_REGISTER(BC, temp);
2237 break;
2238
2239 case 2:
2240 SET_HIGH_REGISTER(DE, temp);
2241 break;
2242
2243 case 3:
2244 SET_LOW_REGISTER(DE, temp);
2245 break;
2246
2247 case 4:
2248 SET_HIGH_REGISTER(HL, temp);
2249 break;
2250
2251 case 5:
2252 SET_LOW_REGISTER(HL, temp);
2253 break;
2254
2255 case 6:
2256 PUT_BYTE(adr, temp);
2257 break;
2258
2259 case 7:
2260 SET_HIGH_REGISTER(AF, temp);
2261 break;
2262 }
2263 break;
2264
2265 case 0xcc: /* CALL Z,nnnn */
2266 CALLC(TSTFLAG(Z));
2267 break;
2268
2269 case 0xcd: /* CALL nnnn */
2270 CALLC(1);
2271 break;
2272
2273 case 0xce: /* ADC A,nn */
2274 temp = RAM_PP(PC);
2275 acu = HIGH_REGISTER(AF);
2276 sum = acu + temp + TSTFLAG(C);
2277 cbits = acu ^ temp ^ sum;
2278 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
2279 break;
2280
2281 case 0xcf: /* RST 8 */
2282 PUSH(PC);
2283 PC = 8;
2284 break;
2285
2286 case 0xd0: /* RET NC */
2287 if (!(TSTFLAG(C)))
2288 POP(PC);
2289 break;
2290
2291 case 0xd1: /* POP DE */
2292 POP(DE);
2293 break;
2294
2295 case 0xd2: /* JP NC,nnnn */
2296 JPC(!TSTFLAG(C));
2297 break;
2298
2299 case 0xd3: /* OUT (nn),A */
2300 out(RAM_PP(PC), HIGH_REGISTER(AF));
2301 break;
2302
2303 case 0xd4: /* CALL NC,nnnn */
2304 CALLC(!TSTFLAG(C));
2305 break;
2306
2307 case 0xd5: /* PUSH DE */
2308 PUSH(DE);
2309 break;
2310
2311 case 0xd6: /* SUB nn */
2312 temp = RAM_PP(PC);
2313 acu = HIGH_REGISTER(AF);
2314 sum = acu - temp;
2315 cbits = acu ^ temp ^ sum;
2316 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
2317 break;
2318
2319 case 0xd7: /* RST 10H */
2320 PUSH(PC);
2321 PC = 0x10;
2322 break;
2323
2324 case 0xd8: /* RET C */
2325 if (TSTFLAG(C))
2326 POP(PC);
2327 break;
2328
2329 case 0xd9: /* EXX */
2330 CHECK_CPU_8080;
2331 temp = BC;
2332 BC = BC1_S;
2333 BC1_S = temp;
2334 temp = DE;
2335 DE = DE1_S;
2336 DE1_S = temp;
2337 temp = HL;
2338 HL = HL1_S;
2339 HL1_S = temp;
2340 break;
2341
2342 case 0xda: /* JP C,nnnn */
2343 JPC(TSTFLAG(C));
2344 break;
2345
2346 case 0xdb: /* IN A,(nn) */
2347 SET_HIGH_REGISTER(AF, in(RAM_PP(PC)));
2348 break;
2349
2350 case 0xdc: /* CALL C,nnnn */
2351 CALLC(TSTFLAG(C));
2352 break;
2353
2354 case 0xdd: /* DD prefix */
2355 CHECK_CPU_8080;
2356 switch (RAM_PP(PC)) {
2357
2358 case 0x09: /* ADD IX,BC */
2359 IX &= ADDRMASK;
2360 BC &= ADDRMASK;
2361 sum = IX + BC;
2362 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IX ^ BC ^ sum) >> 8];
2363 IX = sum;
2364 break;
2365
2366 case 0x19: /* ADD IX,DE */
2367 IX &= ADDRMASK;
2368 DE &= ADDRMASK;
2369 sum = IX + DE;
2370 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IX ^ DE ^ sum) >> 8];
2371 IX = sum;
2372 break;
2373
2374 case 0x21: /* LD IX,nnnn */
2375 IX = GET_WORD(PC);
2376 PC += 2;
2377 break;
2378
2379 case 0x22: /* LD (nnnn),IX */
2380 temp = GET_WORD(PC);
2381 PUT_WORD(temp, IX);
2382 PC += 2;
2383 break;
2384
2385 case 0x23: /* INC IX */
2386 ++IX;
2387 break;
2388
2389 case 0x24: /* INC IXH */
2390 IX += 0x100;
2391 AF = (AF & ~0xfe) | incZ80Table[HIGH_REGISTER(IX)];
2392 break;
2393
2394 case 0x25: /* DEC IXH */
2395 IX -= 0x100;
2396 AF = (AF & ~0xfe) | decZ80Table[HIGH_REGISTER(IX)];
2397 break;
2398
2399 case 0x26: /* LD IXH,nn */
2400 SET_HIGH_REGISTER(IX, RAM_PP(PC));
2401 break;
2402
2403 case 0x29: /* ADD IX,IX */
2404 IX &= ADDRMASK;
2405 sum = IX + IX;
2406 AF = (AF & ~0x3b) | cbitsDup16Table[sum >> 8];
2407 IX = sum;
2408 break;
2409
2410 case 0x2a: /* LD IX,(nnnn) */
2411 temp = GET_WORD(PC);
2412 IX = GET_WORD(temp);
2413 PC += 2;
2414 break;
2415
2416 case 0x2b: /* DEC IX */
2417 --IX;
2418 break;
2419
2420 case 0x2c: /* INC IXL */
2421 temp = LOW_REGISTER(IX) + 1;
2422 SET_LOW_REGISTER(IX, temp);
2423 AF = (AF & ~0xfe) | incZ80Table[temp];
2424 break;
2425
2426 case 0x2d: /* DEC IXL */
2427 temp = LOW_REGISTER(IX) - 1;
2428 SET_LOW_REGISTER(IX, temp);
2429 AF = (AF & ~0xfe) | decZ80Table[temp & 0xff];
2430 break;
2431
2432 case 0x2e: /* LD IXL,nn */
2433 SET_LOW_REGISTER(IX, RAM_PP(PC));
2434 break;
2435
2436 case 0x34: /* INC (IX+dd) */
2437 adr = IX + (int8) RAM_PP(PC);
2438 temp = GET_BYTE(adr) + 1;
2439 PUT_BYTE(adr, temp);
2440 AF = (AF & ~0xfe) | incZ80Table[temp];
2441 break;
2442
2443 case 0x35: /* DEC (IX+dd) */
2444 adr = IX + (int8) RAM_PP(PC);
2445 temp = GET_BYTE(adr) - 1;
2446 PUT_BYTE(adr, temp);
2447 AF = (AF & ~0xfe) | decZ80Table[temp & 0xff];
2448 break;
2449
2450 case 0x36: /* LD (IX+dd),nn */
2451 adr = IX + (int8) RAM_PP(PC);
2452 PUT_BYTE(adr, RAM_PP(PC));
2453 break;
2454
2455 case 0x39: /* ADD IX,SP */
2456 IX &= ADDRMASK;
2457 SP &= ADDRMASK;
2458 sum = IX + SP;
2459 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IX ^ SP ^ sum) >> 8];
2460 IX = sum;
2461 break;
2462
2463 case 0x44: /* LD B,IXH */
2464 SET_HIGH_REGISTER(BC, HIGH_REGISTER(IX));
2465 break;
2466
2467 case 0x45: /* LD B,IXL */
2468 SET_HIGH_REGISTER(BC, LOW_REGISTER(IX));
2469 break;
2470
2471 case 0x46: /* LD B,(IX+dd) */
2472 adr = IX + (int8) RAM_PP(PC);
2473 SET_HIGH_REGISTER(BC, GET_BYTE(adr));
2474 break;
2475
2476 case 0x4c: /* LD C,IXH */
2477 SET_LOW_REGISTER(BC, HIGH_REGISTER(IX));
2478 break;
2479
2480 case 0x4d: /* LD C,IXL */
2481 SET_LOW_REGISTER(BC, LOW_REGISTER(IX));
2482 break;
2483
2484 case 0x4e: /* LD C,(IX+dd) */
2485 adr = IX + (int8) RAM_PP(PC);
2486 SET_LOW_REGISTER(BC, GET_BYTE(adr));
2487 break;
2488
2489 case 0x54: /* LD D,IXH */
2490 SET_HIGH_REGISTER(DE, HIGH_REGISTER(IX));
2491 break;
2492
2493 case 0x55: /* LD D,IXL */
2494 SET_HIGH_REGISTER(DE, LOW_REGISTER(IX));
2495 break;
2496
2497 case 0x56: /* LD D,(IX+dd) */
2498 adr = IX + (int8) RAM_PP(PC);
2499 SET_HIGH_REGISTER(DE, GET_BYTE(adr));
2500 break;
2501
2502 case 0x5c: /* LD E,IXH */
2503 SET_LOW_REGISTER(DE, HIGH_REGISTER(IX));
2504 break;
2505
2506 case 0x5d: /* LD E,IXL */
2507 SET_LOW_REGISTER(DE, LOW_REGISTER(IX));
2508 break;
2509
2510 case 0x5e: /* LD E,(IX+dd) */
2511 adr = IX + (int8) RAM_PP(PC);
2512 SET_LOW_REGISTER(DE, GET_BYTE(adr));
2513 break;
2514
2515 case 0x60: /* LD IXH,B */
2516 SET_HIGH_REGISTER(IX, HIGH_REGISTER(BC));
2517 break;
2518
2519 case 0x61: /* LD IXH,C */
2520 SET_HIGH_REGISTER(IX, LOW_REGISTER(BC));
2521 break;
2522
2523 case 0x62: /* LD IXH,D */
2524 SET_HIGH_REGISTER(IX, HIGH_REGISTER(DE));
2525 break;
2526
2527 case 0x63: /* LD IXH,E */
2528 SET_HIGH_REGISTER(IX, LOW_REGISTER(DE));
2529 break;
2530
2531 case 0x64: /* LD IXH,IXH */
2532 break;
2533
2534 case 0x65: /* LD IXH,IXL */
2535 SET_HIGH_REGISTER(IX, LOW_REGISTER(IX));
2536 break;
2537
2538 case 0x66: /* LD H,(IX+dd) */
2539 adr = IX + (int8) RAM_PP(PC);
2540 SET_HIGH_REGISTER(HL, GET_BYTE(adr));
2541 break;
2542
2543 case 0x67: /* LD IXH,A */
2544 SET_HIGH_REGISTER(IX, HIGH_REGISTER(AF));
2545 break;
2546
2547 case 0x68: /* LD IXL,B */
2548 SET_LOW_REGISTER(IX, HIGH_REGISTER(BC));
2549 break;
2550
2551 case 0x69: /* LD IXL,C */
2552 SET_LOW_REGISTER(IX, LOW_REGISTER(BC));
2553 break;
2554
2555 case 0x6a: /* LD IXL,D */
2556 SET_LOW_REGISTER(IX, HIGH_REGISTER(DE));
2557 break;
2558
2559 case 0x6b: /* LD IXL,E */
2560 SET_LOW_REGISTER(IX, LOW_REGISTER(DE));
2561 break;
2562
2563 case 0x6c: /* LD IXL,IXH */
2564 SET_LOW_REGISTER(IX, HIGH_REGISTER(IX));
2565 break;
2566
2567 case 0x6d: /* LD IXL,IXL */
2568 break;
2569
2570 case 0x6e: /* LD L,(IX+dd) */
2571 adr = IX + (int8) RAM_PP(PC);
2572 SET_LOW_REGISTER(HL, GET_BYTE(adr));
2573 break;
2574
2575 case 0x6f: /* LD IXL,A */
2576 SET_LOW_REGISTER(IX, HIGH_REGISTER(AF));
2577 break;
2578
2579 case 0x70: /* LD (IX+dd),B */
2580 adr = IX + (int8) RAM_PP(PC);
2581 PUT_BYTE(adr, HIGH_REGISTER(BC));
2582 break;
2583
2584 case 0x71: /* LD (IX+dd),C */
2585 adr = IX + (int8) RAM_PP(PC);
2586 PUT_BYTE(adr, LOW_REGISTER(BC));
2587 break;
2588
2589 case 0x72: /* LD (IX+dd),D */
2590 adr = IX + (int8) RAM_PP(PC);
2591 PUT_BYTE(adr, HIGH_REGISTER(DE));
2592 break;
2593
2594 case 0x73: /* LD (IX+dd),E */
2595 adr = IX + (int8) RAM_PP(PC);
2596 PUT_BYTE(adr, LOW_REGISTER(DE));
2597 break;
2598
2599 case 0x74: /* LD (IX+dd),H */
2600 adr = IX + (int8) RAM_PP(PC);
2601 PUT_BYTE(adr, HIGH_REGISTER(HL));
2602 break;
2603
2604 case 0x75: /* LD (IX+dd),L */
2605 adr = IX + (int8) RAM_PP(PC);
2606 PUT_BYTE(adr, LOW_REGISTER(HL));
2607 break;
2608
2609 case 0x77: /* LD (IX+dd),A */
2610 adr = IX + (int8) RAM_PP(PC);
2611 PUT_BYTE(adr, HIGH_REGISTER(AF));
2612 break;
2613
2614 case 0x7c: /* LD A,IXH */
2615 SET_HIGH_REGISTER(AF, HIGH_REGISTER(IX));
2616 break;
2617
2618 case 0x7d: /* LD A,IXL */
2619 SET_HIGH_REGISTER(AF, LOW_REGISTER(IX));
2620 break;
2621
2622 case 0x7e: /* LD A,(IX+dd) */
2623 adr = IX + (int8) RAM_PP(PC);
2624 SET_HIGH_REGISTER(AF, GET_BYTE(adr));
2625 break;
2626
2627 case 0x84: /* ADD A,IXH */
2628 temp = HIGH_REGISTER(IX);
2629 acu = HIGH_REGISTER(AF);
2630 sum = acu + temp;
2631 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
2632 break;
2633
2634 case 0x85: /* ADD A,IXL */
2635 temp = LOW_REGISTER(IX);
2636 acu = HIGH_REGISTER(AF);
2637 sum = acu + temp;
2638 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
2639 break;
2640
2641 case 0x86: /* ADD A,(IX+dd) */
2642 adr = IX + (int8) RAM_PP(PC);
2643 temp = GET_BYTE(adr);
2644 acu = HIGH_REGISTER(AF);
2645 sum = acu + temp;
2646 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
2647 break;
2648
2649 case 0x8c: /* ADC A,IXH */
2650 temp = HIGH_REGISTER(IX);
2651 acu = HIGH_REGISTER(AF);
2652 sum = acu + temp + TSTFLAG(C);
2653 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
2654 break;
2655
2656 case 0x8d: /* ADC A,IXL */
2657 temp = LOW_REGISTER(IX);
2658 acu = HIGH_REGISTER(AF);
2659 sum = acu + temp + TSTFLAG(C);
2660 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
2661 break;
2662
2663 case 0x8e: /* ADC A,(IX+dd) */
2664 adr = IX + (int8) RAM_PP(PC);
2665 temp = GET_BYTE(adr);
2666 acu = HIGH_REGISTER(AF);
2667 sum = acu + temp + TSTFLAG(C);
2668 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
2669 break;
2670
2671 case 0x96: /* SUB (IX+dd) */
2672 adr = IX + (int8) RAM_PP(PC);
2673 temp = GET_BYTE(adr);
2674 acu = HIGH_REGISTER(AF);
2675 sum = acu - temp;
2676 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
2677 break;
2678
2679 case 0x94: /* SUB IXH */
2680 SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */
2681
2682 case 0x9c: /* SBC A,IXH */
2683 temp = HIGH_REGISTER(IX);
2684 acu = HIGH_REGISTER(AF);
2685 sum = acu - temp - TSTFLAG(C);
2686 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
2687 break;
2688
2689 case 0x95: /* SUB IXL */
2690 SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */
2691
2692 case 0x9d: /* SBC A,IXL */
2693 temp = LOW_REGISTER(IX);
2694 acu = HIGH_REGISTER(AF);
2695 sum = acu - temp - TSTFLAG(C);
2696 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
2697 break;
2698
2699 case 0x9e: /* SBC A,(IX+dd) */
2700 adr = IX + (int8) RAM_PP(PC);
2701 temp = GET_BYTE(adr);
2702 acu = HIGH_REGISTER(AF);
2703 sum = acu - temp - TSTFLAG(C);
2704 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
2705 break;
2706
2707 case 0xa4: /* AND IXH */
2708 AF = andTable[((AF & IX) >> 8) & 0xff];
2709 break;
2710
2711 case 0xa5: /* AND IXL */
2712 AF = andTable[((AF >> 8) & IX) & 0xff];
2713 break;
2714
2715 case 0xa6: /* AND (IX+dd) */
2716 adr = IX + (int8) RAM_PP(PC);
2717 AF = andTable[((AF >> 8) & GET_BYTE(adr)) & 0xff];
2718 break;
2719
2720 case 0xac: /* XOR IXH */
2721 AF = xororTable[((AF ^ IX) >> 8) & 0xff];
2722 break;
2723
2724 case 0xad: /* XOR IXL */
2725 AF = xororTable[((AF >> 8) ^ IX) & 0xff];
2726 break;
2727
2728 case 0xae: /* XOR (IX+dd) */
2729 adr = IX + (int8) RAM_PP(PC);
2730 AF = xororTable[((AF >> 8) ^ GET_BYTE(adr)) & 0xff];
2731 break;
2732
2733 case 0xb4: /* OR IXH */
2734 AF = xororTable[((AF | IX) >> 8) & 0xff];
2735 break;
2736
2737 case 0xb5: /* OR IXL */
2738 AF = xororTable[((AF >> 8) | IX) & 0xff];
2739 break;
2740
2741 case 0xb6: /* OR (IX+dd) */
2742 adr = IX + (int8) RAM_PP(PC);
2743 AF = xororTable[((AF >> 8) | GET_BYTE(adr)) & 0xff];
2744 break;
2745
2746 case 0xbc: /* CP IXH */
2747 temp = HIGH_REGISTER(IX);
2748 AF = (AF & ~0x28) | (temp & 0x28);
2749 acu = HIGH_REGISTER(AF);
2750 sum = acu - temp;
2751 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
2752 cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
2753 break;
2754
2755 case 0xbd: /* CP IXL */
2756 temp = LOW_REGISTER(IX);
2757 AF = (AF & ~0x28) | (temp & 0x28);
2758 acu = HIGH_REGISTER(AF);
2759 sum = acu - temp;
2760 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
2761 cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
2762 break;
2763
2764 case 0xbe: /* CP (IX+dd) */
2765 adr = IX + (int8) RAM_PP(PC);
2766 temp = GET_BYTE(adr);
2767 AF = (AF & ~0x28) | (temp & 0x28);
2768 acu = HIGH_REGISTER(AF);
2769 sum = acu - temp;
2770 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
2771 cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
2772 break;
2773
2774 case 0xcb: /* CB prefix */
2775 adr = IX + (int8) RAM_PP(PC);
2776 switch ((op = GET_BYTE(PC)) & 7) {
2777
2778 case 0:
2779 ++PC;
2780 acu = HIGH_REGISTER(BC);
2781 break;
2782
2783 case 1:
2784 ++PC;
2785 acu = LOW_REGISTER(BC);
2786 break;
2787
2788 case 2:
2789 ++PC;
2790 acu = HIGH_REGISTER(DE);
2791 break;
2792
2793 case 3:
2794 ++PC;
2795 acu = LOW_REGISTER(DE);
2796 break;
2797
2798 case 4:
2799 ++PC;
2800 acu = HIGH_REGISTER(HL);
2801 break;
2802
2803 case 5:
2804 ++PC;
2805 acu = LOW_REGISTER(HL);
2806 break;
2807
2808 case 6:
2809 ++PC;
2810 acu = GET_BYTE(adr);
2811 break;
2812
2813 case 7:
2814 ++PC;
2815 acu = HIGH_REGISTER(AF);
2816 break;
2817 }
2818 switch (op & 0xc0) {
2819
2820 case 0x00: /* shift/rotate */
2821 switch (op & 0x38) {
2822
2823 case 0x00:/* RLC */
2824 temp = (acu << 1) | (acu >> 7);
2825 cbits = temp & 1;
2826 goto cbshflg2;
2827
2828 case 0x08:/* RRC */
2829 temp = (acu >> 1) | (acu << 7);
2830 cbits = temp & 0x80;
2831 goto cbshflg2;
2832
2833 case 0x10:/* RL */
2834 temp = (acu << 1) | TSTFLAG(C);
2835 cbits = acu & 0x80;
2836 goto cbshflg2;
2837
2838 case 0x18:/* RR */
2839 temp = (acu >> 1) | (TSTFLAG(C) << 7);
2840 cbits = acu & 1;
2841 goto cbshflg2;
2842
2843 case 0x20:/* SLA */
2844 temp = acu << 1;
2845 cbits = acu & 0x80;
2846 goto cbshflg2;
2847
2848 case 0x28:/* SRA */
2849 temp = (acu >> 1) | (acu & 0x80);
2850 cbits = acu & 1;
2851 goto cbshflg2;
2852
2853 case 0x30:/* SLIA */
2854 temp = (acu << 1) | 1;
2855 cbits = acu & 0x80;
2856 goto cbshflg2;
2857
2858 case 0x38:/* SRL */
2859 temp = acu >> 1;
2860 cbits = acu & 1;
2861 cbshflg2:
2862 AF = (AF & ~0xff) | rotateShiftTable[temp & 0xff] | !!cbits;
2863 }
2864 break;
2865
2866 case 0x40: /* BIT */
2867 if (acu & (1 << ((op >> 3) & 7)))
2868 AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7);
2869 else
2870 AF = (AF & ~0xfe) | 0x54;
2871 if ((op & 7) != 6)
2872 AF |= (acu & 0x28);
2873 temp = acu;
2874 break;
2875
2876 case 0x80: /* RES */
2877 temp = acu & ~(1 << ((op >> 3) & 7));
2878 break;
2879
2880 case 0xc0: /* SET */
2881 temp = acu | (1 << ((op >> 3) & 7));
2882 break;
2883 }
2884 switch (op & 7) {
2885
2886 case 0:
2887 SET_HIGH_REGISTER(BC, temp);
2888 break;
2889
2890 case 1:
2891 SET_LOW_REGISTER(BC, temp);
2892 break;
2893
2894 case 2:
2895 SET_HIGH_REGISTER(DE, temp);
2896 break;
2897
2898 case 3:
2899 SET_LOW_REGISTER(DE, temp);
2900 break;
2901
2902 case 4:
2903 SET_HIGH_REGISTER(HL, temp);
2904 break;
2905
2906 case 5:
2907 SET_LOW_REGISTER(HL, temp);
2908 break;
2909
2910 case 6:
2911 PUT_BYTE(adr, temp);
2912 break;
2913
2914 case 7:
2915 SET_HIGH_REGISTER(AF, temp);
2916 break;
2917 }
2918 break;
2919
2920 case 0xe1: /* POP IX */
2921 POP(IX);
2922 break;
2923
2924 case 0xe3: /* EX (SP),IX */
2925 temp = IX;
2926 POP(IX);
2927 PUSH(temp);
2928 break;
2929
2930 case 0xe5: /* PUSH IX */
2931 PUSH(IX);
2932 break;
2933
2934 case 0xe9: /* JP (IX) */
2935 PC = IX;
2936 break;
2937
2938 case 0xf9: /* LD SP,IX */
2939 SP = IX;
2940 break;
2941
2942 default: /* ignore DD */
2943 CHECK_CPU_Z80;
2944 PC--;
2945 }
2946 break;
2947
2948 case 0xde: /* SBC A,nn */
2949 temp = RAM_PP(PC);
2950 acu = HIGH_REGISTER(AF);
2951 sum = acu - temp - TSTFLAG(C);
2952 cbits = acu ^ temp ^ sum;
2953 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
2954 break;
2955
2956 case 0xdf: /* RST 18H */
2957 PUSH(PC);
2958 PC = 0x18;
2959 break;
2960
2961 case 0xe0: /* RET PO */
2962 if (!(TSTFLAG(P)))
2963 POP(PC);
2964 break;
2965
2966 case 0xe1: /* POP HL */
2967 POP(HL);
2968 break;
2969
2970 case 0xe2: /* JP PO,nnnn */
2971 JPC(!TSTFLAG(P));
2972 break;
2973
2974 case 0xe3: /* EX (SP),HL */
2975 temp = HL;
2976 POP(HL);
2977 PUSH(temp);
2978 break;
2979
2980 case 0xe4: /* CALL PO,nnnn */
2981 CALLC(!TSTFLAG(P));
2982 break;
2983
2984 case 0xe5: /* PUSH HL */
2985 PUSH(HL);
2986 break;
2987
2988 case 0xe6: /* AND nn */
2989 AF = andTable[((AF >> 8) & RAM_PP(PC)) & 0xff];
2990 break;
2991
2992 case 0xe7: /* RST 20H */
2993 PUSH(PC);
2994 PC = 0x20;
2995 break;
2996
2997 case 0xe8: /* RET PE */
2998 if (TSTFLAG(P))
2999 POP(PC);
3000 break;
3001
3002 case 0xe9: /* JP (HL) */
3003 PC = HL;
3004 break;
3005
3006 case 0xea: /* JP PE,nnnn */
3007 JPC(TSTFLAG(P));
3008 break;
3009
3010 case 0xeb: /* EX DE,HL */
3011 temp = HL;
3012 HL = DE;
3013 DE = temp;
3014 break;
3015
3016 case 0xec: /* CALL PE,nnnn */
3017 CALLC(TSTFLAG(P));
3018 break;
3019
3020 case 0xed: /* ED prefix */
3021 CHECK_CPU_8080;
3022 switch (RAM_PP(PC)) {
3023
3024 case 0x40: /* IN B,(C) */
3025 temp = in(LOW_REGISTER(BC));
3026 SET_HIGH_REGISTER(BC, temp);
3027 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
3028 break;
3029
3030 case 0x41: /* OUT (C),B */
3031 out(LOW_REGISTER(BC), HIGH_REGISTER(BC));
3032 break;
3033
3034 case 0x42: /* SBC HL,BC */
3035 HL &= ADDRMASK;
3036 BC &= ADDRMASK;
3037 sum = HL - BC - TSTFLAG(C);
3038 AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
3039 cbits2Z80Table[((HL ^ BC ^ sum) >> 8) & 0x1ff];
3040 HL = sum;
3041 break;
3042
3043 case 0x43: /* LD (nnnn),BC */
3044 temp = GET_WORD(PC);
3045 PUT_WORD(temp, BC);
3046 PC += 2;
3047 break;
3048
3049 case 0x44: /* NEG */
3050
3051 case 0x4C: /* NEG, unofficial */
3052
3053 case 0x54: /* NEG, unofficial */
3054
3055 case 0x5C: /* NEG, unofficial */
3056
3057 case 0x64: /* NEG, unofficial */
3058
3059 case 0x6C: /* NEG, unofficial */
3060
3061 case 0x74: /* NEG, unofficial */
3062
3063 case 0x7C: /* NEG, unofficial */
3064 temp = HIGH_REGISTER(AF);
3065 AF = ((~(AF & 0xff00) + 1) & 0xff00); /* AF = (-(AF & 0xff00) & 0xff00); */
3066 AF |= ((AF >> 8) & 0xa8) | (((AF & 0xff00) == 0) << 6) | negTable[temp];
3067 break;
3068
3069 case 0x45: /* RETN */
3070
3071 case 0x55: /* RETN, unofficial */
3072
3073 case 0x5D: /* RETN, unofficial */
3074
3075 case 0x65: /* RETN, unofficial */
3076
3077 case 0x6D: /* RETN, unofficial */
3078
3079 case 0x75: /* RETN, unofficial */
3080
3081 case 0x7D: /* RETN, unofficial */
3082 IFF_S |= IFF_S >> 1;
3083 POP(PC);
3084 break;
3085
3086 case 0x46: /* IM 0 */
3087 /* interrupt mode 0 */
3088 break;
3089
3090 case 0x47: /* LD I,A */
3091 IR_S = (IR_S & 0xff) | (AF & ~0xff);
3092 break;
3093
3094 case 0x48: /* IN C,(C) */
3095 temp = in(LOW_REGISTER(BC));
3096 SET_LOW_REGISTER(BC, temp);
3097 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
3098 break;
3099
3100 case 0x49: /* OUT (C),C */
3101 out(LOW_REGISTER(BC), LOW_REGISTER(BC));
3102 break;
3103
3104 case 0x4a: /* ADC HL,BC */
3105 HL &= ADDRMASK;
3106 BC &= ADDRMASK;
3107 sum = HL + BC + TSTFLAG(C);
3108 AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
3109 cbitsZ80Table[(HL ^ BC ^ sum) >> 8];
3110 HL = sum;
3111 break;
3112
3113 case 0x4b: /* LD BC,(nnnn) */
3114 temp = GET_WORD(PC);
3115 BC = GET_WORD(temp);
3116 PC += 2;
3117 break;
3118
3119 case 0x4d: /* RETI */
3120 IFF_S |= IFF_S >> 1;
3121 POP(PC);
3122 break;
3123
3124 case 0x4f: /* LD R,A */
3125 IR_S = (IR_S & ~0xff) | ((AF >> 8) & 0xff);
3126 break;
3127
3128 case 0x50: /* IN D,(C) */
3129 temp = in(LOW_REGISTER(BC));
3130 SET_HIGH_REGISTER(DE, temp);
3131 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
3132 break;
3133
3134 case 0x51: /* OUT (C),D */
3135 out(LOW_REGISTER(BC), HIGH_REGISTER(DE));
3136 break;
3137
3138 case 0x52: /* SBC HL,DE */
3139 HL &= ADDRMASK;
3140 DE &= ADDRMASK;
3141 sum = HL - DE - TSTFLAG(C);
3142 AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
3143 cbits2Z80Table[((HL ^ DE ^ sum) >> 8) & 0x1ff];
3144 HL = sum;
3145 break;
3146
3147 case 0x53: /* LD (nnnn),DE */
3148 temp = GET_WORD(PC);
3149 PUT_WORD(temp, DE);
3150 PC += 2;
3151 break;
3152
3153 case 0x56: /* IM 1 */
3154 /* interrupt mode 1 */
3155 break;
3156
3157 case 0x57: /* LD A,I */
3158 AF = (AF & 0x29) | (IR_S & ~0xff) | ((IR_S >> 8) & 0x80) | (((IR_S & ~0xff) == 0) << 6) | ((IFF_S & 2) << 1);
3159 break;
3160
3161 case 0x58: /* IN E,(C) */
3162 temp = in(LOW_REGISTER(BC));
3163 SET_LOW_REGISTER(DE, temp);
3164 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
3165 break;
3166
3167 case 0x59: /* OUT (C),E */
3168 out(LOW_REGISTER(BC), LOW_REGISTER(DE));
3169 break;
3170
3171 case 0x5a: /* ADC HL,DE */
3172 HL &= ADDRMASK;
3173 DE &= ADDRMASK;
3174 sum = HL + DE + TSTFLAG(C);
3175 AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
3176 cbitsZ80Table[(HL ^ DE ^ sum) >> 8];
3177 HL = sum;
3178 break;
3179
3180 case 0x5b: /* LD DE,(nnnn) */
3181 temp = GET_WORD(PC);
3182 DE = GET_WORD(temp);
3183 PC += 2;
3184 break;
3185
3186 case 0x5e: /* IM 2 */
3187 /* interrupt mode 2 */
3188 break;
3189
3190 case 0x5f: /* LD A,R */
3191 AF = (AF & 0x29) | ((IR_S & 0xff) << 8) | (IR_S & 0x80) |
3192 (((IR_S & 0xff) == 0) << 6) | ((IFF_S & 2) << 1);
3193 break;
3194
3195 case 0x60: /* IN H,(C) */
3196 temp = in(LOW_REGISTER(BC));
3197 SET_HIGH_REGISTER(HL, temp);
3198 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
3199 break;
3200
3201 case 0x61: /* OUT (C),H */
3202 out(LOW_REGISTER(BC), HIGH_REGISTER(HL));
3203 break;
3204
3205 case 0x62: /* SBC HL,HL */
3206 HL &= ADDRMASK;
3207 sum = HL - HL - TSTFLAG(C);
3208 AF = (AF & ~0xff) | (((sum & ADDRMASK) == 0) << 6) |
3209 cbits2Z80DupTable[(sum >> 8) & 0x1ff];
3210 HL = sum;
3211 break;
3212
3213 case 0x63: /* LD (nnnn),HL */
3214 temp = GET_WORD(PC);
3215 PUT_WORD(temp, HL);
3216 PC += 2;
3217 break;
3218
3219 case 0x67: /* RRD */
3220 temp = GET_BYTE(HL);
3221 acu = HIGH_REGISTER(AF);
3222 PUT_BYTE(HL, HIGH_DIGIT(temp) | (LOW_DIGIT(acu) << 4));
3223 AF = rrdrldTable[(acu & 0xf0) | LOW_DIGIT(temp)] | (AF & 1);
3224 break;
3225
3226 case 0x68: /* IN L,(C) */
3227 temp = in(LOW_REGISTER(BC));
3228 SET_LOW_REGISTER(HL, temp);
3229 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
3230 break;
3231
3232 case 0x69: /* OUT (C),L */
3233 out(LOW_REGISTER(BC), LOW_REGISTER(HL));
3234 break;
3235
3236 case 0x6a: /* ADC HL,HL */
3237 HL &= ADDRMASK;
3238 sum = HL + HL + TSTFLAG(C);
3239 AF = (AF & ~0xff) | (((sum & ADDRMASK) == 0) << 6) |
3240 cbitsZ80DupTable[sum >> 8];
3241 HL = sum;
3242 break;
3243
3244 case 0x6b: /* LD HL,(nnnn) */
3245 temp = GET_WORD(PC);
3246 HL = GET_WORD(temp);
3247 PC += 2;
3248 break;
3249
3250 case 0x6f: /* RLD */
3251 temp = GET_BYTE(HL);
3252 acu = HIGH_REGISTER(AF);
3253 PUT_BYTE(HL, (LOW_DIGIT(temp) << 4) | LOW_DIGIT(acu));
3254 AF = rrdrldTable[(acu & 0xf0) | HIGH_DIGIT(temp)] | (AF & 1);
3255 break;
3256
3257 case 0x70: /* IN (C) */
3258 temp = in(LOW_REGISTER(BC));
3259 SET_LOW_REGISTER(temp, temp);
3260 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
3261 break;
3262
3263 case 0x71: /* OUT (C),0 */
3264 out(LOW_REGISTER(BC), 0);
3265 break;
3266
3267 case 0x72: /* SBC HL,SP */
3268 HL &= ADDRMASK;
3269 SP &= ADDRMASK;
3270 sum = HL - SP - TSTFLAG(C);
3271 AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
3272 cbits2Z80Table[((HL ^ SP ^ sum) >> 8) & 0x1ff];
3273 HL = sum;
3274 break;
3275
3276 case 0x73: /* LD (nnnn),SP */
3277 temp = GET_WORD(PC);
3278 PUT_WORD(temp, SP);
3279 PC += 2;
3280 break;
3281
3282 case 0x78: /* IN A,(C) */
3283 temp = in(LOW_REGISTER(BC));
3284 SET_HIGH_REGISTER(AF, temp);
3285 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
3286 break;
3287
3288 case 0x79: /* OUT (C),A */
3289 out(LOW_REGISTER(BC), HIGH_REGISTER(AF));
3290 break;
3291
3292 case 0x7a: /* ADC HL,SP */
3293 HL &= ADDRMASK;
3294 SP &= ADDRMASK;
3295 sum = HL + SP + TSTFLAG(C);
3296 AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
3297 cbitsZ80Table[(HL ^ SP ^ sum) >> 8];
3298 HL = sum;
3299 break;
3300
3301 case 0x7b: /* LD SP,(nnnn) */
3302 temp = GET_WORD(PC);
3303 SP = GET_WORD(temp);
3304 PC += 2;
3305 break;
3306
3307 case 0xa0: /* LDI */
3308 acu = RAM_PP(HL);
3309 PUT_BYTE_PP(DE, acu);
3310 acu += HIGH_REGISTER(AF);
3311 AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) |
3312 (((--BC & ADDRMASK) != 0) << 2);
3313 break;
3314
3315 case 0xa1: /* CPI */
3316 acu = HIGH_REGISTER(AF);
3317 temp = RAM_PP(HL);
3318 sum = acu - temp;
3319 cbits = acu ^ temp ^ sum;
3320 AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
3321 (((sum - ((cbits & 16) >> 4)) & 2) << 4) | (cbits & 16) |
3322 ((sum - ((cbits >> 4) & 1)) & 8) |
3323 ((--BC & ADDRMASK) != 0) << 2 | 2;
3324 if ((sum & 15) == 8 && (cbits & 16) != 0)
3325 AF &= ~8;
3326 break;
3327
3328 /* SF, ZF, YF, XF flags are affected by decreasing register B, as in DEC B.
3329 NF flag A is copy of bit 7 of the value read from or written to an I/O port.
3330 INI/INIR/IND/INDR use the C flag in stead of the L register. There is a
3331 catch though, because not the value of C is used, but C + 1 if it's INI/INIR or
3332 C - 1 if it's IND/INDR. So, first of all INI/INIR:
3333 HF and CF Both set if ((HL) + ((C + 1) & 255) > 255)
3334 PF The parity of (((HL) + ((C + 1) & 255)) & 7) xor B) */
3335 case 0xa2: /* INI */
3336 acu = in(LOW_REGISTER(BC));
3337 PUT_BYTE(HL, acu);
3338 ++HL;
3339 temp = HIGH_REGISTER(BC);
3340 BC -= 0x100;
3341 INOUTFLAGS_NONZERO((LOW_REGISTER(BC) + 1) & 0xff);
3342 break;
3343
3344 /* SF, ZF, YF, XF flags are affected by decreasing register B, as in DEC B.
3345 NF flag A is copy of bit 7 of the value read from or written to an I/O port.
3346 And now the for OUTI/OTIR/OUTD/OTDR instructions. Take state of the L
3347 after the increment or decrement of HL; add the value written to the I/O port
3348 to; call that k for now. If k > 255, then the CF and HF flags are set. The PF
3349 flags is set like the parity of k bitwise and'ed with 7, bitwise xor'ed with B.
3350 HF and CF Both set if ((HL) + L > 255)
3351 PF The parity of ((((HL) + L) & 7) xor B) */
3352 case 0xa3: /* OUTI */
3353 acu = GET_BYTE(HL);
3354 out(LOW_REGISTER(BC), acu);
3355 ++HL;
3356 temp = HIGH_REGISTER(BC);
3357 BC -= 0x100;
3358 INOUTFLAGS_NONZERO(LOW_REGISTER(HL));
3359 break;
3360
3361 case 0xa8: /* LDD */
3362 acu = RAM_MM(HL);
3363 PUT_BYTE_MM(DE, acu);
3364 acu += HIGH_REGISTER(AF);
3365 AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) |
3366 (((--BC & ADDRMASK) != 0) << 2);
3367 break;
3368
3369 case 0xa9: /* CPD */
3370 acu = HIGH_REGISTER(AF);
3371 temp = RAM_MM(HL);
3372 sum = acu - temp;
3373 cbits = acu ^ temp ^ sum;
3374 AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
3375 (((sum - ((cbits & 16) >> 4)) & 2) << 4) | (cbits & 16) |
3376 ((sum - ((cbits >> 4) & 1)) & 8) |
3377 ((--BC & ADDRMASK) != 0) << 2 | 2;
3378 if ((sum & 15) == 8 && (cbits & 16) != 0)
3379 AF &= ~8;
3380 break;
3381
3382 /* SF, ZF, YF, XF flags are affected by decreasing register B, as in DEC B.
3383 NF flag A is copy of bit 7 of the value read from or written to an I/O port.
3384 INI/INIR/IND/INDR use the C flag in stead of the L register. There is a
3385 catch though, because not the value of C is used, but C + 1 if it's INI/INIR or
3386 C - 1 if it's IND/INDR. And last IND/INDR:
3387 HF and CF Both set if ((HL) + ((C - 1) & 255) > 255)
3388 PF The parity of (((HL) + ((C - 1) & 255)) & 7) xor B) */
3389 case 0xaa: /* IND */
3390 acu = in(LOW_REGISTER(BC));
3391 PUT_BYTE(HL, acu);
3392 --HL;
3393 temp = HIGH_REGISTER(BC);
3394 BC -= 0x100;
3395 INOUTFLAGS_NONZERO((LOW_REGISTER(BC) - 1) & 0xff);
3396 break;
3397
3398 case 0xab: /* OUTD */
3399 acu = GET_BYTE(HL);
3400 out(LOW_REGISTER(BC), acu);
3401 --HL;
3402 temp = HIGH_REGISTER(BC);
3403 BC -= 0x100;
3404 INOUTFLAGS_NONZERO(LOW_REGISTER(HL));
3405 break;
3406
3407 case 0xb0: /* LDIR */
3408 BC &= ADDRMASK;
3409 if (BC == 0)
3410 BC = 0x10000;
3411 do {
3412 acu = RAM_PP(HL);
3413 PUT_BYTE_PP(DE, acu);
3414 } while (--BC);
3415 acu += HIGH_REGISTER(AF);
3416 AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4);
3417 break;
3418
3419 case 0xb1: /* CPIR */
3420 acu = HIGH_REGISTER(AF);
3421 BC &= ADDRMASK;
3422 if (BC == 0)
3423 BC = 0x10000;
3424 do {
3425 temp = RAM_PP(HL);
3426 op = --BC != 0;
3427 sum = acu - temp;
3428 } while (op && sum != 0);
3429 cbits = acu ^ temp ^ sum;
3430 AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
3431 (((sum - ((cbits & 16) >> 4)) & 2) << 4) |
3432 (cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) |
3433 op << 2 | 2;
3434 if ((sum & 15) == 8 && (cbits & 16) != 0)
3435 AF &= ~8;
3436 break;
3437
3438 case 0xb2: /* INIR */
3439 temp = HIGH_REGISTER(BC);
3440 if (temp == 0)
3441 temp = 0x100;
3442 do {
3443 acu = in(LOW_REGISTER(BC));
3444 PUT_BYTE(HL, acu);
3445 ++HL;
3446 } while (--temp);
3447 temp = HIGH_REGISTER(BC);
3448 SET_HIGH_REGISTER(BC, 0);
3449 INOUTFLAGS_ZERO((LOW_REGISTER(BC) + 1) & 0xff);
3450 break;
3451
3452 case 0xb3: /* OTIR */
3453 temp = HIGH_REGISTER(BC);
3454 if (temp == 0)
3455 temp = 0x100;
3456 do {
3457 acu = GET_BYTE(HL);
3458 out(LOW_REGISTER(BC), acu);
3459 ++HL;
3460 } while (--temp);
3461 temp = HIGH_REGISTER(BC);
3462 SET_HIGH_REGISTER(BC, 0);
3463 INOUTFLAGS_ZERO(LOW_REGISTER(HL));
3464 break;
3465
3466 case 0xb8: /* LDDR */
3467 BC &= ADDRMASK;
3468 if (BC == 0)
3469 BC = 0x10000;
3470 do {
3471 acu = RAM_MM(HL);
3472 PUT_BYTE_MM(DE, acu);
3473 } while (--BC);
3474 acu += HIGH_REGISTER(AF);
3475 AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4);
3476 break;
3477
3478 case 0xb9: /* CPDR */
3479 acu = HIGH_REGISTER(AF);
3480 BC &= ADDRMASK;
3481 if (BC == 0)
3482 BC = 0x10000;
3483 do {
3484 temp = RAM_MM(HL);
3485 op = --BC != 0;
3486 sum = acu - temp;
3487 } while (op && sum != 0);
3488 cbits = acu ^ temp ^ sum;
3489 AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
3490 (((sum - ((cbits & 16) >> 4)) & 2) << 4) |
3491 (cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) |
3492 op << 2 | 2;
3493 if ((sum & 15) == 8 && (cbits & 16) != 0)
3494 AF &= ~8;
3495 break;
3496
3497 case 0xba: /* INDR */
3498 temp = HIGH_REGISTER(BC);
3499 if (temp == 0)
3500 temp = 0x100;
3501 do {
3502 acu = in(LOW_REGISTER(BC));
3503 PUT_BYTE(HL, acu);
3504 --HL;
3505 } while (--temp);
3506 temp = HIGH_REGISTER(BC);
3507 SET_HIGH_REGISTER(BC, 0);
3508 INOUTFLAGS_ZERO((LOW_REGISTER(BC) - 1) & 0xff);
3509 break;
3510
3511 case 0xbb: /* OTDR */
3512 temp = HIGH_REGISTER(BC);
3513 if (temp == 0)
3514 temp = 0x100;
3515 do {
3516 acu = GET_BYTE(HL);
3517 out(LOW_REGISTER(BC), acu);
3518 --HL;
3519 } while (--temp);
3520 temp = HIGH_REGISTER(BC);
3521 SET_HIGH_REGISTER(BC, 0);
3522 INOUTFLAGS_ZERO(LOW_REGISTER(HL));
3523 break;
3524
3525 default: /* ignore ED and following byte */
3526 CHECK_CPU_Z80;
3527 }
3528 break;
3529
3530 case 0xee: /* XOR nn */
3531 AF = xororTable[((AF >> 8) ^ RAM_PP(PC)) & 0xff];
3532 break;
3533
3534 case 0xef: /* RST 28H */
3535 PUSH(PC);
3536 PC = 0x28;
3537 break;
3538
3539 case 0xf0: /* RET P */
3540 if (!(TSTFLAG(S)))
3541 POP(PC);
3542 break;
3543
3544 case 0xf1: /* POP AF */
3545 POP(AF);
3546 break;
3547
3548 case 0xf2: /* JP P,nnnn */
3549 JPC(!TSTFLAG(S));
3550 break;
3551
3552 case 0xf3: /* DI */
3553 IFF_S = 0;
3554 break;
3555
3556 case 0xf4: /* CALL P,nnnn */
3557 CALLC(!TSTFLAG(S));
3558 break;
3559
3560 case 0xf5: /* PUSH AF */
3561 PUSH(AF);
3562 break;
3563
3564 case 0xf6: /* OR nn */
3565 AF = xororTable[((AF >> 8) | RAM_PP(PC)) & 0xff];
3566 break;
3567
3568 case 0xf7: /* RST 30H */
3569 PUSH(PC);
3570 PC = 0x30;
3571 break;
3572
3573 case 0xf8: /* RET M */
3574 if (TSTFLAG(S))
3575 POP(PC);
3576 break;
3577
3578 case 0xf9: /* LD SP,HL */
3579 SP = HL;
3580 break;
3581
3582 case 0xfa: /* JP M,nnnn */
3583 JPC(TSTFLAG(S));
3584 break;
3585
3586 case 0xfb: /* EI */
3587 IFF_S = 3;
3588 break;
3589
3590 case 0xfc: /* CALL M,nnnn */
3591 CALLC(TSTFLAG(S));
3592 break;
3593
3594 case 0xfd: /* FD prefix */
3595 CHECK_CPU_8080;
3596 switch (RAM_PP(PC)) {
3597
3598 case 0x09: /* ADD IY,BC */
3599 IY &= ADDRMASK;
3600 BC &= ADDRMASK;
3601 sum = IY + BC;
3602 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IY ^ BC ^ sum) >> 8];
3603 IY = sum;
3604 break;
3605
3606 case 0x19: /* ADD IY,DE */
3607 IY &= ADDRMASK;
3608 DE &= ADDRMASK;
3609 sum = IY + DE;
3610 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IY ^ DE ^ sum) >> 8];
3611 IY = sum;
3612 break;
3613
3614 case 0x21: /* LD IY,nnnn */
3615 IY = GET_WORD(PC);
3616 PC += 2;
3617 break;
3618
3619 case 0x22: /* LD (nnnn),IY */
3620 temp = GET_WORD(PC);
3621 PUT_WORD(temp, IY);
3622 PC += 2;
3623 break;
3624
3625 case 0x23: /* INC IY */
3626 ++IY;
3627 break;
3628
3629 case 0x24: /* INC IYH */
3630 IY += 0x100;
3631 AF = (AF & ~0xfe) | incZ80Table[HIGH_REGISTER(IY)];
3632 break;
3633
3634 case 0x25: /* DEC IYH */
3635 IY -= 0x100;
3636 AF = (AF & ~0xfe) | decZ80Table[HIGH_REGISTER(IY)];
3637 break;
3638
3639 case 0x26: /* LD IYH,nn */
3640 SET_HIGH_REGISTER(IY, RAM_PP(PC));
3641 break;
3642
3643 case 0x29: /* ADD IY,IY */
3644 IY &= ADDRMASK;
3645 sum = IY + IY;
3646 AF = (AF & ~0x3b) | cbitsDup16Table[sum >> 8];
3647 IY = sum;
3648 break;
3649
3650 case 0x2a: /* LD IY,(nnnn) */
3651 temp = GET_WORD(PC);
3652 IY = GET_WORD(temp);
3653 PC += 2;
3654 break;
3655
3656 case 0x2b: /* DEC IY */
3657 --IY;
3658 break;
3659
3660 case 0x2c: /* INC IYL */
3661 temp = LOW_REGISTER(IY) + 1;
3662 SET_LOW_REGISTER(IY, temp);
3663 AF = (AF & ~0xfe) | incZ80Table[temp];
3664 break;
3665
3666 case 0x2d: /* DEC IYL */
3667 temp = LOW_REGISTER(IY) - 1;
3668 SET_LOW_REGISTER(IY, temp);
3669 AF = (AF & ~0xfe) | decZ80Table[temp & 0xff];
3670 break;
3671
3672 case 0x2e: /* LD IYL,nn */
3673 SET_LOW_REGISTER(IY, RAM_PP(PC));
3674 break;
3675
3676 case 0x34: /* INC (IY+dd) */
3677 adr = IY + (int8) RAM_PP(PC);
3678 temp = GET_BYTE(adr) + 1;
3679 PUT_BYTE(adr, temp);
3680 AF = (AF & ~0xfe) | incZ80Table[temp];
3681 break;
3682
3683 case 0x35: /* DEC (IY+dd) */
3684 adr = IY + (int8) RAM_PP(PC);
3685 temp = GET_BYTE(adr) - 1;
3686 PUT_BYTE(adr, temp);
3687 AF = (AF & ~0xfe) | decZ80Table[temp & 0xff];
3688 break;
3689
3690 case 0x36: /* LD (IY+dd),nn */
3691 adr = IY + (int8) RAM_PP(PC);
3692 PUT_BYTE(adr, RAM_PP(PC));
3693 break;
3694
3695 case 0x39: /* ADD IY,SP */
3696 IY &= ADDRMASK;
3697 SP &= ADDRMASK;
3698 sum = IY + SP;
3699 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IY ^ SP ^ sum) >> 8];
3700 IY = sum;
3701 break;
3702
3703 case 0x44: /* LD B,IYH */
3704 SET_HIGH_REGISTER(BC, HIGH_REGISTER(IY));
3705 break;
3706
3707 case 0x45: /* LD B,IYL */
3708 SET_HIGH_REGISTER(BC, LOW_REGISTER(IY));
3709 break;
3710
3711 case 0x46: /* LD B,(IY+dd) */
3712 adr = IY + (int8) RAM_PP(PC);
3713 SET_HIGH_REGISTER(BC, GET_BYTE(adr));
3714 break;
3715
3716 case 0x4c: /* LD C,IYH */
3717 SET_LOW_REGISTER(BC, HIGH_REGISTER(IY));
3718 break;
3719
3720 case 0x4d: /* LD C,IYL */
3721 SET_LOW_REGISTER(BC, LOW_REGISTER(IY));
3722 break;
3723
3724 case 0x4e: /* LD C,(IY+dd) */
3725 adr = IY + (int8) RAM_PP(PC);
3726 SET_LOW_REGISTER(BC, GET_BYTE(adr));
3727 break;
3728
3729 case 0x54: /* LD D,IYH */
3730 SET_HIGH_REGISTER(DE, HIGH_REGISTER(IY));
3731 break;
3732
3733 case 0x55: /* LD D,IYL */
3734 SET_HIGH_REGISTER(DE, LOW_REGISTER(IY));
3735 break;
3736
3737 case 0x56: /* LD D,(IY+dd) */
3738 adr = IY + (int8) RAM_PP(PC);
3739 SET_HIGH_REGISTER(DE, GET_BYTE(adr));
3740 break;
3741
3742 case 0x5c: /* LD E,IYH */
3743 SET_LOW_REGISTER(DE, HIGH_REGISTER(IY));
3744 break;
3745
3746 case 0x5d: /* LD E,IYL */
3747 SET_LOW_REGISTER(DE, LOW_REGISTER(IY));
3748 break;
3749
3750 case 0x5e: /* LD E,(IY+dd) */
3751 adr = IY + (int8) RAM_PP(PC);
3752 SET_LOW_REGISTER(DE, GET_BYTE(adr));
3753 break;
3754
3755 case 0x60: /* LD IYH,B */
3756 SET_HIGH_REGISTER(IY, HIGH_REGISTER(BC));
3757 break;
3758
3759 case 0x61: /* LD IYH,C */
3760 SET_HIGH_REGISTER(IY, LOW_REGISTER(BC));
3761 break;
3762
3763 case 0x62: /* LD IYH,D */
3764 SET_HIGH_REGISTER(IY, HIGH_REGISTER(DE));
3765 break;
3766
3767 case 0x63: /* LD IYH,E */
3768 SET_HIGH_REGISTER(IY, LOW_REGISTER(DE));
3769 break;
3770
3771 case 0x64: /* LD IYH,IYH */
3772 break;
3773
3774 case 0x65: /* LD IYH,IYL */
3775 SET_HIGH_REGISTER(IY, LOW_REGISTER(IY));
3776 break;
3777
3778 case 0x66: /* LD H,(IY+dd) */
3779 adr = IY + (int8) RAM_PP(PC);
3780 SET_HIGH_REGISTER(HL, GET_BYTE(adr));
3781 break;
3782
3783 case 0x67: /* LD IYH,A */
3784 SET_HIGH_REGISTER(IY, HIGH_REGISTER(AF));
3785 break;
3786
3787 case 0x68: /* LD IYL,B */
3788 SET_LOW_REGISTER(IY, HIGH_REGISTER(BC));
3789 break;
3790
3791 case 0x69: /* LD IYL,C */
3792 SET_LOW_REGISTER(IY, LOW_REGISTER(BC));
3793 break;
3794
3795 case 0x6a: /* LD IYL,D */
3796 SET_LOW_REGISTER(IY, HIGH_REGISTER(DE));
3797 break;
3798
3799 case 0x6b: /* LD IYL,E */
3800 SET_LOW_REGISTER(IY, LOW_REGISTER(DE));
3801 break;
3802
3803 case 0x6c: /* LD IYL,IYH */
3804 SET_LOW_REGISTER(IY, HIGH_REGISTER(IY));
3805 break;
3806
3807 case 0x6d: /* LD IYL,IYL */
3808 break;
3809
3810 case 0x6e: /* LD L,(IY+dd) */
3811 adr = IY + (int8) RAM_PP(PC);
3812 SET_LOW_REGISTER(HL, GET_BYTE(adr));
3813 break;
3814
3815 case 0x6f: /* LD IYL,A */
3816 SET_LOW_REGISTER(IY, HIGH_REGISTER(AF));
3817 break;
3818
3819 case 0x70: /* LD (IY+dd),B */
3820 adr = IY + (int8) RAM_PP(PC);
3821 PUT_BYTE(adr, HIGH_REGISTER(BC));
3822 break;
3823
3824 case 0x71: /* LD (IY+dd),C */
3825 adr = IY + (int8) RAM_PP(PC);
3826 PUT_BYTE(adr, LOW_REGISTER(BC));
3827 break;
3828
3829 case 0x72: /* LD (IY+dd),D */
3830 adr = IY + (int8) RAM_PP(PC);
3831 PUT_BYTE(adr, HIGH_REGISTER(DE));
3832 break;
3833
3834 case 0x73: /* LD (IY+dd),E */
3835 adr = IY + (int8) RAM_PP(PC);
3836 PUT_BYTE(adr, LOW_REGISTER(DE));
3837 break;
3838
3839 case 0x74: /* LD (IY+dd),H */
3840 adr = IY + (int8) RAM_PP(PC);
3841 PUT_BYTE(adr, HIGH_REGISTER(HL));
3842 break;
3843
3844 case 0x75: /* LD (IY+dd),L */
3845 adr = IY + (int8) RAM_PP(PC);
3846 PUT_BYTE(adr, LOW_REGISTER(HL));
3847 break;
3848
3849 case 0x77: /* LD (IY+dd),A */
3850 adr = IY + (int8) RAM_PP(PC);
3851 PUT_BYTE(adr, HIGH_REGISTER(AF));
3852 break;
3853
3854 case 0x7c: /* LD A,IYH */
3855 SET_HIGH_REGISTER(AF, HIGH_REGISTER(IY));
3856 break;
3857
3858 case 0x7d: /* LD A,IYL */
3859 SET_HIGH_REGISTER(AF, LOW_REGISTER(IY));
3860 break;
3861
3862 case 0x7e: /* LD A,(IY+dd) */
3863 adr = IY + (int8) RAM_PP(PC);
3864 SET_HIGH_REGISTER(AF, GET_BYTE(adr));
3865 break;
3866
3867 case 0x84: /* ADD A,IYH */
3868 temp = HIGH_REGISTER(IY);
3869 acu = HIGH_REGISTER(AF);
3870 sum = acu + temp;
3871 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
3872 break;
3873
3874 case 0x85: /* ADD A,IYL */
3875 temp = LOW_REGISTER(IY);
3876 acu = HIGH_REGISTER(AF);
3877 sum = acu + temp;
3878 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
3879 break;
3880
3881 case 0x86: /* ADD A,(IY+dd) */
3882 adr = IY + (int8) RAM_PP(PC);
3883 temp = GET_BYTE(adr);
3884 acu = HIGH_REGISTER(AF);
3885 sum = acu + temp;
3886 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
3887 break;
3888
3889 case 0x8c: /* ADC A,IYH */
3890 temp = HIGH_REGISTER(IY);
3891 acu = HIGH_REGISTER(AF);
3892 sum = acu + temp + TSTFLAG(C);
3893 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
3894 break;
3895
3896 case 0x8d: /* ADC A,IYL */
3897 temp = LOW_REGISTER(IY);
3898 acu = HIGH_REGISTER(AF);
3899 sum = acu + temp + TSTFLAG(C);
3900 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
3901 break;
3902
3903 case 0x8e: /* ADC A,(IY+dd) */
3904 adr = IY + (int8) RAM_PP(PC);
3905 temp = GET_BYTE(adr);
3906 acu = HIGH_REGISTER(AF);
3907 sum = acu + temp + TSTFLAG(C);
3908 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
3909 break;
3910
3911 case 0x96: /* SUB (IY+dd) */
3912 adr = IY + (int8) RAM_PP(PC);
3913 temp = GET_BYTE(adr);
3914 acu = HIGH_REGISTER(AF);
3915 sum = acu - temp;
3916 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
3917 break;
3918
3919 case 0x94: /* SUB IYH */
3920 SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */
3921
3922 case 0x9c: /* SBC A,IYH */
3923 temp = HIGH_REGISTER(IY);
3924 acu = HIGH_REGISTER(AF);
3925 sum = acu - temp - TSTFLAG(C);
3926 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
3927 break;
3928
3929 case 0x95: /* SUB IYL */
3930 SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */
3931
3932 case 0x9d: /* SBC A,IYL */
3933 temp = LOW_REGISTER(IY);
3934 acu = HIGH_REGISTER(AF);
3935 sum = acu - temp - TSTFLAG(C);
3936 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
3937 break;
3938
3939 case 0x9e: /* SBC A,(IY+dd) */
3940 adr = IY + (int8) RAM_PP(PC);
3941 temp = GET_BYTE(adr);
3942 acu = HIGH_REGISTER(AF);
3943 sum = acu - temp - TSTFLAG(C);
3944 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
3945 break;
3946
3947 case 0xa4: /* AND IYH */
3948 AF = andTable[((AF & IY) >> 8) & 0xff];
3949 break;
3950
3951 case 0xa5: /* AND IYL */
3952 AF = andTable[((AF >> 8) & IY) & 0xff];
3953 break;
3954
3955 case 0xa6: /* AND (IY+dd) */
3956 adr = IY + (int8) RAM_PP(PC);
3957 AF = andTable[((AF >> 8) & GET_BYTE(adr)) & 0xff];
3958 break;
3959
3960 case 0xac: /* XOR IYH */
3961 AF = xororTable[((AF ^ IY) >> 8) & 0xff];
3962 break;
3963
3964 case 0xad: /* XOR IYL */
3965 AF = xororTable[((AF >> 8) ^ IY) & 0xff];
3966 break;
3967
3968 case 0xae: /* XOR (IY+dd) */
3969 adr = IY + (int8) RAM_PP(PC);
3970 AF = xororTable[((AF >> 8) ^ GET_BYTE(adr)) & 0xff];
3971 break;
3972
3973 case 0xb4: /* OR IYH */
3974 AF = xororTable[((AF | IY) >> 8) & 0xff];
3975 break;
3976
3977 case 0xb5: /* OR IYL */
3978 AF = xororTable[((AF >> 8) | IY) & 0xff];
3979 break;
3980
3981 case 0xb6: /* OR (IY+dd) */
3982 adr = IY + (int8) RAM_PP(PC);
3983 AF = xororTable[((AF >> 8) | GET_BYTE(adr)) & 0xff];
3984 break;
3985
3986 case 0xbc: /* CP IYH */
3987 temp = HIGH_REGISTER(IY);
3988 AF = (AF & ~0x28) | (temp & 0x28);
3989 acu = HIGH_REGISTER(AF);
3990 sum = acu - temp;
3991 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
3992 cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
3993 break;
3994
3995 case 0xbd: /* CP IYL */
3996 temp = LOW_REGISTER(IY);
3997 AF = (AF & ~0x28) | (temp & 0x28);
3998 acu = HIGH_REGISTER(AF);
3999 sum = acu - temp;
4000 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
4001 cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
4002 break;
4003
4004 case 0xbe: /* CP (IY+dd) */
4005 adr = IY + (int8) RAM_PP(PC);
4006 temp = GET_BYTE(adr);
4007 AF = (AF & ~0x28) | (temp & 0x28);
4008 acu = HIGH_REGISTER(AF);
4009 sum = acu - temp;
4010 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
4011 cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
4012 break;
4013
4014 case 0xcb: /* CB prefix */
4015 adr = IY + (int8) RAM_PP(PC);
4016 switch ((op = GET_BYTE(PC)) & 7) {
4017
4018 case 0:
4019 ++PC;
4020 acu = HIGH_REGISTER(BC);
4021 break;
4022
4023 case 1:
4024 ++PC;
4025 acu = LOW_REGISTER(BC);
4026 break;
4027
4028 case 2:
4029 ++PC;
4030 acu = HIGH_REGISTER(DE);
4031 break;
4032
4033 case 3:
4034 ++PC;
4035 acu = LOW_REGISTER(DE);
4036 break;
4037
4038 case 4:
4039 ++PC;
4040 acu = HIGH_REGISTER(HL);
4041 break;
4042
4043 case 5:
4044 ++PC;
4045 acu = LOW_REGISTER(HL);
4046 break;
4047
4048 case 6:
4049 ++PC;
4050 acu = GET_BYTE(adr);
4051 break;
4052
4053 case 7:
4054 ++PC;
4055 acu = HIGH_REGISTER(AF);
4056 break;
4057 }
4058 switch (op & 0xc0) {
4059
4060 case 0x00: /* shift/rotate */
4061 switch (op & 0x38) {
4062
4063 case 0x00:/* RLC */
4064 temp = (acu << 1) | (acu >> 7);
4065 cbits = temp & 1;
4066 goto cbshflg3;
4067
4068 case 0x08:/* RRC */
4069 temp = (acu >> 1) | (acu << 7);
4070 cbits = temp & 0x80;
4071 goto cbshflg3;
4072
4073 case 0x10:/* RL */
4074 temp = (acu << 1) | TSTFLAG(C);
4075 cbits = acu & 0x80;
4076 goto cbshflg3;
4077
4078 case 0x18:/* RR */
4079 temp = (acu >> 1) | (TSTFLAG(C) << 7);
4080 cbits = acu & 1;
4081 goto cbshflg3;
4082
4083 case 0x20:/* SLA */
4084 temp = acu << 1;
4085 cbits = acu & 0x80;
4086 goto cbshflg3;
4087
4088 case 0x28:/* SRA */
4089 temp = (acu >> 1) | (acu & 0x80);
4090 cbits = acu & 1;
4091 goto cbshflg3;
4092
4093 case 0x30:/* SLIA */
4094 temp = (acu << 1) | 1;
4095 cbits = acu & 0x80;
4096 goto cbshflg3;
4097
4098 case 0x38:/* SRL */
4099 temp = acu >> 1;
4100 cbits = acu & 1;
4101 cbshflg3:
4102 AF = (AF & ~0xff) | rotateShiftTable[temp & 0xff] | !!cbits;
4103 }
4104 break;
4105
4106 case 0x40: /* BIT */
4107 if (acu & (1 << ((op >> 3) & 7)))
4108 AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7);
4109 else
4110 AF = (AF & ~0xfe) | 0x54;
4111 if ((op & 7) != 6)
4112 AF |= (acu & 0x28);
4113 temp = acu;
4114 break;
4115
4116 case 0x80: /* RES */
4117 temp = acu & ~(1 << ((op >> 3) & 7));
4118 break;
4119
4120 case 0xc0: /* SET */
4121 temp = acu | (1 << ((op >> 3) & 7));
4122 break;
4123 }
4124 switch (op & 7) {
4125
4126 case 0:
4127 SET_HIGH_REGISTER(BC, temp);
4128 break;
4129
4130 case 1:
4131 SET_LOW_REGISTER(BC, temp);
4132 break;
4133
4134 case 2:
4135 SET_HIGH_REGISTER(DE, temp);
4136 break;
4137
4138 case 3:
4139 SET_LOW_REGISTER(DE, temp);
4140 break;
4141
4142 case 4:
4143 SET_HIGH_REGISTER(HL, temp);
4144 break;
4145
4146 case 5:
4147 SET_LOW_REGISTER(HL, temp);
4148 break;
4149
4150 case 6:
4151 PUT_BYTE(adr, temp);
4152 break;
4153
4154 case 7:
4155 SET_HIGH_REGISTER(AF, temp);
4156 break;
4157 }
4158 break;
4159
4160 case 0xe1: /* POP IY */
4161 POP(IY);
4162 break;
4163
4164 case 0xe3: /* EX (SP),IY */
4165 temp = IY;
4166 POP(IY);
4167 PUSH(temp);
4168 break;
4169
4170 case 0xe5: /* PUSH IY */
4171 PUSH(IY);
4172 break;
4173
4174 case 0xe9: /* JP (IY) */
4175 PC = IY;
4176 break;
4177
4178 case 0xf9: /* LD SP,IY */
4179 SP = IY;
4180 break;
4181
4182 default: /* ignore FD */
4183 CHECK_CPU_Z80;
4184 PC--;
4185 }
4186 break;
4187
4188 case 0xfe: /* CP nn */
4189 temp = RAM_PP(PC);
4190 AF = (AF & ~0x28) | (temp & 0x28);
4191 acu = HIGH_REGISTER(AF);
4192 sum = acu - temp;
4193 cbits = acu ^ temp ^ sum;
4194 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
4195 (SET_PV) | cbits2Table[cbits & 0x1ff];
4196 break;
4197
4198 case 0xff: /* RST 38H */
4199 PUSH(PC);
4200 PC = 0x38;
4201 }
4202 }
4203 end_decode:
4204
4205 /* simulation halted */
4206 PC_S = (reason == STOP_OPCODE) ? PCX : PC;
4207 AF_S = AF;
4208 BC_S = BC;
4209 DE_S = DE;
4210 HL_S = HL;
4211 IX_S = IX;
4212 IY_S = IY;
4213 SP_S = SP;
4214 return reason;
4215 }
4216