1 /* altairz80_cpu.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 #include <ctype.h>
32 #define SWITCHCPU_DEFAULT 0xfd
33
34 /* Debug flags */
35 #define IN_MSG (1 << 0)
36 #define OUT_MSG (1 << 1)
37
38 #if defined (_WIN32)
39 #include <windows.h>
40 #else
41 #include <unistd.h>
42 #endif
43
44 #define PCQ_SIZE 64 /* must be 2**n */
45 #define PCQ_SIZE_LOG2 6 /* log2 of PCQ_SIZE */
46 #define PCQ_MASK (PCQ_SIZE - 1)
47 #define PCQ_ENTRY(PC) if (pcq[pcq_p] != (PC)) { pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = (PC); }
48
49 #define FLAG_C 1
50 #define FLAG_N 2
51 #define FLAG_P 4
52 #define FLAG_H 16
53 #define FLAG_Z 64
54 #define FLAG_S 128
55
56 #define SETFLAG(f,c) AF = (c) ? AF | FLAG_ ## f : AF & ~FLAG_ ## f
57 #define TSTFLAG(f) ((AF & FLAG_ ## f) != 0)
58
59 #define LOW_DIGIT(x) ((x) & 0xf)
60 #define HIGH_DIGIT(x) (((x) >> 4) & 0xf)
61 #define LOW_REGISTER(x) ((x) & 0xff)
62 #define HIGH_REGISTER(x) (((x) >> 8) & 0xff)
63
64 #define SET_LOW_REGISTER(x, v) x = (((x) & 0xff00) | ((v) & 0xff))
65 #define SET_HIGH_REGISTER(x, v) x = (((x) & 0xff) | (((v) & 0xff) << 8))
66
67 #define PARITY(x) parityTable[(x) & 0xff]
68 /* SET_PV and SET_PV2 are used to provide correct PARITY flag semantics for the 8080 in cases
69 where the Z80 uses the overflow flag
70 */
71 #define SET_PVS(s) ((chiptype == CHIP_TYPE_Z80) ? (((cbits >> 6) ^ (cbits >> 5)) & 4) : (PARITY(s)))
72 #define SET_PV (SET_PVS(sum))
73 #define SET_PV2(x) ((chiptype == CHIP_TYPE_Z80) ? (((temp == (x)) << 2)) : (PARITY(temp)))
74
75 /* CHECK_CPU_8080 must be invoked whenever a Z80 only instruction is executed
76 In case a Z80 instruction is executed on an 8080 the following two cases exist:
77 1) Trapping is enabled: execution stops
78 2) Trapping is not enabled: decoding continues with the next byte
79 */
80 #define CHECK_CPU_8080 \
81 if (chiptype == CHIP_TYPE_8080) { \
82 if (cpu_unit.flags & UNIT_CPU_OPSTOP) { \
83 reason = STOP_OPCODE; \
84 goto end_decode; \
85 } \
86 else { \
87 sim_brk_pend[0] = FALSE; \
88 continue; \
89 } \
90 }
91
92 /* CHECK_CPU_Z80 must be invoked whenever a non Z80 instruction is executed */
93 #define CHECK_CPU_Z80 \
94 if (cpu_unit.flags & UNIT_CPU_OPSTOP) { \
95 reason = STOP_OPCODE; \
96 goto end_decode; \
97 }
98
99 #define POP(x) { \
100 register uint32 y = RAM_PP(SP); \
101 x = y + (RAM_PP(SP) << 8); \
102 }
103
104 #define JPC(cond) { \
105 tStates += 10; \
106 if (cond) { \
107 PCQ_ENTRY(PCX); \
108 PC = GET_WORD(PC); \
109 } \
110 else { \
111 PC += 2; \
112 } \
113 }
114
115 #define CALLC(cond) { \
116 if (cond) { \
117 register uint32 adrr = GET_WORD(PC); \
118 CHECK_BREAK_WORD(SP - 2); \
119 PUSH(PC + 2); \
120 PCQ_ENTRY(PCX); \
121 PC = adrr; \
122 tStates += 17; \
123 } \
124 else { \
125 sim_brk_pend[0] = FALSE; \
126 PC += 2; \
127 tStates += 10; \
128 } \
129 }
130
131 extern int32 sim_int_char;
132 extern int32 sio0s (const int32 port, const int32 io, const int32 data);
133 extern int32 sio0d (const int32 port, const int32 io, const int32 data);
134 extern int32 sio1s (const int32 port, const int32 io, const int32 data);
135 extern int32 sio1d (const int32 port, const int32 io, const int32 data);
136 extern int32 dsk10 (const int32 port, const int32 io, const int32 data);
137 extern int32 dsk11 (const int32 port, const int32 io, const int32 data);
138 extern int32 dsk12 (const int32 port, const int32 io, const int32 data);
139 extern int32 netStatus (const int32 port, const int32 io, const int32 data);
140 extern int32 netData (const int32 port, const int32 io, const int32 data);
141 extern int32 nulldev (const int32 port, const int32 io, const int32 data);
142 extern int32 hdsk_io (const int32 port, const int32 io, const int32 data);
143 extern int32 simh_dev (const int32 port, const int32 io, const int32 data);
144 extern int32 sr_dev (const int32 port, const int32 io, const int32 data);
145 extern void install_ALTAIRbootROM(void);
146 extern void do_SIMH_sleep(void);
147 extern void prepareMemoryAccessMessage(const t_addr loc);
148 extern void prepareInstructionMessage(const t_addr loc, const uint32 op);
149
150 extern FILE *sim_deb;
151
152 extern t_stat sim_instr_nommu(void);
153 extern uint8 MOPT[MAXBANKSIZE];
154 extern t_stat sim_instr_8086(void);
155 extern void cpu8086reset(void);
156
157 /* function prototypes */
158 static t_stat cpu_set_switcher (UNIT *uptr, int32 value, char *cptr, void *desc);
159 static t_stat cpu_reset_switcher(UNIT *uptr, int32 value, char *cptr, void *desc);
160 static t_stat cpu_show_switcher (FILE *st, UNIT *uptr, int32 val, void *desc);
161 static int32 switchcpu_io (const int32 port, const int32 io, const int32 data);
162
163 static t_stat cpu_set_altairrom (UNIT *uptr, int32 value, char *cptr, void *desc);
164 static t_stat cpu_set_noaltairrom (UNIT *uptr, int32 value, char *cptr, void *desc);
165 static t_stat cpu_set_nommu (UNIT *uptr, int32 value, char *cptr, void *desc);
166 static t_stat cpu_set_banked (UNIT *uptr, int32 value, char *cptr, void *desc);
167 static t_stat cpu_set_nonbanked (UNIT *uptr, int32 value, char *cptr, void *desc);
168 static t_stat cpu_set_ramtype (UNIT *uptr, int32 value, char *cptr, void *desc);
169 static t_stat cpu_set_chiptype (UNIT *uptr, int32 value, char *cptr, void *desc);
170 static t_stat cpu_set_size (UNIT *uptr, int32 value, char *cptr, void *desc);
171 static t_stat cpu_set_memory (UNIT *uptr, int32 value, char *cptr, void *desc);
172 static t_stat cpu_clear_command (UNIT *uptr, int32 value, char *cptr, void *desc);
173 static void cpu_clear(void);
174 static t_stat cpu_show (FILE *st, UNIT *uptr, int32 val, void *desc);
175 static t_stat chip_show (FILE *st, UNIT *uptr, int32 val, void *desc);
176 static t_stat cpu_ex(t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
177 static t_stat cpu_dep(t_value val, t_addr addr, UNIT *uptr, int32 sw);
178 static t_stat cpu_reset(DEVICE *dptr);
179 static t_stat sim_instr_mmu(void);
180 static uint32 GetBYTE(register uint32 Addr);
181 static void PutWORD(register uint32 Addr, const register uint32 Value);
182 static void PutBYTE(register uint32 Addr, const register uint32 Value);
183 void out(const uint32 Port, const uint32 Value);
184 uint32 in(const uint32 Port);
185 void altairz80_init(void);
186 t_stat sim_instr(void);
187 t_stat install_bootrom(int32 bootrom[], int32 size, int32 addr, int32 makeROM);
188 uint8 GetBYTEWrapper(const uint32 Addr);
189 void PutBYTEWrapper(const uint32 Addr, const uint32 Value);
190 uint8 GetByteDMA(const uint32 Addr);
191 void PutByteDMA(const uint32 Addr, const uint32 Value);
192 int32 getBankSelect(void);
193 void setBankSelect(const int32 b);
194 uint32 getClockFrequency(void);
195 void setClockFrequency(const uint32 Value);
196 uint32 getCommon(void);
197 t_stat sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag);
198 uint32 sim_map_resource(uint32 baseaddr, uint32 size, uint32 resource_type,
199 int32 (*routine)(const int32, const int32, const int32), uint8 unmap);
200
201 void PutBYTEExtended(register uint32 Addr, const register uint32 Value);
202 uint32 GetBYTEExtended(register uint32 Addr);
203 void cpu_raise_interrupt(uint32 irq);
204
205 /* CPU data structures
206 cpu_dev CPU device descriptor
207 cpu_unit CPU unit descriptor
208 cpu_reg CPU register list
209 cpu_mod CPU modifiers list
210 */
211
212 UNIT cpu_unit = {
213 UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_CPU_ALTAIRROM |
214 UNIT_CPU_STOPONHALT | UNIT_CPU_MMU, MAXBANKSIZE)
215 };
216
217 uint32 PCX = 0; /* external view of PC */
218 int32 AF_S; /* AF register */
219 int32 BC_S; /* BC register */
220 int32 DE_S; /* DE register */
221 int32 HL_S; /* HL register */
222 int32 IX_S; /* IX register */
223 int32 IY_S; /* IY register */
224 int32 PC_S = 0; /* 8080 / Z80 program counter */
225 int32 PCX_S = 0xFFFF0; /* 8086 program counter */
226 int32 SP_S; /* SP register */
227 int32 AF1_S; /* alternate AF register */
228 int32 BC1_S; /* alternate BC register */
229 int32 DE1_S; /* alternate DE register */
230 int32 HL1_S; /* alternate HL register */
231 int32 IFF_S; /* Interrupt Flip Flop */
232 int32 IR_S; /* Interrupt (upper) / Refresh (lower) register */
233 int32 AX_S; /* AX register (8086) */
234 int32 BX_S; /* BX register (8086) */
235 int32 CX_S; /* CX register (8086) */
236 int32 DX_S; /* DX register (8086) */
237 int32 CS_S; /* CS register (8086) */
238 int32 DS_S; /* DS register (8086) */
239 int32 ES_S; /* ES register (8086) */
240 int32 SS_S; /* SS register (8086) */
241 int32 DI_S; /* DI register (8086) */
242 int32 SI_S; /* SI register (8086) */
243 int32 BP_S; /* BP register (8086) */
244 int32 SPX_S; /* SP register (8086) */
245 int32 IP_S; /* IP register (8086) */
246 int32 FLAGS_S; /* flags register (8086) */
247 int32 SR = 0; /* switch register */
248 static int32 bankSelect = 0; /* determines selected memory bank */
249 static uint32 common = 0xc000; /* addresses >= 'common' are in common memory */
250 static uint32 previousCapacity = MAXBANKSIZE; /* safe for previous memory capacity */
251 static uint32 clockFrequency = 0; /* in kHz, 0 means as fast as possible */
252 static uint32 sliceLength = 10; /* length of time-slice for CPU speed */
253 /* adjustment in milliseconds */
254 static uint32 executedTStates = 0; /* executed t-states */
255 static uint16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */
256 static int32 pcq_p = 0; /* PC queue ptr */
257 static REG *pcq_r = NULL; /* PC queue reg ptr */
258
259 /* data structure for IN/OUT instructions */
260 struct idev {
261 int32 (*routine)(const int32, const int32, const int32);
262 };
263
264 static int32 switcherPort = SWITCHCPU_DEFAULT;
265 static struct idev oldSwitcherDevice = { NULL };
266
267 REG cpu_reg[] = {
268 { HRDATA (AF, AF_S, 16) },
269 { HRDATA (BC, BC_S, 16) },
270 { HRDATA (DE, DE_S, 16) },
271 { HRDATA (HL, HL_S, 16) },
272 { HRDATA (IX, IX_S, 16) },
273 { HRDATA (IY, IY_S, 16) },
274 { HRDATA (PC, PC_S, 16 + MAXBANKSLOG2) }, /* 8080 / Z80 PC [6] */
275 { HRDATA (PCX, PCX_S, 16 + MAXBANKSLOG2) }, /* 8086 PC [7] */
276 { HRDATA (SP, SP_S, 16) },
277 { HRDATA (AF1, AF1_S, 16) },
278 { HRDATA (BC1, BC1_S, 16) },
279 { HRDATA (DE1, DE1_S, 16) },
280 { HRDATA (HL1, HL1_S, 16) },
281 { GRDATA (IFF, IFF_S, 2, 2, 0) },
282 { FLDATA (IR, IR_S, 8) },
283 { HRDATA (AX, AX_S, 16) }, /* 8086 */
284 { GRDATA (AL, AX_S, 16, 8, 0) }, /* 8086, low 8 bits of AX */
285 { GRDATA (AH, AX_S, 16, 8, 8) }, /* 8086, high 8 bits of AX */
286 { HRDATA (BX, BX_S, 16) }, /* 8086 */
287 { GRDATA (BL, BX_S, 16, 8, 0) }, /* 8086, low 8 bits of BX */
288 { GRDATA (BH, BX_S, 16, 8, 8) }, /* 8086, high 8 bits of BX */
289 { HRDATA (CX, CX_S, 16) }, /* 8086 */
290 { GRDATA (CL, CX_S, 16, 8, 0) }, /* 8086, low 8 bits of CX */
291 { GRDATA (CH, CX_S, 16, 8, 8) }, /* 8086, high 8 bits of CX */
292 { HRDATA (DX, DX_S, 16) }, /* 8086 */
293 { GRDATA (DL, DX_S, 16, 8, 0) }, /* 8086, low 8 bits of DX */
294 { GRDATA (DH, DX_S, 16, 8, 8) }, /* 8086, high 8 bits of DX */
295 { HRDATA (SPX, SPX_S, 16) }, /* 8086 */
296 { HRDATA (BP, BP_S, 16) }, /* 8086, Base Pointer */
297 { HRDATA (SI, SI_S, 16) }, /* 8086, Source Index */
298 { HRDATA (DI, DI_S, 16) }, /* 8086, Destination Index */
299 { HRDATA (CS, CS_S, 16) }, /* 8086, Code Segment */
300 { HRDATA (DS, DS_S, 16) }, /* 8086, Data Segment */
301 { HRDATA (ES, ES_S, 16) }, /* 8086, Extra Segment */
302 { HRDATA (SS, SS_S, 16) }, /* 8086, Stack Segment */
303 { HRDATA (FLAGS, FLAGS_S, 16) }, /* 8086, FLAGS */
304 { HRDATA (IP, IP_S, 16), REG_RO }, /* 8086, set via PC */
305 { FLDATA (OPSTOP, cpu_unit.flags, UNIT_CPU_V_OPSTOP), REG_HRO },
306 { HRDATA (SR, SR, 8) },
307 { HRDATA (BANK, bankSelect, MAXBANKSLOG2) },
308 { HRDATA (COMMON, common, 32) },
309 { HRDATA (SWITCHERPORT, switcherPort, 8), },
310 { DRDATA (CLOCK, clockFrequency, 32) },
311 { DRDATA (SLICE, sliceLength, 16) },
312 { DRDATA (TSTATES, executedTStates, 32), REG_RO },
313 { HRDATA (CAPACITY, cpu_unit.capac, 32), REG_RO },
314 { HRDATA (PREVCAP, previousCapacity, 32), REG_RO },
315 { BRDATA (PCQ, pcq, 16, 16, PCQ_SIZE), REG_RO + REG_CIRC },
316 { DRDATA (PCQP, pcq_p, PCQ_SIZE_LOG2), REG_HRO },
317 { HRDATA (WRU, sim_int_char, 8) },
318 { NULL }
319 };
320
321 static MTAB cpu_mod[] = {
322 { MTAB_XTD | MTAB_VDV, CHIP_TYPE_8080, NULL, "8080", &cpu_set_chiptype },
323 { MTAB_XTD | MTAB_VDV, CHIP_TYPE_Z80, NULL, "Z80", &cpu_set_chiptype },
324 { MTAB_XTD | MTAB_VDV, CHIP_TYPE_8086, NULL, "8086", &cpu_set_chiptype },
325 { UNIT_CPU_OPSTOP, UNIT_CPU_OPSTOP, "ITRAP", "ITRAP", NULL, &chip_show },
326 { UNIT_CPU_OPSTOP, 0, "NOITRAP", "NOITRAP", NULL, &chip_show },
327 { UNIT_CPU_STOPONHALT, UNIT_CPU_STOPONHALT,"STOPONHALT", "STOPONHALT", NULL },
328 { UNIT_CPU_STOPONHALT, 0, "LOOPONHALT", "LOOPONHALT", NULL },
329 { UNIT_CPU_BANKED, UNIT_CPU_BANKED, "BANKED", "BANKED", &cpu_set_banked },
330 { UNIT_CPU_BANKED, 0, "NONBANKED", "NONBANKED", &cpu_set_nonbanked },
331 { UNIT_CPU_ALTAIRROM, UNIT_CPU_ALTAIRROM, "ALTAIRROM", "ALTAIRROM", &cpu_set_altairrom },
332 { UNIT_CPU_ALTAIRROM, 0, "NOALTAIRROM", "NOALTAIRROM", &cpu_set_noaltairrom},
333 { UNIT_CPU_VERBOSE, UNIT_CPU_VERBOSE, "VERBOSE", "VERBOSE", NULL, &cpu_show },
334 { UNIT_CPU_VERBOSE, 0, "QUIET", "QUIET", NULL },
335 { MTAB_VDV, 0, NULL, "CLEARMEMORY", &cpu_clear_command },
336 { UNIT_CPU_MMU, UNIT_CPU_MMU, "MMU", "MMU", NULL },
337 { UNIT_CPU_MMU, 0, "NOMMU", "NOMMU", &cpu_set_nommu },
338 { MTAB_XTD | MTAB_VDV, 0, NULL, "MEMORY", &cpu_set_memory },
339 { UNIT_CPU_SWITCHER, UNIT_CPU_SWITCHER, "SWITCHER", "SWITCHER", &cpu_set_switcher, &cpu_show_switcher },
340 { UNIT_CPU_SWITCHER, 0, "NOSWITCHER", "NOSWITCHER", &cpu_reset_switcher, &cpu_show_switcher },
341 { MTAB_XTD | MTAB_VDV, 0, NULL, "AZ80", &cpu_set_ramtype },
342 { MTAB_XTD | MTAB_VDV, 1, NULL, "HRAM", &cpu_set_ramtype },
343 { MTAB_XTD | MTAB_VDV, 2, NULL, "VRAM", &cpu_set_ramtype },
344 { MTAB_XTD | MTAB_VDV, 3, NULL, "CRAM", &cpu_set_ramtype },
345 { MTAB_VDV, 4, NULL, "4KB", &cpu_set_size },
346 { MTAB_VDV, 8, NULL, "8KB", &cpu_set_size },
347 { MTAB_VDV, 12, NULL, "12KB", &cpu_set_size },
348 { MTAB_VDV, 16, NULL, "16KB", &cpu_set_size },
349 { MTAB_VDV, 20, NULL, "20KB", &cpu_set_size },
350 { MTAB_VDV, 24, NULL, "24KB", &cpu_set_size },
351 { MTAB_VDV, 28, NULL, "28KB", &cpu_set_size },
352 { MTAB_VDV, 32, NULL, "32KB", &cpu_set_size },
353 { MTAB_VDV, 36, NULL, "36KB", &cpu_set_size },
354 { MTAB_VDV, 40, NULL, "40KB", &cpu_set_size },
355 { MTAB_VDV, 44, NULL, "44KB", &cpu_set_size },
356 { MTAB_VDV, 48, NULL, "48KB", &cpu_set_size },
357 { MTAB_VDV, 52, NULL, "52KB", &cpu_set_size },
358 { MTAB_VDV, 56, NULL, "56KB", &cpu_set_size },
359 { MTAB_VDV, 60, NULL, "60KB", &cpu_set_size },
360 { MTAB_VDV, 64, NULL, "64KB", &cpu_set_size },
361 { 0 }
362 };
363
364 /* Debug Flags */
365 static DEBTAB cpu_dt[] = {
366 { "LOG_IN", IN_MSG },
367 { "LOG_OUT", OUT_MSG },
368 { NULL, 0 }
369 };
370
371 DEVICE cpu_dev = {
372 "CPU", &cpu_unit, cpu_reg, cpu_mod,
373 1, 16, 16, 1, 16, 8,
374 &cpu_ex, &cpu_dep, &cpu_reset,
375 NULL, NULL, NULL,
376 NULL, DEV_DEBUG, 0,
377 cpu_dt, NULL, NULL
378 };
379
380 /* This is the I/O configuration table. There are 255 possible
381 device addresses, if a device is plugged to a port it's routine
382 address is here, 'nulldev' means no device is available
383 */
384 static struct idev dev_table[256] = {
385 {&nulldev}, {&nulldev}, {&sio0d}, {&sio0s}, /* 00 */
386 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 04 */
387 {&dsk10}, {&dsk11}, {&dsk12}, {&nulldev}, /* 08 */
388 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C */
389 {&sio0s}, {&sio0d}, {&sio1s}, {&sio1d}, /* 10 */
390 {&sio0s}, {&sio0d}, {&sio0s}, {&sio0d}, /* 14 */
391 {&sio0s}, {&sio0d}, {&nulldev}, {&nulldev}, /* 18 */
392 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C */
393 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 20 */
394 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 24 */
395 {&netStatus},{&netData},{&netStatus},{&netData}, /* 28 */
396 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C */
397 {&nulldev}, {&nulldev}, {&netStatus},{&netData}, /* 30 */
398 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 34 */
399 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 38 */
400 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C */
401 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 40 */
402 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 44 */
403 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 48 */
404 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 4C */
405 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 50 */
406 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 54 */
407 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 58 */
408 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 5C */
409 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 60 */
410 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 64 */
411 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 68 */
412 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 6C */
413 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 70 */
414 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 74 */
415 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 78 */
416 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 7C */
417 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 80 */
418 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 84 */
419 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 88 */
420 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 8C */
421 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 90 */
422 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 94 */
423 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 98 */
424 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 9C */
425 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* A0 */
426 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* A4 */
427 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* A8 */
428 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* AC */
429 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* B0 */
430 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* B4 */
431 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* B8 */
432 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* BC */
433 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* C0 */
434 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* C4 */
435 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* C8 */
436 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* CC */
437 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D0 */
438 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D4 */
439 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D8 */
440 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* DC */
441 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* E0 */
442 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* E4 */
443 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* E8 */
444 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* EC */
445 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* F0 */
446 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* F4 */
447 {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* F8 */
448 {&nulldev}, {&hdsk_io}, {&simh_dev}, {&sr_dev} /* FC */
449 };
450
451 static int32 ramtype = 0;
452 #define MAX_RAM_TYPE 3
453
454 int32 chiptype = CHIP_TYPE_8080;
455
out(const uint32 Port,const uint32 Value)456 void out(const uint32 Port, const uint32 Value) {
457 if ((cpu_dev.dctrl & OUT_MSG) && sim_deb) {
458 fprintf(sim_deb, "CPU: " ADDRESS_FORMAT
459 " OUT(port=0x%04x [%5d], value=0x%04x [%5d])\n", PCX, Port, Port, Value, Value);
460 fflush(sim_deb);
461 }
462 dev_table[Port & 0xff].routine(Port, 1, Value);
463 if ((cpu_dev.dctrl & OUT_MSG) && sim_deb) {
464 fprintf(sim_deb, "CPU: " ADDRESS_FORMAT
465 " OUT(port=0x%04x [%5d], value=0x%04x [%5d]) done\n", PCX, Port, Port, Value, Value);
466 fflush(sim_deb);
467 }
468 }
469
in(const uint32 Port)470 uint32 in(const uint32 Port) {
471 uint32 result;
472 if ((cpu_dev.dctrl & IN_MSG) && sim_deb) {
473 fprintf(sim_deb, "CPU: " ADDRESS_FORMAT
474 " IN(port=0x%04x [%5d])\n", PCX, Port, Port);
475 fflush(sim_deb);
476 }
477 result = dev_table[Port & 0xff].routine(Port, 0, 0);
478 if ((cpu_dev.dctrl & IN_MSG) && sim_deb) {
479 fprintf(sim_deb, "CPU: " ADDRESS_FORMAT
480 " IN(port=0x%04x [%5d]) = 0x%04x [%5d]\n", PCX, Port, Port, result, result);
481 fflush(sim_deb);
482 }
483 return result;
484 }
485
486 /* the following tables precompute some common subexpressions
487 parityTable[i] 0..255 (number of 1's in i is odd) ? 0 : 4
488 incTable[i] 0..256! (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4)
489 decTable[i] 0..255 (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | 2
490 cbitsTable[i] 0..511 (i & 0x10) | ((i >> 8) & 1)
491 cbitsDup8Table[i] 0..511 (i & 0x10) | ((i >> 8) & 1) | ((i & 0xff) << 8) | (i & 0xa8) |
492 (((i & 0xff) == 0) << 6)
493 cbitsDup16Table[i] 0..511 (i & 0x10) | ((i >> 8) & 1) | (i & 0x28)
494 cbits2Table[i] 0..511 (i & 0x10) | ((i >> 8) & 1) | 2
495 rrcaTable[i] 0..255 ((i & 1) << 15) | ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1)
496 rraTable[i] 0..255 ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1)
497 addTable[i] 0..511 ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6)
498 subTable[i] 0..255 ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | 2
499 andTable[i] 0..255 (i << 8) | (i & 0xa8) | ((i == 0) << 6) | 0x10 | parityTable[i]
500 xororTable[i] 0..255 (i << 8) | (i & 0xa8) | ((i == 0) << 6) | parityTable[i]
501 rotateShiftTable[i] 0..255 (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i & 0xff]
502 incZ80Table[i] 0..256! (i & 0xa8) | (((i & 0xff) == 0) << 6) |
503 (((i & 0xf) == 0) << 4) | ((i == 0x80) << 2)
504 decZ80Table[i] 0..255 (i & 0xa8) | (((i & 0xff) == 0) << 6) |
505 (((i & 0xf) == 0xf) << 4) | ((i == 0x7f) << 2) | 2
506 cbitsZ80Table[i] 0..511 (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1)
507 cbitsZ80DupTable[i] 0..511 (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) |
508 ((i >> 8) & 1) | (i & 0xa8)
509 cbits2Z80Table[i] 0..511 (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2
510 cbits2Z80DupTable[i] 0..511 (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2 |
511 (i & 0xa8)
512 negTable[i] 0..255 (((i & 0x0f) != 0) << 4) | ((i == 0x80) << 2) | 2 | (i != 0)
513 rrdrldTable[i] 0..255 (i << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i]
514 cpTable[i] 0..255 (i & 0x80) | (((i & 0xff) == 0) << 6)
515 */
516
517 /* parityTable[i] = (number of 1's in i is odd) ? 0 : 4, i = 0..255 */
518 static const uint8 parityTable[256] = {
519 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
520 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
521 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
522 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
523 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
524 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
525 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
526 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
527 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
528 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
529 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
530 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
531 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
532 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
533 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
534 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
535 };
536
537 /* incTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4), i = 0..256 */
538 static const uint8 incTable[257] = {
539 80, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
540 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
541 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
542 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
543 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
544 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
545 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
546 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
547 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
548 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
549 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
550 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
551 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
552 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
553 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
554 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, 80
555 };
556
557 /* decTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | 2, i = 0..255 */
558 static const uint8 decTable[256] = {
559 66, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
560 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
561 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
562 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
563 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
564 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
565 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
566 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
567 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
568 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
569 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
570 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
571 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
572 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
573 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
574 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
575 };
576
577 /* cbitsTable[i] = (i & 0x10) | ((i >> 8) & 1), i = 0..511 */
578 static const uint8 cbitsTable[512] = {
579 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
580 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
581 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
582 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
583 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
584 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
585 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
586 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
587 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
588 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
590 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
591 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
592 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
593 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
594 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
595 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
596 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
597 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
598 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
599 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
600 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
601 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
602 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
603 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
604 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
605 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
606 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
607 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
608 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
609 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
610 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
611 };
612
613 /* cbitsDup8Table[i] = (i & 0x10) | ((i >> 8) & 1) | ((i & 0xff) << 8) | (i & 0xa8) |
614 (((i & 0xff) == 0) << 6), i = 0..511 */
615 static const uint16 cbitsDup8Table[512] = {
616 0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700,
617 0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08,
618 0x1010,0x1110,0x1210,0x1310,0x1410,0x1510,0x1610,0x1710,
619 0x1818,0x1918,0x1a18,0x1b18,0x1c18,0x1d18,0x1e18,0x1f18,
620 0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720,
621 0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28,
622 0x3030,0x3130,0x3230,0x3330,0x3430,0x3530,0x3630,0x3730,
623 0x3838,0x3938,0x3a38,0x3b38,0x3c38,0x3d38,0x3e38,0x3f38,
624 0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700,
625 0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08,
626 0x5010,0x5110,0x5210,0x5310,0x5410,0x5510,0x5610,0x5710,
627 0x5818,0x5918,0x5a18,0x5b18,0x5c18,0x5d18,0x5e18,0x5f18,
628 0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720,
629 0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28,
630 0x7030,0x7130,0x7230,0x7330,0x7430,0x7530,0x7630,0x7730,
631 0x7838,0x7938,0x7a38,0x7b38,0x7c38,0x7d38,0x7e38,0x7f38,
632 0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780,
633 0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88,
634 0x9090,0x9190,0x9290,0x9390,0x9490,0x9590,0x9690,0x9790,
635 0x9898,0x9998,0x9a98,0x9b98,0x9c98,0x9d98,0x9e98,0x9f98,
636 0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0,
637 0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8,
638 0xb0b0,0xb1b0,0xb2b0,0xb3b0,0xb4b0,0xb5b0,0xb6b0,0xb7b0,
639 0xb8b8,0xb9b8,0xbab8,0xbbb8,0xbcb8,0xbdb8,0xbeb8,0xbfb8,
640 0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780,
641 0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88,
642 0xd090,0xd190,0xd290,0xd390,0xd490,0xd590,0xd690,0xd790,
643 0xd898,0xd998,0xda98,0xdb98,0xdc98,0xdd98,0xde98,0xdf98,
644 0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0,
645 0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8,
646 0xf0b0,0xf1b0,0xf2b0,0xf3b0,0xf4b0,0xf5b0,0xf6b0,0xf7b0,
647 0xf8b8,0xf9b8,0xfab8,0xfbb8,0xfcb8,0xfdb8,0xfeb8,0xffb8,
648 0x0041,0x0101,0x0201,0x0301,0x0401,0x0501,0x0601,0x0701,
649 0x0809,0x0909,0x0a09,0x0b09,0x0c09,0x0d09,0x0e09,0x0f09,
650 0x1011,0x1111,0x1211,0x1311,0x1411,0x1511,0x1611,0x1711,
651 0x1819,0x1919,0x1a19,0x1b19,0x1c19,0x1d19,0x1e19,0x1f19,
652 0x2021,0x2121,0x2221,0x2321,0x2421,0x2521,0x2621,0x2721,
653 0x2829,0x2929,0x2a29,0x2b29,0x2c29,0x2d29,0x2e29,0x2f29,
654 0x3031,0x3131,0x3231,0x3331,0x3431,0x3531,0x3631,0x3731,
655 0x3839,0x3939,0x3a39,0x3b39,0x3c39,0x3d39,0x3e39,0x3f39,
656 0x4001,0x4101,0x4201,0x4301,0x4401,0x4501,0x4601,0x4701,
657 0x4809,0x4909,0x4a09,0x4b09,0x4c09,0x4d09,0x4e09,0x4f09,
658 0x5011,0x5111,0x5211,0x5311,0x5411,0x5511,0x5611,0x5711,
659 0x5819,0x5919,0x5a19,0x5b19,0x5c19,0x5d19,0x5e19,0x5f19,
660 0x6021,0x6121,0x6221,0x6321,0x6421,0x6521,0x6621,0x6721,
661 0x6829,0x6929,0x6a29,0x6b29,0x6c29,0x6d29,0x6e29,0x6f29,
662 0x7031,0x7131,0x7231,0x7331,0x7431,0x7531,0x7631,0x7731,
663 0x7839,0x7939,0x7a39,0x7b39,0x7c39,0x7d39,0x7e39,0x7f39,
664 0x8081,0x8181,0x8281,0x8381,0x8481,0x8581,0x8681,0x8781,
665 0x8889,0x8989,0x8a89,0x8b89,0x8c89,0x8d89,0x8e89,0x8f89,
666 0x9091,0x9191,0x9291,0x9391,0x9491,0x9591,0x9691,0x9791,
667 0x9899,0x9999,0x9a99,0x9b99,0x9c99,0x9d99,0x9e99,0x9f99,
668 0xa0a1,0xa1a1,0xa2a1,0xa3a1,0xa4a1,0xa5a1,0xa6a1,0xa7a1,
669 0xa8a9,0xa9a9,0xaaa9,0xaba9,0xaca9,0xada9,0xaea9,0xafa9,
670 0xb0b1,0xb1b1,0xb2b1,0xb3b1,0xb4b1,0xb5b1,0xb6b1,0xb7b1,
671 0xb8b9,0xb9b9,0xbab9,0xbbb9,0xbcb9,0xbdb9,0xbeb9,0xbfb9,
672 0xc081,0xc181,0xc281,0xc381,0xc481,0xc581,0xc681,0xc781,
673 0xc889,0xc989,0xca89,0xcb89,0xcc89,0xcd89,0xce89,0xcf89,
674 0xd091,0xd191,0xd291,0xd391,0xd491,0xd591,0xd691,0xd791,
675 0xd899,0xd999,0xda99,0xdb99,0xdc99,0xdd99,0xde99,0xdf99,
676 0xe0a1,0xe1a1,0xe2a1,0xe3a1,0xe4a1,0xe5a1,0xe6a1,0xe7a1,
677 0xe8a9,0xe9a9,0xeaa9,0xeba9,0xeca9,0xeda9,0xeea9,0xefa9,
678 0xf0b1,0xf1b1,0xf2b1,0xf3b1,0xf4b1,0xf5b1,0xf6b1,0xf7b1,
679 0xf8b9,0xf9b9,0xfab9,0xfbb9,0xfcb9,0xfdb9,0xfeb9,0xffb9,
680 };
681
682 /* cbitsDup16Table[i] = (i & 0x10) | ((i >> 8) & 1) | (i & 0x28), i = 0..511 */
683 static const uint8 cbitsDup16Table[512] = {
684 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
685 16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,
686 32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,
687 48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56,
688 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
689 16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,
690 32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,
691 48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56,
692 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
693 16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,
694 32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,
695 48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56,
696 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
697 16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,
698 32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,
699 48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56,
700 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9,
701 17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25,
702 33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41,
703 49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57,
704 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9,
705 17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25,
706 33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41,
707 49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57,
708 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9,
709 17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25,
710 33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41,
711 49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57,
712 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9,
713 17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25,
714 33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41,
715 49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57,
716 };
717
718 /* cbits2Table[i] = (i & 0x10) | ((i >> 8) & 1) | 2, i = 0..511 */
719 static const uint8 cbits2Table[512] = {
720 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
721 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
722 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
723 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
724 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
725 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
726 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
727 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
728 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
729 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
730 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
731 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
732 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
733 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
734 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
735 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
736 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
737 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
738 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
739 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
740 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
741 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
742 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
743 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
744 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
745 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
746 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
747 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
748 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
749 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
750 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
751 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
752 };
753
754 /* rrcaTable[i] = ((i & 1) << 15) | ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1), i = 0..255 */
755 static const uint16 rrcaTable[256] = {
756 0x0000,0x8001,0x0100,0x8101,0x0200,0x8201,0x0300,0x8301,
757 0x0400,0x8401,0x0500,0x8501,0x0600,0x8601,0x0700,0x8701,
758 0x0808,0x8809,0x0908,0x8909,0x0a08,0x8a09,0x0b08,0x8b09,
759 0x0c08,0x8c09,0x0d08,0x8d09,0x0e08,0x8e09,0x0f08,0x8f09,
760 0x1000,0x9001,0x1100,0x9101,0x1200,0x9201,0x1300,0x9301,
761 0x1400,0x9401,0x1500,0x9501,0x1600,0x9601,0x1700,0x9701,
762 0x1808,0x9809,0x1908,0x9909,0x1a08,0x9a09,0x1b08,0x9b09,
763 0x1c08,0x9c09,0x1d08,0x9d09,0x1e08,0x9e09,0x1f08,0x9f09,
764 0x2020,0xa021,0x2120,0xa121,0x2220,0xa221,0x2320,0xa321,
765 0x2420,0xa421,0x2520,0xa521,0x2620,0xa621,0x2720,0xa721,
766 0x2828,0xa829,0x2928,0xa929,0x2a28,0xaa29,0x2b28,0xab29,
767 0x2c28,0xac29,0x2d28,0xad29,0x2e28,0xae29,0x2f28,0xaf29,
768 0x3020,0xb021,0x3120,0xb121,0x3220,0xb221,0x3320,0xb321,
769 0x3420,0xb421,0x3520,0xb521,0x3620,0xb621,0x3720,0xb721,
770 0x3828,0xb829,0x3928,0xb929,0x3a28,0xba29,0x3b28,0xbb29,
771 0x3c28,0xbc29,0x3d28,0xbd29,0x3e28,0xbe29,0x3f28,0xbf29,
772 0x4000,0xc001,0x4100,0xc101,0x4200,0xc201,0x4300,0xc301,
773 0x4400,0xc401,0x4500,0xc501,0x4600,0xc601,0x4700,0xc701,
774 0x4808,0xc809,0x4908,0xc909,0x4a08,0xca09,0x4b08,0xcb09,
775 0x4c08,0xcc09,0x4d08,0xcd09,0x4e08,0xce09,0x4f08,0xcf09,
776 0x5000,0xd001,0x5100,0xd101,0x5200,0xd201,0x5300,0xd301,
777 0x5400,0xd401,0x5500,0xd501,0x5600,0xd601,0x5700,0xd701,
778 0x5808,0xd809,0x5908,0xd909,0x5a08,0xda09,0x5b08,0xdb09,
779 0x5c08,0xdc09,0x5d08,0xdd09,0x5e08,0xde09,0x5f08,0xdf09,
780 0x6020,0xe021,0x6120,0xe121,0x6220,0xe221,0x6320,0xe321,
781 0x6420,0xe421,0x6520,0xe521,0x6620,0xe621,0x6720,0xe721,
782 0x6828,0xe829,0x6928,0xe929,0x6a28,0xea29,0x6b28,0xeb29,
783 0x6c28,0xec29,0x6d28,0xed29,0x6e28,0xee29,0x6f28,0xef29,
784 0x7020,0xf021,0x7120,0xf121,0x7220,0xf221,0x7320,0xf321,
785 0x7420,0xf421,0x7520,0xf521,0x7620,0xf621,0x7720,0xf721,
786 0x7828,0xf829,0x7928,0xf929,0x7a28,0xfa29,0x7b28,0xfb29,
787 0x7c28,0xfc29,0x7d28,0xfd29,0x7e28,0xfe29,0x7f28,0xff29,
788 };
789
790 /* rraTable[i] = ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1), i = 0..255 */
791 static const uint16 rraTable[256] = {
792 0x0000,0x0001,0x0100,0x0101,0x0200,0x0201,0x0300,0x0301,
793 0x0400,0x0401,0x0500,0x0501,0x0600,0x0601,0x0700,0x0701,
794 0x0808,0x0809,0x0908,0x0909,0x0a08,0x0a09,0x0b08,0x0b09,
795 0x0c08,0x0c09,0x0d08,0x0d09,0x0e08,0x0e09,0x0f08,0x0f09,
796 0x1000,0x1001,0x1100,0x1101,0x1200,0x1201,0x1300,0x1301,
797 0x1400,0x1401,0x1500,0x1501,0x1600,0x1601,0x1700,0x1701,
798 0x1808,0x1809,0x1908,0x1909,0x1a08,0x1a09,0x1b08,0x1b09,
799 0x1c08,0x1c09,0x1d08,0x1d09,0x1e08,0x1e09,0x1f08,0x1f09,
800 0x2020,0x2021,0x2120,0x2121,0x2220,0x2221,0x2320,0x2321,
801 0x2420,0x2421,0x2520,0x2521,0x2620,0x2621,0x2720,0x2721,
802 0x2828,0x2829,0x2928,0x2929,0x2a28,0x2a29,0x2b28,0x2b29,
803 0x2c28,0x2c29,0x2d28,0x2d29,0x2e28,0x2e29,0x2f28,0x2f29,
804 0x3020,0x3021,0x3120,0x3121,0x3220,0x3221,0x3320,0x3321,
805 0x3420,0x3421,0x3520,0x3521,0x3620,0x3621,0x3720,0x3721,
806 0x3828,0x3829,0x3928,0x3929,0x3a28,0x3a29,0x3b28,0x3b29,
807 0x3c28,0x3c29,0x3d28,0x3d29,0x3e28,0x3e29,0x3f28,0x3f29,
808 0x4000,0x4001,0x4100,0x4101,0x4200,0x4201,0x4300,0x4301,
809 0x4400,0x4401,0x4500,0x4501,0x4600,0x4601,0x4700,0x4701,
810 0x4808,0x4809,0x4908,0x4909,0x4a08,0x4a09,0x4b08,0x4b09,
811 0x4c08,0x4c09,0x4d08,0x4d09,0x4e08,0x4e09,0x4f08,0x4f09,
812 0x5000,0x5001,0x5100,0x5101,0x5200,0x5201,0x5300,0x5301,
813 0x5400,0x5401,0x5500,0x5501,0x5600,0x5601,0x5700,0x5701,
814 0x5808,0x5809,0x5908,0x5909,0x5a08,0x5a09,0x5b08,0x5b09,
815 0x5c08,0x5c09,0x5d08,0x5d09,0x5e08,0x5e09,0x5f08,0x5f09,
816 0x6020,0x6021,0x6120,0x6121,0x6220,0x6221,0x6320,0x6321,
817 0x6420,0x6421,0x6520,0x6521,0x6620,0x6621,0x6720,0x6721,
818 0x6828,0x6829,0x6928,0x6929,0x6a28,0x6a29,0x6b28,0x6b29,
819 0x6c28,0x6c29,0x6d28,0x6d29,0x6e28,0x6e29,0x6f28,0x6f29,
820 0x7020,0x7021,0x7120,0x7121,0x7220,0x7221,0x7320,0x7321,
821 0x7420,0x7421,0x7520,0x7521,0x7620,0x7621,0x7720,0x7721,
822 0x7828,0x7829,0x7928,0x7929,0x7a28,0x7a29,0x7b28,0x7b29,
823 0x7c28,0x7c29,0x7d28,0x7d29,0x7e28,0x7e29,0x7f28,0x7f29,
824 };
825
826 /* addTable[i] = ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6), i = 0..511 */
827 static const uint16 addTable[512] = {
828 0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700,
829 0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08,
830 0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700,
831 0x1808,0x1908,0x1a08,0x1b08,0x1c08,0x1d08,0x1e08,0x1f08,
832 0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720,
833 0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28,
834 0x3020,0x3120,0x3220,0x3320,0x3420,0x3520,0x3620,0x3720,
835 0x3828,0x3928,0x3a28,0x3b28,0x3c28,0x3d28,0x3e28,0x3f28,
836 0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700,
837 0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08,
838 0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,0x5700,
839 0x5808,0x5908,0x5a08,0x5b08,0x5c08,0x5d08,0x5e08,0x5f08,
840 0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720,
841 0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28,
842 0x7020,0x7120,0x7220,0x7320,0x7420,0x7520,0x7620,0x7720,
843 0x7828,0x7928,0x7a28,0x7b28,0x7c28,0x7d28,0x7e28,0x7f28,
844 0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780,
845 0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88,
846 0x9080,0x9180,0x9280,0x9380,0x9480,0x9580,0x9680,0x9780,
847 0x9888,0x9988,0x9a88,0x9b88,0x9c88,0x9d88,0x9e88,0x9f88,
848 0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0,
849 0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8,
850 0xb0a0,0xb1a0,0xb2a0,0xb3a0,0xb4a0,0xb5a0,0xb6a0,0xb7a0,
851 0xb8a8,0xb9a8,0xbaa8,0xbba8,0xbca8,0xbda8,0xbea8,0xbfa8,
852 0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780,
853 0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88,
854 0xd080,0xd180,0xd280,0xd380,0xd480,0xd580,0xd680,0xd780,
855 0xd888,0xd988,0xda88,0xdb88,0xdc88,0xdd88,0xde88,0xdf88,
856 0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0,
857 0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8,
858 0xf0a0,0xf1a0,0xf2a0,0xf3a0,0xf4a0,0xf5a0,0xf6a0,0xf7a0,
859 0xf8a8,0xf9a8,0xfaa8,0xfba8,0xfca8,0xfda8,0xfea8,0xffa8,
860 0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700,
861 0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08,
862 0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700,
863 0x1808,0x1908,0x1a08,0x1b08,0x1c08,0x1d08,0x1e08,0x1f08,
864 0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720,
865 0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28,
866 0x3020,0x3120,0x3220,0x3320,0x3420,0x3520,0x3620,0x3720,
867 0x3828,0x3928,0x3a28,0x3b28,0x3c28,0x3d28,0x3e28,0x3f28,
868 0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700,
869 0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08,
870 0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,0x5700,
871 0x5808,0x5908,0x5a08,0x5b08,0x5c08,0x5d08,0x5e08,0x5f08,
872 0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720,
873 0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28,
874 0x7020,0x7120,0x7220,0x7320,0x7420,0x7520,0x7620,0x7720,
875 0x7828,0x7928,0x7a28,0x7b28,0x7c28,0x7d28,0x7e28,0x7f28,
876 0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780,
877 0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88,
878 0x9080,0x9180,0x9280,0x9380,0x9480,0x9580,0x9680,0x9780,
879 0x9888,0x9988,0x9a88,0x9b88,0x9c88,0x9d88,0x9e88,0x9f88,
880 0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0,
881 0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8,
882 0xb0a0,0xb1a0,0xb2a0,0xb3a0,0xb4a0,0xb5a0,0xb6a0,0xb7a0,
883 0xb8a8,0xb9a8,0xbaa8,0xbba8,0xbca8,0xbda8,0xbea8,0xbfa8,
884 0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780,
885 0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88,
886 0xd080,0xd180,0xd280,0xd380,0xd480,0xd580,0xd680,0xd780,
887 0xd888,0xd988,0xda88,0xdb88,0xdc88,0xdd88,0xde88,0xdf88,
888 0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0,
889 0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8,
890 0xf0a0,0xf1a0,0xf2a0,0xf3a0,0xf4a0,0xf5a0,0xf6a0,0xf7a0,
891 0xf8a8,0xf9a8,0xfaa8,0xfba8,0xfca8,0xfda8,0xfea8,0xffa8,
892 };
893
894 /* subTable[i] = ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | 2, i = 0..255 */
895 static const uint16 subTable[256] = {
896 0x0042,0x0102,0x0202,0x0302,0x0402,0x0502,0x0602,0x0702,
897 0x080a,0x090a,0x0a0a,0x0b0a,0x0c0a,0x0d0a,0x0e0a,0x0f0a,
898 0x1002,0x1102,0x1202,0x1302,0x1402,0x1502,0x1602,0x1702,
899 0x180a,0x190a,0x1a0a,0x1b0a,0x1c0a,0x1d0a,0x1e0a,0x1f0a,
900 0x2022,0x2122,0x2222,0x2322,0x2422,0x2522,0x2622,0x2722,
901 0x282a,0x292a,0x2a2a,0x2b2a,0x2c2a,0x2d2a,0x2e2a,0x2f2a,
902 0x3022,0x3122,0x3222,0x3322,0x3422,0x3522,0x3622,0x3722,
903 0x382a,0x392a,0x3a2a,0x3b2a,0x3c2a,0x3d2a,0x3e2a,0x3f2a,
904 0x4002,0x4102,0x4202,0x4302,0x4402,0x4502,0x4602,0x4702,
905 0x480a,0x490a,0x4a0a,0x4b0a,0x4c0a,0x4d0a,0x4e0a,0x4f0a,
906 0x5002,0x5102,0x5202,0x5302,0x5402,0x5502,0x5602,0x5702,
907 0x580a,0x590a,0x5a0a,0x5b0a,0x5c0a,0x5d0a,0x5e0a,0x5f0a,
908 0x6022,0x6122,0x6222,0x6322,0x6422,0x6522,0x6622,0x6722,
909 0x682a,0x692a,0x6a2a,0x6b2a,0x6c2a,0x6d2a,0x6e2a,0x6f2a,
910 0x7022,0x7122,0x7222,0x7322,0x7422,0x7522,0x7622,0x7722,
911 0x782a,0x792a,0x7a2a,0x7b2a,0x7c2a,0x7d2a,0x7e2a,0x7f2a,
912 0x8082,0x8182,0x8282,0x8382,0x8482,0x8582,0x8682,0x8782,
913 0x888a,0x898a,0x8a8a,0x8b8a,0x8c8a,0x8d8a,0x8e8a,0x8f8a,
914 0x9082,0x9182,0x9282,0x9382,0x9482,0x9582,0x9682,0x9782,
915 0x988a,0x998a,0x9a8a,0x9b8a,0x9c8a,0x9d8a,0x9e8a,0x9f8a,
916 0xa0a2,0xa1a2,0xa2a2,0xa3a2,0xa4a2,0xa5a2,0xa6a2,0xa7a2,
917 0xa8aa,0xa9aa,0xaaaa,0xabaa,0xacaa,0xadaa,0xaeaa,0xafaa,
918 0xb0a2,0xb1a2,0xb2a2,0xb3a2,0xb4a2,0xb5a2,0xb6a2,0xb7a2,
919 0xb8aa,0xb9aa,0xbaaa,0xbbaa,0xbcaa,0xbdaa,0xbeaa,0xbfaa,
920 0xc082,0xc182,0xc282,0xc382,0xc482,0xc582,0xc682,0xc782,
921 0xc88a,0xc98a,0xca8a,0xcb8a,0xcc8a,0xcd8a,0xce8a,0xcf8a,
922 0xd082,0xd182,0xd282,0xd382,0xd482,0xd582,0xd682,0xd782,
923 0xd88a,0xd98a,0xda8a,0xdb8a,0xdc8a,0xdd8a,0xde8a,0xdf8a,
924 0xe0a2,0xe1a2,0xe2a2,0xe3a2,0xe4a2,0xe5a2,0xe6a2,0xe7a2,
925 0xe8aa,0xe9aa,0xeaaa,0xebaa,0xecaa,0xedaa,0xeeaa,0xefaa,
926 0xf0a2,0xf1a2,0xf2a2,0xf3a2,0xf4a2,0xf5a2,0xf6a2,0xf7a2,
927 0xf8aa,0xf9aa,0xfaaa,0xfbaa,0xfcaa,0xfdaa,0xfeaa,0xffaa,
928 };
929
930 /* andTable[i] = (i << 8) | (i & 0xa8) | ((i == 0) << 6) | 0x10 | parityTable[i], i = 0..255 */
931 static const uint16 andTable[256] = {
932 0x0054,0x0110,0x0210,0x0314,0x0410,0x0514,0x0614,0x0710,
933 0x0818,0x091c,0x0a1c,0x0b18,0x0c1c,0x0d18,0x0e18,0x0f1c,
934 0x1010,0x1114,0x1214,0x1310,0x1414,0x1510,0x1610,0x1714,
935 0x181c,0x1918,0x1a18,0x1b1c,0x1c18,0x1d1c,0x1e1c,0x1f18,
936 0x2030,0x2134,0x2234,0x2330,0x2434,0x2530,0x2630,0x2734,
937 0x283c,0x2938,0x2a38,0x2b3c,0x2c38,0x2d3c,0x2e3c,0x2f38,
938 0x3034,0x3130,0x3230,0x3334,0x3430,0x3534,0x3634,0x3730,
939 0x3838,0x393c,0x3a3c,0x3b38,0x3c3c,0x3d38,0x3e38,0x3f3c,
940 0x4010,0x4114,0x4214,0x4310,0x4414,0x4510,0x4610,0x4714,
941 0x481c,0x4918,0x4a18,0x4b1c,0x4c18,0x4d1c,0x4e1c,0x4f18,
942 0x5014,0x5110,0x5210,0x5314,0x5410,0x5514,0x5614,0x5710,
943 0x5818,0x591c,0x5a1c,0x5b18,0x5c1c,0x5d18,0x5e18,0x5f1c,
944 0x6034,0x6130,0x6230,0x6334,0x6430,0x6534,0x6634,0x6730,
945 0x6838,0x693c,0x6a3c,0x6b38,0x6c3c,0x6d38,0x6e38,0x6f3c,
946 0x7030,0x7134,0x7234,0x7330,0x7434,0x7530,0x7630,0x7734,
947 0x783c,0x7938,0x7a38,0x7b3c,0x7c38,0x7d3c,0x7e3c,0x7f38,
948 0x8090,0x8194,0x8294,0x8390,0x8494,0x8590,0x8690,0x8794,
949 0x889c,0x8998,0x8a98,0x8b9c,0x8c98,0x8d9c,0x8e9c,0x8f98,
950 0x9094,0x9190,0x9290,0x9394,0x9490,0x9594,0x9694,0x9790,
951 0x9898,0x999c,0x9a9c,0x9b98,0x9c9c,0x9d98,0x9e98,0x9f9c,
952 0xa0b4,0xa1b0,0xa2b0,0xa3b4,0xa4b0,0xa5b4,0xa6b4,0xa7b0,
953 0xa8b8,0xa9bc,0xaabc,0xabb8,0xacbc,0xadb8,0xaeb8,0xafbc,
954 0xb0b0,0xb1b4,0xb2b4,0xb3b0,0xb4b4,0xb5b0,0xb6b0,0xb7b4,
955 0xb8bc,0xb9b8,0xbab8,0xbbbc,0xbcb8,0xbdbc,0xbebc,0xbfb8,
956 0xc094,0xc190,0xc290,0xc394,0xc490,0xc594,0xc694,0xc790,
957 0xc898,0xc99c,0xca9c,0xcb98,0xcc9c,0xcd98,0xce98,0xcf9c,
958 0xd090,0xd194,0xd294,0xd390,0xd494,0xd590,0xd690,0xd794,
959 0xd89c,0xd998,0xda98,0xdb9c,0xdc98,0xdd9c,0xde9c,0xdf98,
960 0xe0b0,0xe1b4,0xe2b4,0xe3b0,0xe4b4,0xe5b0,0xe6b0,0xe7b4,
961 0xe8bc,0xe9b8,0xeab8,0xebbc,0xecb8,0xedbc,0xeebc,0xefb8,
962 0xf0b4,0xf1b0,0xf2b0,0xf3b4,0xf4b0,0xf5b4,0xf6b4,0xf7b0,
963 0xf8b8,0xf9bc,0xfabc,0xfbb8,0xfcbc,0xfdb8,0xfeb8,0xffbc,
964 };
965
966 /* xororTable[i] = (i << 8) | (i & 0xa8) | ((i == 0) << 6) | parityTable[i], i = 0..255 */
967 static const uint16 xororTable[256] = {
968 0x0044,0x0100,0x0200,0x0304,0x0400,0x0504,0x0604,0x0700,
969 0x0808,0x090c,0x0a0c,0x0b08,0x0c0c,0x0d08,0x0e08,0x0f0c,
970 0x1000,0x1104,0x1204,0x1300,0x1404,0x1500,0x1600,0x1704,
971 0x180c,0x1908,0x1a08,0x1b0c,0x1c08,0x1d0c,0x1e0c,0x1f08,
972 0x2020,0x2124,0x2224,0x2320,0x2424,0x2520,0x2620,0x2724,
973 0x282c,0x2928,0x2a28,0x2b2c,0x2c28,0x2d2c,0x2e2c,0x2f28,
974 0x3024,0x3120,0x3220,0x3324,0x3420,0x3524,0x3624,0x3720,
975 0x3828,0x392c,0x3a2c,0x3b28,0x3c2c,0x3d28,0x3e28,0x3f2c,
976 0x4000,0x4104,0x4204,0x4300,0x4404,0x4500,0x4600,0x4704,
977 0x480c,0x4908,0x4a08,0x4b0c,0x4c08,0x4d0c,0x4e0c,0x4f08,
978 0x5004,0x5100,0x5200,0x5304,0x5400,0x5504,0x5604,0x5700,
979 0x5808,0x590c,0x5a0c,0x5b08,0x5c0c,0x5d08,0x5e08,0x5f0c,
980 0x6024,0x6120,0x6220,0x6324,0x6420,0x6524,0x6624,0x6720,
981 0x6828,0x692c,0x6a2c,0x6b28,0x6c2c,0x6d28,0x6e28,0x6f2c,
982 0x7020,0x7124,0x7224,0x7320,0x7424,0x7520,0x7620,0x7724,
983 0x782c,0x7928,0x7a28,0x7b2c,0x7c28,0x7d2c,0x7e2c,0x7f28,
984 0x8080,0x8184,0x8284,0x8380,0x8484,0x8580,0x8680,0x8784,
985 0x888c,0x8988,0x8a88,0x8b8c,0x8c88,0x8d8c,0x8e8c,0x8f88,
986 0x9084,0x9180,0x9280,0x9384,0x9480,0x9584,0x9684,0x9780,
987 0x9888,0x998c,0x9a8c,0x9b88,0x9c8c,0x9d88,0x9e88,0x9f8c,
988 0xa0a4,0xa1a0,0xa2a0,0xa3a4,0xa4a0,0xa5a4,0xa6a4,0xa7a0,
989 0xa8a8,0xa9ac,0xaaac,0xaba8,0xacac,0xada8,0xaea8,0xafac,
990 0xb0a0,0xb1a4,0xb2a4,0xb3a0,0xb4a4,0xb5a0,0xb6a0,0xb7a4,
991 0xb8ac,0xb9a8,0xbaa8,0xbbac,0xbca8,0xbdac,0xbeac,0xbfa8,
992 0xc084,0xc180,0xc280,0xc384,0xc480,0xc584,0xc684,0xc780,
993 0xc888,0xc98c,0xca8c,0xcb88,0xcc8c,0xcd88,0xce88,0xcf8c,
994 0xd080,0xd184,0xd284,0xd380,0xd484,0xd580,0xd680,0xd784,
995 0xd88c,0xd988,0xda88,0xdb8c,0xdc88,0xdd8c,0xde8c,0xdf88,
996 0xe0a0,0xe1a4,0xe2a4,0xe3a0,0xe4a4,0xe5a0,0xe6a0,0xe7a4,
997 0xe8ac,0xe9a8,0xeaa8,0xebac,0xeca8,0xedac,0xeeac,0xefa8,
998 0xf0a4,0xf1a0,0xf2a0,0xf3a4,0xf4a0,0xf5a4,0xf6a4,0xf7a0,
999 0xf8a8,0xf9ac,0xfaac,0xfba8,0xfcac,0xfda8,0xfea8,0xffac,
1000 };
1001
1002 /* rotateShiftTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i & 0xff], i = 0..255 */
1003 static const uint8 rotateShiftTable[256] = {
1004 68, 0, 0, 4, 0, 4, 4, 0, 8, 12, 12, 8, 12, 8, 8, 12,
1005 0, 4, 4, 0, 4, 0, 0, 4, 12, 8, 8, 12, 8, 12, 12, 8,
1006 32, 36, 36, 32, 36, 32, 32, 36, 44, 40, 40, 44, 40, 44, 44, 40,
1007 36, 32, 32, 36, 32, 36, 36, 32, 40, 44, 44, 40, 44, 40, 40, 44,
1008 0, 4, 4, 0, 4, 0, 0, 4, 12, 8, 8, 12, 8, 12, 12, 8,
1009 4, 0, 0, 4, 0, 4, 4, 0, 8, 12, 12, 8, 12, 8, 8, 12,
1010 36, 32, 32, 36, 32, 36, 36, 32, 40, 44, 44, 40, 44, 40, 40, 44,
1011 32, 36, 36, 32, 36, 32, 32, 36, 44, 40, 40, 44, 40, 44, 44, 40,
1012 128,132,132,128,132,128,128,132,140,136,136,140,136,140,140,136,
1013 132,128,128,132,128,132,132,128,136,140,140,136,140,136,136,140,
1014 164,160,160,164,160,164,164,160,168,172,172,168,172,168,168,172,
1015 160,164,164,160,164,160,160,164,172,168,168,172,168,172,172,168,
1016 132,128,128,132,128,132,132,128,136,140,140,136,140,136,136,140,
1017 128,132,132,128,132,128,128,132,140,136,136,140,136,140,140,136,
1018 160,164,164,160,164,160,160,164,172,168,168,172,168,172,172,168,
1019 164,160,160,164,160,164,164,160,168,172,172,168,172,168,168,172,
1020 };
1021
1022 /* incZ80Table[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) |
1023 (((i & 0xf) == 0) << 4) | ((i == 0x80) << 2), i = 0..256 */
1024 static const uint8 incZ80Table[257] = {
1025 80, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
1026 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
1027 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
1028 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
1029 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
1030 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
1031 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
1032 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
1033 148,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
1034 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
1035 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
1036 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
1037 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
1038 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
1039 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
1040 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, 80,
1041 };
1042
1043 /* decZ80Table[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) |
1044 (((i & 0xf) == 0xf) << 4) | ((i == 0x7f) << 2) | 2, i = 0..255 */
1045 static const uint8 decZ80Table[256] = {
1046 66, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
1047 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
1048 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
1049 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
1050 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
1051 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
1052 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
1053 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 62,
1054 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
1055 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
1056 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
1057 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
1058 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
1059 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
1060 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
1061 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
1062 };
1063
1064 /* cbitsZ80Table[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1), i = 0..511 */
1065 static const uint8 cbitsZ80Table[512] = {
1066 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1067 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1068 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1069 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1070 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1071 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1072 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1073 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1074 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1075 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
1076 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1077 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
1078 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1079 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
1080 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1081 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
1082 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1083 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
1084 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1085 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
1086 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1087 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
1088 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1089 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
1090 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1091 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
1092 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1093 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
1094 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1095 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
1096 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1097 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
1098 };
1099
1100 /* cbitsZ80DupTable[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) |
1101 ((i >> 8) & 1) | (i & 0xa8), i = 0..511 */
1102 static const uint8 cbitsZ80DupTable[512] = {
1103 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
1104 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24,
1105 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
1106 48, 48, 48, 48, 48, 48, 48, 48, 56, 56, 56, 56, 56, 56, 56, 56,
1107 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
1108 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24,
1109 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
1110 48, 48, 48, 48, 48, 48, 48, 48, 56, 56, 56, 56, 56, 56, 56, 56,
1111 132,132,132,132,132,132,132,132,140,140,140,140,140,140,140,140,
1112 148,148,148,148,148,148,148,148,156,156,156,156,156,156,156,156,
1113 164,164,164,164,164,164,164,164,172,172,172,172,172,172,172,172,
1114 180,180,180,180,180,180,180,180,188,188,188,188,188,188,188,188,
1115 132,132,132,132,132,132,132,132,140,140,140,140,140,140,140,140,
1116 148,148,148,148,148,148,148,148,156,156,156,156,156,156,156,156,
1117 164,164,164,164,164,164,164,164,172,172,172,172,172,172,172,172,
1118 180,180,180,180,180,180,180,180,188,188,188,188,188,188,188,188,
1119 5, 5, 5, 5, 5, 5, 5, 5, 13, 13, 13, 13, 13, 13, 13, 13,
1120 21, 21, 21, 21, 21, 21, 21, 21, 29, 29, 29, 29, 29, 29, 29, 29,
1121 37, 37, 37, 37, 37, 37, 37, 37, 45, 45, 45, 45, 45, 45, 45, 45,
1122 53, 53, 53, 53, 53, 53, 53, 53, 61, 61, 61, 61, 61, 61, 61, 61,
1123 5, 5, 5, 5, 5, 5, 5, 5, 13, 13, 13, 13, 13, 13, 13, 13,
1124 21, 21, 21, 21, 21, 21, 21, 21, 29, 29, 29, 29, 29, 29, 29, 29,
1125 37, 37, 37, 37, 37, 37, 37, 37, 45, 45, 45, 45, 45, 45, 45, 45,
1126 53, 53, 53, 53, 53, 53, 53, 53, 61, 61, 61, 61, 61, 61, 61, 61,
1127 129,129,129,129,129,129,129,129,137,137,137,137,137,137,137,137,
1128 145,145,145,145,145,145,145,145,153,153,153,153,153,153,153,153,
1129 161,161,161,161,161,161,161,161,169,169,169,169,169,169,169,169,
1130 177,177,177,177,177,177,177,177,185,185,185,185,185,185,185,185,
1131 129,129,129,129,129,129,129,129,137,137,137,137,137,137,137,137,
1132 145,145,145,145,145,145,145,145,153,153,153,153,153,153,153,153,
1133 161,161,161,161,161,161,161,161,169,169,169,169,169,169,169,169,
1134 177,177,177,177,177,177,177,177,185,185,185,185,185,185,185,185,
1135 };
1136
1137 /* cbits2Z80Table[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2, i = 0..511 */
1138 static const uint8 cbits2Z80Table[512] = {
1139 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1140 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
1141 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1142 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
1143 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1144 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
1145 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1146 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
1147 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1148 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
1149 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1150 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
1151 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1152 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
1153 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1154 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
1155 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1156 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
1157 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1158 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
1159 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1160 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
1161 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1162 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
1163 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1164 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1165 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1166 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1167 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1168 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1169 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1170 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1171 };
1172
1173 /* cbits2Z80DupTable[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2 |
1174 (i & 0xa8), i = 0..511 */
1175 static const uint8 cbits2Z80DupTable[512] = {
1176 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10,
1177 18, 18, 18, 18, 18, 18, 18, 18, 26, 26, 26, 26, 26, 26, 26, 26,
1178 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 42,
1179 50, 50, 50, 50, 50, 50, 50, 50, 58, 58, 58, 58, 58, 58, 58, 58,
1180 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10,
1181 18, 18, 18, 18, 18, 18, 18, 18, 26, 26, 26, 26, 26, 26, 26, 26,
1182 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 42,
1183 50, 50, 50, 50, 50, 50, 50, 50, 58, 58, 58, 58, 58, 58, 58, 58,
1184 134,134,134,134,134,134,134,134,142,142,142,142,142,142,142,142,
1185 150,150,150,150,150,150,150,150,158,158,158,158,158,158,158,158,
1186 166,166,166,166,166,166,166,166,174,174,174,174,174,174,174,174,
1187 182,182,182,182,182,182,182,182,190,190,190,190,190,190,190,190,
1188 134,134,134,134,134,134,134,134,142,142,142,142,142,142,142,142,
1189 150,150,150,150,150,150,150,150,158,158,158,158,158,158,158,158,
1190 166,166,166,166,166,166,166,166,174,174,174,174,174,174,174,174,
1191 182,182,182,182,182,182,182,182,190,190,190,190,190,190,190,190,
1192 7, 7, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15,
1193 23, 23, 23, 23, 23, 23, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31,
1194 39, 39, 39, 39, 39, 39, 39, 39, 47, 47, 47, 47, 47, 47, 47, 47,
1195 55, 55, 55, 55, 55, 55, 55, 55, 63, 63, 63, 63, 63, 63, 63, 63,
1196 7, 7, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15,
1197 23, 23, 23, 23, 23, 23, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31,
1198 39, 39, 39, 39, 39, 39, 39, 39, 47, 47, 47, 47, 47, 47, 47, 47,
1199 55, 55, 55, 55, 55, 55, 55, 55, 63, 63, 63, 63, 63, 63, 63, 63,
1200 131,131,131,131,131,131,131,131,139,139,139,139,139,139,139,139,
1201 147,147,147,147,147,147,147,147,155,155,155,155,155,155,155,155,
1202 163,163,163,163,163,163,163,163,171,171,171,171,171,171,171,171,
1203 179,179,179,179,179,179,179,179,187,187,187,187,187,187,187,187,
1204 131,131,131,131,131,131,131,131,139,139,139,139,139,139,139,139,
1205 147,147,147,147,147,147,147,147,155,155,155,155,155,155,155,155,
1206 163,163,163,163,163,163,163,163,171,171,171,171,171,171,171,171,
1207 179,179,179,179,179,179,179,179,187,187,187,187,187,187,187,187,
1208 };
1209
1210 /* negTable[i] = (((i & 0x0f) != 0) << 4) | ((i == 0x80) << 2) | 2 | (i != 0), i = 0..255 */
1211 static const uint8 negTable[256] = {
1212 2,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1213 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1214 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1215 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1216 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1217 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1218 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1219 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1220 7,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1221 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1222 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1223 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1224 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1225 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1226 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1227 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
1228 };
1229
1230 /* rrdrldTable[i] = (i << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i], i = 0..255 */
1231 static const uint16 rrdrldTable[256] = {
1232 0x0044,0x0100,0x0200,0x0304,0x0400,0x0504,0x0604,0x0700,
1233 0x0808,0x090c,0x0a0c,0x0b08,0x0c0c,0x0d08,0x0e08,0x0f0c,
1234 0x1000,0x1104,0x1204,0x1300,0x1404,0x1500,0x1600,0x1704,
1235 0x180c,0x1908,0x1a08,0x1b0c,0x1c08,0x1d0c,0x1e0c,0x1f08,
1236 0x2020,0x2124,0x2224,0x2320,0x2424,0x2520,0x2620,0x2724,
1237 0x282c,0x2928,0x2a28,0x2b2c,0x2c28,0x2d2c,0x2e2c,0x2f28,
1238 0x3024,0x3120,0x3220,0x3324,0x3420,0x3524,0x3624,0x3720,
1239 0x3828,0x392c,0x3a2c,0x3b28,0x3c2c,0x3d28,0x3e28,0x3f2c,
1240 0x4000,0x4104,0x4204,0x4300,0x4404,0x4500,0x4600,0x4704,
1241 0x480c,0x4908,0x4a08,0x4b0c,0x4c08,0x4d0c,0x4e0c,0x4f08,
1242 0x5004,0x5100,0x5200,0x5304,0x5400,0x5504,0x5604,0x5700,
1243 0x5808,0x590c,0x5a0c,0x5b08,0x5c0c,0x5d08,0x5e08,0x5f0c,
1244 0x6024,0x6120,0x6220,0x6324,0x6420,0x6524,0x6624,0x6720,
1245 0x6828,0x692c,0x6a2c,0x6b28,0x6c2c,0x6d28,0x6e28,0x6f2c,
1246 0x7020,0x7124,0x7224,0x7320,0x7424,0x7520,0x7620,0x7724,
1247 0x782c,0x7928,0x7a28,0x7b2c,0x7c28,0x7d2c,0x7e2c,0x7f28,
1248 0x8080,0x8184,0x8284,0x8380,0x8484,0x8580,0x8680,0x8784,
1249 0x888c,0x8988,0x8a88,0x8b8c,0x8c88,0x8d8c,0x8e8c,0x8f88,
1250 0x9084,0x9180,0x9280,0x9384,0x9480,0x9584,0x9684,0x9780,
1251 0x9888,0x998c,0x9a8c,0x9b88,0x9c8c,0x9d88,0x9e88,0x9f8c,
1252 0xa0a4,0xa1a0,0xa2a0,0xa3a4,0xa4a0,0xa5a4,0xa6a4,0xa7a0,
1253 0xa8a8,0xa9ac,0xaaac,0xaba8,0xacac,0xada8,0xaea8,0xafac,
1254 0xb0a0,0xb1a4,0xb2a4,0xb3a0,0xb4a4,0xb5a0,0xb6a0,0xb7a4,
1255 0xb8ac,0xb9a8,0xbaa8,0xbbac,0xbca8,0xbdac,0xbeac,0xbfa8,
1256 0xc084,0xc180,0xc280,0xc384,0xc480,0xc584,0xc684,0xc780,
1257 0xc888,0xc98c,0xca8c,0xcb88,0xcc8c,0xcd88,0xce88,0xcf8c,
1258 0xd080,0xd184,0xd284,0xd380,0xd484,0xd580,0xd680,0xd784,
1259 0xd88c,0xd988,0xda88,0xdb8c,0xdc88,0xdd8c,0xde8c,0xdf88,
1260 0xe0a0,0xe1a4,0xe2a4,0xe3a0,0xe4a4,0xe5a0,0xe6a0,0xe7a4,
1261 0xe8ac,0xe9a8,0xeaa8,0xebac,0xeca8,0xedac,0xeeac,0xefa8,
1262 0xf0a4,0xf1a0,0xf2a0,0xf3a4,0xf4a0,0xf5a4,0xf6a4,0xf7a0,
1263 0xf8a8,0xf9ac,0xfaac,0xfba8,0xfcac,0xfda8,0xfea8,0xffac,
1264 };
1265
1266 /* cpTable[i] = (i & 0x80) | (((i & 0xff) == 0) << 6), i = 0..255 */
1267 static const uint8 cpTable[256] = {
1268 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1269 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1270 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1271 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1272 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1273 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1274 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1275 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1276 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1277 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1278 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1279 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1280 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1281 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1282 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1283 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1284 };
1285
1286 /* remove comments to generate table contents and add a call to
1287 altairz80_print_tables in the altairz80_init
1288 static void altairz80_print_tables(void) {
1289 */
1290 /* parityTable */
1291 /*
1292 uint32 i, v;
1293 for (i = 0; i < 256; i++) {
1294 v = ((i & 1) + ((i & 2) >> 1) + ((i & 4) >> 2) + ((i & 8) >> 3) +
1295 ((i & 16) >> 4) + ((i & 32) >> 5) + ((i & 64) >> 6) + ((i & 128) >> 7)) % 2 ? 0 : 4;
1296 printf("%1d,", v);
1297 if ( ((i+1) & 0xf) == 0) {
1298 printf("\n");
1299 }
1300 }
1301 */
1302 /* incTable */
1303 /*
1304 uint32 temp, v;
1305 for (temp = 0; temp <= 256; temp++) {
1306 v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) | (((temp & 0xf) == 0) << 4);
1307 printf("%3d,", v);
1308 if ( ((temp+1) & 0xf) == 0) {
1309 printf("\n");
1310 }
1311 }
1312 */
1313 /* decTable */
1314 /*
1315 uint32 temp, v;
1316 for (temp = 0; temp < 256; temp++) {
1317 v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) | (((temp & 0xf) == 0xf) << 4) | 2;
1318 printf("%3d,", v);
1319 if ( ((temp+1) & 0xf) == 0) {
1320 printf("\n");
1321 }
1322 }
1323 */
1324 /* cbitsTable */
1325 /*
1326 uint32 cbits, v;
1327 for (cbits = 0; cbits < 512; cbits++) {
1328 v = (cbits & 0x10) | ((cbits >> 8) & 1);
1329 printf("%2d,", v);
1330 if ( ((cbits+1) & 0xf) == 0) {
1331 printf("\n");
1332 }
1333 }
1334 */
1335 /* cbitsDup8Table */
1336 /*
1337 uint32 cbits, v;
1338 for (cbits = 0; cbits < 512; cbits++) {
1339 v = (cbits & 0x10) | ((cbits >> 8) & 1) | ((cbits & 0xff) << 8) | (cbits & 0xa8) | (((cbits & 0xff) == 0) << 6);
1340 printf("0x%04x,", v);
1341 if ( ((cbits+1) & 0x7) == 0) {
1342 printf("\n");
1343 }
1344 }
1345 */
1346 /* cbitsDup16Table */
1347 /*
1348 uint32 cbits, v;
1349 for (cbits = 0; cbits < 512; cbits++) {
1350 v = (cbits & 0x10) | ((cbits >> 8) & 1) | (cbits & 0x28);
1351 printf("%2d,", v);
1352 if ( ((cbits+1) & 0xf) == 0) {
1353 printf("\n");
1354 }
1355 }
1356 */
1357 /* cbits2Table */
1358 /*
1359 uint32 cbits, v;
1360 for (cbits = 0; cbits < 512; cbits++) {
1361 v = (cbits & 0x10) | ((cbits >> 8) & 1) | 2;
1362 printf("%2d,", v);
1363 if ( ((cbits+1) & 0xf) == 0) {
1364 printf("\n");
1365 }
1366 }
1367 */
1368 /* rrcaTable */
1369 /*
1370 uint32 temp, sum, v;
1371 for (temp = 0; temp < 256; temp++) {
1372 sum = temp >> 1;
1373 v = ((temp & 1) << 15) | (sum << 8) | (sum & 0x28) | (temp & 1);
1374 printf("0x%04x,", v);
1375 if ( ((temp+1) & 0x7) == 0) {
1376 printf("\n");
1377 }
1378 }
1379 */
1380 /* rraTable */
1381 /*
1382 uint32 temp, sum, v;
1383 for (temp = 0; temp < 256; temp++) {
1384 sum = temp >> 1;
1385 v = (sum << 8) | (sum & 0x28) | (temp & 1);
1386 printf("0x%04x,", v);
1387 if ( ((temp+1) & 0x7) == 0) {
1388 printf("\n");
1389 }
1390 }
1391 */
1392 /* addTable */
1393 /*
1394 uint32 sum, v;
1395 for (sum = 0; sum < 512; sum++) {
1396 v = ((sum & 0xff) << 8) | (sum & 0xa8) | (((sum & 0xff) == 0) << 6);
1397 printf("0x%04x,", v);
1398 if ( ((sum+1) & 0x7) == 0) {
1399 printf("\n");
1400 }
1401 }
1402 */
1403 /* subTable */
1404 /*
1405 uint32 sum, v;
1406 for (sum = 0; sum < 256; sum++) {
1407 v = ((sum & 0xff) << 8) | (sum & 0xa8) | (((sum & 0xff) == 0) << 6) | 2;
1408 printf("0x%04x,", v);
1409 if ( ((sum+1) & 0x7) == 0) {
1410 printf("\n");
1411 }
1412 }
1413 */
1414 /* andTable */
1415 /*
1416 uint32 sum, v;
1417 for (sum = 0; sum < 256; sum++) {
1418 v = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | 0x10 | parityTable[sum];
1419 printf("0x%04x,", v);
1420 if ( ((sum+1) & 0x7) == 0) {
1421 printf("\n");
1422 }
1423 }
1424 */
1425 /* xororTable */
1426 /*
1427 uint32 sum, v;
1428 for (sum = 0; sum < 256; sum++) {
1429 v = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | parityTable[sum];
1430 printf("0x%04x,", v);
1431 if ( ((sum+1) & 0x7) == 0) {
1432 printf("\n");
1433 }
1434 }
1435 */
1436 /* rotateShiftTable */
1437 /*
1438 uint32 temp, v;
1439 for (temp = 0; temp < 256; temp++) {
1440 v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) | PARITY(temp);
1441 printf("%3d,", v);
1442 if ( ((temp+1) & 0xf) == 0) {
1443 printf("\n");
1444 }
1445 }
1446 */
1447 /* incZ80Table */
1448 /*
1449 uint32 temp, v;
1450 for (temp = 0; temp < 256; temp++) {
1451 v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) |
1452 (((temp & 0xf) == 0) << 4) | ((temp == 0x80) << 2);
1453 printf("%3d,", v);
1454 if ( ((temp+1) & 0xf) == 0) {
1455 printf("\n");
1456 }
1457 }
1458 */
1459 /* decZ80Table */
1460 /*
1461 uint32 temp, v;
1462 for (temp = 0; temp < 256; temp++) {
1463 v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) |
1464 (((temp & 0xf) == 0xf) << 4) | ((temp == 0x7f) << 2) | 2;
1465 printf("%3d,", v);
1466 if ( ((temp+1) & 0xf) == 0) {
1467 printf("\n");
1468 }
1469 }
1470 */
1471 /* cbitsZ80Table */
1472 /*
1473 uint32 cbits, v;
1474 for (cbits = 0; cbits < 512; cbits++) {
1475 v = (cbits & 0x10) | (((cbits >> 6) ^ (cbits >> 5)) & 4) |
1476 ((cbits >> 8) & 1);
1477 printf("%2d,", v);
1478 if ( ((cbits+1) & 0xf) == 0) {
1479 printf("\n");
1480 }
1481 }
1482 */
1483 /* cbitsZ80DupTable */
1484 /*
1485 uint32 cbits, v;
1486 for (cbits = 0; cbits < 512; cbits++) {
1487 v = (cbits & 0x10) | (((cbits >> 6) ^ (cbits >> 5)) & 4) |
1488 ((cbits >> 8) & 1) | (cbits & 0xa8);
1489 printf("%3d,", v);
1490 if ( ((cbits+1) & 0xf) == 0) {
1491 printf("\n");
1492 }
1493 }
1494 */
1495 /* cbits2Z80Table */
1496 /*
1497 uint32 cbits, v;
1498 for (cbits = 0; cbits < 512; cbits++) {
1499 v = (((cbits >> 6) ^ (cbits >> 5)) & 4) | (cbits & 0x10) | 2 | ((cbits >> 8) & 1);
1500 printf("%2d,", v);
1501 if ( ((cbits+1) & 0xf) == 0) {
1502 printf("\n");
1503 }
1504 }
1505 */
1506 /* cbits2Z80DupTable */
1507 /*
1508 uint32 cbits, v;
1509 for (cbits = 0; cbits < 512; cbits++) {
1510 v = (((cbits >> 6) ^ (cbits >> 5)) & 4) | (cbits & 0x10) | 2 | ((cbits >> 8) & 1) |
1511 (cbits & 0xa8);
1512 printf("%3d,", v);
1513 if ( ((cbits+1) & 0xf) == 0) {
1514 printf("\n");
1515 }
1516 }
1517 */
1518 /* negTable */
1519 /*
1520 uint32 temp, v;
1521 for (temp = 0; temp < 256; temp++) {
1522 v = (((temp & 0x0f) != 0) << 4) | ((temp == 0x80) << 2) | 2 | (temp != 0);
1523 printf("%2d,", v);
1524 if ( ((temp+1) & 0xf) == 0) {
1525 printf("\n");
1526 }
1527 }
1528 */
1529 /* rrdrldTable */
1530 /*
1531 uint32 acu, v;
1532 for (acu = 0; acu < 256; acu++) {
1533 v = (acu << 8) | (acu & 0xa8) | (((acu & 0xff) == 0) << 6) | parityTable[acu];
1534 printf("0x%04x,", v);
1535 if ( ((acu+1) & 0x7) == 0) {
1536 printf("\n");
1537 }
1538 }
1539 */
1540 /* cpTable */
1541 /*
1542 uint32 sum, v;
1543 for (sum = 0; sum < 256; sum++) {
1544 v = (sum & 0x80) | (((sum & 0xff) == 0) << 6);
1545 printf("%3d,", v);
1546 if ( ((sum+1) & 0xf) == 0) {
1547 printf("\n");
1548 }
1549 }
1550 */
1551 /* remove comments to generate table contents
1552 }
1553 */
1554
1555 /* Memory management */
1556
1557 #define LOG2PAGESIZE 8
1558 #define PAGESIZE (1 << LOG2PAGESIZE)
1559
1560 static uint8 M[MAXMEMORY]; /* RAM which is present */
1561
1562 struct mdev { /* Structure to describe a 2^LOG2PAGESIZE byte page of address space */
1563 /* There are four cases
1564 isRAM isEmpty routine code
1565 TRUE FALSE NULL W page is random access memory (RAM)
1566 FALSE TRUE NULL U no memory at this location
1567 FALSE FALSE NULL R page is read only memory (ROM)
1568 FALSE FALSE not NULL M page is mapped to memory mapped I/O routine
1569 other combinations are undefined!
1570 */
1571 uint32 isRAM;
1572 uint32 isEmpty;
1573 int32 (*routine)(const int32, const int32, const int32);
1574 };
1575
1576 typedef struct mdev MDEV;
1577
1578 static MDEV ROM_PAGE = {FALSE, FALSE, NULL}; /* this makes a page ROM */
1579 static MDEV RAM_PAGE = {TRUE, FALSE, NULL}; /* this makes a page RAM */
1580 static MDEV EMPTY_PAGE = {FALSE, TRUE, NULL}; /* this is non-existing memory */
1581 static MDEV mmu_table[MAXMEMORY >> LOG2PAGESIZE];
1582
1583 /* Memory and I/O Resource Mapping and Unmapping routine. */
sim_map_resource(uint32 baseaddr,uint32 size,uint32 resource_type,int32 (* routine)(const int32,const int32,const int32),uint8 unmap)1584 uint32 sim_map_resource(uint32 baseaddr, uint32 size, uint32 resource_type,
1585 int32 (*routine)(const int32, const int32, const int32), uint8 unmap) {
1586 uint32 page, i, addr;
1587 if (resource_type == RESOURCE_TYPE_MEMORY) {
1588 for (i = 0; i < (size >> LOG2PAGESIZE); i++) {
1589 addr = (baseaddr & 0xfff00) + (i << LOG2PAGESIZE);
1590 if ((cpu_unit.flags & UNIT_CPU_BANKED) && (addr < common))
1591 addr |= bankSelect << MAXBANKSIZELOG2;
1592 page = addr >> LOG2PAGESIZE;
1593 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
1594 printf("%s memory 0x%05x, handler=%p\n", unmap ? "Unmapping" : " Mapping",
1595 addr, routine);
1596 if (unmap) {
1597 if (mmu_table[page].routine == routine) { /* unmap only if it was mapped */
1598 if (MEMORYSIZE < MAXBANKSIZE)
1599 if (addr < MEMORYSIZE)
1600 mmu_table[page] = RAM_PAGE;
1601 else
1602 mmu_table[page] = EMPTY_PAGE;
1603 else
1604 mmu_table[page] = RAM_PAGE;
1605 }
1606 }
1607 else {
1608 mmu_table[page] = ROM_PAGE;
1609 mmu_table[page].routine = routine;
1610 }
1611 }
1612 } else if (resource_type == RESOURCE_TYPE_IO) {
1613 for (i = baseaddr; i < baseaddr + size; i++)
1614 if (unmap) {
1615 if (dev_table[i & 0xff].routine == routine) {
1616 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
1617 printf("Unmapping IO %04x, handler=%p\n", i, routine);
1618 dev_table[i & 0xff].routine = &nulldev;
1619 }
1620 }
1621 else {
1622 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
1623 printf(" Mapping IO %04x, handler=%p\n", i, routine);
1624 dev_table[i & 0xff].routine = routine;
1625 }
1626 } else {
1627 printf("%s: cannot map unknown resource type %d\n", __FUNCTION__, resource_type);
1628 return -1;
1629 }
1630 return 0;
1631 }
1632
PutBYTE(register uint32 Addr,const register uint32 Value)1633 static void PutBYTE(register uint32 Addr, const register uint32 Value) {
1634 MDEV m;
1635
1636 Addr &= ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */
1637 if ((cpu_unit.flags & UNIT_CPU_BANKED) && (Addr < common))
1638 Addr |= bankSelect << MAXBANKSIZELOG2;
1639 m = mmu_table[Addr >> LOG2PAGESIZE];
1640
1641 if (m.isRAM)
1642 M[Addr] = Value;
1643 else if (m.routine)
1644 m.routine(Addr, 1, Value);
1645 else if (cpu_unit.flags & UNIT_CPU_VERBOSE) {
1646 if (m.isEmpty)
1647 printf("CPU: " ADDRESS_FORMAT " Attempt to write to non existing memory " ADDRESS_FORMAT "." NLP, PCX, Addr);
1648 else
1649 printf("CPU: " ADDRESS_FORMAT " Attempt to write to ROM " ADDRESS_FORMAT "." NLP, PCX, Addr);
1650 }
1651 }
1652
PutBYTEExtended(register uint32 Addr,const register uint32 Value)1653 void PutBYTEExtended(register uint32 Addr, const register uint32 Value) {
1654 MDEV m;
1655
1656 Addr &= ADDRMASKEXTENDED;
1657 m = mmu_table[Addr >> LOG2PAGESIZE];
1658
1659 if (m.isRAM)
1660 M[Addr] = Value;
1661 else if (m.routine)
1662 m.routine(Addr, 1, Value);
1663 else if (cpu_unit.flags & UNIT_CPU_VERBOSE) {
1664 if (m.isEmpty)
1665 printf("CPU: " ADDRESS_FORMAT " Attempt to write to non existing memory " ADDRESS_FORMAT "." NLP, PCX, Addr);
1666 else
1667 printf("CPU: " ADDRESS_FORMAT " Attempt to write to ROM " ADDRESS_FORMAT "." NLP, PCX, Addr);
1668 }
1669 }
1670
PutWORD(register uint32 Addr,const register uint32 Value)1671 static void PutWORD(register uint32 Addr, const register uint32 Value) {
1672 PutBYTE(Addr, Value);
1673 PutBYTE(Addr + 1, Value >> 8);
1674 }
1675
GetBYTE(register uint32 Addr)1676 static uint32 GetBYTE(register uint32 Addr) {
1677 MDEV m;
1678
1679 Addr &= ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */
1680 if ((cpu_unit.flags & UNIT_CPU_BANKED) && (Addr < common))
1681 Addr |= bankSelect << MAXBANKSIZELOG2;
1682 m = mmu_table[Addr >> LOG2PAGESIZE];
1683
1684 if (m.isRAM)
1685 return M[Addr]; /* RAM */
1686 if (m.routine)
1687 return m.routine(Addr, 0, 0); /* memory mapped I/O */
1688 if (m.isEmpty) {
1689 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
1690 printf("CPU: " ADDRESS_FORMAT " Attempt to read from non existing memory " ADDRESS_FORMAT "." NLP, PCX, Addr);
1691 return 0xff;
1692 }
1693 return M[Addr]; /* ROM */
1694 }
1695
GetBYTEExtended(register uint32 Addr)1696 uint32 GetBYTEExtended(register uint32 Addr) {
1697 MDEV m;
1698
1699 Addr &= ADDRMASKEXTENDED;
1700 m = mmu_table[Addr >> LOG2PAGESIZE];
1701
1702 if (m.isRAM)
1703 return M[Addr];
1704 if (m.routine)
1705 return m.routine(Addr, 0, 0);
1706 if (m.isEmpty) {
1707 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
1708 printf("CPU: " ADDRESS_FORMAT " Attempt to read from non existing memory " ADDRESS_FORMAT "." NLP, PCX, Addr);
1709 return 0xff;
1710 }
1711 return M[Addr];
1712 }
1713
getBankSelect(void)1714 int32 getBankSelect(void) {
1715 return bankSelect;
1716 }
1717
setBankSelect(const int32 b)1718 void setBankSelect(const int32 b) {
1719 bankSelect = b;
1720 }
1721
getCommon(void)1722 uint32 getCommon(void) {
1723 return common;
1724 }
1725
1726 /* memory access during a simulation */
GetBYTEWrapper(const uint32 Addr)1727 uint8 GetBYTEWrapper(const uint32 Addr) {
1728 if (chiptype == CHIP_TYPE_8086)
1729 return GetBYTEExtended(Addr);
1730 else if (cpu_unit.flags & UNIT_CPU_MMU)
1731 return GetBYTE(Addr);
1732 else
1733 return MOPT[Addr & ADDRMASK];
1734 }
1735
1736 /* memory access during a simulation */
PutBYTEWrapper(const uint32 Addr,const uint32 Value)1737 void PutBYTEWrapper(const uint32 Addr, const uint32 Value) {
1738 if (chiptype == CHIP_TYPE_8086)
1739 PutBYTEExtended(Addr, Value);
1740 else if (cpu_unit.flags & UNIT_CPU_MMU)
1741 PutBYTE(Addr, Value);
1742 else
1743 MOPT[Addr & ADDRMASK] = Value & 0xff;
1744 }
1745
1746 /* DMA memory access during a simulation, suggested by Tony Nicholson */
GetByteDMA(const uint32 Addr)1747 uint8 GetByteDMA(const uint32 Addr) {
1748 if ((chiptype == CHIP_TYPE_8086) || (cpu_unit.flags & UNIT_CPU_MMU))
1749 return GetBYTEExtended(Addr);
1750 else
1751 return MOPT[Addr & ADDRMASK];
1752 }
1753
PutByteDMA(const uint32 Addr,const uint32 Value)1754 void PutByteDMA(const uint32 Addr, const uint32 Value) {
1755 if ((chiptype == CHIP_TYPE_8086) || (cpu_unit.flags & UNIT_CPU_MMU))
1756 PutBYTEExtended(Addr, Value);
1757 else
1758 MOPT[Addr & ADDRMASK] = Value & 0xff;
1759 }
1760
1761 #define RAM_PP(Addr) GetBYTE(Addr++)
1762 #define RAM_MM(Addr) GetBYTE(Addr--)
1763 #define GET_WORD(Addr) (GetBYTE(Addr) | (GetBYTE(Addr + 1) << 8))
1764 #define PUT_BYTE_PP(a,v) PutBYTE(a++, v)
1765 #define PUT_BYTE_MM(a,v) PutBYTE(a--, v)
1766 #define MM_PUT_BYTE(a,v) PutBYTE(--a, v)
1767
1768 #define MASK_BRK (TRUE + 1)
1769
1770 /* this is a modified version of sim_brk_test with two differences:
1771 1) is does not set sim_brk_pend to FALSE (this is left to the instruction decode)
1772 2) it returns MASK_BRK if a breakpoint is found but should be ignored
1773 */
sim_brk_lookup(const t_addr loc,const int32 btyp)1774 static int32 sim_brk_lookup (const t_addr loc, const int32 btyp) {
1775 extern t_bool sim_brk_pend[SIM_BKPT_N_SPC];
1776 extern t_addr sim_brk_ploc[SIM_BKPT_N_SPC];
1777 extern char *sim_brk_act;
1778 BRKTAB *bp;
1779 if ((bp = sim_brk_fnd (loc)) && /* entry in table? */
1780 (btyp & bp -> typ) && /* type match? */
1781 (!sim_brk_pend[0] || (loc != sim_brk_ploc[0])) && /* new location? */
1782 (--(bp -> cnt) <= 0)) { /* count reach 0? */
1783 bp -> cnt = 0; /* reset count */
1784 sim_brk_ploc[0] = loc; /* save location */
1785 sim_brk_act = bp -> act; /* set up actions */
1786 sim_brk_pend[0] = TRUE; /* don't do twice */
1787 return TRUE;
1788 }
1789 return (sim_brk_pend[0] && (loc == sim_brk_ploc[0])) ? MASK_BRK : FALSE;
1790 }
1791
1792 #define PUSH(x) { \
1793 MM_PUT_BYTE(SP, (x) >> 8); \
1794 MM_PUT_BYTE(SP, x); \
1795 }
1796
1797 #define CHECK_BREAK_BYTE(a) \
1798 if (sim_brk_summ) { \
1799 if (sim_brk_test((a) & 0xffff, SWMASK('M'))) { \
1800 reason = STOP_MEM; \
1801 prepareMemoryAccessMessage((a) & 0xffff); \
1802 goto end_decode; \
1803 } \
1804 sim_brk_pend[0] = FALSE; \
1805 }
1806
1807 #define CHECK_BREAK_TWO_BYTES_EXTENDED(a1, a2, iCode) \
1808 if (sim_brk_summ) { \
1809 int32 brl = sim_brk_lookup((a1) & 0xffff, SWMASK('M')); \
1810 if ((brl == TRUE) || (brl == FALSE) && (sim_brk_lookup((a2) \
1811 & 0xffff, SWMASK('M')) == TRUE)) { \
1812 reason = STOP_MEM; \
1813 prepareMemoryAccessMessage((brl ? (a1):(a2)) & 0xffff); \
1814 iCode; \
1815 goto end_decode; \
1816 } \
1817 sim_brk_pend[0] = FALSE; \
1818 }
1819
1820 #define CHECK_BREAK_TWO_BYTES(a1, a2) CHECK_BREAK_TWO_BYTES_EXTENDED(a1, a2,;)
1821
1822 #define CHECK_BREAK_WORD(a) CHECK_BREAK_TWO_BYTES(a, (a + 1))
1823
1824 #define HALTINSTRUCTION 0x76
1825
1826 /* Macros for the IN/OUT instructions INI/INIR/IND/INDR/OUTI/OTIR/OUTD/OTDR
1827
1828 Pre condition
1829 temp == value of register B at entry of the instruction
1830 acu == value of transferred byte (IN or OUT)
1831 Post condition
1832 F is set correctly
1833
1834 Use INOUTFLAGS_ZERO(x) for INIR/INDR/OTIR/OTDR where
1835 x == (C + 1) & 0xff for INIR
1836 x == L for OTIR and OTDR
1837 x == (C - 1) & 0xff for INDR
1838 Use INOUTFLAGS_NONZERO(x) for INI/IND/OUTI/OUTD where
1839 x == (C + 1) & 0xff for INI
1840 x == L for OUTI and OUTD
1841 x == (C - 1) & 0xff for IND
1842 */
1843 #define INOUTFLAGS(syxz, x) \
1844 AF = (AF & 0xff00) | (syxz) | /* SF, YF, XF, ZF */ \
1845 ((acu & 0x80) >> 6) | /* NF */ \
1846 ((acu + (x)) > 0xff ? (FLAG_C | FLAG_H) : 0) | /* CF, HF */ \
1847 parityTable[((acu + (x)) & 7) ^ temp] /* PF */
1848
1849 #define INOUTFLAGS_ZERO(x) INOUTFLAGS(FLAG_Z, x)
1850 #define INOUTFLAGS_NONZERO(x) \
1851 INOUTFLAGS((HIGH_REGISTER(BC) & 0xa8) | ((HIGH_REGISTER(BC) == 0) << 6), x)
1852
1853 int32 switch_cpu_now = TRUE; /* hharte */
1854
sim_instr(void)1855 t_stat sim_instr (void) {
1856 uint32 i;
1857 t_stat result;
1858 if ((chiptype == CHIP_TYPE_8086) || (cpu_unit.flags & UNIT_CPU_MMU))
1859 do {
1860 result = (chiptype == CHIP_TYPE_8086) ? sim_instr_8086() : sim_instr_mmu();
1861 } while (switch_cpu_now == FALSE);
1862 else {
1863 for (i = 0; i < MAXBANKSIZE; i++)
1864 MOPT[i] = M[i];
1865 result = sim_instr_nommu();
1866 for (i = 0; i < MAXBANKSIZE; i++)
1867 M[i] = MOPT[i];
1868 }
1869 return result;
1870 }
1871
1872 static int32 clockHasChanged = FALSE;
1873
getClockFrequency(void)1874 uint32 getClockFrequency(void) {
1875 return clockFrequency;
1876 }
1877
setClockFrequency(const uint32 Value)1878 void setClockFrequency(const uint32 Value) {
1879 clockFrequency = Value;
1880 clockHasChanged = TRUE;
1881 }
1882
sim_instr_mmu(void)1883 static t_stat sim_instr_mmu (void) {
1884 extern int32 sim_interval;
1885 extern t_bool sim_brk_pend[SIM_BKPT_N_SPC];
1886 extern int32 timerInterrupt;
1887 extern int32 timerInterruptHandler;
1888 extern int32 keyboardInterrupt;
1889 extern uint32 keyboardInterruptHandler;
1890 extern uint32 sim_os_msec(void);
1891 extern const t_bool rtc_avail;
1892 extern uint32 sim_brk_summ;
1893 int32 reason = SCPE_OK;
1894 register uint32 specialProcessing;
1895 register uint32 AF;
1896 register uint32 BC;
1897 register uint32 DE;
1898 register uint32 HL;
1899 register uint32 PC;
1900 register uint32 SP;
1901 register uint32 IX;
1902 register uint32 IY;
1903 register uint32 temp = 0;
1904 register uint32 acu = 0;
1905 register uint32 sum;
1906 register uint32 cbits;
1907 register uint32 op;
1908 register uint32 adr;
1909 /* tStates contains the number of t-states executed. One t-state is executed
1910 in one microsecond on a 1MHz CPU. tStates is used for real-time simulations. */
1911 register uint32 tStates;
1912 uint32 tStatesInSlice; /* number of t-states in 10 mSec time-slice */
1913 uint32 startTime, now;
1914 int32 tStateModifier = FALSE;
1915
1916 switch_cpu_now = TRUE; /* hharte */
1917
1918 AF = AF_S;
1919 BC = BC_S;
1920 DE = DE_S;
1921 HL = HL_S;
1922 PC = PC_S & ADDRMASK;
1923 SP = SP_S;
1924 IX = IX_S;
1925 IY = IY_S;
1926 specialProcessing = clockFrequency | timerInterrupt | keyboardInterrupt | sim_brk_summ;
1927 tStates = 0;
1928 if (rtc_avail) {
1929 startTime = sim_os_msec();
1930 tStatesInSlice = sliceLength*clockFrequency;
1931 }
1932 else /* make sure that sim_os_msec() is not called later */
1933 clockFrequency = startTime = tStatesInSlice = 0;
1934
1935 /* main instruction fetch/decode loop */
1936 while (switch_cpu_now == TRUE) { /* loop until halted */
1937 if (sim_interval <= 0) { /* check clock queue */
1938 #if !UNIX_PLATFORM
1939 if ((reason = sim_os_poll_kbd()) == SCPE_STOP) /* poll on platforms without reliable signalling */
1940 break;
1941 #endif
1942 if ((reason = sim_process_event()))
1943 break;
1944 if (clockHasChanged) {
1945 clockHasChanged = FALSE;
1946 tStates = 0;
1947 if (rtc_avail) {
1948 startTime = sim_os_msec();
1949 tStatesInSlice = sliceLength*clockFrequency;
1950 }
1951 else /* make sure that sim_os_msec() is not called later */
1952 clockFrequency = startTime = tStatesInSlice = 0;
1953 }
1954 specialProcessing = clockFrequency | timerInterrupt | keyboardInterrupt | sim_brk_summ;
1955 }
1956
1957 if (specialProcessing) { /* quick check for special processing */
1958 if (clockFrequency && (tStates >= tStatesInSlice)) {
1959 /* clockFrequency != 0 implies that real time clock is available */
1960 startTime += sliceLength;
1961 tStates -= tStatesInSlice;
1962 if (startTime > (now = sim_os_msec())) {
1963 #if defined (_WIN32)
1964 Sleep(startTime - now);
1965 #else
1966 usleep(1000 * (startTime - now));
1967 #endif
1968 }
1969 }
1970
1971 if (timerInterrupt && (IFF_S & 1)) {
1972 timerInterrupt = FALSE;
1973 specialProcessing = clockFrequency | sim_brk_summ;
1974 IFF_S = 0; /* disable interrupts */
1975 CHECK_BREAK_TWO_BYTES_EXTENDED(SP - 2, SP - 1, (timerInterrupt = TRUE, IFF_S |= 1));
1976 if ((GetBYTE(PC) == HALTINSTRUCTION) && ((cpu_unit.flags & UNIT_CPU_STOPONHALT) == 0)) {
1977 PUSH(PC + 1);
1978 PCQ_ENTRY(PC);
1979 }
1980 else {
1981 PUSH(PC);
1982 PCQ_ENTRY(PC - 1);
1983 }
1984 PC = timerInterruptHandler & ADDRMASK;
1985 }
1986
1987 if (keyboardInterrupt && (IFF_S & 1)) {
1988 keyboardInterrupt = FALSE;
1989 specialProcessing = clockFrequency | sim_brk_summ;
1990 IFF_S = 0; /* disable interrupts */
1991 CHECK_BREAK_TWO_BYTES_EXTENDED(SP - 2, SP - 1, (keyboardInterrupt = TRUE, IFF_S |= 1));
1992 if ((GetBYTE(PC) == HALTINSTRUCTION) && ((cpu_unit.flags & UNIT_CPU_STOPONHALT) == 0)) {
1993 PUSH(PC + 1);
1994 PCQ_ENTRY(PC);
1995 }
1996 else {
1997 PUSH(PC);
1998 PCQ_ENTRY(PC - 1);
1999 }
2000 PC = keyboardInterruptHandler & ADDRMASK;
2001 }
2002
2003 if (sim_brk_summ) {
2004 if (sim_brk_test(PC, (2u << SIM_BKPT_V_SPC) | SWMASK('E'))) { /* breakpoint? */
2005 reason = STOP_IBKPT; /* stop simulation */
2006 break;
2007 }
2008 if (sim_brk_test(GetBYTE(PC), (1u << SIM_BKPT_V_SPC) | SWMASK('I'))) { /* instruction breakpoint? */
2009 reason = STOP_INSTR; /* stop simulation */
2010 prepareInstructionMessage(PC, GetBYTE(PC));
2011 break;
2012 }
2013 }
2014 }
2015
2016 PCX = PC;
2017 sim_interval--;
2018
2019 /* make sure that each instructions properly sets sim_brk_pend:
2020 1) Either directly to FALSE if no memory access takes place or
2021 2) through a call to a Check... routine
2022 */
2023 switch(RAM_PP(PC)) {
2024
2025 case 0x00: /* NOP */
2026 tStates += 4;
2027 sim_brk_pend[0] = FALSE;
2028 break;
2029
2030 case 0x01: /* LD BC,nnnn */
2031 tStates += 10;
2032 sim_brk_pend[0] = FALSE;
2033 BC = GET_WORD(PC);
2034 PC += 2;
2035 break;
2036
2037 case 0x02: /* LD (BC),A */
2038 tStates += 7;
2039 CHECK_BREAK_BYTE(BC)
2040 PutBYTE(BC, HIGH_REGISTER(AF));
2041 break;
2042
2043 case 0x03: /* INC BC */
2044 tStates += 6;
2045 sim_brk_pend[0] = FALSE;
2046 ++BC;
2047 break;
2048
2049 case 0x04: /* INC B */
2050 tStates += 4;
2051 sim_brk_pend[0] = FALSE;
2052 BC += 0x100;
2053 temp = HIGH_REGISTER(BC);
2054 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80); /* SET_PV2 uses temp */
2055 break;
2056
2057 case 0x05: /* DEC B */
2058 tStates += 4;
2059 sim_brk_pend[0] = FALSE;
2060 BC -= 0x100;
2061 temp = HIGH_REGISTER(BC);
2062 AF = (AF & ~0xfe) | decTable[temp] | SET_PV2(0x7f); /* SET_PV2 uses temp */
2063 break;
2064
2065 case 0x06: /* LD B,nn */
2066 tStates += 7;
2067 sim_brk_pend[0] = FALSE;
2068 SET_HIGH_REGISTER(BC, RAM_PP(PC));
2069 break;
2070
2071 case 0x07: /* RLCA */
2072 tStates += 4;
2073 sim_brk_pend[0] = FALSE;
2074 AF = ((AF >> 7) & 0x0128) | ((AF << 1) & ~0x1ff) |
2075 (AF & 0xc4) | ((AF >> 15) & 1);
2076 break;
2077
2078 case 0x08: /* EX AF,AF' */
2079 tStates += 4;
2080 sim_brk_pend[0] = FALSE;
2081 CHECK_CPU_8080;
2082 temp = AF;
2083 AF = AF1_S;
2084 AF1_S = temp;
2085 break;
2086
2087 case 0x09: /* ADD HL,BC */
2088 tStates += 11;
2089 sim_brk_pend[0] = FALSE;
2090 HL &= ADDRMASK;
2091 BC &= ADDRMASK;
2092 sum = HL + BC;
2093 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(HL ^ BC ^ sum) >> 8];
2094 HL = sum;
2095 break;
2096
2097 case 0x0a: /* LD A,(BC) */
2098 tStates += 7;
2099 CHECK_BREAK_BYTE(BC)
2100 SET_HIGH_REGISTER(AF, GetBYTE(BC));
2101 break;
2102
2103 case 0x0b: /* DEC BC */
2104 tStates += 6;
2105 sim_brk_pend[0] = FALSE;
2106 --BC;
2107 break;
2108
2109 case 0x0c: /* INC C */
2110 tStates += 4;
2111 sim_brk_pend[0] = FALSE;
2112 temp = LOW_REGISTER(BC) + 1;
2113 SET_LOW_REGISTER(BC, temp);
2114 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80);
2115 break;
2116
2117 case 0x0d: /* DEC C */
2118 tStates += 4;
2119 sim_brk_pend[0] = FALSE;
2120 temp = LOW_REGISTER(BC) - 1;
2121 SET_LOW_REGISTER(BC, temp);
2122 AF = (AF & ~0xfe) | decTable[temp & 0xff] | SET_PV2(0x7f);
2123 break;
2124
2125 case 0x0e: /* LD C,nn */
2126 tStates += 7;
2127 sim_brk_pend[0] = FALSE;
2128 SET_LOW_REGISTER(BC, RAM_PP(PC));
2129 break;
2130
2131 case 0x0f: /* RRCA */
2132 tStates += 4;
2133 sim_brk_pend[0] = FALSE;
2134 AF = (AF & 0xc4) | rrcaTable[HIGH_REGISTER(AF)];
2135 break;
2136
2137 case 0x10: /* DJNZ dd */
2138 sim_brk_pend[0] = FALSE;
2139 CHECK_CPU_8080;
2140 if ((BC -= 0x100) & 0xff00) {
2141 PCQ_ENTRY(PCX);
2142 PC += (int8) GetBYTE(PC) + 1;
2143 tStates += 13;
2144 }
2145 else {
2146 PC++;
2147 tStates += 8;
2148 }
2149 break;
2150
2151 case 0x11: /* LD DE,nnnn */
2152 tStates += 10;
2153 sim_brk_pend[0] = FALSE;
2154 DE = GET_WORD(PC);
2155 PC += 2;
2156 break;
2157
2158 case 0x12: /* LD (DE),A */
2159 tStates += 7;
2160 CHECK_BREAK_BYTE(DE)
2161 PutBYTE(DE, HIGH_REGISTER(AF));
2162 break;
2163
2164 case 0x13: /* INC DE */
2165 tStates += 6;
2166 sim_brk_pend[0] = FALSE;
2167 ++DE;
2168 break;
2169
2170 case 0x14: /* INC D */
2171 tStates += 4;
2172 sim_brk_pend[0] = FALSE;
2173 DE += 0x100;
2174 temp = HIGH_REGISTER(DE);
2175 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80); /* SET_PV2 uses temp */
2176 break;
2177
2178 case 0x15: /* DEC D */
2179 tStates += 4;
2180 sim_brk_pend[0] = FALSE;
2181 DE -= 0x100;
2182 temp = HIGH_REGISTER(DE);
2183 AF = (AF & ~0xfe) | decTable[temp] | SET_PV2(0x7f); /* SET_PV2 uses temp */
2184 break;
2185
2186 case 0x16: /* LD D,nn */
2187 tStates += 7;
2188 sim_brk_pend[0] = FALSE;
2189 SET_HIGH_REGISTER(DE, RAM_PP(PC));
2190 break;
2191
2192 case 0x17: /* RLA */
2193 tStates += 4;
2194 sim_brk_pend[0] = FALSE;
2195 AF = ((AF << 8) & 0x0100) | ((AF >> 7) & 0x28) | ((AF << 1) & ~0x01ff) |
2196 (AF & 0xc4) | ((AF >> 15) & 1);
2197 break;
2198
2199 case 0x18: /* JR dd */
2200 tStates += 12;
2201 sim_brk_pend[0] = FALSE;
2202 CHECK_CPU_8080;
2203 PCQ_ENTRY(PCX);
2204 PC += (int8) GetBYTE(PC) + 1;
2205 break;
2206
2207 case 0x19: /* ADD HL,DE */
2208 tStates += 11;
2209 sim_brk_pend[0] = FALSE;
2210 HL &= ADDRMASK;
2211 DE &= ADDRMASK;
2212 sum = HL + DE;
2213 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(HL ^ DE ^ sum) >> 8];
2214 HL = sum;
2215 break;
2216
2217 case 0x1a: /* LD A,(DE) */
2218 tStates += 7;
2219 CHECK_BREAK_BYTE(DE)
2220 SET_HIGH_REGISTER(AF, GetBYTE(DE));
2221 break;
2222
2223 case 0x1b: /* DEC DE */
2224 tStates += 6;
2225 sim_brk_pend[0] = FALSE;
2226 --DE;
2227 break;
2228
2229 case 0x1c: /* INC E */
2230 tStates += 4;
2231 sim_brk_pend[0] = FALSE;
2232 temp = LOW_REGISTER(DE) + 1;
2233 SET_LOW_REGISTER(DE, temp);
2234 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80);
2235 break;
2236
2237 case 0x1d: /* DEC E */
2238 tStates += 4;
2239 sim_brk_pend[0] = FALSE;
2240 temp = LOW_REGISTER(DE) - 1;
2241 SET_LOW_REGISTER(DE, temp);
2242 AF = (AF & ~0xfe) | decTable[temp & 0xff] | SET_PV2(0x7f);
2243 break;
2244
2245 case 0x1e: /* LD E,nn */
2246 tStates += 7;
2247 sim_brk_pend[0] = FALSE;
2248 SET_LOW_REGISTER(DE, RAM_PP(PC));
2249 break;
2250
2251 case 0x1f: /* RRA */
2252 tStates += 4;
2253 sim_brk_pend[0] = FALSE;
2254 AF = ((AF & 1) << 15) | (AF & 0xc4) | rraTable[HIGH_REGISTER(AF)];
2255 break;
2256
2257 case 0x20: /* JR NZ,dd */
2258 sim_brk_pend[0] = FALSE;
2259 CHECK_CPU_8080;
2260 if (TSTFLAG(Z)) {
2261 PC++;
2262 tStates += 7;
2263 }
2264 else {
2265 PCQ_ENTRY(PCX);
2266 PC += (int8) GetBYTE(PC) + 1;
2267 tStates += 12;
2268 }
2269 break;
2270
2271 case 0x21: /* LD HL,nnnn */
2272 tStates += 10;
2273 sim_brk_pend[0] = FALSE;
2274 HL = GET_WORD(PC);
2275 PC += 2;
2276 break;
2277
2278 case 0x22: /* LD (nnnn),HL */
2279 tStates += 16;
2280 temp = GET_WORD(PC);
2281 CHECK_BREAK_WORD(temp);
2282 PutWORD(temp, HL);
2283 PC += 2;
2284 break;
2285
2286 case 0x23: /* INC HL */
2287 tStates += 6;
2288 sim_brk_pend[0] = FALSE;
2289 ++HL;
2290 break;
2291
2292 case 0x24: /* INC H */
2293 tStates += 4;
2294 sim_brk_pend[0] = FALSE;
2295 HL += 0x100;
2296 temp = HIGH_REGISTER(HL);
2297 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80); /* SET_PV2 uses temp */
2298 break;
2299
2300 case 0x25: /* DEC H */
2301 tStates += 4;
2302 sim_brk_pend[0] = FALSE;
2303 HL -= 0x100;
2304 temp = HIGH_REGISTER(HL);
2305 AF = (AF & ~0xfe) | decTable[temp] | SET_PV2(0x7f); /* SET_PV2 uses temp */
2306 break;
2307
2308 case 0x26: /* LD H,nn */
2309 tStates += 7;
2310 sim_brk_pend[0] = FALSE;
2311 SET_HIGH_REGISTER(HL, RAM_PP(PC));
2312 break;
2313
2314 case 0x27: /* DAA */
2315 tStates += 4;
2316 sim_brk_pend[0] = FALSE;
2317 acu = HIGH_REGISTER(AF);
2318 temp = LOW_DIGIT(acu);
2319 cbits = TSTFLAG(C);
2320 if (TSTFLAG(N)) { /* last operation was a subtract */
2321 int hd = cbits || acu > 0x99;
2322 if (TSTFLAG(H) || (temp > 9)) { /* adjust low digit */
2323 if (temp > 5) {
2324 SETFLAG(H, 0);
2325 }
2326 acu -= 6;
2327 acu &= 0xff;
2328 }
2329 if (hd)
2330 acu -= 0x160; /* adjust high digit */
2331 }
2332 else { /* last operation was an add */
2333 if (TSTFLAG(H) || (temp > 9)) { /* adjust low digit */
2334 SETFLAG(H, (temp > 9));
2335 acu += 6;
2336 }
2337 if (cbits || ((acu & 0x1f0) > 0x90))
2338 acu += 0x60; /* adjust high digit */
2339 }
2340 AF = (AF & 0x12) | rrdrldTable[acu & 0xff] | ((acu >> 8) & 1) | cbits;
2341 break;
2342
2343 case 0x28: /* JR Z,dd */
2344 sim_brk_pend[0] = FALSE;
2345 CHECK_CPU_8080;
2346 if (TSTFLAG(Z)) {
2347 PCQ_ENTRY(PCX);
2348 PC += (int8) GetBYTE(PC) + 1;
2349 tStates += 12;
2350 }
2351 else {
2352 PC++;
2353 tStates += 7;
2354 }
2355 break;
2356
2357 case 0x29: /* ADD HL,HL */
2358 tStates += 11;
2359 sim_brk_pend[0] = FALSE;
2360 HL &= ADDRMASK;
2361 sum = HL + HL;
2362 AF = (AF & ~0x3b) | cbitsDup16Table[sum >> 8];
2363 HL = sum;
2364 break;
2365
2366 case 0x2a: /* LD HL,(nnnn) */
2367 tStates += 16;
2368 temp = GET_WORD(PC);
2369 CHECK_BREAK_WORD(temp);
2370 HL = GET_WORD(temp);
2371 PC += 2;
2372 break;
2373
2374 case 0x2b: /* DEC HL */
2375 tStates += 6;
2376 sim_brk_pend[0] = FALSE;
2377 --HL;
2378 break;
2379
2380 case 0x2c: /* INC L */
2381 tStates += 4;
2382 sim_brk_pend[0] = FALSE;
2383 temp = LOW_REGISTER(HL) + 1;
2384 SET_LOW_REGISTER(HL, temp);
2385 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80);
2386 break;
2387
2388 case 0x2d: /* DEC L */
2389 tStates += 4;
2390 sim_brk_pend[0] = FALSE;
2391 temp = LOW_REGISTER(HL) - 1;
2392 SET_LOW_REGISTER(HL, temp);
2393 AF = (AF & ~0xfe) | decTable[temp & 0xff] | SET_PV2(0x7f);
2394 break;
2395
2396 case 0x2e: /* LD L,nn */
2397 tStates += 7;
2398 sim_brk_pend[0] = FALSE;
2399 SET_LOW_REGISTER(HL, RAM_PP(PC));
2400 break;
2401
2402 case 0x2f: /* CPL */
2403 tStates += 4;
2404 sim_brk_pend[0] = FALSE;
2405 AF = (~AF & ~0xff) | (AF & 0xc5) | ((~AF >> 8) & 0x28) | 0x12;
2406 break;
2407
2408 case 0x30: /* JR NC,dd */
2409 sim_brk_pend[0] = FALSE;
2410 CHECK_CPU_8080;
2411 if (TSTFLAG(C)) {
2412 PC++;
2413 tStates += 7;
2414 }
2415 else {
2416 PCQ_ENTRY(PCX);
2417 PC += (int8) GetBYTE(PC) + 1;
2418 tStates += 12;
2419 }
2420 break;
2421
2422 case 0x31: /* LD SP,nnnn */
2423 tStates += 10;
2424 sim_brk_pend[0] = FALSE;
2425 SP = GET_WORD(PC);
2426 PC += 2;
2427 break;
2428
2429 case 0x32: /* LD (nnnn),A */
2430 tStates += 13;
2431 temp = GET_WORD(PC);
2432 CHECK_BREAK_BYTE(temp);
2433 PutBYTE(temp, HIGH_REGISTER(AF));
2434 PC += 2;
2435 break;
2436
2437 case 0x33: /* INC SP */
2438 tStates += 6;
2439 sim_brk_pend[0] = FALSE;
2440 ++SP;
2441 break;
2442
2443 case 0x34: /* INC (HL) */
2444 tStates += 11;
2445 CHECK_BREAK_BYTE(HL);
2446 temp = GetBYTE(HL) + 1;
2447 PutBYTE(HL, temp);
2448 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80);
2449 break;
2450
2451 case 0x35: /* DEC (HL) */
2452 tStates += 11;
2453 CHECK_BREAK_BYTE(HL);
2454 temp = GetBYTE(HL) - 1;
2455 PutBYTE(HL, temp);
2456 AF = (AF & ~0xfe) | decTable[temp & 0xff] | SET_PV2(0x7f);
2457 break;
2458
2459 case 0x36: /* LD (HL),nn */
2460 tStates += 10;
2461 CHECK_BREAK_BYTE(HL);
2462 PutBYTE(HL, RAM_PP(PC));
2463 break;
2464
2465 case 0x37: /* SCF */
2466 tStates += 4;
2467 sim_brk_pend[0] = FALSE;
2468 AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | 1;
2469 break;
2470
2471 case 0x38: /* JR C,dd */
2472 sim_brk_pend[0] = FALSE;
2473 CHECK_CPU_8080;
2474 if (TSTFLAG(C)) {
2475 PCQ_ENTRY(PCX);
2476 PC += (int8) GetBYTE(PC) + 1;
2477 tStates += 12;
2478 }
2479 else {
2480 PC++;
2481 tStates += 7;
2482 }
2483 break;
2484
2485 case 0x39: /* ADD HL,SP */
2486 tStates += 11;
2487 sim_brk_pend[0] = FALSE;
2488 HL &= ADDRMASK;
2489 SP &= ADDRMASK;
2490 sum = HL + SP;
2491 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(HL ^ SP ^ sum) >> 8];
2492 HL = sum;
2493 break;
2494
2495 case 0x3a: /* LD A,(nnnn) */
2496 tStates += 13;
2497 temp = GET_WORD(PC);
2498 CHECK_BREAK_BYTE(temp);
2499 SET_HIGH_REGISTER(AF, GetBYTE(temp));
2500 PC += 2;
2501 break;
2502
2503 case 0x3b: /* DEC SP */
2504 tStates += 6;
2505 sim_brk_pend[0] = FALSE;
2506 --SP;
2507 break;
2508
2509 case 0x3c: /* INC A */
2510 tStates += 4;
2511 sim_brk_pend[0] = FALSE;
2512 AF += 0x100;
2513 temp = HIGH_REGISTER(AF);
2514 AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80); /* SET_PV2 uses temp */
2515 break;
2516
2517 case 0x3d: /* DEC A */
2518 tStates += 4;
2519 sim_brk_pend[0] = FALSE;
2520 AF -= 0x100;
2521 temp = HIGH_REGISTER(AF);
2522 AF = (AF & ~0xfe) | decTable[temp] | SET_PV2(0x7f); /* SET_PV2 uses temp */
2523 break;
2524
2525 case 0x3e: /* LD A,nn */
2526 tStates += 7;
2527 sim_brk_pend[0] = FALSE;
2528 SET_HIGH_REGISTER(AF, RAM_PP(PC));
2529 break;
2530
2531 case 0x3f: /* CCF */
2532 tStates += 4;
2533 sim_brk_pend[0] = FALSE;
2534 AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | ((AF & 1) << 4) | (~AF & 1);
2535 break;
2536
2537 case 0x40: /* LD B,B */
2538 tStates += 4;
2539 sim_brk_pend[0] = FALSE; /* nop */
2540 break;
2541
2542 case 0x41: /* LD B,C */
2543 tStates += 4;
2544 sim_brk_pend[0] = FALSE;
2545 BC = (BC & 0xff) | ((BC & 0xff) << 8);
2546 break;
2547
2548 case 0x42: /* LD B,D */
2549 tStates += 4;
2550 sim_brk_pend[0] = FALSE;
2551 BC = (BC & 0xff) | (DE & ~0xff);
2552 break;
2553
2554 case 0x43: /* LD B,E */
2555 tStates += 4;
2556 sim_brk_pend[0] = FALSE;
2557 BC = (BC & 0xff) | ((DE & 0xff) << 8);
2558 break;
2559
2560 case 0x44: /* LD B,H */
2561 tStates += 4;
2562 sim_brk_pend[0] = FALSE;
2563 BC = (BC & 0xff) | (HL & ~0xff);
2564 break;
2565
2566 case 0x45: /* LD B,L */
2567 tStates += 4;
2568 sim_brk_pend[0] = FALSE;
2569 BC = (BC & 0xff) | ((HL & 0xff) << 8);
2570 break;
2571
2572 case 0x46: /* LD B,(HL) */
2573 tStates += 7;
2574 CHECK_BREAK_BYTE(HL);
2575 SET_HIGH_REGISTER(BC, GetBYTE(HL));
2576 break;
2577
2578 case 0x47: /* LD B,A */
2579 tStates += 4;
2580 sim_brk_pend[0] = FALSE;
2581 BC = (BC & 0xff) | (AF & ~0xff);
2582 break;
2583
2584 case 0x48: /* LD C,B */
2585 tStates += 4;
2586 sim_brk_pend[0] = FALSE;
2587 BC = (BC & ~0xff) | ((BC >> 8) & 0xff);
2588 break;
2589
2590 case 0x49: /* LD C,C */
2591 tStates += 4;
2592 sim_brk_pend[0] = FALSE; /* nop */
2593 break;
2594
2595 case 0x4a: /* LD C,D */
2596 tStates += 4;
2597 sim_brk_pend[0] = FALSE;
2598 BC = (BC & ~0xff) | ((DE >> 8) & 0xff);
2599 break;
2600
2601 case 0x4b: /* LD C,E */
2602 tStates += 4;
2603 sim_brk_pend[0] = FALSE;
2604 BC = (BC & ~0xff) | (DE & 0xff);
2605 break;
2606
2607 case 0x4c: /* LD C,H */
2608 tStates += 4;
2609 sim_brk_pend[0] = FALSE;
2610 BC = (BC & ~0xff) | ((HL >> 8) & 0xff);
2611 break;
2612
2613 case 0x4d: /* LD C,L */
2614 tStates += 4;
2615 sim_brk_pend[0] = FALSE;
2616 BC = (BC & ~0xff) | (HL & 0xff);
2617 break;
2618
2619 case 0x4e: /* LD C,(HL) */
2620 tStates += 7;
2621 CHECK_BREAK_BYTE(HL);
2622 SET_LOW_REGISTER(BC, GetBYTE(HL));
2623 break;
2624
2625 case 0x4f: /* LD C,A */
2626 tStates += 4;
2627 sim_brk_pend[0] = FALSE;
2628 BC = (BC & ~0xff) | ((AF >> 8) & 0xff);
2629 break;
2630
2631 case 0x50: /* LD D,B */
2632 tStates += 4;
2633 sim_brk_pend[0] = FALSE;
2634 DE = (DE & 0xff) | (BC & ~0xff);
2635 break;
2636
2637 case 0x51: /* LD D,C */
2638 tStates += 4;
2639 sim_brk_pend[0] = FALSE;
2640 DE = (DE & 0xff) | ((BC & 0xff) << 8);
2641 break;
2642
2643 case 0x52: /* LD D,D */
2644 tStates += 4;
2645 sim_brk_pend[0] = FALSE; /* nop */
2646 break;
2647
2648 case 0x53: /* LD D,E */
2649 tStates += 4;
2650 sim_brk_pend[0] = FALSE;
2651 DE = (DE & 0xff) | ((DE & 0xff) << 8);
2652 break;
2653
2654 case 0x54: /* LD D,H */
2655 tStates += 4;
2656 sim_brk_pend[0] = FALSE;
2657 DE = (DE & 0xff) | (HL & ~0xff);
2658 break;
2659
2660 case 0x55: /* LD D,L */
2661 tStates += 4;
2662 sim_brk_pend[0] = FALSE;
2663 DE = (DE & 0xff) | ((HL & 0xff) << 8);
2664 break;
2665
2666 case 0x56: /* LD D,(HL) */
2667 tStates += 7;
2668 CHECK_BREAK_BYTE(HL);
2669 SET_HIGH_REGISTER(DE, GetBYTE(HL));
2670 break;
2671
2672 case 0x57: /* LD D,A */
2673 tStates += 4;
2674 sim_brk_pend[0] = FALSE;
2675 DE = (DE & 0xff) | (AF & ~0xff);
2676 break;
2677
2678 case 0x58: /* LD E,B */
2679 tStates += 4;
2680 sim_brk_pend[0] = FALSE;
2681 DE = (DE & ~0xff) | ((BC >> 8) & 0xff);
2682 break;
2683
2684 case 0x59: /* LD E,C */
2685 tStates += 4;
2686 sim_brk_pend[0] = FALSE;
2687 DE = (DE & ~0xff) | (BC & 0xff);
2688 break;
2689
2690 case 0x5a: /* LD E,D */
2691 tStates += 4;
2692 sim_brk_pend[0] = FALSE;
2693 DE = (DE & ~0xff) | ((DE >> 8) & 0xff);
2694 break;
2695
2696 case 0x5b: /* LD E,E */
2697 tStates += 4;
2698 sim_brk_pend[0] = FALSE; /* nop */
2699 break;
2700
2701 case 0x5c: /* LD E,H */
2702 tStates += 4;
2703 sim_brk_pend[0] = FALSE;
2704 DE = (DE & ~0xff) | ((HL >> 8) & 0xff);
2705 break;
2706
2707 case 0x5d: /* LD E,L */
2708 tStates += 4;
2709 sim_brk_pend[0] = FALSE;
2710 DE = (DE & ~0xff) | (HL & 0xff);
2711 break;
2712
2713 case 0x5e: /* LD E,(HL) */
2714 tStates += 7;
2715 CHECK_BREAK_BYTE(HL);
2716 SET_LOW_REGISTER(DE, GetBYTE(HL));
2717 break;
2718
2719 case 0x5f: /* LD E,A */
2720 tStates += 4;
2721 sim_brk_pend[0] = FALSE;
2722 DE = (DE & ~0xff) | ((AF >> 8) & 0xff);
2723 break;
2724
2725 case 0x60: /* LD H,B */
2726 tStates += 4;
2727 sim_brk_pend[0] = FALSE;
2728 HL = (HL & 0xff) | (BC & ~0xff);
2729 break;
2730
2731 case 0x61: /* LD H,C */
2732 tStates += 4;
2733 sim_brk_pend[0] = FALSE;
2734 HL = (HL & 0xff) | ((BC & 0xff) << 8);
2735 break;
2736
2737 case 0x62: /* LD H,D */
2738 tStates += 4;
2739 sim_brk_pend[0] = FALSE;
2740 HL = (HL & 0xff) | (DE & ~0xff);
2741 break;
2742
2743 case 0x63: /* LD H,E */
2744 tStates += 4;
2745 sim_brk_pend[0] = FALSE;
2746 HL = (HL & 0xff) | ((DE & 0xff) << 8);
2747 break;
2748
2749 case 0x64: /* LD H,H */
2750 tStates += 4;
2751 sim_brk_pend[0] = FALSE; /* nop */
2752 break;
2753
2754 case 0x65: /* LD H,L */
2755 tStates += 4;
2756 sim_brk_pend[0] = FALSE;
2757 HL = (HL & 0xff) | ((HL & 0xff) << 8);
2758 break;
2759
2760 case 0x66: /* LD H,(HL) */
2761 tStates += 7;
2762 CHECK_BREAK_BYTE(HL);
2763 SET_HIGH_REGISTER(HL, GetBYTE(HL));
2764 break;
2765
2766 case 0x67: /* LD H,A */
2767 tStates += 4;
2768 sim_brk_pend[0] = FALSE;
2769 HL = (HL & 0xff) | (AF & ~0xff);
2770 break;
2771
2772 case 0x68: /* LD L,B */
2773 tStates += 4;
2774 sim_brk_pend[0] = FALSE;
2775 HL = (HL & ~0xff) | ((BC >> 8) & 0xff);
2776 break;
2777
2778 case 0x69: /* LD L,C */
2779 tStates += 4;
2780 sim_brk_pend[0] = FALSE;
2781 HL = (HL & ~0xff) | (BC & 0xff);
2782 break;
2783
2784 case 0x6a: /* LD L,D */
2785 tStates += 4;
2786 sim_brk_pend[0] = FALSE;
2787 HL = (HL & ~0xff) | ((DE >> 8) & 0xff);
2788 break;
2789
2790 case 0x6b: /* LD L,E */
2791 tStates += 4;
2792 sim_brk_pend[0] = FALSE;
2793 HL = (HL & ~0xff) | (DE & 0xff);
2794 break;
2795
2796 case 0x6c: /* LD L,H */
2797 tStates += 4;
2798 sim_brk_pend[0] = FALSE;
2799 HL = (HL & ~0xff) | ((HL >> 8) & 0xff);
2800 break;
2801
2802 case 0x6d: /* LD L,L */
2803 tStates += 4;
2804 sim_brk_pend[0] = FALSE; /* nop */
2805 break;
2806
2807 case 0x6e: /* LD L,(HL) */
2808 tStates += 7;
2809 CHECK_BREAK_BYTE(HL);
2810 SET_LOW_REGISTER(HL, GetBYTE(HL));
2811 break;
2812
2813 case 0x6f: /* LD L,A */
2814 tStates += 4;
2815 sim_brk_pend[0] = FALSE;
2816 HL = (HL & ~0xff) | ((AF >> 8) & 0xff);
2817 break;
2818
2819 case 0x70: /* LD (HL),B */
2820 tStates += 7;
2821 CHECK_BREAK_BYTE(HL);
2822 PutBYTE(HL, HIGH_REGISTER(BC));
2823 break;
2824
2825 case 0x71: /* LD (HL),C */
2826 tStates += 7;
2827 CHECK_BREAK_BYTE(HL);
2828 PutBYTE(HL, LOW_REGISTER(BC));
2829 break;
2830
2831 case 0x72: /* LD (HL),D */
2832 tStates += 7;
2833 CHECK_BREAK_BYTE(HL);
2834 PutBYTE(HL, HIGH_REGISTER(DE));
2835 break;
2836
2837 case 0x73: /* LD (HL),E */
2838 tStates += 7;
2839 CHECK_BREAK_BYTE(HL);
2840 PutBYTE(HL, LOW_REGISTER(DE));
2841 break;
2842
2843 case 0x74: /* LD (HL),H */
2844 tStates += 7;
2845 CHECK_BREAK_BYTE(HL);
2846 PutBYTE(HL, HIGH_REGISTER(HL));
2847 break;
2848
2849 case 0x75: /* LD (HL),L */
2850 tStates += 7;
2851 CHECK_BREAK_BYTE(HL);
2852 PutBYTE(HL, LOW_REGISTER(HL));
2853 break;
2854
2855 case HALTINSTRUCTION: /* HALT */
2856 tStates += 4;
2857 sim_brk_pend[0] = FALSE;
2858 PC--;
2859 if (cpu_unit.flags & UNIT_CPU_STOPONHALT) {
2860 reason = STOP_HALT;
2861 goto end_decode;
2862 }
2863 sim_interval = 0;
2864 do_SIMH_sleep(); /* reduce CPU load in busy wait */
2865 break;
2866
2867 case 0x77: /* LD (HL),A */
2868 tStates += 7;
2869 CHECK_BREAK_BYTE(HL);
2870 PutBYTE(HL, HIGH_REGISTER(AF));
2871 break;
2872
2873 case 0x78: /* LD A,B */
2874 tStates += 4;
2875 sim_brk_pend[0] = FALSE;
2876 AF = (AF & 0xff) | (BC & ~0xff);
2877 break;
2878
2879 case 0x79: /* LD A,C */
2880 tStates += 4;
2881 sim_brk_pend[0] = FALSE;
2882 AF = (AF & 0xff) | ((BC & 0xff) << 8);
2883 break;
2884
2885 case 0x7a: /* LD A,D */
2886 tStates += 4;
2887 sim_brk_pend[0] = FALSE;
2888 AF = (AF & 0xff) | (DE & ~0xff);
2889 break;
2890
2891 case 0x7b: /* LD A,E */
2892 tStates += 4;
2893 sim_brk_pend[0] = FALSE;
2894 AF = (AF & 0xff) | ((DE & 0xff) << 8);
2895 break;
2896
2897 case 0x7c: /* LD A,H */
2898 tStates += 4;
2899 sim_brk_pend[0] = FALSE;
2900 AF = (AF & 0xff) | (HL & ~0xff);
2901 break;
2902
2903 case 0x7d: /* LD A,L */
2904 tStates += 4;
2905 sim_brk_pend[0] = FALSE;
2906 AF = (AF & 0xff) | ((HL & 0xff) << 8);
2907 break;
2908
2909 case 0x7e: /* LD A,(HL) */
2910 tStates += 7;
2911 CHECK_BREAK_BYTE(HL);
2912 SET_HIGH_REGISTER(AF, GetBYTE(HL));
2913 break;
2914
2915 case 0x7f: /* LD A,A */
2916 tStates += 4;
2917 sim_brk_pend[0] = FALSE; /* nop */
2918 break;
2919
2920 case 0x80: /* ADD A,B */
2921 tStates += 4;
2922 sim_brk_pend[0] = FALSE;
2923 temp = HIGH_REGISTER(BC);
2924 acu = HIGH_REGISTER(AF);
2925 sum = acu + temp;
2926 cbits = acu ^ temp ^ sum;
2927 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
2928 break;
2929
2930 case 0x81: /* ADD A,C */
2931 tStates += 4;
2932 sim_brk_pend[0] = FALSE;
2933 temp = LOW_REGISTER(BC);
2934 acu = HIGH_REGISTER(AF);
2935 sum = acu + temp;
2936 cbits = acu ^ temp ^ sum;
2937 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
2938 break;
2939
2940 case 0x82: /* ADD A,D */
2941 tStates += 4;
2942 sim_brk_pend[0] = FALSE;
2943 temp = HIGH_REGISTER(DE);
2944 acu = HIGH_REGISTER(AF);
2945 sum = acu + temp;
2946 cbits = acu ^ temp ^ sum;
2947 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
2948 break;
2949
2950 case 0x83: /* ADD A,E */
2951 tStates += 4;
2952 sim_brk_pend[0] = FALSE;
2953 temp = LOW_REGISTER(DE);
2954 acu = HIGH_REGISTER(AF);
2955 sum = acu + temp;
2956 cbits = acu ^ temp ^ sum;
2957 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
2958 break;
2959
2960 case 0x84: /* ADD A,H */
2961 tStates += 4;
2962 sim_brk_pend[0] = FALSE;
2963 temp = HIGH_REGISTER(HL);
2964 acu = HIGH_REGISTER(AF);
2965 sum = acu + temp;
2966 cbits = acu ^ temp ^ sum;
2967 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
2968 break;
2969
2970 case 0x85: /* ADD A,L */
2971 tStates += 4;
2972 sim_brk_pend[0] = FALSE;
2973 temp = LOW_REGISTER(HL);
2974 acu = HIGH_REGISTER(AF);
2975 sum = acu + temp;
2976 cbits = acu ^ temp ^ sum;
2977 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
2978 break;
2979
2980 case 0x86: /* ADD A,(HL) */
2981 tStates += 7;
2982 CHECK_BREAK_BYTE(HL);
2983 temp = GetBYTE(HL);
2984 acu = HIGH_REGISTER(AF);
2985 sum = acu + temp;
2986 cbits = acu ^ temp ^ sum;
2987 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
2988 break;
2989
2990 case 0x87: /* ADD A,A */
2991 tStates += 4;
2992 sim_brk_pend[0] = FALSE;
2993 cbits = 2 * HIGH_REGISTER(AF);
2994 AF = cbitsDup8Table[cbits] | (SET_PVS(cbits));
2995 break;
2996
2997 case 0x88: /* ADC A,B */
2998 tStates += 4;
2999 sim_brk_pend[0] = FALSE;
3000 temp = HIGH_REGISTER(BC);
3001 acu = HIGH_REGISTER(AF);
3002 sum = acu + temp + TSTFLAG(C);
3003 cbits = acu ^ temp ^ sum;
3004 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
3005 break;
3006
3007 case 0x89: /* ADC A,C */
3008 tStates += 4;
3009 sim_brk_pend[0] = FALSE;
3010 temp = LOW_REGISTER(BC);
3011 acu = HIGH_REGISTER(AF);
3012 sum = acu + temp + TSTFLAG(C);
3013 cbits = acu ^ temp ^ sum;
3014 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
3015 break;
3016
3017 case 0x8a: /* ADC A,D */
3018 tStates += 4;
3019 sim_brk_pend[0] = FALSE;
3020 temp = HIGH_REGISTER(DE);
3021 acu = HIGH_REGISTER(AF);
3022 sum = acu + temp + TSTFLAG(C);
3023 cbits = acu ^ temp ^ sum;
3024 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
3025 break;
3026
3027 case 0x8b: /* ADC A,E */
3028 tStates += 4;
3029 sim_brk_pend[0] = FALSE;
3030 temp = LOW_REGISTER(DE);
3031 acu = HIGH_REGISTER(AF);
3032 sum = acu + temp + TSTFLAG(C);
3033 cbits = acu ^ temp ^ sum;
3034 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
3035 break;
3036
3037 case 0x8c: /* ADC A,H */
3038 tStates += 4;
3039 sim_brk_pend[0] = FALSE;
3040 temp = HIGH_REGISTER(HL);
3041 acu = HIGH_REGISTER(AF);
3042 sum = acu + temp + TSTFLAG(C);
3043 cbits = acu ^ temp ^ sum;
3044 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
3045 break;
3046
3047 case 0x8d: /* ADC A,L */
3048 tStates += 4;
3049 sim_brk_pend[0] = FALSE;
3050 temp = LOW_REGISTER(HL);
3051 acu = HIGH_REGISTER(AF);
3052 sum = acu + temp + TSTFLAG(C);
3053 cbits = acu ^ temp ^ sum;
3054 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
3055 break;
3056
3057 case 0x8e: /* ADC A,(HL) */
3058 tStates += 7;
3059 CHECK_BREAK_BYTE(HL);
3060 temp = GetBYTE(HL);
3061 acu = HIGH_REGISTER(AF);
3062 sum = acu + temp + TSTFLAG(C);
3063 cbits = acu ^ temp ^ sum;
3064 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
3065 break;
3066
3067 case 0x8f: /* ADC A,A */
3068 tStates += 4;
3069 sim_brk_pend[0] = FALSE;
3070 cbits = 2 * HIGH_REGISTER(AF) + TSTFLAG(C);
3071 AF = cbitsDup8Table[cbits] | (SET_PVS(cbits));
3072 break;
3073
3074 case 0x90: /* SUB B */
3075 tStates += 4;
3076 sim_brk_pend[0] = FALSE;
3077 temp = HIGH_REGISTER(BC);
3078 acu = HIGH_REGISTER(AF);
3079 sum = acu - temp;
3080 cbits = acu ^ temp ^ sum;
3081 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3082 break;
3083
3084 case 0x91: /* SUB C */
3085 tStates += 4;
3086 sim_brk_pend[0] = FALSE;
3087 temp = LOW_REGISTER(BC);
3088 acu = HIGH_REGISTER(AF);
3089 sum = acu - temp;
3090 cbits = acu ^ temp ^ sum;
3091 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3092 break;
3093
3094 case 0x92: /* SUB D */
3095 tStates += 4;
3096 sim_brk_pend[0] = FALSE;
3097 temp = HIGH_REGISTER(DE);
3098 acu = HIGH_REGISTER(AF);
3099 sum = acu - temp;
3100 cbits = acu ^ temp ^ sum;
3101 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3102 break;
3103
3104 case 0x93: /* SUB E */
3105 tStates += 4;
3106 sim_brk_pend[0] = FALSE;
3107 temp = LOW_REGISTER(DE);
3108 acu = HIGH_REGISTER(AF);
3109 sum = acu - temp;
3110 cbits = acu ^ temp ^ sum;
3111 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3112 break;
3113
3114 case 0x94: /* SUB H */
3115 tStates += 4;
3116 sim_brk_pend[0] = FALSE;
3117 temp = HIGH_REGISTER(HL);
3118 acu = HIGH_REGISTER(AF);
3119 sum = acu - temp;
3120 cbits = acu ^ temp ^ sum;
3121 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3122 break;
3123
3124 case 0x95: /* SUB L */
3125 tStates += 4;
3126 sim_brk_pend[0] = FALSE;
3127 temp = LOW_REGISTER(HL);
3128 acu = HIGH_REGISTER(AF);
3129 sum = acu - temp;
3130 cbits = acu ^ temp ^ sum;
3131 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3132 break;
3133
3134 case 0x96: /* SUB (HL) */
3135 tStates += 7;
3136 CHECK_BREAK_BYTE(HL);
3137 temp = GetBYTE(HL);
3138 acu = HIGH_REGISTER(AF);
3139 sum = acu - temp;
3140 cbits = acu ^ temp ^ sum;
3141 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3142 break;
3143
3144 case 0x97: /* SUB A */
3145 tStates += 4;
3146 sim_brk_pend[0] = FALSE;
3147 AF = (chiptype == CHIP_TYPE_Z80) ? 0x42 : 0x46;
3148 break;
3149
3150 case 0x98: /* SBC A,B */
3151 tStates += 4;
3152 sim_brk_pend[0] = FALSE;
3153 temp = HIGH_REGISTER(BC);
3154 acu = HIGH_REGISTER(AF);
3155 sum = acu - temp - TSTFLAG(C);
3156 cbits = acu ^ temp ^ sum;
3157 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3158 break;
3159
3160 case 0x99: /* SBC A,C */
3161 tStates += 4;
3162 sim_brk_pend[0] = FALSE;
3163 temp = LOW_REGISTER(BC);
3164 acu = HIGH_REGISTER(AF);
3165 sum = acu - temp - TSTFLAG(C);
3166 cbits = acu ^ temp ^ sum;
3167 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3168 break;
3169
3170 case 0x9a: /* SBC A,D */
3171 tStates += 4;
3172 sim_brk_pend[0] = FALSE;
3173 temp = HIGH_REGISTER(DE);
3174 acu = HIGH_REGISTER(AF);
3175 sum = acu - temp - TSTFLAG(C);
3176 cbits = acu ^ temp ^ sum;
3177 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3178 break;
3179
3180 case 0x9b: /* SBC A,E */
3181 tStates += 4;
3182 sim_brk_pend[0] = FALSE;
3183 temp = LOW_REGISTER(DE);
3184 acu = HIGH_REGISTER(AF);
3185 sum = acu - temp - TSTFLAG(C);
3186 cbits = acu ^ temp ^ sum;
3187 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3188 break;
3189
3190 case 0x9c: /* SBC A,H */
3191 tStates += 4;
3192 sim_brk_pend[0] = FALSE;
3193 temp = HIGH_REGISTER(HL);
3194 acu = HIGH_REGISTER(AF);
3195 sum = acu - temp - TSTFLAG(C);
3196 cbits = acu ^ temp ^ sum;
3197 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3198 break;
3199
3200 case 0x9d: /* SBC A,L */
3201 tStates += 4;
3202 sim_brk_pend[0] = FALSE;
3203 temp = LOW_REGISTER(HL);
3204 acu = HIGH_REGISTER(AF);
3205 sum = acu - temp - TSTFLAG(C);
3206 cbits = acu ^ temp ^ sum;
3207 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3208 break;
3209
3210 case 0x9e: /* SBC A,(HL) */
3211 tStates += 7;
3212 CHECK_BREAK_BYTE(HL);
3213 temp = GetBYTE(HL);
3214 acu = HIGH_REGISTER(AF);
3215 sum = acu - temp - TSTFLAG(C);
3216 cbits = acu ^ temp ^ sum;
3217 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3218 break;
3219
3220 case 0x9f: /* SBC A,A */
3221 tStates += 4;
3222 sim_brk_pend[0] = FALSE;
3223 cbits = -TSTFLAG(C);
3224 AF = subTable[cbits & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PVS(cbits));
3225 break;
3226
3227 case 0xa0: /* AND B */
3228 tStates += 4;
3229 sim_brk_pend[0] = FALSE;
3230 AF = andTable[((AF & BC) >> 8) & 0xff];
3231 break;
3232
3233 case 0xa1: /* AND C */
3234 tStates += 4;
3235 sim_brk_pend[0] = FALSE;
3236 AF = andTable[((AF >> 8) & BC) & 0xff];
3237 break;
3238
3239 case 0xa2: /* AND D */
3240 tStates += 4;
3241 sim_brk_pend[0] = FALSE;
3242 AF = andTable[((AF & DE) >> 8) & 0xff];
3243 break;
3244
3245 case 0xa3: /* AND E */
3246 tStates += 4;
3247 sim_brk_pend[0] = FALSE;
3248 AF = andTable[((AF >> 8) & DE) & 0xff];
3249 break;
3250
3251 case 0xa4: /* AND H */
3252 tStates += 4;
3253 sim_brk_pend[0] = FALSE;
3254 AF = andTable[((AF & HL) >> 8) & 0xff];
3255 break;
3256
3257 case 0xa5: /* AND L */
3258 tStates += 4;
3259 sim_brk_pend[0] = FALSE;
3260 AF = andTable[((AF >> 8) & HL) & 0xff];
3261 break;
3262
3263 case 0xa6: /* AND (HL) */
3264 tStates += 7;
3265 CHECK_BREAK_BYTE(HL);
3266 AF = andTable[((AF >> 8) & GetBYTE(HL)) & 0xff];
3267 break;
3268
3269 case 0xa7: /* AND A */
3270 tStates += 4;
3271 sim_brk_pend[0] = FALSE;
3272 AF = andTable[(AF >> 8) & 0xff];
3273 break;
3274
3275 case 0xa8: /* XOR B */
3276 tStates += 4;
3277 sim_brk_pend[0] = FALSE;
3278 AF = xororTable[((AF ^ BC) >> 8) & 0xff];
3279 break;
3280
3281 case 0xa9: /* XOR C */
3282 tStates += 4;
3283 sim_brk_pend[0] = FALSE;
3284 AF = xororTable[((AF >> 8) ^ BC) & 0xff];
3285 break;
3286
3287 case 0xaa: /* XOR D */
3288 tStates += 4;
3289 sim_brk_pend[0] = FALSE;
3290 AF = xororTable[((AF ^ DE) >> 8) & 0xff];
3291 break;
3292
3293 case 0xab: /* XOR E */
3294 tStates += 4;
3295 sim_brk_pend[0] = FALSE;
3296 AF = xororTable[((AF >> 8) ^ DE) & 0xff];
3297 break;
3298
3299 case 0xac: /* XOR H */
3300 tStates += 4;
3301 sim_brk_pend[0] = FALSE;
3302 AF = xororTable[((AF ^ HL) >> 8) & 0xff];
3303 break;
3304
3305 case 0xad: /* XOR L */
3306 tStates += 4;
3307 sim_brk_pend[0] = FALSE;
3308 AF = xororTable[((AF >> 8) ^ HL) & 0xff];
3309 break;
3310
3311 case 0xae: /* XOR (HL) */
3312 tStates += 7;
3313 CHECK_BREAK_BYTE(HL);
3314 AF = xororTable[((AF >> 8) ^ GetBYTE(HL)) & 0xff];
3315 break;
3316
3317 case 0xaf: /* XOR A */
3318 tStates += 4;
3319 sim_brk_pend[0] = FALSE;
3320 AF = 0x44;
3321 break;
3322
3323 case 0xb0: /* OR B */
3324 tStates += 4;
3325 sim_brk_pend[0] = FALSE;
3326 AF = xororTable[((AF | BC) >> 8) & 0xff];
3327 break;
3328
3329 case 0xb1: /* OR C */
3330 tStates += 4;
3331 sim_brk_pend[0] = FALSE;
3332 AF = xororTable[((AF >> 8) | BC) & 0xff];
3333 break;
3334
3335 case 0xb2: /* OR D */
3336 tStates += 4;
3337 sim_brk_pend[0] = FALSE;
3338 AF = xororTable[((AF | DE) >> 8) & 0xff];
3339 break;
3340
3341 case 0xb3: /* OR E */
3342 tStates += 4;
3343 sim_brk_pend[0] = FALSE;
3344 AF = xororTable[((AF >> 8) | DE) & 0xff];
3345 break;
3346
3347 case 0xb4: /* OR H */
3348 tStates += 4;
3349 sim_brk_pend[0] = FALSE;
3350 AF = xororTable[((AF | HL) >> 8) & 0xff];
3351 break;
3352
3353 case 0xb5: /* OR L */
3354 tStates += 4;
3355 sim_brk_pend[0] = FALSE;
3356 AF = xororTable[((AF >> 8) | HL) & 0xff];
3357 break;
3358
3359 case 0xb6: /* OR (HL) */
3360 tStates += 7;
3361 CHECK_BREAK_BYTE(HL);
3362 AF = xororTable[((AF >> 8) | GetBYTE(HL)) & 0xff];
3363 break;
3364
3365 case 0xb7: /* OR A */
3366 tStates += 4;
3367 sim_brk_pend[0] = FALSE;
3368 AF = xororTable[(AF >> 8) & 0xff];
3369 break;
3370
3371 case 0xb8: /* CP B */
3372 tStates += 4;
3373 sim_brk_pend[0] = FALSE;
3374 temp = HIGH_REGISTER(BC);
3375 AF = (AF & ~0x28) | (temp & 0x28);
3376 acu = HIGH_REGISTER(AF);
3377 sum = acu - temp;
3378 cbits = acu ^ temp ^ sum;
3379 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
3380 (SET_PV) | cbits2Table[cbits & 0x1ff];
3381 break;
3382
3383 case 0xb9: /* CP C */
3384 tStates += 4;
3385 sim_brk_pend[0] = FALSE;
3386 temp = LOW_REGISTER(BC);
3387 AF = (AF & ~0x28) | (temp & 0x28);
3388 acu = HIGH_REGISTER(AF);
3389 sum = acu - temp;
3390 cbits = acu ^ temp ^ sum;
3391 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
3392 (SET_PV) | cbits2Table[cbits & 0x1ff];
3393 break;
3394
3395 case 0xba: /* CP D */
3396 tStates += 4;
3397 sim_brk_pend[0] = FALSE;
3398 temp = HIGH_REGISTER(DE);
3399 AF = (AF & ~0x28) | (temp & 0x28);
3400 acu = HIGH_REGISTER(AF);
3401 sum = acu - temp;
3402 cbits = acu ^ temp ^ sum;
3403 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
3404 (SET_PV) | cbits2Table[cbits & 0x1ff];
3405 break;
3406
3407 case 0xbb: /* CP E */
3408 tStates += 4;
3409 sim_brk_pend[0] = FALSE;
3410 temp = LOW_REGISTER(DE);
3411 AF = (AF & ~0x28) | (temp & 0x28);
3412 acu = HIGH_REGISTER(AF);
3413 sum = acu - temp;
3414 cbits = acu ^ temp ^ sum;
3415 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
3416 (SET_PV) | cbits2Table[cbits & 0x1ff];
3417 break;
3418
3419 case 0xbc: /* CP H */
3420 tStates += 4;
3421 sim_brk_pend[0] = FALSE;
3422 temp = HIGH_REGISTER(HL);
3423 AF = (AF & ~0x28) | (temp & 0x28);
3424 acu = HIGH_REGISTER(AF);
3425 sum = acu - temp;
3426 cbits = acu ^ temp ^ sum;
3427 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
3428 (SET_PV) | cbits2Table[cbits & 0x1ff];
3429 break;
3430
3431 case 0xbd: /* CP L */
3432 tStates += 4;
3433 sim_brk_pend[0] = FALSE;
3434 temp = LOW_REGISTER(HL);
3435 AF = (AF & ~0x28) | (temp & 0x28);
3436 acu = HIGH_REGISTER(AF);
3437 sum = acu - temp;
3438 cbits = acu ^ temp ^ sum;
3439 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
3440 (SET_PV) | cbits2Table[cbits & 0x1ff];
3441 break;
3442
3443 case 0xbe: /* CP (HL) */
3444 tStates += 7;
3445 CHECK_BREAK_BYTE(HL);
3446 temp = GetBYTE(HL);
3447 AF = (AF & ~0x28) | (temp & 0x28);
3448 acu = HIGH_REGISTER(AF);
3449 sum = acu - temp;
3450 cbits = acu ^ temp ^ sum;
3451 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
3452 (SET_PV) | cbits2Table[cbits & 0x1ff];
3453 break;
3454
3455 case 0xbf: /* CP A */
3456 tStates += 4;
3457 sim_brk_pend[0] = FALSE;
3458 SET_LOW_REGISTER(AF, (HIGH_REGISTER(AF) & 0x28) | (chiptype == CHIP_TYPE_Z80 ? 0x42 : 0x46));
3459 break;
3460
3461 case 0xc0: /* RET NZ */
3462 if (TSTFLAG(Z)) {
3463 sim_brk_pend[0] = FALSE;
3464 tStates += 5;
3465 }
3466 else {
3467 CHECK_BREAK_WORD(SP);
3468 PCQ_ENTRY(PCX);
3469 POP(PC);
3470 tStates += 11;
3471 }
3472 break;
3473
3474 case 0xc1: /* POP BC */
3475 tStates += 10;
3476 CHECK_BREAK_WORD(SP);
3477 POP(BC);
3478 break;
3479
3480 case 0xc2: /* JP NZ,nnnn */
3481 sim_brk_pend[0] = FALSE;
3482 JPC(!TSTFLAG(Z)); /* also updates tStates */
3483 break;
3484
3485 case 0xc3: /* JP nnnn */
3486 sim_brk_pend[0] = FALSE;
3487 JPC(1); /* also updates tStates */
3488 break;
3489
3490 case 0xc4: /* CALL NZ,nnnn */
3491 CALLC(!TSTFLAG(Z)); /* also updates tStates */
3492 break;
3493
3494 case 0xc5: /* PUSH BC */
3495 tStates += 11;
3496 CHECK_BREAK_WORD(SP - 2);
3497 PUSH(BC);
3498 break;
3499
3500 case 0xc6: /* ADD A,nn */
3501 tStates += 7;
3502 sim_brk_pend[0] = FALSE;
3503 temp = RAM_PP(PC);
3504 acu = HIGH_REGISTER(AF);
3505 sum = acu + temp;
3506 cbits = acu ^ temp ^ sum;
3507 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
3508 break;
3509
3510 case 0xc7: /* RST 0 */
3511 tStates += 11;
3512 CHECK_BREAK_WORD(SP - 2);
3513 PUSH(PC);
3514 PCQ_ENTRY(PCX);
3515 PC = 0;
3516 break;
3517
3518 case 0xc8: /* RET Z */
3519 if (TSTFLAG(Z)) {
3520 CHECK_BREAK_WORD(SP);
3521 PCQ_ENTRY(PCX);
3522 POP(PC);
3523 tStates += 11;
3524 }
3525 else {
3526 sim_brk_pend[0] = FALSE;
3527 tStates += 5;
3528 }
3529 break;
3530
3531 case 0xc9: /* RET */
3532 tStates += 10;
3533 CHECK_BREAK_WORD(SP);
3534 PCQ_ENTRY(PCX);
3535 POP(PC);
3536 break;
3537
3538 case 0xca: /* JP Z,nnnn */
3539 sim_brk_pend[0] = FALSE;
3540 JPC(TSTFLAG(Z)); /* also updates tStates */
3541 break;
3542
3543 case 0xcb: /* CB prefix */
3544 CHECK_CPU_8080;
3545 adr = HL;
3546 switch ((op = GetBYTE(PC)) & 7) {
3547
3548 case 0:
3549 sim_brk_pend[0] = tStateModifier = FALSE;
3550 ++PC;
3551 acu = HIGH_REGISTER(BC);
3552 tStates += 8;
3553 break;
3554
3555 case 1:
3556 sim_brk_pend[0] = tStateModifier = FALSE;
3557 ++PC;
3558 acu = LOW_REGISTER(BC);
3559 tStates += 8;
3560 break;
3561
3562 case 2:
3563 sim_brk_pend[0] = tStateModifier = FALSE;
3564 ++PC;
3565 acu = HIGH_REGISTER(DE);
3566 tStates += 8;
3567 break;
3568
3569 case 3:
3570 sim_brk_pend[0] = tStateModifier = FALSE;
3571 ++PC;
3572 acu = LOW_REGISTER(DE);
3573 tStates += 8;
3574 break;
3575
3576 case 4:
3577 sim_brk_pend[0] = tStateModifier = FALSE;
3578 ++PC;
3579 acu = HIGH_REGISTER(HL);
3580 tStates += 8;
3581 break;
3582
3583 case 5:
3584 sim_brk_pend[0] = tStateModifier = FALSE;
3585 ++PC;
3586 acu = LOW_REGISTER(HL);
3587 tStates += 8;
3588 break;
3589
3590 case 6:
3591 CHECK_BREAK_BYTE(adr);
3592 ++PC;
3593 acu = GetBYTE(adr);
3594 tStateModifier = TRUE;
3595 tStates += 15;
3596 break;
3597
3598 case 7:
3599 sim_brk_pend[0] = tStateModifier = FALSE;
3600 ++PC;
3601 acu = HIGH_REGISTER(AF);
3602 tStates += 8;
3603 break;
3604 }
3605 switch (op & 0xc0) {
3606
3607 case 0x00: /* shift/rotate */
3608 switch (op & 0x38) {
3609
3610 case 0x00: /* RLC */
3611 temp = (acu << 1) | (acu >> 7);
3612 cbits = temp & 1;
3613 goto cbshflg1;
3614
3615 case 0x08: /* RRC */
3616 temp = (acu >> 1) | (acu << 7);
3617 cbits = temp & 0x80;
3618 goto cbshflg1;
3619
3620 case 0x10: /* RL */
3621 temp = (acu << 1) | TSTFLAG(C);
3622 cbits = acu & 0x80;
3623 goto cbshflg1;
3624
3625 case 0x18: /* RR */
3626 temp = (acu >> 1) | (TSTFLAG(C) << 7);
3627 cbits = acu & 1;
3628 goto cbshflg1;
3629
3630 case 0x20: /* SLA */
3631 temp = acu << 1;
3632 cbits = acu & 0x80;
3633 goto cbshflg1;
3634
3635 case 0x28: /* SRA */
3636 temp = (acu >> 1) | (acu & 0x80);
3637 cbits = acu & 1;
3638 goto cbshflg1;
3639
3640 case 0x30: /* SLIA */
3641 temp = (acu << 1) | 1;
3642 cbits = acu & 0x80;
3643 goto cbshflg1;
3644
3645 case 0x38: /* SRL */
3646 temp = acu >> 1;
3647 cbits = acu & 1;
3648 cbshflg1:
3649 AF = (AF & ~0xff) | rotateShiftTable[temp & 0xff] | !!cbits;
3650 /* !!cbits == 0 if cbits == 0 !!cbits == 1 if cbits > 0 */
3651 }
3652 break;
3653
3654 case 0x40: /* BIT */
3655 if (tStateModifier)
3656 tStates -= 3;
3657 if (acu & (1 << ((op >> 3) & 7)))
3658 AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7);
3659 else
3660 AF = (AF & ~0xfe) | 0x54;
3661 if ((op & 7) != 6)
3662 AF |= (acu & 0x28);
3663 temp = acu;
3664 break;
3665
3666 case 0x80: /* RES */
3667 temp = acu & ~(1 << ((op >> 3) & 7));
3668 break;
3669
3670 case 0xc0: /* SET */
3671 temp = acu | (1 << ((op >> 3) & 7));
3672 break;
3673 }
3674
3675 switch (op & 7) {
3676
3677 case 0:
3678 SET_HIGH_REGISTER(BC, temp);
3679 break;
3680
3681 case 1:
3682 SET_LOW_REGISTER(BC, temp);
3683 break;
3684
3685 case 2:
3686 SET_HIGH_REGISTER(DE, temp);
3687 break;
3688
3689 case 3:
3690 SET_LOW_REGISTER(DE, temp);
3691 break;
3692
3693 case 4:
3694 SET_HIGH_REGISTER(HL, temp);
3695 break;
3696
3697 case 5:
3698 SET_LOW_REGISTER(HL, temp);
3699 break;
3700
3701 case 6:
3702 PutBYTE(adr, temp);
3703 break;
3704
3705 case 7:
3706 SET_HIGH_REGISTER(AF, temp);
3707 break;
3708 }
3709 break;
3710
3711 case 0xcc: /* CALL Z,nnnn */
3712 CALLC(TSTFLAG(Z)); /* also updates tStates */
3713 break;
3714
3715 case 0xcd: /* CALL nnnn */
3716 CALLC(1); /* also updates tStates */
3717 break;
3718
3719 case 0xce: /* ADC A,nn */
3720 tStates += 7;
3721 sim_brk_pend[0] = FALSE;
3722 temp = RAM_PP(PC);
3723 acu = HIGH_REGISTER(AF);
3724 sum = acu + temp + TSTFLAG(C);
3725 cbits = acu ^ temp ^ sum;
3726 AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
3727 break;
3728
3729 case 0xcf: /* RST 8 */
3730 tStates += 11;
3731 CHECK_BREAK_WORD(SP - 2);
3732 PUSH(PC);
3733 PCQ_ENTRY(PCX);
3734 PC = 8;
3735 break;
3736
3737 case 0xd0: /* RET NC */
3738 if (TSTFLAG(C)) {
3739 sim_brk_pend[0] = FALSE;
3740 tStates += 5;
3741 }
3742 else {
3743 CHECK_BREAK_WORD(SP);
3744 PCQ_ENTRY(PCX);
3745 POP(PC);
3746 tStates += 11;
3747 }
3748 break;
3749
3750 case 0xd1: /* POP DE */
3751 tStates += 10;
3752 CHECK_BREAK_WORD(SP);
3753 POP(DE);
3754 break;
3755
3756 case 0xd2: /* JP NC,nnnn */
3757 sim_brk_pend[0] = FALSE;
3758 JPC(!TSTFLAG(C)); /* also updates tStates */
3759 break;
3760
3761 case 0xd3: /* OUT (nn),A */
3762 tStates += 11;
3763 sim_brk_pend[0] = FALSE;
3764 out(RAM_PP(PC), HIGH_REGISTER(AF));
3765 break;
3766
3767 case 0xd4: /* CALL NC,nnnn */
3768 CALLC(!TSTFLAG(C)); /* also updates tStates */
3769 break;
3770
3771 case 0xd5: /* PUSH DE */
3772 tStates += 11;
3773 CHECK_BREAK_WORD(SP - 2);
3774 PUSH(DE);
3775 break;
3776
3777 case 0xd6: /* SUB nn */
3778 tStates += 7;
3779 sim_brk_pend[0] = FALSE;
3780 temp = RAM_PP(PC);
3781 acu = HIGH_REGISTER(AF);
3782 sum = acu - temp;
3783 cbits = acu ^ temp ^ sum;
3784 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
3785 break;
3786
3787 case 0xd7: /* RST 10H */
3788 tStates += 11;
3789 CHECK_BREAK_WORD(SP - 2);
3790 PUSH(PC);
3791 PCQ_ENTRY(PCX);
3792 PC = 0x10;
3793 break;
3794
3795 case 0xd8: /* RET C */
3796 if (TSTFLAG(C)) {
3797 CHECK_BREAK_WORD(SP);
3798 PCQ_ENTRY(PCX);
3799 POP(PC);
3800 tStates += 11;
3801 }
3802 else {
3803 sim_brk_pend[0] = FALSE;
3804 tStates += 5;
3805 }
3806 break;
3807
3808 case 0xd9: /* EXX */
3809 tStates += 4;
3810 sim_brk_pend[0] = FALSE;
3811 CHECK_CPU_8080;
3812 temp = BC;
3813 BC = BC1_S;
3814 BC1_S = temp;
3815 temp = DE;
3816 DE = DE1_S;
3817 DE1_S = temp;
3818 temp = HL;
3819 HL = HL1_S;
3820 HL1_S = temp;
3821 break;
3822
3823 case 0xda: /* JP C,nnnn */
3824 sim_brk_pend[0] = FALSE;
3825 JPC(TSTFLAG(C)); /* also updates tStates */
3826 break;
3827
3828 case 0xdb: /* IN A,(nn) */
3829 tStates += 11;
3830 sim_brk_pend[0] = FALSE;
3831 SET_HIGH_REGISTER(AF, in(RAM_PP(PC)));
3832 break;
3833
3834 case 0xdc: /* CALL C,nnnn */
3835 CALLC(TSTFLAG(C)); /* also updates tStates */
3836 break;
3837
3838 case 0xdd: /* DD prefix */
3839 CHECK_CPU_8080;
3840 switch (RAM_PP(PC)) {
3841
3842 case 0x09: /* ADD IX,BC */
3843 tStates += 15;
3844 sim_brk_pend[0] = FALSE;
3845 IX &= ADDRMASK;
3846 BC &= ADDRMASK;
3847 sum = IX + BC;
3848 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IX ^ BC ^ sum) >> 8];
3849 IX = sum;
3850 break;
3851
3852 case 0x19: /* ADD IX,DE */
3853 tStates += 15;
3854 sim_brk_pend[0] = FALSE;
3855 IX &= ADDRMASK;
3856 DE &= ADDRMASK;
3857 sum = IX + DE;
3858 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IX ^ DE ^ sum) >> 8];
3859 IX = sum;
3860 break;
3861
3862 case 0x21: /* LD IX,nnnn */
3863 tStates += 14;
3864 sim_brk_pend[0] = FALSE;
3865 IX = GET_WORD(PC);
3866 PC += 2;
3867 break;
3868
3869 case 0x22: /* LD (nnnn),IX */
3870 tStates += 20;
3871 temp = GET_WORD(PC);
3872 CHECK_BREAK_WORD(temp);
3873 PutWORD(temp, IX);
3874 PC += 2;
3875 break;
3876
3877 case 0x23: /* INC IX */
3878 tStates += 10;
3879 sim_brk_pend[0] = FALSE;
3880 ++IX;
3881 break;
3882
3883 case 0x24: /* INC IXH */
3884 tStates += 9;
3885 sim_brk_pend[0] = FALSE;
3886 IX += 0x100;
3887 AF = (AF & ~0xfe) | incZ80Table[HIGH_REGISTER(IX)];
3888 break;
3889
3890 case 0x25: /* DEC IXH */
3891 tStates += 9;
3892 sim_brk_pend[0] = FALSE;
3893 IX -= 0x100;
3894 AF = (AF & ~0xfe) | decZ80Table[HIGH_REGISTER(IX)];
3895 break;
3896
3897 case 0x26: /* LD IXH,nn */
3898 tStates += 9;
3899 sim_brk_pend[0] = FALSE;
3900 SET_HIGH_REGISTER(IX, RAM_PP(PC));
3901 break;
3902
3903 case 0x29: /* ADD IX,IX */
3904 tStates += 15;
3905 sim_brk_pend[0] = FALSE;
3906 IX &= ADDRMASK;
3907 sum = IX + IX;
3908 AF = (AF & ~0x3b) | cbitsDup16Table[sum >> 8];
3909 IX = sum;
3910 break;
3911
3912 case 0x2a: /* LD IX,(nnnn) */
3913 tStates += 20;
3914 temp = GET_WORD(PC);
3915 CHECK_BREAK_WORD(temp);
3916 IX = GET_WORD(temp);
3917 PC += 2;
3918 break;
3919
3920 case 0x2b: /* DEC IX */
3921 tStates += 10;
3922 sim_brk_pend[0] = FALSE;
3923 --IX;
3924 break;
3925
3926 case 0x2c: /* INC IXL */
3927 tStates += 9;
3928 sim_brk_pend[0] = FALSE;
3929 temp = LOW_REGISTER(IX) + 1;
3930 SET_LOW_REGISTER(IX, temp);
3931 AF = (AF & ~0xfe) | incZ80Table[temp];
3932 break;
3933
3934 case 0x2d: /* DEC IXL */
3935 tStates += 9;
3936 sim_brk_pend[0] = FALSE;
3937 temp = LOW_REGISTER(IX) - 1;
3938 SET_LOW_REGISTER(IX, temp);
3939 AF = (AF & ~0xfe) | decZ80Table[temp & 0xff];
3940 break;
3941
3942 case 0x2e: /* LD IXL,nn */
3943 tStates += 9;
3944 sim_brk_pend[0] = FALSE;
3945 SET_LOW_REGISTER(IX, RAM_PP(PC));
3946 break;
3947
3948 case 0x34: /* INC (IX+dd) */
3949 tStates += 23;
3950 adr = IX + (int8) RAM_PP(PC);
3951 CHECK_BREAK_BYTE(adr);
3952 temp = GetBYTE(adr) + 1;
3953 PutBYTE(adr, temp);
3954 AF = (AF & ~0xfe) | incZ80Table[temp];
3955 break;
3956
3957 case 0x35: /* DEC (IX+dd) */
3958 tStates += 23;
3959 adr = IX + (int8) RAM_PP(PC);
3960 CHECK_BREAK_BYTE(adr);
3961 temp = GetBYTE(adr) - 1;
3962 PutBYTE(adr, temp);
3963 AF = (AF & ~0xfe) | decZ80Table[temp & 0xff];
3964 break;
3965
3966 case 0x36: /* LD (IX+dd),nn */
3967 tStates += 19;
3968 adr = IX + (int8) RAM_PP(PC);
3969 CHECK_BREAK_BYTE(adr);
3970 PutBYTE(adr, RAM_PP(PC));
3971 break;
3972
3973 case 0x39: /* ADD IX,SP */
3974 tStates += 15;
3975 sim_brk_pend[0] = FALSE;
3976 IX &= ADDRMASK;
3977 SP &= ADDRMASK;
3978 sum = IX + SP;
3979 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IX ^ SP ^ sum) >> 8];
3980 IX = sum;
3981 break;
3982
3983 case 0x44: /* LD B,IXH */
3984 tStates += 9;
3985 sim_brk_pend[0] = FALSE;
3986 SET_HIGH_REGISTER(BC, HIGH_REGISTER(IX));
3987 break;
3988
3989 case 0x45: /* LD B,IXL */
3990 tStates += 9;
3991 sim_brk_pend[0] = FALSE;
3992 SET_HIGH_REGISTER(BC, LOW_REGISTER(IX));
3993 break;
3994
3995 case 0x46: /* LD B,(IX+dd) */
3996 tStates += 19;
3997 adr = IX + (int8) RAM_PP(PC);
3998 CHECK_BREAK_BYTE(adr);
3999 SET_HIGH_REGISTER(BC, GetBYTE(adr));
4000 break;
4001
4002 case 0x4c: /* LD C,IXH */
4003 tStates += 9;
4004 sim_brk_pend[0] = FALSE;
4005 SET_LOW_REGISTER(BC, HIGH_REGISTER(IX));
4006 break;
4007
4008 case 0x4d: /* LD C,IXL */
4009 tStates += 9;
4010 sim_brk_pend[0] = FALSE;
4011 SET_LOW_REGISTER(BC, LOW_REGISTER(IX));
4012 break;
4013
4014 case 0x4e: /* LD C,(IX+dd) */
4015 tStates += 19;
4016 adr = IX + (int8) RAM_PP(PC);
4017 CHECK_BREAK_BYTE(adr);
4018 SET_LOW_REGISTER(BC, GetBYTE(adr));
4019 break;
4020
4021 case 0x54: /* LD D,IXH */
4022 tStates += 9;
4023 sim_brk_pend[0] = FALSE;
4024 SET_HIGH_REGISTER(DE, HIGH_REGISTER(IX));
4025 break;
4026
4027 case 0x55: /* LD D,IXL */
4028 tStates += 9;
4029 sim_brk_pend[0] = FALSE;
4030 SET_HIGH_REGISTER(DE, LOW_REGISTER(IX));
4031 break;
4032
4033 case 0x56: /* LD D,(IX+dd) */
4034 tStates += 19;
4035 adr = IX + (int8) RAM_PP(PC);
4036 CHECK_BREAK_BYTE(adr);
4037 SET_HIGH_REGISTER(DE, GetBYTE(adr));
4038 break;
4039
4040 case 0x5c: /* LD E,IXH */
4041 tStates += 9;
4042 sim_brk_pend[0] = FALSE;
4043 SET_LOW_REGISTER(DE, HIGH_REGISTER(IX));
4044 break;
4045
4046 case 0x5d: /* LD E,IXL */
4047 tStates += 9;
4048 sim_brk_pend[0] = FALSE;
4049 SET_LOW_REGISTER(DE, LOW_REGISTER(IX));
4050 break;
4051
4052 case 0x5e: /* LD E,(IX+dd) */
4053 tStates += 19;
4054 adr = IX + (int8) RAM_PP(PC);
4055 CHECK_BREAK_BYTE(adr);
4056 SET_LOW_REGISTER(DE, GetBYTE(adr));
4057 break;
4058
4059 case 0x60: /* LD IXH,B */
4060 tStates += 9;
4061 sim_brk_pend[0] = FALSE;
4062 SET_HIGH_REGISTER(IX, HIGH_REGISTER(BC));
4063 break;
4064
4065 case 0x61: /* LD IXH,C */
4066 tStates += 9;
4067 sim_brk_pend[0] = FALSE;
4068 SET_HIGH_REGISTER(IX, LOW_REGISTER(BC));
4069 break;
4070
4071 case 0x62: /* LD IXH,D */
4072 tStates += 9;
4073 sim_brk_pend[0] = FALSE;
4074 SET_HIGH_REGISTER(IX, HIGH_REGISTER(DE));
4075 break;
4076
4077 case 0x63: /* LD IXH,E */
4078 tStates += 9;
4079 sim_brk_pend[0] = FALSE;
4080 SET_HIGH_REGISTER(IX, LOW_REGISTER(DE));
4081 break;
4082
4083 case 0x64: /* LD IXH,IXH */
4084 tStates += 9;
4085 sim_brk_pend[0] = FALSE; /* nop */
4086 break;
4087
4088 case 0x65: /* LD IXH,IXL */
4089 tStates += 9;
4090 sim_brk_pend[0] = FALSE;
4091 SET_HIGH_REGISTER(IX, LOW_REGISTER(IX));
4092 break;
4093
4094 case 0x66: /* LD H,(IX+dd) */
4095 tStates += 19;
4096 adr = IX + (int8) RAM_PP(PC);
4097 CHECK_BREAK_BYTE(adr);
4098 SET_HIGH_REGISTER(HL, GetBYTE(adr));
4099 break;
4100
4101 case 0x67: /* LD IXH,A */
4102 tStates += 9;
4103 sim_brk_pend[0] = FALSE;
4104 SET_HIGH_REGISTER(IX, HIGH_REGISTER(AF));
4105 break;
4106
4107 case 0x68: /* LD IXL,B */
4108 tStates += 9;
4109 sim_brk_pend[0] = FALSE;
4110 SET_LOW_REGISTER(IX, HIGH_REGISTER(BC));
4111 break;
4112
4113 case 0x69: /* LD IXL,C */
4114 tStates += 9;
4115 sim_brk_pend[0] = FALSE;
4116 SET_LOW_REGISTER(IX, LOW_REGISTER(BC));
4117 break;
4118
4119 case 0x6a: /* LD IXL,D */
4120 tStates += 9;
4121 sim_brk_pend[0] = FALSE;
4122 SET_LOW_REGISTER(IX, HIGH_REGISTER(DE));
4123 break;
4124
4125 case 0x6b: /* LD IXL,E */
4126 tStates += 9;
4127 sim_brk_pend[0] = FALSE;
4128 SET_LOW_REGISTER(IX, LOW_REGISTER(DE));
4129 break;
4130
4131 case 0x6c: /* LD IXL,IXH */
4132 tStates += 9;
4133 sim_brk_pend[0] = FALSE;
4134 SET_LOW_REGISTER(IX, HIGH_REGISTER(IX));
4135 break;
4136
4137 case 0x6d: /* LD IXL,IXL */
4138 tStates += 9;
4139 sim_brk_pend[0] = FALSE; /* nop */
4140 break;
4141
4142 case 0x6e: /* LD L,(IX+dd) */
4143 tStates += 19;
4144 adr = IX + (int8) RAM_PP(PC);
4145 CHECK_BREAK_BYTE(adr);
4146 SET_LOW_REGISTER(HL, GetBYTE(adr));
4147 break;
4148
4149 case 0x6f: /* LD IXL,A */
4150 tStates += 9;
4151 sim_brk_pend[0] = FALSE;
4152 SET_LOW_REGISTER(IX, HIGH_REGISTER(AF));
4153 break;
4154
4155 case 0x70: /* LD (IX+dd),B */
4156 tStates += 19;
4157 adr = IX + (int8) RAM_PP(PC);
4158 CHECK_BREAK_BYTE(adr);
4159 PutBYTE(adr, HIGH_REGISTER(BC));
4160 break;
4161
4162 case 0x71: /* LD (IX+dd),C */
4163 tStates += 19;
4164 adr = IX + (int8) RAM_PP(PC);
4165 CHECK_BREAK_BYTE(adr);
4166 PutBYTE(adr, LOW_REGISTER(BC));
4167 break;
4168
4169 case 0x72: /* LD (IX+dd),D */
4170 tStates += 19;
4171 adr = IX + (int8) RAM_PP(PC);
4172 CHECK_BREAK_BYTE(adr);
4173 PutBYTE(adr, HIGH_REGISTER(DE));
4174 break;
4175
4176 case 0x73: /* LD (IX+dd),E */
4177 tStates += 19;
4178 adr = IX + (int8) RAM_PP(PC);
4179 CHECK_BREAK_BYTE(adr);
4180 PutBYTE(adr, LOW_REGISTER(DE));
4181 break;
4182
4183 case 0x74: /* LD (IX+dd),H */
4184 tStates += 19;
4185 adr = IX + (int8) RAM_PP(PC);
4186 CHECK_BREAK_BYTE(adr);
4187 PutBYTE(adr, HIGH_REGISTER(HL));
4188 break;
4189
4190 case 0x75: /* LD (IX+dd),L */
4191 tStates += 19;
4192 adr = IX + (int8) RAM_PP(PC);
4193 CHECK_BREAK_BYTE(adr);
4194 PutBYTE(adr, LOW_REGISTER(HL));
4195 break;
4196
4197 case 0x77: /* LD (IX+dd),A */
4198 tStates += 19;
4199 adr = IX + (int8) RAM_PP(PC);
4200 CHECK_BREAK_BYTE(adr);
4201 PutBYTE(adr, HIGH_REGISTER(AF));
4202 break;
4203
4204 case 0x7c: /* LD A,IXH */
4205 tStates += 9;
4206 sim_brk_pend[0] = FALSE;
4207 SET_HIGH_REGISTER(AF, HIGH_REGISTER(IX));
4208 break;
4209
4210 case 0x7d: /* LD A,IXL */
4211 tStates += 9;
4212 sim_brk_pend[0] = FALSE;
4213 SET_HIGH_REGISTER(AF, LOW_REGISTER(IX));
4214 break;
4215
4216 case 0x7e: /* LD A,(IX+dd) */
4217 tStates += 19;
4218 adr = IX + (int8) RAM_PP(PC);
4219 CHECK_BREAK_BYTE(adr);
4220 SET_HIGH_REGISTER(AF, GetBYTE(adr));
4221 break;
4222
4223 case 0x84: /* ADD A,IXH */
4224 tStates += 9;
4225 sim_brk_pend[0] = FALSE;
4226 temp = HIGH_REGISTER(IX);
4227 acu = HIGH_REGISTER(AF);
4228 sum = acu + temp;
4229 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
4230 break;
4231
4232 case 0x85: /* ADD A,IXL */
4233 tStates += 9;
4234 sim_brk_pend[0] = FALSE;
4235 temp = LOW_REGISTER(IX);
4236 acu = HIGH_REGISTER(AF);
4237 sum = acu + temp;
4238 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
4239 break;
4240
4241 case 0x86: /* ADD A,(IX+dd) */
4242 tStates += 19;
4243 adr = IX + (int8) RAM_PP(PC);
4244 CHECK_BREAK_BYTE(adr);
4245 temp = GetBYTE(adr);
4246 acu = HIGH_REGISTER(AF);
4247 sum = acu + temp;
4248 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
4249 break;
4250
4251 case 0x8c: /* ADC A,IXH */
4252 tStates += 9;
4253 sim_brk_pend[0] = FALSE;
4254 temp = HIGH_REGISTER(IX);
4255 acu = HIGH_REGISTER(AF);
4256 sum = acu + temp + TSTFLAG(C);
4257 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
4258 break;
4259
4260 case 0x8d: /* ADC A,IXL */
4261 tStates += 9;
4262 sim_brk_pend[0] = FALSE;
4263 temp = LOW_REGISTER(IX);
4264 acu = HIGH_REGISTER(AF);
4265 sum = acu + temp + TSTFLAG(C);
4266 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
4267 break;
4268
4269 case 0x8e: /* ADC A,(IX+dd) */
4270 tStates += 19;
4271 adr = IX + (int8) RAM_PP(PC);
4272 CHECK_BREAK_BYTE(adr);
4273 temp = GetBYTE(adr);
4274 acu = HIGH_REGISTER(AF);
4275 sum = acu + temp + TSTFLAG(C);
4276 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
4277 break;
4278
4279 case 0x96: /* SUB (IX+dd) */
4280 tStates += 19;
4281 adr = IX + (int8) RAM_PP(PC);
4282 CHECK_BREAK_BYTE(adr);
4283 temp = GetBYTE(adr);
4284 acu = HIGH_REGISTER(AF);
4285 sum = acu - temp;
4286 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
4287 break;
4288
4289 case 0x94: /* SUB IXH */
4290 SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */
4291
4292 case 0x9c: /* SBC A,IXH */
4293 tStates += 9;
4294 sim_brk_pend[0] = FALSE;
4295 temp = HIGH_REGISTER(IX);
4296 acu = HIGH_REGISTER(AF);
4297 sum = acu - temp - TSTFLAG(C);
4298 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
4299 break;
4300
4301 case 0x95: /* SUB IXL */
4302 SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */
4303
4304 case 0x9d: /* SBC A,IXL */
4305 tStates += 9;
4306 sim_brk_pend[0] = FALSE;
4307 temp = LOW_REGISTER(IX);
4308 acu = HIGH_REGISTER(AF);
4309 sum = acu - temp - TSTFLAG(C);
4310 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
4311 break;
4312
4313 case 0x9e: /* SBC A,(IX+dd) */
4314 tStates += 19;
4315 adr = IX + (int8) RAM_PP(PC);
4316 CHECK_BREAK_BYTE(adr);
4317 temp = GetBYTE(adr);
4318 acu = HIGH_REGISTER(AF);
4319 sum = acu - temp - TSTFLAG(C);
4320 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
4321 break;
4322
4323 case 0xa4: /* AND IXH */
4324 tStates += 9;
4325 sim_brk_pend[0] = FALSE;
4326 AF = andTable[((AF & IX) >> 8) & 0xff];
4327 break;
4328
4329 case 0xa5: /* AND IXL */
4330 tStates += 9;
4331 sim_brk_pend[0] = FALSE;
4332 AF = andTable[((AF >> 8) & IX) & 0xff];
4333 break;
4334
4335 case 0xa6: /* AND (IX+dd) */
4336 tStates += 19;
4337 adr = IX + (int8) RAM_PP(PC);
4338 CHECK_BREAK_BYTE(adr);
4339 AF = andTable[((AF >> 8) & GetBYTE(adr)) & 0xff];
4340 break;
4341
4342 case 0xac: /* XOR IXH */
4343 tStates += 9;
4344 sim_brk_pend[0] = FALSE;
4345 AF = xororTable[((AF ^ IX) >> 8) & 0xff];
4346 break;
4347
4348 case 0xad: /* XOR IXL */
4349 tStates += 9;
4350 sim_brk_pend[0] = FALSE;
4351 AF = xororTable[((AF >> 8) ^ IX) & 0xff];
4352 break;
4353
4354 case 0xae: /* XOR (IX+dd) */
4355 tStates += 19;
4356 adr = IX + (int8) RAM_PP(PC);
4357 CHECK_BREAK_BYTE(adr);
4358 AF = xororTable[((AF >> 8) ^ GetBYTE(adr)) & 0xff];
4359 break;
4360
4361 case 0xb4: /* OR IXH */
4362 tStates += 9;
4363 sim_brk_pend[0] = FALSE;
4364 AF = xororTable[((AF | IX) >> 8) & 0xff];
4365 break;
4366
4367 case 0xb5: /* OR IXL */
4368 tStates += 9;
4369 sim_brk_pend[0] = FALSE;
4370 AF = xororTable[((AF >> 8) | IX) & 0xff];
4371 break;
4372
4373 case 0xb6: /* OR (IX+dd) */
4374 tStates += 19;
4375 adr = IX + (int8) RAM_PP(PC);
4376 CHECK_BREAK_BYTE(adr);
4377 AF = xororTable[((AF >> 8) | GetBYTE(adr)) & 0xff];
4378 break;
4379
4380 case 0xbc: /* CP IXH */
4381 tStates += 9;
4382 sim_brk_pend[0] = FALSE;
4383 temp = HIGH_REGISTER(IX);
4384 AF = (AF & ~0x28) | (temp & 0x28);
4385 acu = HIGH_REGISTER(AF);
4386 sum = acu - temp;
4387 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
4388 cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
4389 break;
4390
4391 case 0xbd: /* CP IXL */
4392 tStates += 9;
4393 sim_brk_pend[0] = FALSE;
4394 temp = LOW_REGISTER(IX);
4395 AF = (AF & ~0x28) | (temp & 0x28);
4396 acu = HIGH_REGISTER(AF);
4397 sum = acu - temp;
4398 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
4399 cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
4400 break;
4401
4402 case 0xbe: /* CP (IX+dd) */
4403 tStates += 19;
4404 adr = IX + (int8) RAM_PP(PC);
4405 CHECK_BREAK_BYTE(adr);
4406 temp = GetBYTE(adr);
4407 AF = (AF & ~0x28) | (temp & 0x28);
4408 acu = HIGH_REGISTER(AF);
4409 sum = acu - temp;
4410 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
4411 cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
4412 break;
4413
4414 case 0xcb: /* CB prefix */
4415 adr = IX + (int8) RAM_PP(PC);
4416 switch ((op = GetBYTE(PC)) & 7) {
4417
4418 case 0:
4419 sim_brk_pend[0] = FALSE;
4420 ++PC;
4421 acu = HIGH_REGISTER(BC);
4422 break;
4423
4424 case 1:
4425 sim_brk_pend[0] = FALSE;
4426 ++PC;
4427 acu = LOW_REGISTER(BC);
4428 break;
4429
4430 case 2:
4431 sim_brk_pend[0] = FALSE;
4432 ++PC;
4433 acu = HIGH_REGISTER(DE);
4434 break;
4435
4436 case 3:
4437 sim_brk_pend[0] = FALSE;
4438 ++PC;
4439 acu = LOW_REGISTER(DE);
4440 break;
4441
4442 case 4:
4443 sim_brk_pend[0] = FALSE;
4444 ++PC;
4445 acu = HIGH_REGISTER(HL);
4446 break;
4447
4448 case 5:
4449 sim_brk_pend[0] = FALSE;
4450 ++PC;
4451 acu = LOW_REGISTER(HL);
4452 break;
4453
4454 case 6:
4455 CHECK_BREAK_BYTE(adr);
4456 ++PC;
4457 acu = GetBYTE(adr);
4458 break;
4459
4460 case 7:
4461 sim_brk_pend[0] = FALSE;
4462 ++PC;
4463 acu = HIGH_REGISTER(AF);
4464 break;
4465 }
4466 switch (op & 0xc0) {
4467
4468 case 0x00: /* shift/rotate */
4469 tStates += 23;
4470 switch (op & 0x38) {
4471
4472 case 0x00: /* RLC */
4473 temp = (acu << 1) | (acu >> 7);
4474 cbits = temp & 1;
4475 goto cbshflg2;
4476
4477 case 0x08: /* RRC */
4478 temp = (acu >> 1) | (acu << 7);
4479 cbits = temp & 0x80;
4480 goto cbshflg2;
4481
4482 case 0x10: /* RL */
4483 temp = (acu << 1) | TSTFLAG(C);
4484 cbits = acu & 0x80;
4485 goto cbshflg2;
4486
4487 case 0x18: /* RR */
4488 temp = (acu >> 1) | (TSTFLAG(C) << 7);
4489 cbits = acu & 1;
4490 goto cbshflg2;
4491
4492 case 0x20: /* SLA */
4493 temp = acu << 1;
4494 cbits = acu & 0x80;
4495 goto cbshflg2;
4496
4497 case 0x28: /* SRA */
4498 temp = (acu >> 1) | (acu & 0x80);
4499 cbits = acu & 1;
4500 goto cbshflg2;
4501
4502 case 0x30: /* SLIA */
4503 temp = (acu << 1) | 1;
4504 cbits = acu & 0x80;
4505 goto cbshflg2;
4506
4507 case 0x38: /* SRL */
4508 temp = acu >> 1;
4509 cbits = acu & 1;
4510 cbshflg2:
4511 AF = (AF & ~0xff) | rotateShiftTable[temp & 0xff] | !!cbits;
4512 /* !!cbits == 0 if cbits == 0 !!cbits == 1 if cbits > 0 */
4513 }
4514 break;
4515
4516 case 0x40: /* BIT */
4517 tStates += 20;
4518 if (acu & (1 << ((op >> 3) & 7)))
4519 AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7);
4520 else
4521 AF = (AF & ~0xfe) | 0x54;
4522 if ((op & 7) != 6)
4523 AF |= (acu & 0x28);
4524 temp = acu;
4525 break;
4526
4527 case 0x80: /* RES */
4528 tStates += 23;
4529 temp = acu & ~(1 << ((op >> 3) & 7));
4530 break;
4531
4532 case 0xc0: /* SET */
4533 tStates += 23;
4534 temp = acu | (1 << ((op >> 3) & 7));
4535 break;
4536 }
4537 switch (op & 7) {
4538
4539 case 0:
4540 SET_HIGH_REGISTER(BC, temp);
4541 break;
4542
4543 case 1:
4544 SET_LOW_REGISTER(BC, temp);
4545 break;
4546
4547 case 2:
4548 SET_HIGH_REGISTER(DE, temp);
4549 break;
4550
4551 case 3:
4552 SET_LOW_REGISTER(DE, temp);
4553 break;
4554
4555 case 4:
4556 SET_HIGH_REGISTER(HL, temp);
4557 break;
4558
4559 case 5:
4560 SET_LOW_REGISTER(HL, temp);
4561 break;
4562
4563 case 6:
4564 PutBYTE(adr, temp);
4565 break;
4566
4567 case 7:
4568 SET_HIGH_REGISTER(AF, temp);
4569 break;
4570 }
4571 break;
4572
4573 case 0xe1: /* POP IX */
4574 tStates += 14;
4575 CHECK_BREAK_WORD(SP);
4576 POP(IX);
4577 break;
4578
4579 case 0xe3: /* EX (SP),IX */
4580 tStates += 23;
4581 CHECK_BREAK_WORD(SP);
4582 temp = IX;
4583 POP(IX);
4584 PUSH(temp);
4585 break;
4586
4587 case 0xe5: /* PUSH IX */
4588 tStates += 15;
4589 CHECK_BREAK_WORD(SP - 2);
4590 PUSH(IX);
4591 break;
4592
4593 case 0xe9: /* JP (IX) */
4594 tStates += 8;
4595 sim_brk_pend[0] = FALSE;
4596 PCQ_ENTRY(PCX);
4597 PC = IX;
4598 break;
4599
4600 case 0xf9: /* LD SP,IX */
4601 tStates += 10;
4602 sim_brk_pend[0] = FALSE;
4603 SP = IX;
4604 break;
4605
4606 default: /* ignore DD */
4607 sim_brk_pend[0] = FALSE;
4608 CHECK_CPU_Z80;
4609 PC--;
4610 }
4611 break;
4612
4613 case 0xde: /* SBC A,nn */
4614 tStates += 7;
4615 sim_brk_pend[0] = FALSE;
4616 temp = RAM_PP(PC);
4617 acu = HIGH_REGISTER(AF);
4618 sum = acu - temp - TSTFLAG(C);
4619 cbits = acu ^ temp ^ sum;
4620 AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
4621 break;
4622
4623 case 0xdf: /* RST 18H */
4624 tStates += 11;
4625 CHECK_BREAK_WORD(SP - 2);
4626 PUSH(PC);
4627 PCQ_ENTRY(PCX);
4628 PC = 0x18;
4629 break;
4630
4631 case 0xe0: /* RET PO */
4632 if (TSTFLAG(P)) {
4633 sim_brk_pend[0] = FALSE;
4634 tStates += 5;
4635 }
4636 else {
4637 CHECK_BREAK_WORD(SP);
4638 PCQ_ENTRY(PCX);
4639 POP(PC);
4640 tStates += 11;
4641 }
4642 break;
4643
4644 case 0xe1: /* POP HL */
4645 tStates += 10;
4646 CHECK_BREAK_WORD(SP);
4647 POP(HL);
4648 break;
4649
4650 case 0xe2: /* JP PO,nnnn */
4651 sim_brk_pend[0] = FALSE;
4652 JPC(!TSTFLAG(P)); /* also updates tStates */
4653 break;
4654
4655 case 0xe3: /* EX (SP),HL */
4656 tStates += 19;
4657 CHECK_BREAK_WORD(SP);
4658 temp = HL;
4659 POP(HL);
4660 PUSH(temp);
4661 break;
4662
4663 case 0xe4: /* CALL PO,nnnn */
4664 CALLC(!TSTFLAG(P)); /* also updates tStates */
4665 break;
4666
4667 case 0xe5: /* PUSH HL */
4668 tStates += 11;
4669 CHECK_BREAK_WORD(SP - 2);
4670 PUSH(HL);
4671 break;
4672
4673 case 0xe6: /* AND nn */
4674 tStates += 7;
4675 sim_brk_pend[0] = FALSE;
4676 AF = andTable[((AF >> 8) & RAM_PP(PC)) & 0xff];
4677 break;
4678
4679 case 0xe7: /* RST 20H */
4680 tStates += 11;
4681 CHECK_BREAK_WORD(SP - 2);
4682 PUSH(PC);
4683 PCQ_ENTRY(PCX);
4684 PC = 0x20;
4685 break;
4686
4687 case 0xe8: /* RET PE */
4688 if (TSTFLAG(P)) {
4689 CHECK_BREAK_WORD(SP);
4690 PCQ_ENTRY(PCX);
4691 POP(PC);
4692 tStates += 11;
4693 }
4694 else {
4695 sim_brk_pend[0] = FALSE;
4696 tStates += 5;
4697 }
4698 break;
4699
4700 case 0xe9: /* JP (HL) */
4701 tStates += 4;
4702 sim_brk_pend[0] = FALSE;
4703 PCQ_ENTRY(PCX);
4704 PC = HL;
4705 break;
4706
4707 case 0xea: /* JP PE,nnnn */
4708 sim_brk_pend[0] = FALSE;
4709 JPC(TSTFLAG(P)); /* also updates tStates */
4710 break;
4711
4712 case 0xeb: /* EX DE,HL */
4713 tStates += 4;
4714 sim_brk_pend[0] = FALSE;
4715 temp = HL;
4716 HL = DE;
4717 DE = temp;
4718 break;
4719
4720 case 0xec: /* CALL PE,nnnn */
4721 CALLC(TSTFLAG(P)); /* also updates tStates */
4722 break;
4723
4724 case 0xed: /* ED prefix */
4725 CHECK_CPU_8080;
4726 switch (RAM_PP(PC)) {
4727
4728 case 0x40: /* IN B,(C) */
4729 tStates += 12;
4730 sim_brk_pend[0] = FALSE;
4731 temp = in(LOW_REGISTER(BC));
4732 SET_HIGH_REGISTER(BC, temp);
4733 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
4734 break;
4735
4736 case 0x41: /* OUT (C),B */
4737 tStates += 12;
4738 sim_brk_pend[0] = FALSE;
4739 out(LOW_REGISTER(BC), HIGH_REGISTER(BC));
4740 break;
4741
4742 case 0x42: /* SBC HL,BC */
4743 tStates += 15;
4744 sim_brk_pend[0] = FALSE;
4745 HL &= ADDRMASK;
4746 BC &= ADDRMASK;
4747 sum = HL - BC - TSTFLAG(C);
4748 AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
4749 cbits2Z80Table[((HL ^ BC ^ sum) >> 8) & 0x1ff];
4750 HL = sum;
4751 break;
4752
4753 case 0x43: /* LD (nnnn),BC */
4754 tStates += 20;
4755 temp = GET_WORD(PC);
4756 CHECK_BREAK_WORD(temp);
4757 PutWORD(temp, BC);
4758 PC += 2;
4759 break;
4760
4761 case 0x44: /* NEG */
4762
4763 case 0x4C: /* NEG, unofficial */
4764
4765 case 0x54: /* NEG, unofficial */
4766
4767 case 0x5C: /* NEG, unofficial */
4768
4769 case 0x64: /* NEG, unofficial */
4770
4771 case 0x6C: /* NEG, unofficial */
4772
4773 case 0x74: /* NEG, unofficial */
4774
4775 case 0x7C: /* NEG, unofficial */
4776 tStates += 8;
4777 sim_brk_pend[0] = FALSE;
4778 temp = HIGH_REGISTER(AF);
4779 AF = ((~(AF & 0xff00) + 1) & 0xff00); /* AF = (-(AF & 0xff00) & 0xff00); */
4780 AF |= ((AF >> 8) & 0xa8) | (((AF & 0xff00) == 0) << 6) | negTable[temp];
4781 break;
4782
4783 case 0x45: /* RETN */
4784
4785 case 0x55: /* RETN, unofficial */
4786
4787 case 0x5D: /* RETN, unofficial */
4788
4789 case 0x65: /* RETN, unofficial */
4790
4791 case 0x6D: /* RETN, unofficial */
4792
4793 case 0x75: /* RETN, unofficial */
4794
4795 case 0x7D: /* RETN, unofficial */
4796 tStates += 14;
4797 IFF_S |= IFF_S >> 1;
4798 CHECK_BREAK_WORD(SP);
4799 PCQ_ENTRY(PCX);
4800 POP(PC);
4801 break;
4802
4803 case 0x46: /* IM 0 */
4804 tStates += 8;
4805 sim_brk_pend[0] = FALSE;
4806 /* interrupt mode 0 */
4807 break;
4808
4809 case 0x47: /* LD I,A */
4810 tStates += 9;
4811 sim_brk_pend[0] = FALSE;
4812 IR_S = (IR_S & 0xff) | (AF & ~0xff);
4813 break;
4814
4815 case 0x48: /* IN C,(C) */
4816 tStates += 12;
4817 sim_brk_pend[0] = FALSE;
4818 temp = in(LOW_REGISTER(BC));
4819 SET_LOW_REGISTER(BC, temp);
4820 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
4821 break;
4822
4823 case 0x49: /* OUT (C),C */
4824 tStates += 12;
4825 sim_brk_pend[0] = FALSE;
4826 out(LOW_REGISTER(BC), LOW_REGISTER(BC));
4827 break;
4828
4829 case 0x4a: /* ADC HL,BC */
4830 tStates += 15;
4831 sim_brk_pend[0] = FALSE;
4832 HL &= ADDRMASK;
4833 BC &= ADDRMASK;
4834 sum = HL + BC + TSTFLAG(C);
4835 AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
4836 cbitsZ80Table[(HL ^ BC ^ sum) >> 8];
4837 HL = sum;
4838 break;
4839
4840 case 0x4b: /* LD BC,(nnnn) */
4841 tStates += 20;
4842 temp = GET_WORD(PC);
4843 CHECK_BREAK_WORD(temp);
4844 BC = GET_WORD(temp);
4845 PC += 2;
4846 break;
4847
4848 case 0x4d: /* RETI */
4849 tStates += 14;
4850 IFF_S |= IFF_S >> 1;
4851 CHECK_BREAK_WORD(SP);
4852 PCQ_ENTRY(PCX);
4853 POP(PC);
4854 break;
4855
4856 case 0x4f: /* LD R,A */
4857 tStates += 9;
4858 sim_brk_pend[0] = FALSE;
4859 IR_S = (IR_S & ~0xff) | ((AF >> 8) & 0xff);
4860 break;
4861
4862 case 0x50: /* IN D,(C) */
4863 tStates += 12;
4864 sim_brk_pend[0] = FALSE;
4865 temp = in(LOW_REGISTER(BC));
4866 SET_HIGH_REGISTER(DE, temp);
4867 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
4868 break;
4869
4870 case 0x51: /* OUT (C),D */
4871 tStates += 12;
4872 sim_brk_pend[0] = FALSE;
4873 out(LOW_REGISTER(BC), HIGH_REGISTER(DE));
4874 break;
4875
4876 case 0x52: /* SBC HL,DE */
4877 tStates += 15;
4878 sim_brk_pend[0] = FALSE;
4879 HL &= ADDRMASK;
4880 DE &= ADDRMASK;
4881 sum = HL - DE - TSTFLAG(C);
4882 AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
4883 cbits2Z80Table[((HL ^ DE ^ sum) >> 8) & 0x1ff];
4884 HL = sum;
4885 break;
4886
4887 case 0x53: /* LD (nnnn),DE */
4888 tStates += 20;
4889 temp = GET_WORD(PC);
4890 CHECK_BREAK_WORD(temp);
4891 PutWORD(temp, DE);
4892 PC += 2;
4893 break;
4894
4895 case 0x56: /* IM 1 */
4896 tStates += 8;
4897 sim_brk_pend[0] = FALSE;
4898 /* interrupt mode 1 */
4899 break;
4900
4901 case 0x57: /* LD A,I */
4902 tStates += 9;
4903 sim_brk_pend[0] = FALSE;
4904 AF = (AF & 0x29) | (IR_S & ~0xff) | ((IR_S >> 8) & 0x80) | (((IR_S & ~0xff) == 0) << 6) | ((IFF_S & 2) << 1);
4905 break;
4906
4907 case 0x58: /* IN E,(C) */
4908 tStates += 12;
4909 sim_brk_pend[0] = FALSE;
4910 temp = in(LOW_REGISTER(BC));
4911 SET_LOW_REGISTER(DE, temp);
4912 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
4913 break;
4914
4915 case 0x59: /* OUT (C),E */
4916 tStates += 12;
4917 sim_brk_pend[0] = FALSE;
4918 out(LOW_REGISTER(BC), LOW_REGISTER(DE));
4919 break;
4920
4921 case 0x5a: /* ADC HL,DE */
4922 tStates += 15;
4923 sim_brk_pend[0] = FALSE;
4924 HL &= ADDRMASK;
4925 DE &= ADDRMASK;
4926 sum = HL + DE + TSTFLAG(C);
4927 AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
4928 cbitsZ80Table[(HL ^ DE ^ sum) >> 8];
4929 HL = sum;
4930 break;
4931
4932 case 0x5b: /* LD DE,(nnnn) */
4933 tStates += 20;
4934 temp = GET_WORD(PC);
4935 CHECK_BREAK_WORD(temp);
4936 DE = GET_WORD(temp);
4937 PC += 2;
4938 break;
4939
4940 case 0x5e: /* IM 2 */
4941 tStates += 8;
4942 sim_brk_pend[0] = FALSE;
4943 /* interrupt mode 2 */
4944 break;
4945
4946 case 0x5f: /* LD A,R */
4947 tStates += 9;
4948 sim_brk_pend[0] = FALSE;
4949 AF = (AF & 0x29) | ((IR_S & 0xff) << 8) | (IR_S & 0x80) |
4950 (((IR_S & 0xff) == 0) << 6) | ((IFF_S & 2) << 1);
4951 break;
4952
4953 case 0x60: /* IN H,(C) */
4954 tStates += 12;
4955 sim_brk_pend[0] = FALSE;
4956 temp = in(LOW_REGISTER(BC));
4957 SET_HIGH_REGISTER(HL, temp);
4958 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
4959 break;
4960
4961 case 0x61: /* OUT (C),H */
4962 tStates += 12;
4963 sim_brk_pend[0] = FALSE;
4964 out(LOW_REGISTER(BC), HIGH_REGISTER(HL));
4965 break;
4966
4967 case 0x62: /* SBC HL,HL */
4968 tStates += 15;
4969 sim_brk_pend[0] = FALSE;
4970 HL &= ADDRMASK;
4971 sum = HL - HL - TSTFLAG(C);
4972 AF = (AF & ~0xff) | (((sum & ADDRMASK) == 0) << 6) |
4973 cbits2Z80DupTable[(sum >> 8) & 0x1ff];
4974 HL = sum;
4975 break;
4976
4977 case 0x63: /* LD (nnnn),HL */
4978 tStates += 20;
4979 temp = GET_WORD(PC);
4980 CHECK_BREAK_WORD(temp);
4981 PutWORD(temp, HL);
4982 PC += 2;
4983 break;
4984
4985 case 0x67: /* RRD */
4986 tStates += 18;
4987 sim_brk_pend[0] = FALSE;
4988 temp = GetBYTE(HL);
4989 acu = HIGH_REGISTER(AF);
4990 PutBYTE(HL, HIGH_DIGIT(temp) | (LOW_DIGIT(acu) << 4));
4991 AF = rrdrldTable[(acu & 0xf0) | LOW_DIGIT(temp)] | (AF & 1);
4992 break;
4993
4994 case 0x68: /* IN L,(C) */
4995 tStates += 12;
4996 sim_brk_pend[0] = FALSE;
4997 temp = in(LOW_REGISTER(BC));
4998 SET_LOW_REGISTER(HL, temp);
4999 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
5000 break;
5001
5002 case 0x69: /* OUT (C),L */
5003 tStates += 12;
5004 sim_brk_pend[0] = FALSE;
5005 out(LOW_REGISTER(BC), LOW_REGISTER(HL));
5006 break;
5007
5008 case 0x6a: /* ADC HL,HL */
5009 tStates += 15;
5010 sim_brk_pend[0] = FALSE;
5011 HL &= ADDRMASK;
5012 sum = HL + HL + TSTFLAG(C);
5013 AF = (AF & ~0xff) | (((sum & ADDRMASK) == 0) << 6) |
5014 cbitsZ80DupTable[sum >> 8];
5015 HL = sum;
5016 break;
5017
5018 case 0x6b: /* LD HL,(nnnn) */
5019 tStates += 20;
5020 temp = GET_WORD(PC);
5021 CHECK_BREAK_WORD(temp);
5022 HL = GET_WORD(temp);
5023 PC += 2;
5024 break;
5025
5026 case 0x6f: /* RLD */
5027 tStates += 18;
5028 sim_brk_pend[0] = FALSE;
5029 temp = GetBYTE(HL);
5030 acu = HIGH_REGISTER(AF);
5031 PutBYTE(HL, (LOW_DIGIT(temp) << 4) | LOW_DIGIT(acu));
5032 AF = rrdrldTable[(acu & 0xf0) | HIGH_DIGIT(temp)] | (AF & 1);
5033 break;
5034
5035 case 0x70: /* IN (C) */
5036 tStates += 12;
5037 sim_brk_pend[0] = FALSE;
5038 temp = in(LOW_REGISTER(BC));
5039 SET_LOW_REGISTER(temp, temp);
5040 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
5041 break;
5042
5043 case 0x71: /* OUT (C),0 */
5044 tStates += 12;
5045 sim_brk_pend[0] = FALSE;
5046 out(LOW_REGISTER(BC), 0);
5047 break;
5048
5049 case 0x72: /* SBC HL,SP */
5050 tStates += 15;
5051 sim_brk_pend[0] = FALSE;
5052 HL &= ADDRMASK;
5053 SP &= ADDRMASK;
5054 sum = HL - SP - TSTFLAG(C);
5055 AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
5056 cbits2Z80Table[((HL ^ SP ^ sum) >> 8) & 0x1ff];
5057 HL = sum;
5058 break;
5059
5060 case 0x73: /* LD (nnnn),SP */
5061 tStates += 20;
5062 temp = GET_WORD(PC);
5063 CHECK_BREAK_WORD(temp);
5064 PutWORD(temp, SP);
5065 PC += 2;
5066 break;
5067
5068 case 0x78: /* IN A,(C) */
5069 tStates += 12;
5070 sim_brk_pend[0] = FALSE;
5071 temp = in(LOW_REGISTER(BC));
5072 SET_HIGH_REGISTER(AF, temp);
5073 AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
5074 break;
5075
5076 case 0x79: /* OUT (C),A */
5077 tStates += 12;
5078 sim_brk_pend[0] = FALSE;
5079 out(LOW_REGISTER(BC), HIGH_REGISTER(AF));
5080 break;
5081
5082 case 0x7a: /* ADC HL,SP */
5083 tStates += 15;
5084 sim_brk_pend[0] = FALSE;
5085 HL &= ADDRMASK;
5086 SP &= ADDRMASK;
5087 sum = HL + SP + TSTFLAG(C);
5088 AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
5089 cbitsZ80Table[(HL ^ SP ^ sum) >> 8];
5090 HL = sum;
5091 break;
5092
5093 case 0x7b: /* LD SP,(nnnn) */
5094 tStates += 20;
5095 temp = GET_WORD(PC);
5096 CHECK_BREAK_WORD(temp);
5097 SP = GET_WORD(temp);
5098 PC += 2;
5099 break;
5100
5101 case 0xa0: /* LDI */
5102 tStates += 16;
5103 CHECK_BREAK_TWO_BYTES(HL, DE);
5104 acu = RAM_PP(HL);
5105 PUT_BYTE_PP(DE, acu);
5106 acu += HIGH_REGISTER(AF);
5107 AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) |
5108 (((--BC & ADDRMASK) != 0) << 2);
5109 break;
5110
5111 case 0xa1: /* CPI */
5112 tStates += 16;
5113 CHECK_BREAK_BYTE(HL);
5114 acu = HIGH_REGISTER(AF);
5115 temp = RAM_PP(HL);
5116 sum = acu - temp;
5117 cbits = acu ^ temp ^ sum;
5118 AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
5119 (((sum - ((cbits & 16) >> 4)) & 2) << 4) | (cbits & 16) |
5120 ((sum - ((cbits >> 4) & 1)) & 8) |
5121 ((--BC & ADDRMASK) != 0) << 2 | 2;
5122 if ((sum & 15) == 8 && (cbits & 16) != 0)
5123 AF &= ~8;
5124 break;
5125
5126 /* SF, ZF, YF, XF flags are affected by decreasing register B, as in DEC B.
5127 NF flag A is copy of bit 7 of the value read from or written to an I/O port.
5128 INI/INIR/IND/INDR use the C flag in stead of the L register. There is a
5129 catch though, because not the value of C is used, but C + 1 if it's INI/INIR or
5130 C - 1 if it's IND/INDR. So, first of all INI/INIR:
5131 HF and CF Both set if ((HL) + ((C + 1) & 255) > 255)
5132 PF The parity of (((HL) + ((C + 1) & 255)) & 7) xor B) */
5133 case 0xa2: /* INI */
5134 tStates += 16;
5135 CHECK_BREAK_BYTE(HL);
5136 acu = in(LOW_REGISTER(BC));
5137 PutBYTE(HL, acu);
5138 ++HL;
5139 temp = HIGH_REGISTER(BC);
5140 BC -= 0x100;
5141 INOUTFLAGS_NONZERO((LOW_REGISTER(BC) + 1) & 0xff);
5142 break;
5143
5144 /* SF, ZF, YF, XF flags are affected by decreasing register B, as in DEC B.
5145 NF flag A is copy of bit 7 of the value read from or written to an I/O port.
5146 And now the for OUTI/OTIR/OUTD/OTDR instructions. Take state of the L
5147 after the increment or decrement of HL; add the value written to the I/O port
5148 to; call that k for now. If k > 255, then the CF and HF flags are set. The PF
5149 flags is set like the parity of k bitwise and'ed with 7, bitwise xor'ed with B.
5150 HF and CF Both set if ((HL) + L > 255)
5151 PF The parity of ((((HL) + L) & 7) xor B) */
5152 case 0xa3: /* OUTI */
5153 tStates += 16;
5154 CHECK_BREAK_BYTE(HL);
5155 acu = GetBYTE(HL);
5156 out(LOW_REGISTER(BC), acu);
5157 ++HL;
5158 temp = HIGH_REGISTER(BC);
5159 BC -= 0x100;
5160 INOUTFLAGS_NONZERO(LOW_REGISTER(HL));
5161 break;
5162
5163 case 0xa8: /* LDD */
5164 tStates += 16;
5165 CHECK_BREAK_TWO_BYTES(HL, DE);
5166 acu = RAM_MM(HL);
5167 PUT_BYTE_MM(DE, acu);
5168 acu += HIGH_REGISTER(AF);
5169 AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) |
5170 (((--BC & ADDRMASK) != 0) << 2);
5171 break;
5172
5173 case 0xa9: /* CPD */
5174 tStates += 16;
5175 CHECK_BREAK_BYTE(HL);
5176 acu = HIGH_REGISTER(AF);
5177 temp = RAM_MM(HL);
5178 sum = acu - temp;
5179 cbits = acu ^ temp ^ sum;
5180 AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
5181 (((sum - ((cbits & 16) >> 4)) & 2) << 4) | (cbits & 16) |
5182 ((sum - ((cbits >> 4) & 1)) & 8) |
5183 ((--BC & ADDRMASK) != 0) << 2 | 2;
5184 if ((sum & 15) == 8 && (cbits & 16) != 0)
5185 AF &= ~8;
5186 break;
5187
5188 /* SF, ZF, YF, XF flags are affected by decreasing register B, as in DEC B.
5189 NF flag A is copy of bit 7 of the value read from or written to an I/O port.
5190 INI/INIR/IND/INDR use the C flag in stead of the L register. There is a
5191 catch though, because not the value of C is used, but C + 1 if it's INI/INIR or
5192 C - 1 if it's IND/INDR. And last IND/INDR:
5193 HF and CF Both set if ((HL) + ((C - 1) & 255) > 255)
5194 PF The parity of (((HL) + ((C - 1) & 255)) & 7) xor B) */
5195 case 0xaa: /* IND */
5196 tStates += 16;
5197 CHECK_BREAK_BYTE(HL);
5198 acu = in(LOW_REGISTER(BC));
5199 PutBYTE(HL, acu);
5200 --HL;
5201 temp = HIGH_REGISTER(BC);
5202 BC -= 0x100;
5203 INOUTFLAGS_NONZERO((LOW_REGISTER(BC) - 1) & 0xff);
5204 break;
5205
5206 case 0xab: /* OUTD */
5207 tStates += 16;
5208 CHECK_BREAK_BYTE(HL);
5209 acu = GetBYTE(HL);
5210 out(LOW_REGISTER(BC), acu);
5211 --HL;
5212 temp = HIGH_REGISTER(BC);
5213 BC -= 0x100;
5214 INOUTFLAGS_NONZERO(LOW_REGISTER(HL));
5215 break;
5216
5217 case 0xb0: /* LDIR */
5218 tStates -= 5;
5219 BC &= ADDRMASK;
5220 if (BC == 0)
5221 BC = 0x10000;
5222 do {
5223 tStates += 21;
5224 CHECK_BREAK_TWO_BYTES(HL, DE);
5225 acu = RAM_PP(HL);
5226 PUT_BYTE_PP(DE, acu);
5227 } while (--BC);
5228 acu += HIGH_REGISTER(AF);
5229 AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4);
5230 break;
5231
5232 case 0xb1: /* CPIR */
5233 tStates -= 5;
5234 acu = HIGH_REGISTER(AF);
5235 BC &= ADDRMASK;
5236 if (BC == 0)
5237 BC = 0x10000;
5238 do {
5239 tStates += 21;
5240 CHECK_BREAK_BYTE(HL);
5241 temp = RAM_PP(HL);
5242 op = --BC != 0;
5243 sum = acu - temp;
5244 } while (op && sum != 0);
5245 cbits = acu ^ temp ^ sum;
5246 AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
5247 (((sum - ((cbits & 16) >> 4)) & 2) << 4) |
5248 (cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) |
5249 op << 2 | 2;
5250 if ((sum & 15) == 8 && (cbits & 16) != 0)
5251 AF &= ~8;
5252 break;
5253
5254 case 0xb2: /* INIR */
5255 tStates -= 5;
5256 temp = HIGH_REGISTER(BC);
5257 if (temp == 0)
5258 temp = 0x100;
5259 do {
5260 tStates += 21;
5261 CHECK_BREAK_BYTE(HL);
5262 acu = in(LOW_REGISTER(BC));
5263 PutBYTE(HL, acu);
5264 ++HL;
5265 } while (--temp);
5266 temp = HIGH_REGISTER(BC);
5267 SET_HIGH_REGISTER(BC, 0);
5268 INOUTFLAGS_ZERO((LOW_REGISTER(BC) + 1) & 0xff);
5269 break;
5270
5271 case 0xb3: /* OTIR */
5272 tStates -= 5;
5273 temp = HIGH_REGISTER(BC);
5274 if (temp == 0)
5275 temp = 0x100;
5276 do {
5277 tStates += 21;
5278 CHECK_BREAK_BYTE(HL);
5279 acu = GetBYTE(HL);
5280 out(LOW_REGISTER(BC), acu);
5281 ++HL;
5282 } while (--temp);
5283 temp = HIGH_REGISTER(BC);
5284 SET_HIGH_REGISTER(BC, 0);
5285 INOUTFLAGS_ZERO(LOW_REGISTER(HL));
5286 break;
5287
5288 case 0xb8: /* LDDR */
5289 tStates -= 5;
5290 BC &= ADDRMASK;
5291 if (BC == 0)
5292 BC = 0x10000;
5293 do {
5294 tStates += 21;
5295 CHECK_BREAK_TWO_BYTES(HL, DE);
5296 acu = RAM_MM(HL);
5297 PUT_BYTE_MM(DE, acu);
5298 } while (--BC);
5299 acu += HIGH_REGISTER(AF);
5300 AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4);
5301 break;
5302
5303 case 0xb9: /* CPDR */
5304 tStates -= 5;
5305 acu = HIGH_REGISTER(AF);
5306 BC &= ADDRMASK;
5307 if (BC == 0)
5308 BC = 0x10000;
5309 do {
5310 tStates += 21;
5311 CHECK_BREAK_BYTE(HL);
5312 temp = RAM_MM(HL);
5313 op = --BC != 0;
5314 sum = acu - temp;
5315 } while (op && sum != 0);
5316 cbits = acu ^ temp ^ sum;
5317 AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
5318 (((sum - ((cbits & 16) >> 4)) & 2) << 4) |
5319 (cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) |
5320 op << 2 | 2;
5321 if ((sum & 15) == 8 && (cbits & 16) != 0)
5322 AF &= ~8;
5323 break;
5324
5325 case 0xba: /* INDR */
5326 tStates -= 5;
5327 temp = HIGH_REGISTER(BC);
5328 if (temp == 0)
5329 temp = 0x100;
5330 do {
5331 tStates += 21;
5332 CHECK_BREAK_BYTE(HL);
5333 acu = in(LOW_REGISTER(BC));
5334 PutBYTE(HL, acu);
5335 --HL;
5336 } while (--temp);
5337 temp = HIGH_REGISTER(BC);
5338 SET_HIGH_REGISTER(BC, 0);
5339 INOUTFLAGS_ZERO((LOW_REGISTER(BC) - 1) & 0xff);
5340 break;
5341
5342 case 0xbb: /* OTDR */
5343 tStates -= 5;
5344 temp = HIGH_REGISTER(BC);
5345 if (temp == 0)
5346 temp = 0x100;
5347 do {
5348 tStates += 21;
5349 CHECK_BREAK_BYTE(HL);
5350 acu = GetBYTE(HL);
5351 out(LOW_REGISTER(BC), acu);
5352 --HL;
5353 } while (--temp);
5354 temp = HIGH_REGISTER(BC);
5355 SET_HIGH_REGISTER(BC, 0);
5356 INOUTFLAGS_ZERO(LOW_REGISTER(HL));
5357 break;
5358
5359 default: /* ignore ED and following byte */
5360 sim_brk_pend[0] = FALSE;
5361 CHECK_CPU_Z80;
5362 }
5363 break;
5364
5365 case 0xee: /* XOR nn */
5366 tStates += 7;
5367 sim_brk_pend[0] = FALSE;
5368 AF = xororTable[((AF >> 8) ^ RAM_PP(PC)) & 0xff];
5369 break;
5370
5371 case 0xef: /* RST 28H */
5372 tStates += 11;
5373 CHECK_BREAK_WORD(SP - 2);
5374 PUSH(PC);
5375 PCQ_ENTRY(PCX);
5376 PC = 0x28;
5377 break;
5378
5379 case 0xf0: /* RET P */
5380 if (TSTFLAG(S)) {
5381 sim_brk_pend[0] = FALSE;
5382 tStates += 5;
5383 }
5384 else {
5385 CHECK_BREAK_WORD(SP);
5386 PCQ_ENTRY(PCX);
5387 POP(PC);
5388 tStates += 11;
5389 }
5390 break;
5391
5392 case 0xf1: /* POP AF */
5393 tStates += 10;
5394 CHECK_BREAK_WORD(SP);
5395 POP(AF);
5396 break;
5397
5398 case 0xf2: /* JP P,nnnn */
5399 sim_brk_pend[0] = FALSE;
5400 JPC(!TSTFLAG(S)); /* also updates tStates */
5401 break;
5402
5403 case 0xf3: /* DI */
5404 tStates += 4;
5405 sim_brk_pend[0] = FALSE;
5406 IFF_S = 0;
5407 break;
5408
5409 case 0xf4: /* CALL P,nnnn */
5410 CALLC(!TSTFLAG(S)); /* also updates tStates */
5411 break;
5412
5413 case 0xf5: /* PUSH AF */
5414 tStates += 11;
5415 CHECK_BREAK_WORD(SP - 2);
5416 PUSH(AF);
5417 break;
5418
5419 case 0xf6: /* OR nn */
5420 tStates += 7;
5421 sim_brk_pend[0] = FALSE;
5422 AF = xororTable[((AF >> 8) | RAM_PP(PC)) & 0xff];
5423 break;
5424
5425 case 0xf7: /* RST 30H */
5426 tStates += 11;
5427 CHECK_BREAK_WORD(SP - 2);
5428 PUSH(PC);
5429 PCQ_ENTRY(PCX);
5430 PC = 0x30;
5431 break;
5432
5433 case 0xf8: /* RET M */
5434 if (TSTFLAG(S)) {
5435 CHECK_BREAK_WORD(SP);
5436 PCQ_ENTRY(PCX);
5437 POP(PC);
5438 tStates += 11;
5439 }
5440 else {
5441 sim_brk_pend[0] = FALSE;
5442 tStates += 5;
5443 }
5444 break;
5445
5446 case 0xf9: /* LD SP,HL */
5447 tStates += 6;
5448 sim_brk_pend[0] = FALSE;
5449 SP = HL;
5450 break;
5451
5452 case 0xfa: /* JP M,nnnn */
5453 sim_brk_pend[0] = FALSE;
5454 JPC(TSTFLAG(S)); /* also updates tStates */
5455 break;
5456
5457 case 0xfb: /* EI */
5458 tStates += 4;
5459 sim_brk_pend[0] = FALSE;
5460 IFF_S = 3;
5461 break;
5462
5463 case 0xfc: /* CALL M,nnnn */
5464 CALLC(TSTFLAG(S)); /* also updates tStates */
5465 break;
5466
5467 case 0xfd: /* FD prefix */
5468 CHECK_CPU_8080;
5469 switch (RAM_PP(PC)) {
5470
5471 case 0x09: /* ADD IY,BC */
5472 tStates += 15;
5473 sim_brk_pend[0] = FALSE;
5474 IY &= ADDRMASK;
5475 BC &= ADDRMASK;
5476 sum = IY + BC;
5477 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IY ^ BC ^ sum) >> 8];
5478 IY = sum;
5479 break;
5480
5481 case 0x19: /* ADD IY,DE */
5482 tStates += 15;
5483 sim_brk_pend[0] = FALSE;
5484 IY &= ADDRMASK;
5485 DE &= ADDRMASK;
5486 sum = IY + DE;
5487 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IY ^ DE ^ sum) >> 8];
5488 IY = sum;
5489 break;
5490
5491 case 0x21: /* LD IY,nnnn */
5492 tStates += 14;
5493 sim_brk_pend[0] = FALSE;
5494 IY = GET_WORD(PC);
5495 PC += 2;
5496 break;
5497
5498 case 0x22: /* LD (nnnn),IY */
5499 tStates += 20;
5500 temp = GET_WORD(PC);
5501 CHECK_BREAK_WORD(temp);
5502 PutWORD(temp, IY);
5503 PC += 2;
5504 break;
5505
5506 case 0x23: /* INC IY */
5507 tStates += 10;
5508 sim_brk_pend[0] = FALSE;
5509 ++IY;
5510 break;
5511
5512 case 0x24: /* INC IYH */
5513 tStates += 9;
5514 sim_brk_pend[0] = FALSE;
5515 IY += 0x100;
5516 AF = (AF & ~0xfe) | incZ80Table[HIGH_REGISTER(IY)];
5517 break;
5518
5519 case 0x25: /* DEC IYH */
5520 tStates += 9;
5521 sim_brk_pend[0] = FALSE;
5522 IY -= 0x100;
5523 AF = (AF & ~0xfe) | decZ80Table[HIGH_REGISTER(IY)];
5524 break;
5525
5526 case 0x26: /* LD IYH,nn */
5527 tStates += 9;
5528 sim_brk_pend[0] = FALSE;
5529 SET_HIGH_REGISTER(IY, RAM_PP(PC));
5530 break;
5531
5532 case 0x29: /* ADD IY,IY */
5533 tStates += 15;
5534 sim_brk_pend[0] = FALSE;
5535 IY &= ADDRMASK;
5536 sum = IY + IY;
5537 AF = (AF & ~0x3b) | cbitsDup16Table[sum >> 8];
5538 IY = sum;
5539 break;
5540
5541 case 0x2a: /* LD IY,(nnnn) */
5542 tStates += 20;
5543 temp = GET_WORD(PC);
5544 CHECK_BREAK_WORD(temp);
5545 IY = GET_WORD(temp);
5546 PC += 2;
5547 break;
5548
5549 case 0x2b: /* DEC IY */
5550 tStates += 10;
5551 sim_brk_pend[0] = FALSE;
5552 --IY;
5553 break;
5554
5555 case 0x2c: /* INC IYL */
5556 tStates += 9;
5557 sim_brk_pend[0] = FALSE;
5558 temp = LOW_REGISTER(IY) + 1;
5559 SET_LOW_REGISTER(IY, temp);
5560 AF = (AF & ~0xfe) | incZ80Table[temp];
5561 break;
5562
5563 case 0x2d: /* DEC IYL */
5564 tStates += 9;
5565 sim_brk_pend[0] = FALSE;
5566 temp = LOW_REGISTER(IY) - 1;
5567 SET_LOW_REGISTER(IY, temp);
5568 AF = (AF & ~0xfe) | decZ80Table[temp & 0xff];
5569 break;
5570
5571 case 0x2e: /* LD IYL,nn */
5572 tStates += 9;
5573 sim_brk_pend[0] = FALSE;
5574 SET_LOW_REGISTER(IY, RAM_PP(PC));
5575 break;
5576
5577 case 0x34: /* INC (IY+dd) */
5578 tStates += 23;
5579 adr = IY + (int8) RAM_PP(PC);
5580 CHECK_BREAK_BYTE(adr);
5581 temp = GetBYTE(adr) + 1;
5582 PutBYTE(adr, temp);
5583 AF = (AF & ~0xfe) | incZ80Table[temp];
5584 break;
5585
5586 case 0x35: /* DEC (IY+dd) */
5587 tStates += 23;
5588 adr = IY + (int8) RAM_PP(PC);
5589 CHECK_BREAK_BYTE(adr);
5590 temp = GetBYTE(adr) - 1;
5591 PutBYTE(adr, temp);
5592 AF = (AF & ~0xfe) | decZ80Table[temp & 0xff];
5593 break;
5594
5595 case 0x36: /* LD (IY+dd),nn */
5596 tStates += 19;
5597 adr = IY + (int8) RAM_PP(PC);
5598 CHECK_BREAK_BYTE(adr);
5599 PutBYTE(adr, RAM_PP(PC));
5600 break;
5601
5602 case 0x39: /* ADD IY,SP */
5603 tStates += 15;
5604 sim_brk_pend[0] = FALSE;
5605 IY &= ADDRMASK;
5606 SP &= ADDRMASK;
5607 sum = IY + SP;
5608 AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IY ^ SP ^ sum) >> 8];
5609 IY = sum;
5610 break;
5611
5612 case 0x44: /* LD B,IYH */
5613 tStates += 9;
5614 sim_brk_pend[0] = FALSE;
5615 SET_HIGH_REGISTER(BC, HIGH_REGISTER(IY));
5616 break;
5617
5618 case 0x45: /* LD B,IYL */
5619 tStates += 9;
5620 sim_brk_pend[0] = FALSE;
5621 SET_HIGH_REGISTER(BC, LOW_REGISTER(IY));
5622 break;
5623
5624 case 0x46: /* LD B,(IY+dd) */
5625 tStates += 19;
5626 adr = IY + (int8) RAM_PP(PC);
5627 CHECK_BREAK_BYTE(adr);
5628 SET_HIGH_REGISTER(BC, GetBYTE(adr));
5629 break;
5630
5631 case 0x4c: /* LD C,IYH */
5632 tStates += 9;
5633 sim_brk_pend[0] = FALSE;
5634 SET_LOW_REGISTER(BC, HIGH_REGISTER(IY));
5635 break;
5636
5637 case 0x4d: /* LD C,IYL */
5638 tStates += 9;
5639 sim_brk_pend[0] = FALSE;
5640 SET_LOW_REGISTER(BC, LOW_REGISTER(IY));
5641 break;
5642
5643 case 0x4e: /* LD C,(IY+dd) */
5644 tStates += 19;
5645 adr = IY + (int8) RAM_PP(PC);
5646 CHECK_BREAK_BYTE(adr);
5647 SET_LOW_REGISTER(BC, GetBYTE(adr));
5648 break;
5649
5650 case 0x54: /* LD D,IYH */
5651 tStates += 9;
5652 sim_brk_pend[0] = FALSE;
5653 SET_HIGH_REGISTER(DE, HIGH_REGISTER(IY));
5654 break;
5655
5656 case 0x55: /* LD D,IYL */
5657 tStates += 9;
5658 sim_brk_pend[0] = FALSE;
5659 SET_HIGH_REGISTER(DE, LOW_REGISTER(IY));
5660 break;
5661
5662 case 0x56: /* LD D,(IY+dd) */
5663 tStates += 19;
5664 adr = IY + (int8) RAM_PP(PC);
5665 CHECK_BREAK_BYTE(adr);
5666 SET_HIGH_REGISTER(DE, GetBYTE(adr));
5667 break;
5668
5669 case 0x5c: /* LD E,IYH */
5670 tStates += 9;
5671 sim_brk_pend[0] = FALSE;
5672 SET_LOW_REGISTER(DE, HIGH_REGISTER(IY));
5673 break;
5674
5675 case 0x5d: /* LD E,IYL */
5676 tStates += 9;
5677 sim_brk_pend[0] = FALSE;
5678 SET_LOW_REGISTER(DE, LOW_REGISTER(IY));
5679 break;
5680
5681 case 0x5e: /* LD E,(IY+dd) */
5682 tStates += 19;
5683 adr = IY + (int8) RAM_PP(PC);
5684 CHECK_BREAK_BYTE(adr);
5685 SET_LOW_REGISTER(DE, GetBYTE(adr));
5686 break;
5687
5688 case 0x60: /* LD IYH,B */
5689 tStates += 9;
5690 sim_brk_pend[0] = FALSE;
5691 SET_HIGH_REGISTER(IY, HIGH_REGISTER(BC));
5692 break;
5693
5694 case 0x61: /* LD IYH,C */
5695 tStates += 9;
5696 sim_brk_pend[0] = FALSE;
5697 SET_HIGH_REGISTER(IY, LOW_REGISTER(BC));
5698 break;
5699
5700 case 0x62: /* LD IYH,D */
5701 tStates += 9;
5702 sim_brk_pend[0] = FALSE;
5703 SET_HIGH_REGISTER(IY, HIGH_REGISTER(DE));
5704 break;
5705
5706 case 0x63: /* LD IYH,E */
5707 tStates += 9;
5708 sim_brk_pend[0] = FALSE;
5709 SET_HIGH_REGISTER(IY, LOW_REGISTER(DE));
5710 break;
5711
5712 case 0x64: /* LD IYH,IYH */
5713 tStates += 9;
5714 sim_brk_pend[0] = FALSE; /* nop */
5715 break;
5716
5717 case 0x65: /* LD IYH,IYL */
5718 tStates += 9;
5719 sim_brk_pend[0] = FALSE;
5720 SET_HIGH_REGISTER(IY, LOW_REGISTER(IY));
5721 break;
5722
5723 case 0x66: /* LD H,(IY+dd) */
5724 tStates += 19;
5725 adr = IY + (int8) RAM_PP(PC);
5726 CHECK_BREAK_BYTE(adr);
5727 SET_HIGH_REGISTER(HL, GetBYTE(adr));
5728 break;
5729
5730 case 0x67: /* LD IYH,A */
5731 tStates += 9;
5732 sim_brk_pend[0] = FALSE;
5733 SET_HIGH_REGISTER(IY, HIGH_REGISTER(AF));
5734 break;
5735
5736 case 0x68: /* LD IYL,B */
5737 tStates += 9;
5738 sim_brk_pend[0] = FALSE;
5739 SET_LOW_REGISTER(IY, HIGH_REGISTER(BC));
5740 break;
5741
5742 case 0x69: /* LD IYL,C */
5743 tStates += 9;
5744 sim_brk_pend[0] = FALSE;
5745 SET_LOW_REGISTER(IY, LOW_REGISTER(BC));
5746 break;
5747
5748 case 0x6a: /* LD IYL,D */
5749 tStates += 9;
5750 sim_brk_pend[0] = FALSE;
5751 SET_LOW_REGISTER(IY, HIGH_REGISTER(DE));
5752 break;
5753
5754 case 0x6b: /* LD IYL,E */
5755 tStates += 9;
5756 sim_brk_pend[0] = FALSE;
5757 SET_LOW_REGISTER(IY, LOW_REGISTER(DE));
5758 break;
5759
5760 case 0x6c: /* LD IYL,IYH */
5761 tStates += 9;
5762 sim_brk_pend[0] = FALSE;
5763 SET_LOW_REGISTER(IY, HIGH_REGISTER(IY));
5764 break;
5765
5766 case 0x6d: /* LD IYL,IYL */
5767 tStates += 9;
5768 sim_brk_pend[0] = FALSE; /* nop */
5769 break;
5770
5771 case 0x6e: /* LD L,(IY+dd) */
5772 tStates += 19;
5773 adr = IY + (int8) RAM_PP(PC);
5774 CHECK_BREAK_BYTE(adr);
5775 SET_LOW_REGISTER(HL, GetBYTE(adr));
5776 break;
5777
5778 case 0x6f: /* LD IYL,A */
5779 tStates += 9;
5780 sim_brk_pend[0] = FALSE;
5781 SET_LOW_REGISTER(IY, HIGH_REGISTER(AF));
5782 break;
5783
5784 case 0x70: /* LD (IY+dd),B */
5785 tStates += 19;
5786 adr = IY + (int8) RAM_PP(PC);
5787 CHECK_BREAK_BYTE(adr);
5788 PutBYTE(adr, HIGH_REGISTER(BC));
5789 break;
5790
5791 case 0x71: /* LD (IY+dd),C */
5792 tStates += 19;
5793 adr = IY + (int8) RAM_PP(PC);
5794 CHECK_BREAK_BYTE(adr);
5795 PutBYTE(adr, LOW_REGISTER(BC));
5796 break;
5797
5798 case 0x72: /* LD (IY+dd),D */
5799 tStates += 19;
5800 adr = IY + (int8) RAM_PP(PC);
5801 CHECK_BREAK_BYTE(adr);
5802 PutBYTE(adr, HIGH_REGISTER(DE));
5803 break;
5804
5805 case 0x73: /* LD (IY+dd),E */
5806 tStates += 19;
5807 adr = IY + (int8) RAM_PP(PC);
5808 CHECK_BREAK_BYTE(adr);
5809 PutBYTE(adr, LOW_REGISTER(DE));
5810 break;
5811
5812 case 0x74: /* LD (IY+dd),H */
5813 tStates += 19;
5814 adr = IY + (int8) RAM_PP(PC);
5815 CHECK_BREAK_BYTE(adr);
5816 PutBYTE(adr, HIGH_REGISTER(HL));
5817 break;
5818
5819 case 0x75: /* LD (IY+dd),L */
5820 tStates += 19;
5821 adr = IY + (int8) RAM_PP(PC);
5822 CHECK_BREAK_BYTE(adr);
5823 PutBYTE(adr, LOW_REGISTER(HL));
5824 break;
5825
5826 case 0x77: /* LD (IY+dd),A */
5827 tStates += 19;
5828 adr = IY + (int8) RAM_PP(PC);
5829 CHECK_BREAK_BYTE(adr);
5830 PutBYTE(adr, HIGH_REGISTER(AF));
5831 break;
5832
5833 case 0x7c: /* LD A,IYH */
5834 tStates += 9;
5835 sim_brk_pend[0] = FALSE;
5836 SET_HIGH_REGISTER(AF, HIGH_REGISTER(IY));
5837 break;
5838
5839 case 0x7d: /* LD A,IYL */
5840 tStates += 9;
5841 sim_brk_pend[0] = FALSE;
5842 SET_HIGH_REGISTER(AF, LOW_REGISTER(IY));
5843 break;
5844
5845 case 0x7e: /* LD A,(IY+dd) */
5846 tStates += 19;
5847 adr = IY + (int8) RAM_PP(PC);
5848 CHECK_BREAK_BYTE(adr);
5849 SET_HIGH_REGISTER(AF, GetBYTE(adr));
5850 break;
5851
5852 case 0x84: /* ADD A,IYH */
5853 tStates += 9;
5854 sim_brk_pend[0] = FALSE;
5855 temp = HIGH_REGISTER(IY);
5856 acu = HIGH_REGISTER(AF);
5857 sum = acu + temp;
5858 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
5859 break;
5860
5861 case 0x85: /* ADD A,IYL */
5862 tStates += 9;
5863 sim_brk_pend[0] = FALSE;
5864 temp = LOW_REGISTER(IY);
5865 acu = HIGH_REGISTER(AF);
5866 sum = acu + temp;
5867 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
5868 break;
5869
5870 case 0x86: /* ADD A,(IY+dd) */
5871 tStates += 19;
5872 adr = IY + (int8) RAM_PP(PC);
5873 CHECK_BREAK_BYTE(adr);
5874 temp = GetBYTE(adr);
5875 acu = HIGH_REGISTER(AF);
5876 sum = acu + temp;
5877 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
5878 break;
5879
5880 case 0x8c: /* ADC A,IYH */
5881 tStates += 9;
5882 sim_brk_pend[0] = FALSE;
5883 temp = HIGH_REGISTER(IY);
5884 acu = HIGH_REGISTER(AF);
5885 sum = acu + temp + TSTFLAG(C);
5886 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
5887 break;
5888
5889 case 0x8d: /* ADC A,IYL */
5890 tStates += 9;
5891 sim_brk_pend[0] = FALSE;
5892 temp = LOW_REGISTER(IY);
5893 acu = HIGH_REGISTER(AF);
5894 sum = acu + temp + TSTFLAG(C);
5895 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
5896 break;
5897
5898 case 0x8e: /* ADC A,(IY+dd) */
5899 tStates += 19;
5900 adr = IY + (int8) RAM_PP(PC);
5901 CHECK_BREAK_BYTE(adr);
5902 temp = GetBYTE(adr);
5903 acu = HIGH_REGISTER(AF);
5904 sum = acu + temp + TSTFLAG(C);
5905 AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
5906 break;
5907
5908 case 0x96: /* SUB (IY+dd) */
5909 tStates += 19;
5910 adr = IY + (int8) RAM_PP(PC);
5911 CHECK_BREAK_BYTE(adr);
5912 temp = GetBYTE(adr);
5913 acu = HIGH_REGISTER(AF);
5914 sum = acu - temp;
5915 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
5916 break;
5917
5918 case 0x94: /* SUB IYH */
5919 SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */
5920
5921 case 0x9c: /* SBC A,IYH */
5922 tStates += 9;
5923 sim_brk_pend[0] = FALSE;
5924 temp = HIGH_REGISTER(IY);
5925 acu = HIGH_REGISTER(AF);
5926 sum = acu - temp - TSTFLAG(C);
5927 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
5928 break;
5929
5930 case 0x95: /* SUB IYL */
5931 SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */
5932
5933 case 0x9d: /* SBC A,IYL */
5934 tStates += 9;
5935 sim_brk_pend[0] = FALSE;
5936 temp = LOW_REGISTER(IY);
5937 acu = HIGH_REGISTER(AF);
5938 sum = acu - temp - TSTFLAG(C);
5939 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
5940 break;
5941
5942 case 0x9e: /* SBC A,(IY+dd) */
5943 tStates += 19;
5944 adr = IY + (int8) RAM_PP(PC);
5945 CHECK_BREAK_BYTE(adr);
5946 temp = GetBYTE(adr);
5947 acu = HIGH_REGISTER(AF);
5948 sum = acu - temp - TSTFLAG(C);
5949 AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
5950 break;
5951
5952 case 0xa4: /* AND IYH */
5953 tStates += 9;
5954 sim_brk_pend[0] = FALSE;
5955 AF = andTable[((AF & IY) >> 8) & 0xff];
5956 break;
5957
5958 case 0xa5: /* AND IYL */
5959 tStates += 9;
5960 sim_brk_pend[0] = FALSE;
5961 AF = andTable[((AF >> 8) & IY) & 0xff];
5962 break;
5963
5964 case 0xa6: /* AND (IY+dd) */
5965 tStates += 19;
5966 adr = IY + (int8) RAM_PP(PC);
5967 CHECK_BREAK_BYTE(adr);
5968 AF = andTable[((AF >> 8) & GetBYTE(adr)) & 0xff];
5969 break;
5970
5971 case 0xac: /* XOR IYH */
5972 tStates += 9;
5973 sim_brk_pend[0] = FALSE;
5974 AF = xororTable[((AF ^ IY) >> 8) & 0xff];
5975 break;
5976
5977 case 0xad: /* XOR IYL */
5978 tStates += 9;
5979 sim_brk_pend[0] = FALSE;
5980 AF = xororTable[((AF >> 8) ^ IY) & 0xff];
5981 break;
5982
5983 case 0xae: /* XOR (IY+dd) */
5984 tStates += 19;
5985 adr = IY + (int8) RAM_PP(PC);
5986 CHECK_BREAK_BYTE(adr);
5987 AF = xororTable[((AF >> 8) ^ GetBYTE(adr)) & 0xff];
5988 break;
5989
5990 case 0xb4: /* OR IYH */
5991 tStates += 9;
5992 sim_brk_pend[0] = FALSE;
5993 AF = xororTable[((AF | IY) >> 8) & 0xff];
5994 break;
5995
5996 case 0xb5: /* OR IYL */
5997 tStates += 9;
5998 sim_brk_pend[0] = FALSE;
5999 AF = xororTable[((AF >> 8) | IY) & 0xff];
6000 break;
6001
6002 case 0xb6: /* OR (IY+dd) */
6003 tStates += 19;
6004 adr = IY + (int8) RAM_PP(PC);
6005 CHECK_BREAK_BYTE(adr);
6006 AF = xororTable[((AF >> 8) | GetBYTE(adr)) & 0xff];
6007 break;
6008
6009 case 0xbc: /* CP IYH */
6010 tStates += 9;
6011 sim_brk_pend[0] = FALSE;
6012 temp = HIGH_REGISTER(IY);
6013 AF = (AF & ~0x28) | (temp & 0x28);
6014 acu = HIGH_REGISTER(AF);
6015 sum = acu - temp;
6016 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
6017 cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
6018 break;
6019
6020 case 0xbd: /* CP IYL */
6021 tStates += 9;
6022 sim_brk_pend[0] = FALSE;
6023 temp = LOW_REGISTER(IY);
6024 AF = (AF & ~0x28) | (temp & 0x28);
6025 acu = HIGH_REGISTER(AF);
6026 sum = acu - temp;
6027 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
6028 cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
6029 break;
6030
6031 case 0xbe: /* CP (IY+dd) */
6032 tStates += 19;
6033 adr = IY + (int8) RAM_PP(PC);
6034 CHECK_BREAK_BYTE(adr);
6035 temp = GetBYTE(adr);
6036 AF = (AF & ~0x28) | (temp & 0x28);
6037 acu = HIGH_REGISTER(AF);
6038 sum = acu - temp;
6039 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
6040 cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
6041 break;
6042
6043 case 0xcb: /* CB prefix */
6044 adr = IY + (int8) RAM_PP(PC);
6045 switch ((op = GetBYTE(PC)) & 7) {
6046
6047 case 0:
6048 sim_brk_pend[0] = FALSE;
6049 ++PC;
6050 acu = HIGH_REGISTER(BC);
6051 break;
6052
6053 case 1:
6054 sim_brk_pend[0] = FALSE;
6055 ++PC;
6056 acu = LOW_REGISTER(BC);
6057 break;
6058
6059 case 2:
6060 sim_brk_pend[0] = FALSE;
6061 ++PC;
6062 acu = HIGH_REGISTER(DE);
6063 break;
6064
6065 case 3:
6066 sim_brk_pend[0] = FALSE;
6067 ++PC;
6068 acu = LOW_REGISTER(DE);
6069 break;
6070
6071 case 4:
6072 sim_brk_pend[0] = FALSE;
6073 ++PC;
6074 acu = HIGH_REGISTER(HL);
6075 break;
6076
6077 case 5:
6078 sim_brk_pend[0] = FALSE;
6079 ++PC;
6080 acu = LOW_REGISTER(HL);
6081 break;
6082
6083 case 6:
6084 CHECK_BREAK_BYTE(adr);
6085 ++PC;
6086 acu = GetBYTE(adr);
6087 break;
6088
6089 case 7:
6090 sim_brk_pend[0] = FALSE;
6091 ++PC;
6092 acu = HIGH_REGISTER(AF);
6093 break;
6094 }
6095 switch (op & 0xc0) {
6096
6097 case 0x00: /* shift/rotate */
6098 tStates += 23;
6099 switch (op & 0x38) {
6100
6101 case 0x00: /* RLC */
6102 temp = (acu << 1) | (acu >> 7);
6103 cbits = temp & 1;
6104 goto cbshflg3;
6105
6106 case 0x08: /* RRC */
6107 temp = (acu >> 1) | (acu << 7);
6108 cbits = temp & 0x80;
6109 goto cbshflg3;
6110
6111 case 0x10: /* RL */
6112 temp = (acu << 1) | TSTFLAG(C);
6113 cbits = acu & 0x80;
6114 goto cbshflg3;
6115
6116 case 0x18: /* RR */
6117 temp = (acu >> 1) | (TSTFLAG(C) << 7);
6118 cbits = acu & 1;
6119 goto cbshflg3;
6120
6121 case 0x20: /* SLA */
6122 temp = acu << 1;
6123 cbits = acu & 0x80;
6124 goto cbshflg3;
6125
6126 case 0x28: /* SRA */
6127 temp = (acu >> 1) | (acu & 0x80);
6128 cbits = acu & 1;
6129 goto cbshflg3;
6130
6131 case 0x30: /* SLIA */
6132 temp = (acu << 1) | 1;
6133 cbits = acu & 0x80;
6134 goto cbshflg3;
6135
6136 case 0x38: /* SRL */
6137 temp = acu >> 1;
6138 cbits = acu & 1;
6139 cbshflg3:
6140 AF = (AF & ~0xff) | rotateShiftTable[temp & 0xff] | !!cbits;
6141 /* !!cbits == 0 if cbits == 0 !!cbits == 1 if cbits > 0 */
6142 }
6143 break;
6144
6145 case 0x40: /* BIT */
6146 tStates += 20;
6147 if (acu & (1 << ((op >> 3) & 7)))
6148 AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7);
6149 else
6150 AF = (AF & ~0xfe) | 0x54;
6151 if ((op & 7) != 6)
6152 AF |= (acu & 0x28);
6153 temp = acu;
6154 break;
6155
6156 case 0x80: /* RES */
6157 tStates += 23;
6158 temp = acu & ~(1 << ((op >> 3) & 7));
6159 break;
6160
6161 case 0xc0: /* SET */
6162 tStates += 23;
6163 temp = acu | (1 << ((op >> 3) & 7));
6164 break;
6165 }
6166 switch (op & 7) {
6167
6168 case 0:
6169 SET_HIGH_REGISTER(BC, temp);
6170 break;
6171
6172 case 1:
6173 SET_LOW_REGISTER(BC, temp);
6174 break;
6175
6176 case 2:
6177 SET_HIGH_REGISTER(DE, temp);
6178 break;
6179
6180 case 3:
6181 SET_LOW_REGISTER(DE, temp);
6182 break;
6183
6184 case 4:
6185 SET_HIGH_REGISTER(HL, temp);
6186 break;
6187
6188 case 5:
6189 SET_LOW_REGISTER(HL, temp);
6190 break;
6191
6192 case 6:
6193 PutBYTE(adr, temp);
6194 break;
6195
6196 case 7:
6197 SET_HIGH_REGISTER(AF, temp);
6198 break;
6199 }
6200 break;
6201
6202 case 0xe1: /* POP IY */
6203 tStates += 14;
6204 CHECK_BREAK_WORD(SP);
6205 POP(IY);
6206 break;
6207
6208 case 0xe3: /* EX (SP),IY */
6209 tStates += 23;
6210 CHECK_BREAK_WORD(SP);
6211 temp = IY;
6212 POP(IY);
6213 PUSH(temp);
6214 break;
6215
6216 case 0xe5: /* PUSH IY */
6217 tStates += 15;
6218 CHECK_BREAK_WORD(SP - 2);
6219 PUSH(IY);
6220 break;
6221
6222 case 0xe9: /* JP (IY) */
6223 tStates += 8;
6224 sim_brk_pend[0] = FALSE;
6225 PCQ_ENTRY(PCX);
6226 PC = IY;
6227 break;
6228
6229 case 0xf9: /* LD SP,IY */
6230 tStates += 10;
6231 sim_brk_pend[0] = FALSE;
6232 SP = IY;
6233 break;
6234
6235 default: /* ignore FD */
6236 sim_brk_pend[0] = FALSE;
6237 CHECK_CPU_Z80;
6238 PC--;
6239 }
6240 break;
6241
6242 case 0xfe: /* CP nn */
6243 tStates += 7;
6244 sim_brk_pend[0] = FALSE;
6245 temp = RAM_PP(PC);
6246 AF = (AF & ~0x28) | (temp & 0x28);
6247 acu = HIGH_REGISTER(AF);
6248 sum = acu - temp;
6249 cbits = acu ^ temp ^ sum;
6250 AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
6251 (SET_PV) | cbits2Table[cbits & 0x1ff];
6252 break;
6253
6254 case 0xff: /* RST 38H */
6255 tStates += 11;
6256 CHECK_BREAK_WORD(SP - 2);
6257 PUSH(PC);
6258 PCQ_ENTRY(PCX);
6259 PC = 0x38;
6260 }
6261 }
6262
6263 /* It we stopped processing instructions because of a switch to the other
6264 * CPU, then fixup the reason code.
6265 */
6266 if (switch_cpu_now == FALSE) {
6267 reason = SCPE_OK;
6268 }
6269
6270 end_decode:
6271
6272 /* simulation halted */
6273 PC_S = ((reason == STOP_OPCODE) || (reason == STOP_MEM)) ? PCX : (PC & ADDRMASK);
6274 pcq_r -> qptr = pcq_p; /* update pc q ptr */
6275 AF_S = AF;
6276 BC_S = BC;
6277 DE_S = DE;
6278 HL_S = HL;
6279 IX_S = IX;
6280 IY_S = IY;
6281 SP_S = SP;
6282 executedTStates = tStates;
6283 return reason;
6284 }
6285
6286 /* reset routine */
6287
cpu_reset(DEVICE * dptr)6288 static t_stat cpu_reset(DEVICE *dptr) {
6289 extern uint32 sim_brk_types, sim_brk_dflt; /* breakpoint info */
6290 int32 i;
6291 AF_S = AF1_S = 0;
6292 BC_S = DE_S = HL_S = 0;
6293 BC1_S = DE1_S = HL1_S = 0;
6294 IR_S = IX_S = IY_S = SP_S = 0;
6295 IFF_S = 3;
6296 setBankSelect(0);
6297 cpu8086reset();
6298 sim_brk_types = (SWMASK('E') | SWMASK('I') | SWMASK('M'));
6299 sim_brk_dflt = SWMASK('E');
6300 for (i = 0; i < PCQ_SIZE; i++)
6301 pcq[i] = 0;
6302 pcq_p = 0;
6303 pcq_r = find_reg("PCQ", NULL, dptr);
6304 if (pcq_r)
6305 pcq_r -> qptr = 0;
6306 else
6307 return SCPE_IERR;
6308 return SCPE_OK;
6309 }
6310
install_bootrom(int32 bootrom[],int32 size,int32 addr,int32 makeROM)6311 t_stat install_bootrom(int32 bootrom[], int32 size, int32 addr, int32 makeROM) {
6312 int32 i;
6313 if (addr & (PAGESIZE - 1))
6314 return SCPE_IERR;
6315 for (i = 0; i < size; i++) {
6316 if (makeROM && ((i & (PAGESIZE - 1)) == 0))
6317 mmu_table[(i + addr) >> LOG2PAGESIZE] = ROM_PAGE;
6318 M[i + addr] = bootrom[i] & 0xff;
6319 }
6320 return SCPE_OK;
6321 }
6322
6323 /* memory examine */
cpu_ex(t_value * vptr,t_addr addr,UNIT * uptr,int32 sw)6324 static t_stat cpu_ex(t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) {
6325 int32 oldBankSelect;
6326 if (chiptype == CHIP_TYPE_8086)
6327 *vptr = GetBYTEExtended(addr);
6328 else {
6329 oldBankSelect = getBankSelect();
6330 setBankSelect((addr >> MAXBANKSIZELOG2) & BANKMASK);
6331 *vptr = GetBYTE(addr & ADDRMASK);
6332 setBankSelect(oldBankSelect);
6333 }
6334 return SCPE_OK;
6335 }
6336
6337 /* memory deposit */
cpu_dep(t_value val,t_addr addr,UNIT * uptr,int32 sw)6338 static t_stat cpu_dep(t_value val, t_addr addr, UNIT *uptr, int32 sw) {
6339 int32 oldBankSelect;
6340 if (chiptype == CHIP_TYPE_8086)
6341 PutBYTEExtended(addr, val);
6342 else {
6343 oldBankSelect = getBankSelect();
6344 setBankSelect((addr >> MAXBANKSIZELOG2) & BANKMASK);
6345 PutBYTE(addr & ADDRMASK, val);
6346 setBankSelect(oldBankSelect);
6347 }
6348 return SCPE_OK;
6349 }
6350
6351 struct cpuflag {
6352 int32 mask; /* bit mask within CPU status register */
6353 char name; /* character to print if flag is set */
6354 };
6355 typedef struct cpuflag CPUFLAG;
6356
6357 static CPUFLAG cpuflags8086[] = {
6358 {1 << 11, 'O'},
6359 {1 << 10, 'D'},
6360 {1 << 9, 'I'},
6361 {1 << 8, 'T'},
6362 {1 << 7, 'S'},
6363 {1 << 6, 'Z'},
6364 {1 << 4, 'A'},
6365 {1 << 2, 'P'},
6366 {1 << 0, 'C'},
6367 {0, 0} /* last mask must be 0 */
6368 };
6369
6370 static CPUFLAG cpuflags8080[] = {
6371 {1 << 7, 'S'},
6372 {1 << 6, 'Z'},
6373 {1 << 4, 'A'},
6374 {1 << 3, 'P'},
6375 {1 << 1, 'N'},
6376 {1 << 0, 'C'},
6377 {0, 0} /* last mask must be 0 */
6378 };
6379
6380 static CPUFLAG cpuflagsZ80[] = {
6381 {1 << 7, 'S'},
6382 {1 << 6, 'Z'},
6383 {1 << 4, 'A'},
6384 {1 << 3, 'V'},
6385 {1 << 1, 'N'},
6386 {1 << 0, 'C'},
6387 {0, 0} /* last mask must be 0 */
6388 };
6389
6390 /* needs to be set for each chiptype <= MAX_CHIP_TYPE */
6391 static char *chipTypeToString[] = { "8080", "Z80", "8086" };
6392 static int32 *flagregister[] = { &AF_S, &AF_S, &FLAGS_S };
6393 static CPUFLAG *cpuflags[] = { cpuflags8080, cpuflagsZ80, cpuflags8086 };
6394
6395 /* needs to be set for each ramtype <= MAX_RAM_TYPE */
6396 static char *ramTypeToString[] = { "AZ80", "HRAM", "VRAM", "CRAM" };
6397
chip_show(FILE * st,UNIT * uptr,int32 val,void * desc)6398 static t_stat chip_show(FILE *st, UNIT *uptr, int32 val, void *desc) {
6399 fprintf(st, cpu_unit.flags & UNIT_CPU_OPSTOP ? "ITRAP, " : "NOITRAP, ");
6400 if (chiptype <= MAX_CHIP_TYPE)
6401 fprintf(st, "%s", chipTypeToString[chiptype]);
6402 fprintf(st, ", ");
6403 if (ramtype <= MAX_RAM_TYPE)
6404 fprintf(st, "%s", ramTypeToString[ramtype]);
6405 return SCPE_OK;
6406 }
6407
cpu_show(FILE * st,UNIT * uptr,int32 val,void * desc)6408 static t_stat cpu_show(FILE *st, UNIT *uptr, int32 val, void *desc) {
6409 uint32 i, maxBanks, first = TRUE;
6410 MDEV m;
6411 maxBanks = ((cpu_unit.flags & UNIT_CPU_BANKED) ||
6412 (chiptype == CHIP_TYPE_8086)) ? MAXBANKS : 1;
6413 fprintf(st, "VERBOSE,\n ");
6414 for (i = 0; i < 4; i++)
6415 fprintf(st, "0123456789ABCDEF");
6416 fprintf(st, " [16k]");
6417 for (i = 0; i < (maxBanks * (MAXBANKSIZE >> LOG2PAGESIZE)); i++) {
6418 if ((i & 0x3f) == 0)
6419 fprintf(st, "\n%05X: ", (i << LOG2PAGESIZE));
6420 m = mmu_table[i];
6421 if (m.isRAM)
6422 fprintf(st, "W");
6423 else if (m.isEmpty)
6424 fprintf(st, "U");
6425 else if (m.routine)
6426 fprintf(st, "M");
6427 else
6428 fprintf(st, "R");
6429 }
6430 fprintf(st, ",\n0x[");
6431 /* show which ports are assigned */
6432 for (i = 0; i < 256; i++)
6433 if (dev_table[i].routine != &nulldev) {
6434 if (first)
6435 first = FALSE;
6436 else
6437 fprintf(st, " ");
6438 fprintf(st, "%02X", i);
6439 }
6440 fprintf(st, "]");
6441 if (chiptype <= MAX_CHIP_TYPE) {
6442 first = TRUE;
6443 /* show verbose CPU flags */
6444 for (i = 0; cpuflags[chiptype][i].mask; i++)
6445 if (*flagregister[chiptype] & cpuflags[chiptype][i].mask) {
6446 if (first) {
6447 first = FALSE;
6448 fprintf(st, " ");
6449 }
6450 fprintf(st, "%c", cpuflags[chiptype][i].name);
6451 }
6452 }
6453 return SCPE_OK;
6454 }
6455
cpu_clear(void)6456 static void cpu_clear(void) {
6457 uint32 i;
6458 for (i = 0; i < MAXMEMORY; i++) M[i] = 0;
6459 for (i = 0; i < (MAXMEMORY >> LOG2PAGESIZE); i++)
6460 mmu_table[i] = RAM_PAGE;
6461 for (i = (MEMORYSIZE >> LOG2PAGESIZE); i < (MAXMEMORY >> LOG2PAGESIZE); i++)
6462 mmu_table[i] = EMPTY_PAGE;
6463 if (cpu_unit.flags & UNIT_CPU_ALTAIRROM)
6464 install_ALTAIRbootROM();
6465 clockHasChanged = FALSE;
6466 }
6467
cpu_clear_command(UNIT * uptr,int32 value,char * cptr,void * desc)6468 static t_stat cpu_clear_command(UNIT *uptr, int32 value, char *cptr, void *desc) {
6469 cpu_clear();
6470 return SCPE_OK;
6471 }
6472
cpu_set_altairrom(UNIT * uptr,int32 value,char * cptr,void * desc)6473 static t_stat cpu_set_altairrom(UNIT *uptr, int32 value, char *cptr, void *desc) {
6474 install_ALTAIRbootROM();
6475 return SCPE_OK;
6476 }
6477
cpu_set_noaltairrom(UNIT * uptr,int32 value,char * cptr,void * desc)6478 static t_stat cpu_set_noaltairrom(UNIT *uptr, int32 value, char *cptr, void *desc) {
6479 mmu_table[ALTAIR_ROM_LOW >> LOG2PAGESIZE] = MEMORYSIZE < MAXBANKSIZE ?
6480 EMPTY_PAGE : RAM_PAGE;
6481 return SCPE_OK;
6482 }
6483
cpu_set_nommu(UNIT * uptr,int32 value,char * cptr,void * desc)6484 static t_stat cpu_set_nommu(UNIT *uptr, int32 value, char *cptr, void *desc) {
6485 if (chiptype == CHIP_TYPE_8086) {
6486 printf("Cannot switch off MMU for 8086 CPU.\n");
6487 return SCPE_ARG;
6488 }
6489 if (cpu_unit.flags & UNIT_CPU_BANKED) {
6490 printf("Cannot switch off MMU for banked memory.\n");
6491 return SCPE_ARG;
6492 }
6493 if (((chiptype == CHIP_TYPE_8080) || (chiptype == CHIP_TYPE_Z80)) &&
6494 (MEMORYSIZE < MAXBANKSIZE)) {
6495 printf("Cannot switch off MMU when memory is %iKB < %iKB.\n",
6496 MEMORYSIZE >> KBLOG2, MAXBANKSIZE >> KBLOG2);
6497 return SCPE_ARG;
6498 }
6499 return SCPE_OK;
6500 }
6501
cpu_set_banked(UNIT * uptr,int32 value,char * cptr,void * desc)6502 static t_stat cpu_set_banked(UNIT *uptr, int32 value, char *cptr, void *desc) {
6503 if ((chiptype == CHIP_TYPE_8080) || (chiptype == CHIP_TYPE_Z80)) {
6504 if (MEMORYSIZE <= MAXBANKSIZE)
6505 previousCapacity = MEMORYSIZE;
6506 MEMORYSIZE = MAXMEMORY;
6507 cpu_dev.awidth = MAXBANKSIZELOG2 + MAXBANKSLOG2;
6508 cpu_clear();
6509 }
6510 else if (chiptype == CHIP_TYPE_8086) {
6511 printf("Cannot use banked memory for 8086 CPU.\n");
6512 return SCPE_ARG;
6513 }
6514 return SCPE_OK;
6515 }
6516
cpu_set_nonbanked(UNIT * uptr,int32 value,char * cptr,void * desc)6517 static t_stat cpu_set_nonbanked(UNIT *uptr, int32 value, char *cptr, void *desc) {
6518 if ((chiptype == CHIP_TYPE_8080) || (chiptype == CHIP_TYPE_Z80)) {
6519 MEMORYSIZE = previousCapacity;
6520 cpu_dev.awidth = MAXBANKSIZELOG2;
6521 cpu_clear();
6522 }
6523 return SCPE_OK;
6524 }
6525
bankseldev(const int32 port,const int32 io,const int32 data)6526 static int32 bankseldev(const int32 port, const int32 io, const int32 data) {
6527 if (io) {
6528 switch(ramtype) {
6529 case 1:
6530 if (data & 0x40) {
6531 printf("HRAM: Parity %s" NLP, data & 1 ? "ON" : "OFF");
6532 } else {
6533 printf("HRAM BANKSEL=%02x" NLP, data);
6534 }
6535 break;
6536 case 2:
6537 /* printf("VRAM BANKSEL=%02x" NLP, data);*/
6538 switch(data & 0xFF) {
6539 case 0x01:
6540 /* case 0x41: // OASIS uses this for some reason? */
6541 setBankSelect(0);
6542 break;
6543 case 0x02:
6544 /* case 0x42: // OASIS uses this for some reason? */
6545 setBankSelect(1);
6546 break;
6547 case 0x04:
6548 setBankSelect(2);
6549 break;
6550 case 0x08:
6551 setBankSelect(3);
6552 break;
6553 case 0x10:
6554 setBankSelect(4);
6555 break;
6556 case 0x20:
6557 setBankSelect(5);
6558 break;
6559 case 0x40:
6560 setBankSelect(6);
6561 break;
6562 case 0x80:
6563 setBankSelect(7);
6564 break;
6565 default:
6566 /* printf("Invalid bank select 0x%02x for VRAM" NLP, data);*/
6567 break;
6568 }
6569 break;
6570 case 3:
6571 /* printf(ADDRESS_FORMAT " CRAM BANKSEL=%02x" NLP, PCX, data); */
6572 switch(data & 0x7F) {
6573 case 0x01:
6574 setBankSelect(0);
6575 break;
6576 case 0x02:
6577 setBankSelect(1);
6578 break;
6579 case 0x04:
6580 setBankSelect(2);
6581 break;
6582 case 0x08:
6583 setBankSelect(3);
6584 break;
6585 case 0x10:
6586 setBankSelect(4);
6587 break;
6588 case 0x20:
6589 setBankSelect(5);
6590 break;
6591 case 0x40:
6592 setBankSelect(6);
6593 break;
6594 /* case 0x80: */
6595 /* setBankSelect(7); */
6596 /* break; */
6597 default:
6598 printf("Invalid bank select 0x%02x for CRAM" NLP, data);
6599 break;
6600 }
6601
6602 break;
6603 case 0:
6604 default:
6605 break;
6606 }
6607 return 0;
6608 } else {
6609 return(0xFF);
6610 }
6611 }
6612
cpu_set_chiptype_short(int32 value,uint32 need_cpu_clear)6613 static void cpu_set_chiptype_short(int32 value, uint32 need_cpu_clear) {
6614 extern REG *sim_PC;
6615 if ((chiptype == value) || (chiptype > MAX_CHIP_TYPE))
6616 return; /* nothing to do */
6617 if (((chiptype == CHIP_TYPE_8080) && (value == CHIP_TYPE_Z80)) ||
6618 ((chiptype == CHIP_TYPE_Z80) && (value == CHIP_TYPE_8080))) {
6619 chiptype = value;
6620 return;
6621 }
6622 chiptype = value;
6623 if (chiptype == CHIP_TYPE_8086) {
6624 if (MEMORYSIZE <= MAXBANKSIZE)
6625 previousCapacity = MEMORYSIZE;
6626 MEMORYSIZE = MAXMEMORY;
6627 cpu_unit.flags &= ~(UNIT_CPU_BANKED | UNIT_CPU_ALTAIRROM);
6628 cpu_unit.flags |= UNIT_CPU_MMU;
6629 cpu_dev.awidth = MAXBANKSIZELOG2 + MAXBANKSLOG2;
6630 if (need_cpu_clear)
6631 cpu_clear();
6632 sim_PC = &cpu_reg[7];
6633 }
6634 else if ((chiptype == CHIP_TYPE_8080) || (chiptype == CHIP_TYPE_Z80)) {
6635 MEMORYSIZE = previousCapacity;
6636 cpu_dev.awidth = MAXBANKSIZELOG2;
6637 if (need_cpu_clear)
6638 cpu_clear();
6639 sim_PC = &cpu_reg[6];
6640 }
6641 }
6642
cpu_set_chiptype(UNIT * uptr,int32 value,char * cptr,void * desc)6643 static t_stat cpu_set_chiptype(UNIT *uptr, int32 value, char *cptr, void *desc) {
6644 cpu_set_chiptype_short(value, TRUE);
6645 return SCPE_OK;
6646 }
6647
switchcpu_io(const int32 port,const int32 io,const int32 data)6648 static int32 switchcpu_io(const int32 port, const int32 io, const int32 data) {
6649 int32 new_chiptype = 0;
6650 if (io == 0) { /* Read, switch CPU */
6651 switch(chiptype) {
6652 case CHIP_TYPE_8080:
6653 case CHIP_TYPE_Z80:
6654 if (cpu_unit.flags & UNIT_CPU_VERBOSE) {
6655 printf("CPU: " ADDRESS_FORMAT " SWITCH(port=%02x) to 8086" NLP, PCX, port);
6656 }
6657 new_chiptype = CHIP_TYPE_8086;
6658 switch_cpu_now = FALSE; /* hharte */
6659 break;
6660 case CHIP_TYPE_8086:
6661 if (cpu_unit.flags & UNIT_CPU_VERBOSE) {
6662 printf("CPU: " ADDRESS_FORMAT " SWITCH(port=%02x) to 8085/Z80" NLP, PCX, port);
6663 }
6664 new_chiptype = CHIP_TYPE_Z80;
6665 switch_cpu_now = FALSE; /* hharte */
6666 break;
6667 default:
6668 printf("%s: invalid chiptype: %d\n", __FUNCTION__, chiptype);
6669 break;
6670 }
6671
6672 cpu_set_chiptype_short(new_chiptype, FALSE);
6673 return(0xFF); /* Return High-Z Data */
6674 } else {
6675 printf("%s: Set EXT_ADDR=%02x\n", __FUNCTION__, data);
6676 }
6677 return 0;
6678 }
6679
cpu_show_switcher(FILE * st,UNIT * uptr,int32 val,void * desc)6680 static t_stat cpu_show_switcher(FILE *st, UNIT *uptr, int32 val, void *desc) {
6681 if ((cpu_unit.flags & UNIT_CPU_SWITCHER) && (switcherPort >= 0))
6682 fprintf(st, "SWITCHER=0x%02x", switcherPort);
6683 else
6684 fprintf(st, "NOSWITCHER");
6685 return SCPE_OK;
6686 }
6687
cpu_set_switcher(UNIT * uptr,int32 value,char * cptr,void * desc)6688 static t_stat cpu_set_switcher(UNIT *uptr, int32 value, char *cptr, void *desc) {
6689 struct idev safe;
6690 switcherPort &= 0xff;
6691 safe = dev_table[switcherPort];
6692 if (sim_map_resource(switcherPort, 1, RESOURCE_TYPE_IO, &switchcpu_io, FALSE)) {
6693 printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, switcherPort);
6694 return SCPE_ARG;
6695 }
6696 oldSwitcherDevice = safe;
6697 return SCPE_OK;
6698 }
6699
cpu_reset_switcher(UNIT * uptr,int32 value,char * cptr,void * desc)6700 static t_stat cpu_reset_switcher(UNIT *uptr, int32 value, char *cptr, void *desc) {
6701 if (sim_map_resource(switcherPort, 1, RESOURCE_TYPE_IO, oldSwitcherDevice.routine, FALSE)) {
6702 printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, switcherPort);
6703 return SCPE_ARG;
6704 }
6705 return SCPE_OK;
6706 }
6707
cpu_set_ramtype(UNIT * uptr,int32 value,char * cptr,void * desc)6708 static t_stat cpu_set_ramtype(UNIT *uptr, int32 value, char *cptr, void *desc) {
6709
6710 if (value == ramtype) {
6711 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
6712 printf("RAM Selection unchanged\n");
6713 return SCPE_OK;
6714 }
6715
6716 switch(ramtype) {
6717 case 1:
6718 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
6719 printf("Unmapping NorthStar HRAM\n");
6720 sim_map_resource(0xC0, 1, RESOURCE_TYPE_IO, &bankseldev, TRUE);
6721 break;
6722 case 2:
6723 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
6724 printf("Unmapping Vector RAM\n");
6725 sim_map_resource(0x40, 1, RESOURCE_TYPE_IO, &bankseldev, TRUE);
6726 break;
6727 case 3:
6728 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
6729 printf("Unmapping Cromemco RAM\n");
6730 sim_map_resource(0x40, 1, RESOURCE_TYPE_IO, &bankseldev, TRUE);
6731 break;
6732 case 0:
6733 default:
6734 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
6735 printf("Unmapping AltairZ80 RAM\n");
6736 break;
6737 }
6738
6739 switch(value) {
6740 case 1:
6741 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
6742 printf("NorthStar HRAM Selected\n");
6743 sim_map_resource(0xC0, 1, RESOURCE_TYPE_IO, &bankseldev, FALSE);
6744 break;
6745 case 2:
6746 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
6747 printf("Vector RAM Selected\n");
6748 sim_map_resource(0x40, 1, RESOURCE_TYPE_IO, &bankseldev, FALSE);
6749 break;
6750 case 3:
6751 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
6752 printf("Cromemco RAM Selected\n");
6753 sim_map_resource(0x40, 1, RESOURCE_TYPE_IO, &bankseldev, FALSE);
6754 break;
6755 case 0:
6756 default:
6757 if (cpu_unit.flags & UNIT_CPU_VERBOSE)
6758 printf("AltairZ80 RAM Selected\n");
6759 break;
6760 }
6761
6762 ramtype = value;
6763 return SCPE_OK;
6764 }
6765
6766 /* set memory to 'size' kilo byte */
set_size(uint32 size)6767 static t_stat set_size(uint32 size) {
6768 uint32 maxsize = (((chiptype == CHIP_TYPE_8080) || (chiptype == CHIP_TYPE_Z80)) &&
6769 ((cpu_unit.flags & UNIT_CPU_BANKED) == 0)) ? MAXBANKSIZE : MAXMEMORY;
6770 size <<= KBLOG2;
6771 if (cpu_unit.flags & UNIT_CPU_BANKED)
6772 size &= ~ADDRMASK;
6773 cpu_unit.flags |= UNIT_CPU_MMU;
6774 if (size < KB)
6775 MEMORYSIZE = KB;
6776 else if (size > maxsize)
6777 MEMORYSIZE = maxsize;
6778 else
6779 MEMORYSIZE = size;
6780 cpu_dev.awidth = MAXBANKSIZELOG2;
6781 if (size > MAXBANKSIZE)
6782 cpu_dev.awidth += MAXBANKSLOG2;
6783 cpu_clear();
6784 return SCPE_OK;
6785 }
6786
cpu_set_size(UNIT * uptr,int32 value,char * cptr,void * desc)6787 static t_stat cpu_set_size(UNIT *uptr, int32 value, char *cptr, void *desc) {
6788 return set_size(value);
6789 }
6790
cpu_set_memory(UNIT * uptr,int32 value,char * cptr,void * desc)6791 static t_stat cpu_set_memory(UNIT *uptr, int32 value, char *cptr, void *desc) {
6792 uint32 size, result, i;
6793 if (cptr == NULL)
6794 return SCPE_ARG;
6795 result = sscanf(cptr, "%i%n", &size, &i);
6796 if ((result == 1) && (cptr[i] == 'K') && ((cptr[i + 1] == 0) ||
6797 ((cptr[i + 1] == 'B') && (cptr[i + 2] == 0))))
6798 return set_size(size);
6799 return SCPE_ARG;
6800 }
6801
6802 /* AltairZ80 Simulator initialization */
altairz80_init(void)6803 void altairz80_init(void) {
6804 cpu_clear();
6805 /* altairz80_print_tables(); */
6806 }
6807
6808 void (*sim_vm_init) (void) = &altairz80_init;
6809
6810 /* This is the binary loader. The input file is considered to be a string of
6811 literal bytes with no special format. The load starts at the current value
6812 of the PC if no start address is given. If the input string ends with ROM
6813 (not case sensitive) the memory area is made read only.
6814 ALTAIRROM/NOALTAIRROM settings are ignored.
6815 */
6816
6817 #define PLURAL(x) (x), (x) == 1 ? "" : "s"
6818
sim_load(FILE * fileref,char * cptr,char * fnam,int32 flag)6819 t_stat sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag) {
6820 int32 i;
6821 uint32 addr, cnt = 0, org, pagesModified = 0, makeROM = FALSE;
6822 t_addr j, lo, hi;
6823 char *result;
6824 MDEV m;
6825 char gbuf[CBUFSIZE];
6826 if (flag) {
6827 result = get_range(NULL, cptr, &lo, &hi, 16, ADDRMASKEXTENDED, 0);
6828 if (result == NULL)
6829 return SCPE_ARG;
6830 for (j = lo; j <= hi; j++) {
6831 if (putc(GetBYTEExtended(j), fileref) == EOF)
6832 return SCPE_IOERR;
6833 }
6834 printf("%d byte%s dumped [%x - %x].\n", PLURAL(hi + 1 - lo), lo, hi);
6835 }
6836 else {
6837 if (*cptr == 0)
6838 addr = (chiptype == CHIP_TYPE_8086) ? PCX_S : PC_S;
6839 else {
6840 get_glyph(cptr, gbuf, 0);
6841 if (strcmp(gbuf, "ROM") == 0) {
6842 addr = (chiptype == CHIP_TYPE_8086) ? PCX_S : PC_S;
6843 makeROM = TRUE;
6844 }
6845 else {
6846 addr = strtotv(cptr, &result, 16) & ADDRMASKEXTENDED;
6847 if (cptr == result)
6848 return SCPE_ARG;
6849 while (isspace(*result)) result++;
6850 get_glyph(result, gbuf, 0);
6851 if (strcmp(gbuf, "ROM") == 0)
6852 makeROM = TRUE;
6853 }
6854 }
6855 /* addr is start address to load to, makeROM == TRUE iff memory should become ROM */
6856 org = addr;
6857 while ((addr < MAXMEMORY) && ((i = getc(fileref)) != EOF)) {
6858 m = mmu_table[addr >> LOG2PAGESIZE];
6859 if (!m.isRAM && m.isEmpty) {
6860 mmu_table[addr >> LOG2PAGESIZE] = RAM_PAGE;
6861 pagesModified++;
6862 m = RAM_PAGE;
6863 }
6864 if (makeROM) {
6865 mmu_table[addr >> LOG2PAGESIZE] = ROM_PAGE;
6866 m = ROM_PAGE;
6867 }
6868 if (!m.isRAM && m.routine)
6869 m.routine(addr, 1, i);
6870 else
6871 M[addr] = i;
6872 addr++;
6873 cnt++;
6874 } /* end while */
6875 printf("%d byte%s [%d page%s] loaded at %x%s.\n", PLURAL(cnt),
6876 PLURAL((cnt + 0xff) >> 8), org, makeROM ? " [ROM]" : "");
6877 if (pagesModified)
6878 printf("Warning: %d page%s modified.\n", PLURAL(pagesModified));
6879 }
6880 return SCPE_OK;
6881 }
6882
cpu_raise_interrupt(uint32 irq)6883 void cpu_raise_interrupt(uint32 irq) {
6884 extern void cpu8086_intr(uint8 intrnum);
6885
6886 if (chiptype == CHIP_TYPE_8086) {
6887 cpu8086_intr(irq);
6888 } else if (cpu_unit.flags & UNIT_CPU_VERBOSE) {
6889 printf("Interrupts not fully supported for chiptype: %s\n",
6890 (chiptype <= MAX_CHIP_TYPE) ? chipTypeToString[chiptype] : "????");
6891 }
6892 }
6893