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