1 /* altairz80_cpu.c: MITS Altair CPU (8080 and Z80)
3 Copyright (c) 2002-2008, Peter Schorn
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:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
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.
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.
26 Based on work by Charles E Owen (c) 1997
27 Code for Z80 CPU from Frank D. Cringle ((c) 1995 under GNU license)
30 #include "altairz80_defs.h"
32 #define SWITCHCPU_DEFAULT 0xfd
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); }
52 #define SETFLAG(f,c) AF = (c) ? AF | FLAG_ ## f : AF & ~FLAG_ ## f
53 #define TSTFLAG(f) ((AF & FLAG_ ## f) != 0)
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)
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))
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
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)))
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
76 #define CHECK_CPU_8080 \
77 if (chiptype == CHIP_TYPE_8080) { \
78 if (cpu_unit.flags & UNIT_CPU_OPSTOP) { \
79 reason = STOP_OPCODE; \
83 sim_brk_pend[0] = FALSE; \
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; \
96 register uint32 y = RAM_PP(SP); \
97 x = y + (RAM_PP(SP) << 8); \
100 #define JPC(cond) { \
111 #define CALLC(cond) { \
113 register uint32 adrr = GET_WORD(PC); \
114 CHECK_BREAK_WORD(SP - 2); \
121 sim_brk_pend[0] = FALSE; \
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);
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);
152 /* function prototypes */
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
);
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
);
194 void PutBYTEExtended(register uint32 Addr
, const register uint32 Value
);
195 uint32
GetBYTEExtended(register uint32 Addr
);
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
205 UDATA (NULL
, UNIT_FIX
| UNIT_BINK
| UNIT_CPU_ALTAIRROM
|
206 UNIT_CPU_STOPONHALT
| UNIT_CPU_MMU
, MAXBANKSIZE
)
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 */
249 static int32 pcq_p
= 0; /* PC queue ptr */
250 static REG
*pcq_r
= NULL
; /* PC queue reg ptr */
252 /* data structure for IN/OUT instructions */
254 int32 (*routine
)(const int32
, const int32
, const int32
);
258 static int32 switcherPort
= SWITCHCPU_DEFAULT
;
259 static struct idev oldSwitcherDevice
= { NULL
};
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) },
304 { HRDATA (SWITCHERPORT
, switcherPort
, 8), },
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) },
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
},
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
},
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
},
363 "CPU", &cpu_unit
, cpu_reg
, cpu_mod
,
365 &cpu_ex
, &cpu_dep
, &cpu_reset
,
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
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 */
442 static int32 ramtype
= 0;
443 int32 chiptype
= CHIP_TYPE_8080
;
445 void out(const uint32 Port
, const uint32 Value
) {
446 dev_table
[Port
& 0xff].routine(Port
, 1, Value
);
449 uint32
in(const uint32 Port
) {
450 return dev_table
[Port
& 0xff].routine(Port
, 0, 0);
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 |
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)
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,
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
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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) {
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;
1265 if ( ((i+1) & 0xf) == 0) {
1273 for (temp = 0; temp <= 256; temp++) {
1274 v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) | (((temp & 0xf) == 0) << 4);
1276 if ( ((temp+1) & 0xf) == 0) {
1284 for (temp = 0; temp < 256; temp++) {
1285 v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) | (((temp & 0xf) == 0xf) << 4) | 2;
1287 if ( ((temp+1) & 0xf) == 0) {
1295 for (cbits = 0; cbits < 512; cbits++) {
1296 v = (cbits & 0x10) | ((cbits >> 8) & 1);
1298 if ( ((cbits+1) & 0xf) == 0) {
1303 /* cbitsDup8Table */
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) {
1314 /* cbitsDup16Table */
1317 for (cbits = 0; cbits < 512; cbits++) {
1318 v = (cbits & 0x10) | ((cbits >> 8) & 1) | (cbits & 0x28);
1320 if ( ((cbits+1) & 0xf) == 0) {
1328 for (cbits = 0; cbits < 512; cbits++) {
1329 v = (cbits & 0x10) | ((cbits >> 8) & 1) | 2;
1331 if ( ((cbits+1) & 0xf) == 0) {
1338 uint32 temp, sum, v;
1339 for (temp = 0; temp < 256; temp++) {
1341 v = ((temp & 1) << 15) | (sum << 8) | (sum & 0x28) | (temp & 1);
1342 printf("0x%04x,", v);
1343 if ( ((temp+1) & 0x7) == 0) {
1350 uint32 temp, sum, v;
1351 for (temp = 0; temp < 256; temp++) {
1353 v = (sum << 8) | (sum & 0x28) | (temp & 1);
1354 printf("0x%04x,", v);
1355 if ( ((temp+1) & 0x7) == 0) {
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) {
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) {
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) {
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) {
1404 /* rotateShiftTable */
1407 for (temp = 0; temp < 256; temp++) {
1408 v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) | PARITY(temp);
1410 if ( ((temp+1) & 0xf) == 0) {
1418 for (temp = 0; temp < 256; temp++) {
1419 v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) |
1420 (((temp & 0xf) == 0) << 4) | ((temp == 0x80) << 2);
1422 if ( ((temp+1) & 0xf) == 0) {
1430 for (temp = 0; temp < 256; temp++) {
1431 v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) |
1432 (((temp & 0xf) == 0xf) << 4) | ((temp == 0x7f) << 2) | 2;
1434 if ( ((temp+1) & 0xf) == 0) {
1442 for (cbits = 0; cbits < 512; cbits++) {
1443 v = (cbits & 0x10) | (((cbits >> 6) ^ (cbits >> 5)) & 4) |
1446 if ( ((cbits+1) & 0xf) == 0) {
1451 /* cbitsZ80DupTable */
1454 for (cbits = 0; cbits < 512; cbits++) {
1455 v = (cbits & 0x10) | (((cbits >> 6) ^ (cbits >> 5)) & 4) |
1456 ((cbits >> 8) & 1) | (cbits & 0xa8);
1458 if ( ((cbits+1) & 0xf) == 0) {
1463 /* cbits2Z80Table */
1466 for (cbits = 0; cbits < 512; cbits++) {
1467 v = (((cbits >> 6) ^ (cbits >> 5)) & 4) | (cbits & 0x10) | 2 | ((cbits >> 8) & 1);
1469 if ( ((cbits+1) & 0xf) == 0) {
1474 /* cbits2Z80DupTable */
1477 for (cbits = 0; cbits < 512; cbits++) {
1478 v = (((cbits >> 6) ^ (cbits >> 5)) & 4) | (cbits & 0x10) | 2 | ((cbits >> 8) & 1) |
1481 if ( ((cbits+1) & 0xf) == 0) {
1489 for (temp = 0; temp < 256; temp++) {
1490 v = (((temp & 0x0f) != 0) << 4) | ((temp == 0x80) << 2) | 2 | (temp != 0);
1492 if ( ((temp+1) & 0xf) == 0) {
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) {
1511 for (sum = 0; sum < 256; sum++) {
1512 v = (sum & 0x80) | (((sum & 0xff) == 0) << 6);
1514 if ( ((sum+1) & 0xf) == 0) {
1519 /* remove comments to generate table contents
1523 /* Memory management */
1525 #define LOG2PAGESIZE 8
1526 #define PAGESIZE (1 << LOG2PAGESIZE)
1528 static uint8 M
[MAXMEMORY
]; /* RAM which is present */
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!
1541 int32 (*routine
)(const int32
, const int32
, const int32
);
1544 typedef struct mdev MDEV
;
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
];
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",
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
;
1570 mmu_table
[page
] = EMPTY_PAGE
;
1572 mmu_table
[page
] = RAM_PAGE
;
1575 mmu_table
[page
] = ROM_PAGE
;
1576 mmu_table
[page
].routine
= routine
;
1579 } else if (resource_type
== RESOURCE_TYPE_IO
) {
1580 for (i
= baseaddr
; i
< baseaddr
+ size
; i
++)
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
;
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
;
1594 printf("%s: cannot map unknown resource type %d\n", __FUNCTION__
, resource_type
);
1600 static void PutBYTE(register uint32 Addr
, const register uint32 Value
) {
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
];
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
) {
1612 MESSAGE_2("Attempt to write to non existing memory " ADDRESS_FORMAT
".", Addr
);
1615 MESSAGE_2("Attempt to write to ROM " ADDRESS_FORMAT
".", Addr
);
1620 void PutBYTEExtended(register uint32 Addr
, const register uint32 Value
) {
1623 Addr
&= ADDRMASKEXTENDED
;
1624 m
= mmu_table
[Addr
>> LOG2PAGESIZE
];
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
) {
1630 MESSAGE_2("Attempt to write to non existing memory " ADDRESS_FORMAT
".", Addr
);
1633 MESSAGE_2("Attempt to write to ROM " ADDRESS_FORMAT
".", Addr
);
1638 static void PutWORD(register uint32 Addr
, const register uint32 Value
) {
1639 PutBYTE(Addr
, Value
);
1640 PutBYTE(Addr
+ 1, Value
>> 8);
1643 static uint32
GetBYTE(register uint32 Addr
) {
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
];
1651 if (m
.isRAM
) return M
[Addr
]; /* RAM */
1652 if (m
.routine
) return m
.routine(Addr
, 0, 0); /* memory mapped I/O */
1654 if (cpu_unit
.flags
& UNIT_CPU_VERBOSE
) {
1655 MESSAGE_2("Attempt to read from non existing memory " ADDRESS_FORMAT
".", Addr
);
1659 return M
[Addr
]; /* ROM */
1662 uint32
GetBYTEExtended(register uint32 Addr
) {
1665 Addr
&= ADDRMASKEXTENDED
;
1666 m
= mmu_table
[Addr
>> LOG2PAGESIZE
];
1668 if (m
.isRAM
) return M
[Addr
];
1669 if (m
.routine
) return m
.routine(Addr
, 0, 0);
1671 if (cpu_unit
.flags
& UNIT_CPU_VERBOSE
) {
1672 MESSAGE_2("Attempt to read from non existing memory " ADDRESS_FORMAT
".", Addr
);
1679 int32
getBankSelect(void) {
1683 void setBankSelect(const int32 b
) {
1687 uint32
getCommon(void) {
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
);
1698 return MOPT
[Addr
& ADDRMASK
];
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
);
1708 MOPT
[Addr
& ADDRMASK
] = Value
& 0xff;
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)
1718 #define MASK_BRK (TRUE + 1)
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
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
;
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 */
1739 return (sim_brk_pend
[0] && (loc
== sim_brk_ploc
[0])) ? MASK_BRK
: FALSE
;
1742 static void prepareMemoryAccessMessage(t_addr loc
) {
1743 extern char memoryAccessMessage
[];
1744 sprintf(memoryAccessMessage
, "Memory access breakpoint [%04xh]", loc
);
1748 MM_PUT_BYTE(SP, (x) >> 8); \
1749 MM_PUT_BYTE(SP, x); \
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); \
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; \
1766 else if (br1 || br2) { \
1767 reason = STOP_MEM; \
1769 prepareMemoryAccessMessage((a1) & 0xffff); \
1772 prepareMemoryAccessMessage((a2) & 0xffff); \
1778 sim_brk_pend[0] = FALSE; \
1782 #define CHECK_BREAK_TWO_BYTES(a1, a2) CHECK_BREAK_TWO_BYTES_EXTENDED(a1, a2,;)
1784 #define CHECK_BREAK_WORD(a) CHECK_BREAK_TWO_BYTES(a, (a + 1))
1786 #define HALTINSTRUCTION 0x76
1788 /* Macros for the IN/OUT instructions INI/INIR/IND/INDR/OUTI/OTIR/OUTD/OTDR
1791 temp == value of register B at entry of the instruction
1792 acu == value of transferred byte (IN or OUT)
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
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 */
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)
1815 t_stat
sim_instr (void) {
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
];
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
;
1837 register uint32 specialProcessing
;
1846 register uint32 temp
= 0;
1847 register uint32 acu
= 0;
1848 register uint32 sum
;
1849 register uint32 cbits
;
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
;
1863 PC
= PC_S
& ADDRMASK
;
1867 specialProcessing
= clockFrequency
| timerInterrupt
| keyboardInterrupt
| sim_brk_summ
;
1870 startTime
= sim_os_msec();
1871 tStatesInSlice
= sliceLength
*clockFrequency
;
1873 else { /* make sure that sim_os_msec() is not called later */
1874 clockFrequency
= startTime
= tStatesInSlice
= 0;
1877 /* main instruction fetch/decode loop */
1878 while (TRUE
) { /* loop until halted */
1879 if (sim_interval
<= 0) { /* check clock queue */
1881 if ((reason
= sim_os_poll_kbd()) == SCPE_STOP
) { /* poll on platforms without reliable signalling */
1885 if ( (reason
= sim_process_event()) ) break;
1887 specialProcessing
= clockFrequency
| timerInterrupt
| keyboardInterrupt
| sim_brk_summ
;
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
);
1899 usleep(1000 * (startTime
- now
));
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)) {
1917 PC
= timerInterruptHandler
& ADDRMASK
;
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)) {
1933 PC
= keyboardInterruptHandler
& ADDRMASK
;
1937 if (sim_brk_lookup(PC
, SWMASK('E')) == TRUE
) { /* breakpoint? */
1938 reason
= STOP_IBKPT
; /* stop simulation */
1941 if (sim_brk_test(GetBYTE(PC
), (1u << SIM_BKPT_V_SPC
) | SWMASK('I'))) { /* instruction breakpoint? */
1942 reason
= STOP_IBKPT
; /* stop simulation */
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
1955 switch(RAM_PP(PC
)) {
1957 case 0x00: /* NOP */
1959 sim_brk_pend
[0] = FALSE
;
1962 case 0x01: /* LD BC,nnnn */
1964 sim_brk_pend
[0] = FALSE
;
1969 case 0x02: /* LD (BC),A */
1971 CHECK_BREAK_BYTE(BC
)
1972 PutBYTE(BC
, HIGH_REGISTER(AF
));
1975 case 0x03: /* INC BC */
1977 sim_brk_pend
[0] = FALSE
;
1981 case 0x04: /* INC B */
1983 sim_brk_pend
[0] = FALSE
;
1985 temp
= HIGH_REGISTER(BC
);
1986 AF
= (AF
& ~0xfe) | incTable
[temp
] | SET_PV2(0x80); /* SET_PV2 uses temp */
1989 case 0x05: /* DEC B */
1991 sim_brk_pend
[0] = FALSE
;
1993 temp
= HIGH_REGISTER(BC
);
1994 AF
= (AF
& ~0xfe) | decTable
[temp
] | SET_PV2(0x7f); /* SET_PV2 uses temp */
1997 case 0x06: /* LD B,nn */
1999 sim_brk_pend
[0] = FALSE
;
2000 SET_HIGH_REGISTER(BC
, RAM_PP(PC
));
2003 case 0x07: /* RLCA */
2005 sim_brk_pend
[0] = FALSE
;
2006 AF
= ((AF
>> 7) & 0x0128) | ((AF
<< 1) & ~0x1ff) |
2007 (AF
& 0xc4) | ((AF
>> 15) & 1);
2010 case 0x08: /* EX AF,AF' */
2012 sim_brk_pend
[0] = FALSE
;
2019 case 0x09: /* ADD HL,BC */
2021 sim_brk_pend
[0] = FALSE
;
2025 AF
= (AF
& ~0x3b) | ((sum
>> 8) & 0x28) | cbitsTable
[(HL
^ BC
^ sum
) >> 8];
2029 case 0x0a: /* LD A,(BC) */
2031 CHECK_BREAK_BYTE(BC
)
2032 SET_HIGH_REGISTER(AF
, GetBYTE(BC
));
2035 case 0x0b: /* DEC BC */
2037 sim_brk_pend
[0] = FALSE
;
2041 case 0x0c: /* INC C */
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);
2049 case 0x0d: /* DEC C */
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);
2057 case 0x0e: /* LD C,nn */
2059 sim_brk_pend
[0] = FALSE
;
2060 SET_LOW_REGISTER(BC
, RAM_PP(PC
));
2063 case 0x0f: /* RRCA */
2065 sim_brk_pend
[0] = FALSE
;
2066 AF
= (AF
& 0xc4) | rrcaTable
[HIGH_REGISTER(AF
)];
2069 case 0x10: /* DJNZ dd */
2070 sim_brk_pend
[0] = FALSE
;
2072 if ((BC
-= 0x100) & 0xff00) {
2074 PC
+= (int8
) GetBYTE(PC
) + 1;
2083 case 0x11: /* LD DE,nnnn */
2085 sim_brk_pend
[0] = FALSE
;
2090 case 0x12: /* LD (DE),A */
2092 CHECK_BREAK_BYTE(DE
)
2093 PutBYTE(DE
, HIGH_REGISTER(AF
));
2096 case 0x13: /* INC DE */
2098 sim_brk_pend
[0] = FALSE
;
2102 case 0x14: /* INC D */
2104 sim_brk_pend
[0] = FALSE
;
2106 temp
= HIGH_REGISTER(DE
);
2107 AF
= (AF
& ~0xfe) | incTable
[temp
] | SET_PV2(0x80); /* SET_PV2 uses temp */
2110 case 0x15: /* DEC D */
2112 sim_brk_pend
[0] = FALSE
;
2114 temp
= HIGH_REGISTER(DE
);
2115 AF
= (AF
& ~0xfe) | decTable
[temp
] | SET_PV2(0x7f); /* SET_PV2 uses temp */
2118 case 0x16: /* LD D,nn */
2120 sim_brk_pend
[0] = FALSE
;
2121 SET_HIGH_REGISTER(DE
, RAM_PP(PC
));
2124 case 0x17: /* RLA */
2126 sim_brk_pend
[0] = FALSE
;
2127 AF
= ((AF
<< 8) & 0x0100) | ((AF
>> 7) & 0x28) | ((AF
<< 1) & ~0x01ff) |
2128 (AF
& 0xc4) | ((AF
>> 15) & 1);
2131 case 0x18: /* JR dd */
2133 sim_brk_pend
[0] = FALSE
;
2136 PC
+= (int8
) GetBYTE(PC
) + 1;
2139 case 0x19: /* ADD HL,DE */
2141 sim_brk_pend
[0] = FALSE
;
2145 AF
= (AF
& ~0x3b) | ((sum
>> 8) & 0x28) | cbitsTable
[(HL
^ DE
^ sum
) >> 8];
2149 case 0x1a: /* LD A,(DE) */
2151 CHECK_BREAK_BYTE(DE
)
2152 SET_HIGH_REGISTER(AF
, GetBYTE(DE
));
2155 case 0x1b: /* DEC DE */
2157 sim_brk_pend
[0] = FALSE
;
2161 case 0x1c: /* INC E */
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);
2169 case 0x1d: /* DEC E */
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);
2177 case 0x1e: /* LD E,nn */
2179 sim_brk_pend
[0] = FALSE
;
2180 SET_LOW_REGISTER(DE
, RAM_PP(PC
));
2183 case 0x1f: /* RRA */
2185 sim_brk_pend
[0] = FALSE
;
2186 AF
= ((AF
& 1) << 15) | (AF
& 0xc4) | rraTable
[HIGH_REGISTER(AF
)];
2189 case 0x20: /* JR NZ,dd */
2190 sim_brk_pend
[0] = FALSE
;
2198 PC
+= (int8
) GetBYTE(PC
) + 1;
2203 case 0x21: /* LD HL,nnnn */
2205 sim_brk_pend
[0] = FALSE
;
2210 case 0x22: /* LD (nnnn),HL */
2212 temp
= GET_WORD(PC
);
2213 CHECK_BREAK_WORD(temp
);
2218 case 0x23: /* INC HL */
2220 sim_brk_pend
[0] = FALSE
;
2224 case 0x24: /* INC H */
2226 sim_brk_pend
[0] = FALSE
;
2228 temp
= HIGH_REGISTER(HL
);
2229 AF
= (AF
& ~0xfe) | incTable
[temp
] | SET_PV2(0x80); /* SET_PV2 uses temp */
2232 case 0x25: /* DEC H */
2234 sim_brk_pend
[0] = FALSE
;
2236 temp
= HIGH_REGISTER(HL
);
2237 AF
= (AF
& ~0xfe) | decTable
[temp
] | SET_PV2(0x7f); /* SET_PV2 uses temp */
2240 case 0x26: /* LD H,nn */
2242 sim_brk_pend
[0] = FALSE
;
2243 SET_HIGH_REGISTER(HL
, RAM_PP(PC
));
2246 case 0x27: /* DAA */
2248 sim_brk_pend
[0] = FALSE
;
2249 acu
= HIGH_REGISTER(AF
);
2250 temp
= LOW_DIGIT(acu
);
2252 if (TSTFLAG(N
)) { /* last operation was a subtract */
2253 int hd
= cbits
|| acu
> 0x99;
2254 if (TSTFLAG(H
) || (temp
> 9)) { /* adjust low digit */
2261 if (hd
) acu
-= 0x160; /* adjust high digit */
2263 else { /* last operation was an add */
2264 if (TSTFLAG(H
) || (temp
> 9)) { /* adjust low digit */
2265 SETFLAG(H
, (temp
> 9));
2268 if (cbits
|| ((acu
& 0x1f0) > 0x90)) acu
+= 0x60; /* adjust high digit */
2270 AF
= (AF
& 0x12) | rrdrldTable
[acu
& 0xff] | ((acu
>> 8) & 1) | cbits
;
2273 case 0x28: /* JR Z,dd */
2274 sim_brk_pend
[0] = FALSE
;
2278 PC
+= (int8
) GetBYTE(PC
) + 1;
2287 case 0x29: /* ADD HL,HL */
2289 sim_brk_pend
[0] = FALSE
;
2292 AF
= (AF
& ~0x3b) | cbitsDup16Table
[sum
>> 8];
2296 case 0x2a: /* LD HL,(nnnn) */
2298 temp
= GET_WORD(PC
);
2299 CHECK_BREAK_WORD(temp
);
2300 HL
= GET_WORD(temp
);
2304 case 0x2b: /* DEC HL */
2306 sim_brk_pend
[0] = FALSE
;
2310 case 0x2c: /* INC L */
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);
2318 case 0x2d: /* DEC L */
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);
2326 case 0x2e: /* LD L,nn */
2328 sim_brk_pend
[0] = FALSE
;
2329 SET_LOW_REGISTER(HL
, RAM_PP(PC
));
2332 case 0x2f: /* CPL */
2334 sim_brk_pend
[0] = FALSE
;
2335 AF
= (~AF
& ~0xff) | (AF
& 0xc5) | ((~AF
>> 8) & 0x28) | 0x12;
2338 case 0x30: /* JR NC,dd */
2339 sim_brk_pend
[0] = FALSE
;
2347 PC
+= (int8
) GetBYTE(PC
) + 1;
2352 case 0x31: /* LD SP,nnnn */
2354 sim_brk_pend
[0] = FALSE
;
2359 case 0x32: /* LD (nnnn),A */
2361 temp
= GET_WORD(PC
);
2362 CHECK_BREAK_BYTE(temp
);
2363 PutBYTE(temp
, HIGH_REGISTER(AF
));
2367 case 0x33: /* INC SP */
2369 sim_brk_pend
[0] = FALSE
;
2373 case 0x34: /* INC (HL) */
2375 CHECK_BREAK_BYTE(HL
);
2376 temp
= GetBYTE(HL
) + 1;
2378 AF
= (AF
& ~0xfe) | incTable
[temp
] | SET_PV2(0x80);
2381 case 0x35: /* DEC (HL) */
2383 CHECK_BREAK_BYTE(HL
);
2384 temp
= GetBYTE(HL
) - 1;
2386 AF
= (AF
& ~0xfe) | decTable
[temp
& 0xff] | SET_PV2(0x7f);
2389 case 0x36: /* LD (HL),nn */
2391 CHECK_BREAK_BYTE(HL
);
2392 PutBYTE(HL
, RAM_PP(PC
));
2395 case 0x37: /* SCF */
2397 sim_brk_pend
[0] = FALSE
;
2398 AF
= (AF
& ~0x3b) | ((AF
>> 8) & 0x28) | 1;
2401 case 0x38: /* JR C,dd */
2402 sim_brk_pend
[0] = FALSE
;
2406 PC
+= (int8
) GetBYTE(PC
) + 1;
2415 case 0x39: /* ADD HL,SP */
2417 sim_brk_pend
[0] = FALSE
;
2421 AF
= (AF
& ~0x3b) | ((sum
>> 8) & 0x28) | cbitsTable
[(HL
^ SP
^ sum
) >> 8];
2425 case 0x3a: /* LD A,(nnnn) */
2427 temp
= GET_WORD(PC
);
2428 CHECK_BREAK_BYTE(temp
);
2429 SET_HIGH_REGISTER(AF
, GetBYTE(temp
));
2433 case 0x3b: /* DEC SP */
2435 sim_brk_pend
[0] = FALSE
;
2439 case 0x3c: /* INC A */
2441 sim_brk_pend
[0] = FALSE
;
2443 temp
= HIGH_REGISTER(AF
);
2444 AF
= (AF
& ~0xfe) | incTable
[temp
] | SET_PV2(0x80); /* SET_PV2 uses temp */
2447 case 0x3d: /* DEC A */
2449 sim_brk_pend
[0] = FALSE
;
2451 temp
= HIGH_REGISTER(AF
);
2452 AF
= (AF
& ~0xfe) | decTable
[temp
] | SET_PV2(0x7f); /* SET_PV2 uses temp */
2455 case 0x3e: /* LD A,nn */
2457 sim_brk_pend
[0] = FALSE
;
2458 SET_HIGH_REGISTER(AF
, RAM_PP(PC
));
2461 case 0x3f: /* CCF */
2463 sim_brk_pend
[0] = FALSE
;
2464 AF
= (AF
& ~0x3b) | ((AF
>> 8) & 0x28) | ((AF
& 1) << 4) | (~AF
& 1);
2467 case 0x40: /* LD B,B */
2469 sim_brk_pend
[0] = FALSE
; /* nop */
2472 case 0x41: /* LD B,C */
2474 sim_brk_pend
[0] = FALSE
;
2475 BC
= (BC
& 0xff) | ((BC
& 0xff) << 8);
2478 case 0x42: /* LD B,D */
2480 sim_brk_pend
[0] = FALSE
;
2481 BC
= (BC
& 0xff) | (DE
& ~0xff);
2484 case 0x43: /* LD B,E */
2486 sim_brk_pend
[0] = FALSE
;
2487 BC
= (BC
& 0xff) | ((DE
& 0xff) << 8);
2490 case 0x44: /* LD B,H */
2492 sim_brk_pend
[0] = FALSE
;
2493 BC
= (BC
& 0xff) | (HL
& ~0xff);
2496 case 0x45: /* LD B,L */
2498 sim_brk_pend
[0] = FALSE
;
2499 BC
= (BC
& 0xff) | ((HL
& 0xff) << 8);
2502 case 0x46: /* LD B,(HL) */
2504 CHECK_BREAK_BYTE(HL
);
2505 SET_HIGH_REGISTER(BC
, GetBYTE(HL
));
2508 case 0x47: /* LD B,A */
2510 sim_brk_pend
[0] = FALSE
;
2511 BC
= (BC
& 0xff) | (AF
& ~0xff);
2514 case 0x48: /* LD C,B */
2516 sim_brk_pend
[0] = FALSE
;
2517 BC
= (BC
& ~0xff) | ((BC
>> 8) & 0xff);
2520 case 0x49: /* LD C,C */
2522 sim_brk_pend
[0] = FALSE
; /* nop */
2525 case 0x4a: /* LD C,D */
2527 sim_brk_pend
[0] = FALSE
;
2528 BC
= (BC
& ~0xff) | ((DE
>> 8) & 0xff);
2531 case 0x4b: /* LD C,E */
2533 sim_brk_pend
[0] = FALSE
;
2534 BC
= (BC
& ~0xff) | (DE
& 0xff);
2537 case 0x4c: /* LD C,H */
2539 sim_brk_pend
[0] = FALSE
;
2540 BC
= (BC
& ~0xff) | ((HL
>> 8) & 0xff);
2543 case 0x4d: /* LD C,L */
2545 sim_brk_pend
[0] = FALSE
;
2546 BC
= (BC
& ~0xff) | (HL
& 0xff);
2549 case 0x4e: /* LD C,(HL) */
2551 CHECK_BREAK_BYTE(HL
);
2552 SET_LOW_REGISTER(BC
, GetBYTE(HL
));
2555 case 0x4f: /* LD C,A */
2557 sim_brk_pend
[0] = FALSE
;
2558 BC
= (BC
& ~0xff) | ((AF
>> 8) & 0xff);
2561 case 0x50: /* LD D,B */
2563 sim_brk_pend
[0] = FALSE
;
2564 DE
= (DE
& 0xff) | (BC
& ~0xff);
2567 case 0x51: /* LD D,C */
2569 sim_brk_pend
[0] = FALSE
;
2570 DE
= (DE
& 0xff) | ((BC
& 0xff) << 8);
2573 case 0x52: /* LD D,D */
2575 sim_brk_pend
[0] = FALSE
; /* nop */
2578 case 0x53: /* LD D,E */
2580 sim_brk_pend
[0] = FALSE
;
2581 DE
= (DE
& 0xff) | ((DE
& 0xff) << 8);
2584 case 0x54: /* LD D,H */
2586 sim_brk_pend
[0] = FALSE
;
2587 DE
= (DE
& 0xff) | (HL
& ~0xff);
2590 case 0x55: /* LD D,L */
2592 sim_brk_pend
[0] = FALSE
;
2593 DE
= (DE
& 0xff) | ((HL
& 0xff) << 8);
2596 case 0x56: /* LD D,(HL) */
2598 CHECK_BREAK_BYTE(HL
);
2599 SET_HIGH_REGISTER(DE
, GetBYTE(HL
));
2602 case 0x57: /* LD D,A */
2604 sim_brk_pend
[0] = FALSE
;
2605 DE
= (DE
& 0xff) | (AF
& ~0xff);
2608 case 0x58: /* LD E,B */
2610 sim_brk_pend
[0] = FALSE
;
2611 DE
= (DE
& ~0xff) | ((BC
>> 8) & 0xff);
2614 case 0x59: /* LD E,C */
2616 sim_brk_pend
[0] = FALSE
;
2617 DE
= (DE
& ~0xff) | (BC
& 0xff);
2620 case 0x5a: /* LD E,D */
2622 sim_brk_pend
[0] = FALSE
;
2623 DE
= (DE
& ~0xff) | ((DE
>> 8) & 0xff);
2626 case 0x5b: /* LD E,E */
2628 sim_brk_pend
[0] = FALSE
; /* nop */
2631 case 0x5c: /* LD E,H */
2633 sim_brk_pend
[0] = FALSE
;
2634 DE
= (DE
& ~0xff) | ((HL
>> 8) & 0xff);
2637 case 0x5d: /* LD E,L */
2639 sim_brk_pend
[0] = FALSE
;
2640 DE
= (DE
& ~0xff) | (HL
& 0xff);
2643 case 0x5e: /* LD E,(HL) */
2645 CHECK_BREAK_BYTE(HL
);
2646 SET_LOW_REGISTER(DE
, GetBYTE(HL
));
2649 case 0x5f: /* LD E,A */
2651 sim_brk_pend
[0] = FALSE
;
2652 DE
= (DE
& ~0xff) | ((AF
>> 8) & 0xff);
2655 case 0x60: /* LD H,B */
2657 sim_brk_pend
[0] = FALSE
;
2658 HL
= (HL
& 0xff) | (BC
& ~0xff);
2661 case 0x61: /* LD H,C */
2663 sim_brk_pend
[0] = FALSE
;
2664 HL
= (HL
& 0xff) | ((BC
& 0xff) << 8);
2667 case 0x62: /* LD H,D */
2669 sim_brk_pend
[0] = FALSE
;
2670 HL
= (HL
& 0xff) | (DE
& ~0xff);
2673 case 0x63: /* LD H,E */
2675 sim_brk_pend
[0] = FALSE
;
2676 HL
= (HL
& 0xff) | ((DE
& 0xff) << 8);
2679 case 0x64: /* LD H,H */
2681 sim_brk_pend
[0] = FALSE
; /* nop */
2684 case 0x65: /* LD H,L */
2686 sim_brk_pend
[0] = FALSE
;
2687 HL
= (HL
& 0xff) | ((HL
& 0xff) << 8);
2690 case 0x66: /* LD H,(HL) */
2692 CHECK_BREAK_BYTE(HL
);
2693 SET_HIGH_REGISTER(HL
, GetBYTE(HL
));
2696 case 0x67: /* LD H,A */
2698 sim_brk_pend
[0] = FALSE
;
2699 HL
= (HL
& 0xff) | (AF
& ~0xff);
2702 case 0x68: /* LD L,B */
2704 sim_brk_pend
[0] = FALSE
;
2705 HL
= (HL
& ~0xff) | ((BC
>> 8) & 0xff);
2708 case 0x69: /* LD L,C */
2710 sim_brk_pend
[0] = FALSE
;
2711 HL
= (HL
& ~0xff) | (BC
& 0xff);
2714 case 0x6a: /* LD L,D */
2716 sim_brk_pend
[0] = FALSE
;
2717 HL
= (HL
& ~0xff) | ((DE
>> 8) & 0xff);
2720 case 0x6b: /* LD L,E */
2722 sim_brk_pend
[0] = FALSE
;
2723 HL
= (HL
& ~0xff) | (DE
& 0xff);
2726 case 0x6c: /* LD L,H */
2728 sim_brk_pend
[0] = FALSE
;
2729 HL
= (HL
& ~0xff) | ((HL
>> 8) & 0xff);
2732 case 0x6d: /* LD L,L */
2734 sim_brk_pend
[0] = FALSE
; /* nop */
2737 case 0x6e: /* LD L,(HL) */
2739 CHECK_BREAK_BYTE(HL
);
2740 SET_LOW_REGISTER(HL
, GetBYTE(HL
));
2743 case 0x6f: /* LD L,A */
2745 sim_brk_pend
[0] = FALSE
;
2746 HL
= (HL
& ~0xff) | ((AF
>> 8) & 0xff);
2749 case 0x70: /* LD (HL),B */
2751 CHECK_BREAK_BYTE(HL
);
2752 PutBYTE(HL
, HIGH_REGISTER(BC
));
2755 case 0x71: /* LD (HL),C */
2757 CHECK_BREAK_BYTE(HL
);
2758 PutBYTE(HL
, LOW_REGISTER(BC
));
2761 case 0x72: /* LD (HL),D */
2763 CHECK_BREAK_BYTE(HL
);
2764 PutBYTE(HL
, HIGH_REGISTER(DE
));
2767 case 0x73: /* LD (HL),E */
2769 CHECK_BREAK_BYTE(HL
);
2770 PutBYTE(HL
, LOW_REGISTER(DE
));
2773 case 0x74: /* LD (HL),H */
2775 CHECK_BREAK_BYTE(HL
);
2776 PutBYTE(HL
, HIGH_REGISTER(HL
));
2779 case 0x75: /* LD (HL),L */
2781 CHECK_BREAK_BYTE(HL
);
2782 PutBYTE(HL
, LOW_REGISTER(HL
));
2785 case HALTINSTRUCTION
: /* HALT */
2787 sim_brk_pend
[0] = FALSE
;
2789 if (cpu_unit
.flags
& UNIT_CPU_STOPONHALT
) {
2794 do_SIMH_sleep(); /* reduce CPU load in busy wait */
2797 case 0x77: /* LD (HL),A */
2799 CHECK_BREAK_BYTE(HL
);
2800 PutBYTE(HL
, HIGH_REGISTER(AF
));
2803 case 0x78: /* LD A,B */
2805 sim_brk_pend
[0] = FALSE
;
2806 AF
= (AF
& 0xff) | (BC
& ~0xff);
2809 case 0x79: /* LD A,C */
2811 sim_brk_pend
[0] = FALSE
;
2812 AF
= (AF
& 0xff) | ((BC
& 0xff) << 8);
2815 case 0x7a: /* LD A,D */
2817 sim_brk_pend
[0] = FALSE
;
2818 AF
= (AF
& 0xff) | (DE
& ~0xff);
2821 case 0x7b: /* LD A,E */
2823 sim_brk_pend
[0] = FALSE
;
2824 AF
= (AF
& 0xff) | ((DE
& 0xff) << 8);
2827 case 0x7c: /* LD A,H */
2829 sim_brk_pend
[0] = FALSE
;
2830 AF
= (AF
& 0xff) | (HL
& ~0xff);
2833 case 0x7d: /* LD A,L */
2835 sim_brk_pend
[0] = FALSE
;
2836 AF
= (AF
& 0xff) | ((HL
& 0xff) << 8);
2839 case 0x7e: /* LD A,(HL) */
2841 CHECK_BREAK_BYTE(HL
);
2842 SET_HIGH_REGISTER(AF
, GetBYTE(HL
));
2845 case 0x7f: /* LD A,A */
2847 sim_brk_pend
[0] = FALSE
; /* nop */
2850 case 0x80: /* ADD A,B */
2852 sim_brk_pend
[0] = FALSE
;
2853 temp
= HIGH_REGISTER(BC
);
2854 acu
= HIGH_REGISTER(AF
);
2856 cbits
= acu
^ temp
^ sum
;
2857 AF
= addTable
[sum
] | cbitsTable
[cbits
] | (SET_PV
);
2860 case 0x81: /* ADD A,C */
2862 sim_brk_pend
[0] = FALSE
;
2863 temp
= LOW_REGISTER(BC
);
2864 acu
= HIGH_REGISTER(AF
);
2866 cbits
= acu
^ temp
^ sum
;
2867 AF
= addTable
[sum
] | cbitsTable
[cbits
] | (SET_PV
);
2870 case 0x82: /* ADD A,D */
2872 sim_brk_pend
[0] = FALSE
;
2873 temp
= HIGH_REGISTER(DE
);
2874 acu
= HIGH_REGISTER(AF
);
2876 cbits
= acu
^ temp
^ sum
;
2877 AF
= addTable
[sum
] | cbitsTable
[cbits
] | (SET_PV
);
2880 case 0x83: /* ADD A,E */
2882 sim_brk_pend
[0] = FALSE
;
2883 temp
= LOW_REGISTER(DE
);
2884 acu
= HIGH_REGISTER(AF
);
2886 cbits
= acu
^ temp
^ sum
;
2887 AF
= addTable
[sum
] | cbitsTable
[cbits
] | (SET_PV
);
2890 case 0x84: /* ADD A,H */
2892 sim_brk_pend
[0] = FALSE
;
2893 temp
= HIGH_REGISTER(HL
);
2894 acu
= HIGH_REGISTER(AF
);
2896 cbits
= acu
^ temp
^ sum
;
2897 AF
= addTable
[sum
] | cbitsTable
[cbits
] | (SET_PV
);
2900 case 0x85: /* ADD A,L */
2902 sim_brk_pend
[0] = FALSE
;
2903 temp
= LOW_REGISTER(HL
);
2904 acu
= HIGH_REGISTER(AF
);
2906 cbits
= acu
^ temp
^ sum
;
2907 AF
= addTable
[sum
] | cbitsTable
[cbits
] | (SET_PV
);
2910 case 0x86: /* ADD A,(HL) */
2912 CHECK_BREAK_BYTE(HL
);
2914 acu
= HIGH_REGISTER(AF
);
2916 cbits
= acu
^ temp
^ sum
;
2917 AF
= addTable
[sum
] | cbitsTable
[cbits
] | (SET_PV
);
2920 case 0x87: /* ADD A,A */
2922 sim_brk_pend
[0] = FALSE
;
2923 cbits
= 2 * HIGH_REGISTER(AF
);
2924 AF
= cbitsDup8Table
[cbits
] | (SET_PVS(cbits
));
2927 case 0x88: /* ADC A,B */
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
);
2937 case 0x89: /* ADC A,C */
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
);
2947 case 0x8a: /* ADC A,D */
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
);
2957 case 0x8b: /* ADC A,E */
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
);
2967 case 0x8c: /* ADC A,H */
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
);
2977 case 0x8d: /* ADC A,L */
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
);
2987 case 0x8e: /* ADC A,(HL) */
2989 CHECK_BREAK_BYTE(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
);
2997 case 0x8f: /* ADC A,A */
2999 sim_brk_pend
[0] = FALSE
;
3000 cbits
= 2 * HIGH_REGISTER(AF
) + TSTFLAG(C
);
3001 AF
= cbitsDup8Table
[cbits
] | (SET_PVS(cbits
));
3004 case 0x90: /* SUB B */
3006 sim_brk_pend
[0] = FALSE
;
3007 temp
= HIGH_REGISTER(BC
);
3008 acu
= HIGH_REGISTER(AF
);
3010 cbits
= acu
^ temp
^ sum
;
3011 AF
= subTable
[sum
& 0xff] | cbitsTable
[cbits
& 0x1ff] | (SET_PV
);
3014 case 0x91: /* SUB C */
3016 sim_brk_pend
[0] = FALSE
;
3017 temp
= LOW_REGISTER(BC
);
3018 acu
= HIGH_REGISTER(AF
);
3020 cbits
= acu
^ temp
^ sum
;
3021 AF
= subTable
[sum
& 0xff] | cbitsTable
[cbits
& 0x1ff] | (SET_PV
);
3024 case 0x92: /* SUB D */
3026 sim_brk_pend
[0] = FALSE
;
3027 temp
= HIGH_REGISTER(DE
);
3028 acu
= HIGH_REGISTER(AF
);
3030 cbits
= acu
^ temp
^ sum
;
3031 AF
= subTable
[sum
& 0xff] | cbitsTable
[cbits
& 0x1ff] | (SET_PV
);
3034 case 0x93: /* SUB E */
3036 sim_brk_pend
[0] = FALSE
;
3037 temp
= LOW_REGISTER(DE
);
3038 acu
= HIGH_REGISTER(AF
);
3040 cbits
= acu
^ temp
^ sum
;
3041 AF
= subTable
[sum
& 0xff] | cbitsTable
[cbits
& 0x1ff] | (SET_PV
);
3044 case 0x94: /* SUB H */
3046 sim_brk_pend
[0] = FALSE
;
3047 temp
= HIGH_REGISTER(HL
);
3048 acu
= HIGH_REGISTER(AF
);
3050 cbits
= acu
^ temp
^ sum
;
3051 AF
= subTable
[sum
& 0xff] | cbitsTable
[cbits
& 0x1ff] | (SET_PV
);
3054 case 0x95: /* SUB L */
3056 sim_brk_pend
[0] = FALSE
;
3057 temp
= LOW_REGISTER(HL
);
3058 acu
= HIGH_REGISTER(AF
);
3060 cbits
= acu
^ temp
^ sum
;
3061 AF
= subTable
[sum
& 0xff] | cbitsTable
[cbits
& 0x1ff] | (SET_PV
);
3064 case 0x96: /* SUB (HL) */
3066 CHECK_BREAK_BYTE(HL
);
3068 acu
= HIGH_REGISTER(AF
);
3070 cbits
= acu
^ temp
^ sum
;
3071 AF
= subTable
[sum
& 0xff] | cbitsTable
[cbits
& 0x1ff] | (SET_PV
);
3074 case 0x97: /* SUB A */
3076 sim_brk_pend
[0] = FALSE
;
3077 AF
= (chiptype
== CHIP_TYPE_Z80
) ? 0x42 : 0x46;
3080 case 0x98: /* SBC A,B */
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
);
3090 case 0x99: /* SBC A,C */
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
);
3100 case 0x9a: /* SBC A,D */
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
);
3110 case 0x9b: /* SBC A,E */
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
);
3120 case 0x9c: /* SBC A,H */
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
);
3130 case 0x9d: /* SBC A,L */
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
);
3140 case 0x9e: /* SBC A,(HL) */
3142 CHECK_BREAK_BYTE(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
);
3150 case 0x9f: /* SBC A,A */
3152 sim_brk_pend
[0] = FALSE
;
3153 cbits
= -TSTFLAG(C
);
3154 AF
= subTable
[cbits
& 0xff] | cbitsTable
[cbits
& 0x1ff] | (SET_PVS(cbits
));
3157 case 0xa0: /* AND B */
3159 sim_brk_pend
[0] = FALSE
;
3160 AF
= andTable
[((AF
& BC
) >> 8) & 0xff];
3163 case 0xa1: /* AND C */
3165 sim_brk_pend
[0] = FALSE
;
3166 AF
= andTable
[((AF
>> 8) & BC
) & 0xff];
3169 case 0xa2: /* AND D */
3171 sim_brk_pend
[0] = FALSE
;
3172 AF
= andTable
[((AF
& DE
) >> 8) & 0xff];
3175 case 0xa3: /* AND E */
3177 sim_brk_pend
[0] = FALSE
;
3178 AF
= andTable
[((AF
>> 8) & DE
) & 0xff];
3181 case 0xa4: /* AND H */
3183 sim_brk_pend
[0] = FALSE
;
3184 AF
= andTable
[((AF
& HL
) >> 8) & 0xff];
3187 case 0xa5: /* AND L */
3189 sim_brk_pend
[0] = FALSE
;
3190 AF
= andTable
[((AF
>> 8) & HL
) & 0xff];
3193 case 0xa6: /* AND (HL) */
3195 CHECK_BREAK_BYTE(HL
);
3196 AF
= andTable
[((AF
>> 8) & GetBYTE(HL
)) & 0xff];
3199 case 0xa7: /* AND A */
3201 sim_brk_pend
[0] = FALSE
;
3202 AF
= andTable
[(AF
>> 8) & 0xff];
3205 case 0xa8: /* XOR B */
3207 sim_brk_pend
[0] = FALSE
;
3208 AF
= xororTable
[((AF
^ BC
) >> 8) & 0xff];
3211 case 0xa9: /* XOR C */
3213 sim_brk_pend
[0] = FALSE
;
3214 AF
= xororTable
[((AF
>> 8) ^ BC
) & 0xff];
3217 case 0xaa: /* XOR D */
3219 sim_brk_pend
[0] = FALSE
;
3220 AF
= xororTable
[((AF
^ DE
) >> 8) & 0xff];
3223 case 0xab: /* XOR E */
3225 sim_brk_pend
[0] = FALSE
;
3226 AF
= xororTable
[((AF
>> 8) ^ DE
) & 0xff];
3229 case 0xac: /* XOR H */
3231 sim_brk_pend
[0] = FALSE
;
3232 AF
= xororTable
[((AF
^ HL
) >> 8) & 0xff];
3235 case 0xad: /* XOR L */
3237 sim_brk_pend
[0] = FALSE
;
3238 AF
= xororTable
[((AF
>> 8) ^ HL
) & 0xff];
3241 case 0xae: /* XOR (HL) */
3243 CHECK_BREAK_BYTE(HL
);
3244 AF
= xororTable
[((AF
>> 8) ^ GetBYTE(HL
)) & 0xff];
3247 case 0xaf: /* XOR A */
3249 sim_brk_pend
[0] = FALSE
;
3253 case 0xb0: /* OR B */
3255 sim_brk_pend
[0] = FALSE
;
3256 AF
= xororTable
[((AF
| BC
) >> 8) & 0xff];
3259 case 0xb1: /* OR C */
3261 sim_brk_pend
[0] = FALSE
;
3262 AF
= xororTable
[((AF
>> 8) | BC
) & 0xff];
3265 case 0xb2: /* OR D */
3267 sim_brk_pend
[0] = FALSE
;
3268 AF
= xororTable
[((AF
| DE
) >> 8) & 0xff];
3271 case 0xb3: /* OR E */
3273 sim_brk_pend
[0] = FALSE
;
3274 AF
= xororTable
[((AF
>> 8) | DE
) & 0xff];
3277 case 0xb4: /* OR H */
3279 sim_brk_pend
[0] = FALSE
;
3280 AF
= xororTable
[((AF
| HL
) >> 8) & 0xff];
3283 case 0xb5: /* OR L */
3285 sim_brk_pend
[0] = FALSE
;
3286 AF
= xororTable
[((AF
>> 8) | HL
) & 0xff];
3289 case 0xb6: /* OR (HL) */
3291 CHECK_BREAK_BYTE(HL
);
3292 AF
= xororTable
[((AF
>> 8) | GetBYTE(HL
)) & 0xff];
3295 case 0xb7: /* OR A */
3297 sim_brk_pend
[0] = FALSE
;
3298 AF
= xororTable
[(AF
>> 8) & 0xff];
3301 case 0xb8: /* CP B */
3303 sim_brk_pend
[0] = FALSE
;
3304 temp
= HIGH_REGISTER(BC
);
3305 AF
= (AF
& ~0x28) | (temp
& 0x28);
3306 acu
= HIGH_REGISTER(AF
);
3308 cbits
= acu
^ temp
^ sum
;
3309 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
3310 (SET_PV
) | cbits2Table
[cbits
& 0x1ff];
3313 case 0xb9: /* CP C */
3315 sim_brk_pend
[0] = FALSE
;
3316 temp
= LOW_REGISTER(BC
);
3317 AF
= (AF
& ~0x28) | (temp
& 0x28);
3318 acu
= HIGH_REGISTER(AF
);
3320 cbits
= acu
^ temp
^ sum
;
3321 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
3322 (SET_PV
) | cbits2Table
[cbits
& 0x1ff];
3325 case 0xba: /* CP D */
3327 sim_brk_pend
[0] = FALSE
;
3328 temp
= HIGH_REGISTER(DE
);
3329 AF
= (AF
& ~0x28) | (temp
& 0x28);
3330 acu
= HIGH_REGISTER(AF
);
3332 cbits
= acu
^ temp
^ sum
;
3333 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
3334 (SET_PV
) | cbits2Table
[cbits
& 0x1ff];
3337 case 0xbb: /* CP E */
3339 sim_brk_pend
[0] = FALSE
;
3340 temp
= LOW_REGISTER(DE
);
3341 AF
= (AF
& ~0x28) | (temp
& 0x28);
3342 acu
= HIGH_REGISTER(AF
);
3344 cbits
= acu
^ temp
^ sum
;
3345 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
3346 (SET_PV
) | cbits2Table
[cbits
& 0x1ff];
3349 case 0xbc: /* CP H */
3351 sim_brk_pend
[0] = FALSE
;
3352 temp
= HIGH_REGISTER(HL
);
3353 AF
= (AF
& ~0x28) | (temp
& 0x28);
3354 acu
= HIGH_REGISTER(AF
);
3356 cbits
= acu
^ temp
^ sum
;
3357 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
3358 (SET_PV
) | cbits2Table
[cbits
& 0x1ff];
3361 case 0xbd: /* CP L */
3363 sim_brk_pend
[0] = FALSE
;
3364 temp
= LOW_REGISTER(HL
);
3365 AF
= (AF
& ~0x28) | (temp
& 0x28);
3366 acu
= HIGH_REGISTER(AF
);
3368 cbits
= acu
^ temp
^ sum
;
3369 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
3370 (SET_PV
) | cbits2Table
[cbits
& 0x1ff];
3373 case 0xbe: /* CP (HL) */
3375 CHECK_BREAK_BYTE(HL
);
3377 AF
= (AF
& ~0x28) | (temp
& 0x28);
3378 acu
= HIGH_REGISTER(AF
);
3380 cbits
= acu
^ temp
^ sum
;
3381 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
3382 (SET_PV
) | cbits2Table
[cbits
& 0x1ff];
3385 case 0xbf: /* CP A */
3387 sim_brk_pend
[0] = FALSE
;
3388 SET_LOW_REGISTER(AF
, (HIGH_REGISTER(AF
) & 0x28) | (chiptype
== CHIP_TYPE_Z80
? 0x42 : 0x46));
3391 case 0xc0: /* RET NZ */
3393 sim_brk_pend
[0] = FALSE
;
3397 CHECK_BREAK_WORD(SP
);
3404 case 0xc1: /* POP BC */
3406 CHECK_BREAK_WORD(SP
);
3410 case 0xc2: /* JP NZ,nnnn */
3411 sim_brk_pend
[0] = FALSE
;
3412 JPC(!TSTFLAG(Z
)); /* also updates tStates */
3415 case 0xc3: /* JP nnnn */
3416 sim_brk_pend
[0] = FALSE
;
3417 JPC(1); /* also updates tStates */
3420 case 0xc4: /* CALL NZ,nnnn */
3421 CALLC(!TSTFLAG(Z
)); /* also updates tStates */
3424 case 0xc5: /* PUSH BC */
3426 CHECK_BREAK_WORD(SP
- 2);
3430 case 0xc6: /* ADD A,nn */
3432 sim_brk_pend
[0] = FALSE
;
3434 acu
= HIGH_REGISTER(AF
);
3436 cbits
= acu
^ temp
^ sum
;
3437 AF
= addTable
[sum
] | cbitsTable
[cbits
] | (SET_PV
);
3440 case 0xc7: /* RST 0 */
3442 CHECK_BREAK_WORD(SP
- 2);
3448 case 0xc8: /* RET Z */
3450 CHECK_BREAK_WORD(SP
);
3456 sim_brk_pend
[0] = FALSE
;
3461 case 0xc9: /* RET */
3463 CHECK_BREAK_WORD(SP
);
3468 case 0xca: /* JP Z,nnnn */
3469 sim_brk_pend
[0] = FALSE
;
3470 JPC(TSTFLAG(Z
)); /* also updates tStates */
3473 case 0xcb: /* CB prefix */
3476 switch ((op
= GetBYTE(PC
)) & 7) {
3479 sim_brk_pend
[0] = tStateModifier
= FALSE
;
3481 acu
= HIGH_REGISTER(BC
);
3486 sim_brk_pend
[0] = tStateModifier
= FALSE
;
3488 acu
= LOW_REGISTER(BC
);
3493 sim_brk_pend
[0] = tStateModifier
= FALSE
;
3495 acu
= HIGH_REGISTER(DE
);
3500 sim_brk_pend
[0] = tStateModifier
= FALSE
;
3502 acu
= LOW_REGISTER(DE
);
3507 sim_brk_pend
[0] = tStateModifier
= FALSE
;
3509 acu
= HIGH_REGISTER(HL
);
3514 sim_brk_pend
[0] = tStateModifier
= FALSE
;
3516 acu
= LOW_REGISTER(HL
);
3521 CHECK_BREAK_BYTE(adr
);
3524 tStateModifier
= TRUE
;
3529 sim_brk_pend
[0] = tStateModifier
= FALSE
;
3531 acu
= HIGH_REGISTER(AF
);
3535 switch (op
& 0xc0) {
3537 case 0x00: /* shift/rotate */
3538 switch (op
& 0x38) {
3540 case 0x00: /* RLC */
3541 temp
= (acu
<< 1) | (acu
>> 7);
3545 case 0x08: /* RRC */
3546 temp
= (acu
>> 1) | (acu
<< 7);
3547 cbits
= temp
& 0x80;
3551 temp
= (acu
<< 1) | TSTFLAG(C
);
3556 temp
= (acu
>> 1) | (TSTFLAG(C
) << 7);
3560 case 0x20: /* SLA */
3565 case 0x28: /* SRA */
3566 temp
= (acu
>> 1) | (acu
& 0x80);
3570 case 0x30: /* SLIA */
3571 temp
= (acu
<< 1) | 1;
3575 case 0x38: /* SRL */
3579 AF
= (AF
& ~0xff) | rotateShiftTable
[temp
& 0xff] | !!cbits
;
3580 /* !!cbits == 0 if cbits == 0 !!cbits == 1 if cbits > 0 */
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);
3593 case 0x80: /* RES */
3594 temp
= acu
& ~(1 << ((op
>> 3) & 7));
3597 case 0xc0: /* SET */
3598 temp
= acu
| (1 << ((op
>> 3) & 7));
3605 SET_HIGH_REGISTER(BC
, temp
);
3609 SET_LOW_REGISTER(BC
, temp
);
3613 SET_HIGH_REGISTER(DE
, temp
);
3617 SET_LOW_REGISTER(DE
, temp
);
3621 SET_HIGH_REGISTER(HL
, temp
);
3625 SET_LOW_REGISTER(HL
, temp
);
3633 SET_HIGH_REGISTER(AF
, temp
);
3638 case 0xcc: /* CALL Z,nnnn */
3639 CALLC(TSTFLAG(Z
)); /* also updates tStates */
3642 case 0xcd: /* CALL nnnn */
3643 CALLC(1); /* also updates tStates */
3646 case 0xce: /* ADC A,nn */
3648 sim_brk_pend
[0] = FALSE
;
3650 acu
= HIGH_REGISTER(AF
);
3651 sum
= acu
+ temp
+ TSTFLAG(C
);
3652 cbits
= acu
^ temp
^ sum
;
3653 AF
= addTable
[sum
] | cbitsTable
[cbits
] | (SET_PV
);
3656 case 0xcf: /* RST 8 */
3658 CHECK_BREAK_WORD(SP
- 2);
3664 case 0xd0: /* RET NC */
3666 sim_brk_pend
[0] = FALSE
;
3670 CHECK_BREAK_WORD(SP
);
3677 case 0xd1: /* POP DE */
3679 CHECK_BREAK_WORD(SP
);
3683 case 0xd2: /* JP NC,nnnn */
3684 sim_brk_pend
[0] = FALSE
;
3685 JPC(!TSTFLAG(C
)); /* also updates tStates */
3688 case 0xd3: /* OUT (nn),A */
3690 sim_brk_pend
[0] = FALSE
;
3691 out(RAM_PP(PC
), HIGH_REGISTER(AF
));
3694 case 0xd4: /* CALL NC,nnnn */
3695 CALLC(!TSTFLAG(C
)); /* also updates tStates */
3698 case 0xd5: /* PUSH DE */
3700 CHECK_BREAK_WORD(SP
- 2);
3704 case 0xd6: /* SUB nn */
3706 sim_brk_pend
[0] = FALSE
;
3708 acu
= HIGH_REGISTER(AF
);
3710 cbits
= acu
^ temp
^ sum
;
3711 AF
= subTable
[sum
& 0xff] | cbitsTable
[cbits
& 0x1ff] | (SET_PV
);
3714 case 0xd7: /* RST 10H */
3716 CHECK_BREAK_WORD(SP
- 2);
3722 case 0xd8: /* RET C */
3724 CHECK_BREAK_WORD(SP
);
3730 sim_brk_pend
[0] = FALSE
;
3735 case 0xd9: /* EXX */
3737 sim_brk_pend
[0] = FALSE
;
3750 case 0xda: /* JP C,nnnn */
3751 sim_brk_pend
[0] = FALSE
;
3752 JPC(TSTFLAG(C
)); /* also updates tStates */
3755 case 0xdb: /* IN A,(nn) */
3757 sim_brk_pend
[0] = FALSE
;
3758 SET_HIGH_REGISTER(AF
, in(RAM_PP(PC
)));
3761 case 0xdc: /* CALL C,nnnn */
3762 CALLC(TSTFLAG(C
)); /* also updates tStates */
3765 case 0xdd: /* DD prefix */
3767 switch (op
= RAM_PP(PC
)) {
3769 case 0x09: /* ADD IX,BC */
3771 sim_brk_pend
[0] = FALSE
;
3775 AF
= (AF
& ~0x3b) | ((sum
>> 8) & 0x28) | cbitsTable
[(IX
^ BC
^ sum
) >> 8];
3779 case 0x19: /* ADD IX,DE */
3781 sim_brk_pend
[0] = FALSE
;
3785 AF
= (AF
& ~0x3b) | ((sum
>> 8) & 0x28) | cbitsTable
[(IX
^ DE
^ sum
) >> 8];
3789 case 0x21: /* LD IX,nnnn */
3791 sim_brk_pend
[0] = FALSE
;
3796 case 0x22: /* LD (nnnn),IX */
3798 temp
= GET_WORD(PC
);
3799 CHECK_BREAK_WORD(temp
);
3804 case 0x23: /* INC IX */
3806 sim_brk_pend
[0] = FALSE
;
3810 case 0x24: /* INC IXH */
3812 sim_brk_pend
[0] = FALSE
;
3814 AF
= (AF
& ~0xfe) | incZ80Table
[HIGH_REGISTER(IX
)];
3817 case 0x25: /* DEC IXH */
3819 sim_brk_pend
[0] = FALSE
;
3821 AF
= (AF
& ~0xfe) | decZ80Table
[HIGH_REGISTER(IX
)];
3824 case 0x26: /* LD IXH,nn */
3826 sim_brk_pend
[0] = FALSE
;
3827 SET_HIGH_REGISTER(IX
, RAM_PP(PC
));
3830 case 0x29: /* ADD IX,IX */
3832 sim_brk_pend
[0] = FALSE
;
3835 AF
= (AF
& ~0x3b) | cbitsDup16Table
[sum
>> 8];
3839 case 0x2a: /* LD IX,(nnnn) */
3841 temp
= GET_WORD(PC
);
3842 CHECK_BREAK_WORD(temp
);
3843 IX
= GET_WORD(temp
);
3847 case 0x2b: /* DEC IX */
3849 sim_brk_pend
[0] = FALSE
;
3853 case 0x2c: /* INC IXL */
3855 sim_brk_pend
[0] = FALSE
;
3856 temp
= LOW_REGISTER(IX
) + 1;
3857 SET_LOW_REGISTER(IX
, temp
);
3858 AF
= (AF
& ~0xfe) | incZ80Table
[temp
];
3861 case 0x2d: /* DEC IXL */
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];
3869 case 0x2e: /* LD IXL,nn */
3871 sim_brk_pend
[0] = FALSE
;
3872 SET_LOW_REGISTER(IX
, RAM_PP(PC
));
3875 case 0x34: /* INC (IX+dd) */
3877 adr
= IX
+ (int8
) RAM_PP(PC
);
3878 CHECK_BREAK_BYTE(adr
);
3879 temp
= GetBYTE(adr
) + 1;
3881 AF
= (AF
& ~0xfe) | incZ80Table
[temp
];
3884 case 0x35: /* DEC (IX+dd) */
3886 adr
= IX
+ (int8
) RAM_PP(PC
);
3887 CHECK_BREAK_BYTE(adr
);
3888 temp
= GetBYTE(adr
) - 1;
3890 AF
= (AF
& ~0xfe) | decZ80Table
[temp
& 0xff];
3893 case 0x36: /* LD (IX+dd),nn */
3895 adr
= IX
+ (int8
) RAM_PP(PC
);
3896 CHECK_BREAK_BYTE(adr
);
3897 PutBYTE(adr
, RAM_PP(PC
));
3900 case 0x39: /* ADD IX,SP */
3902 sim_brk_pend
[0] = FALSE
;
3906 AF
= (AF
& ~0x3b) | ((sum
>> 8) & 0x28) | cbitsTable
[(IX
^ SP
^ sum
) >> 8];
3910 case 0x44: /* LD B,IXH */
3912 sim_brk_pend
[0] = FALSE
;
3913 SET_HIGH_REGISTER(BC
, HIGH_REGISTER(IX
));
3916 case 0x45: /* LD B,IXL */
3918 sim_brk_pend
[0] = FALSE
;
3919 SET_HIGH_REGISTER(BC
, LOW_REGISTER(IX
));
3922 case 0x46: /* LD B,(IX+dd) */
3924 adr
= IX
+ (int8
) RAM_PP(PC
);
3925 CHECK_BREAK_BYTE(adr
);
3926 SET_HIGH_REGISTER(BC
, GetBYTE(adr
));
3929 case 0x4c: /* LD C,IXH */
3931 sim_brk_pend
[0] = FALSE
;
3932 SET_LOW_REGISTER(BC
, HIGH_REGISTER(IX
));
3935 case 0x4d: /* LD C,IXL */
3937 sim_brk_pend
[0] = FALSE
;
3938 SET_LOW_REGISTER(BC
, LOW_REGISTER(IX
));
3941 case 0x4e: /* LD C,(IX+dd) */
3943 adr
= IX
+ (int8
) RAM_PP(PC
);
3944 CHECK_BREAK_BYTE(adr
);
3945 SET_LOW_REGISTER(BC
, GetBYTE(adr
));
3948 case 0x54: /* LD D,IXH */
3950 sim_brk_pend
[0] = FALSE
;
3951 SET_HIGH_REGISTER(DE
, HIGH_REGISTER(IX
));
3954 case 0x55: /* LD D,IXL */
3956 sim_brk_pend
[0] = FALSE
;
3957 SET_HIGH_REGISTER(DE
, LOW_REGISTER(IX
));
3960 case 0x56: /* LD D,(IX+dd) */
3962 adr
= IX
+ (int8
) RAM_PP(PC
);
3963 CHECK_BREAK_BYTE(adr
);
3964 SET_HIGH_REGISTER(DE
, GetBYTE(adr
));
3967 case 0x5c: /* LD E,IXH */
3969 sim_brk_pend
[0] = FALSE
;
3970 SET_LOW_REGISTER(DE
, HIGH_REGISTER(IX
));
3973 case 0x5d: /* LD E,IXL */
3975 sim_brk_pend
[0] = FALSE
;
3976 SET_LOW_REGISTER(DE
, LOW_REGISTER(IX
));
3979 case 0x5e: /* LD E,(IX+dd) */
3981 adr
= IX
+ (int8
) RAM_PP(PC
);
3982 CHECK_BREAK_BYTE(adr
);
3983 SET_LOW_REGISTER(DE
, GetBYTE(adr
));
3986 case 0x60: /* LD IXH,B */
3988 sim_brk_pend
[0] = FALSE
;
3989 SET_HIGH_REGISTER(IX
, HIGH_REGISTER(BC
));
3992 case 0x61: /* LD IXH,C */
3994 sim_brk_pend
[0] = FALSE
;
3995 SET_HIGH_REGISTER(IX
, LOW_REGISTER(BC
));
3998 case 0x62: /* LD IXH,D */
4000 sim_brk_pend
[0] = FALSE
;
4001 SET_HIGH_REGISTER(IX
, HIGH_REGISTER(DE
));
4004 case 0x63: /* LD IXH,E */
4006 sim_brk_pend
[0] = FALSE
;
4007 SET_HIGH_REGISTER(IX
, LOW_REGISTER(DE
));
4010 case 0x64: /* LD IXH,IXH */
4012 sim_brk_pend
[0] = FALSE
; /* nop */
4015 case 0x65: /* LD IXH,IXL */
4017 sim_brk_pend
[0] = FALSE
;
4018 SET_HIGH_REGISTER(IX
, LOW_REGISTER(IX
));
4021 case 0x66: /* LD H,(IX+dd) */
4023 adr
= IX
+ (int8
) RAM_PP(PC
);
4024 CHECK_BREAK_BYTE(adr
);
4025 SET_HIGH_REGISTER(HL
, GetBYTE(adr
));
4028 case 0x67: /* LD IXH,A */
4030 sim_brk_pend
[0] = FALSE
;
4031 SET_HIGH_REGISTER(IX
, HIGH_REGISTER(AF
));
4034 case 0x68: /* LD IXL,B */
4036 sim_brk_pend
[0] = FALSE
;
4037 SET_LOW_REGISTER(IX
, HIGH_REGISTER(BC
));
4040 case 0x69: /* LD IXL,C */
4042 sim_brk_pend
[0] = FALSE
;
4043 SET_LOW_REGISTER(IX
, LOW_REGISTER(BC
));
4046 case 0x6a: /* LD IXL,D */
4048 sim_brk_pend
[0] = FALSE
;
4049 SET_LOW_REGISTER(IX
, HIGH_REGISTER(DE
));
4052 case 0x6b: /* LD IXL,E */
4054 sim_brk_pend
[0] = FALSE
;
4055 SET_LOW_REGISTER(IX
, LOW_REGISTER(DE
));
4058 case 0x6c: /* LD IXL,IXH */
4060 sim_brk_pend
[0] = FALSE
;
4061 SET_LOW_REGISTER(IX
, HIGH_REGISTER(IX
));
4064 case 0x6d: /* LD IXL,IXL */
4066 sim_brk_pend
[0] = FALSE
; /* nop */
4069 case 0x6e: /* LD L,(IX+dd) */
4071 adr
= IX
+ (int8
) RAM_PP(PC
);
4072 CHECK_BREAK_BYTE(adr
);
4073 SET_LOW_REGISTER(HL
, GetBYTE(adr
));
4076 case 0x6f: /* LD IXL,A */
4078 sim_brk_pend
[0] = FALSE
;
4079 SET_LOW_REGISTER(IX
, HIGH_REGISTER(AF
));
4082 case 0x70: /* LD (IX+dd),B */
4084 adr
= IX
+ (int8
) RAM_PP(PC
);
4085 CHECK_BREAK_BYTE(adr
);
4086 PutBYTE(adr
, HIGH_REGISTER(BC
));
4089 case 0x71: /* LD (IX+dd),C */
4091 adr
= IX
+ (int8
) RAM_PP(PC
);
4092 CHECK_BREAK_BYTE(adr
);
4093 PutBYTE(adr
, LOW_REGISTER(BC
));
4096 case 0x72: /* LD (IX+dd),D */
4098 adr
= IX
+ (int8
) RAM_PP(PC
);
4099 CHECK_BREAK_BYTE(adr
);
4100 PutBYTE(adr
, HIGH_REGISTER(DE
));
4103 case 0x73: /* LD (IX+dd),E */
4105 adr
= IX
+ (int8
) RAM_PP(PC
);
4106 CHECK_BREAK_BYTE(adr
);
4107 PutBYTE(adr
, LOW_REGISTER(DE
));
4110 case 0x74: /* LD (IX+dd),H */
4112 adr
= IX
+ (int8
) RAM_PP(PC
);
4113 CHECK_BREAK_BYTE(adr
);
4114 PutBYTE(adr
, HIGH_REGISTER(HL
));
4117 case 0x75: /* LD (IX+dd),L */
4119 adr
= IX
+ (int8
) RAM_PP(PC
);
4120 CHECK_BREAK_BYTE(adr
);
4121 PutBYTE(adr
, LOW_REGISTER(HL
));
4124 case 0x77: /* LD (IX+dd),A */
4126 adr
= IX
+ (int8
) RAM_PP(PC
);
4127 CHECK_BREAK_BYTE(adr
);
4128 PutBYTE(adr
, HIGH_REGISTER(AF
));
4131 case 0x7c: /* LD A,IXH */
4133 sim_brk_pend
[0] = FALSE
;
4134 SET_HIGH_REGISTER(AF
, HIGH_REGISTER(IX
));
4137 case 0x7d: /* LD A,IXL */
4139 sim_brk_pend
[0] = FALSE
;
4140 SET_HIGH_REGISTER(AF
, LOW_REGISTER(IX
));
4143 case 0x7e: /* LD A,(IX+dd) */
4145 adr
= IX
+ (int8
) RAM_PP(PC
);
4146 CHECK_BREAK_BYTE(adr
);
4147 SET_HIGH_REGISTER(AF
, GetBYTE(adr
));
4150 case 0x84: /* ADD A,IXH */
4152 sim_brk_pend
[0] = FALSE
;
4153 temp
= HIGH_REGISTER(IX
);
4154 acu
= HIGH_REGISTER(AF
);
4156 AF
= addTable
[sum
] | cbitsZ80Table
[acu
^ temp
^ sum
];
4159 case 0x85: /* ADD A,IXL */
4161 sim_brk_pend
[0] = FALSE
;
4162 temp
= LOW_REGISTER(IX
);
4163 acu
= HIGH_REGISTER(AF
);
4165 AF
= addTable
[sum
] | cbitsZ80Table
[acu
^ temp
^ sum
];
4168 case 0x86: /* ADD A,(IX+dd) */
4170 adr
= IX
+ (int8
) RAM_PP(PC
);
4171 CHECK_BREAK_BYTE(adr
);
4172 temp
= GetBYTE(adr
);
4173 acu
= HIGH_REGISTER(AF
);
4175 AF
= addTable
[sum
] | cbitsZ80Table
[acu
^ temp
^ sum
];
4178 case 0x8c: /* ADC A,IXH */
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
];
4187 case 0x8d: /* ADC A,IXL */
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
];
4196 case 0x8e: /* ADC A,(IX+dd) */
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
];
4206 case 0x96: /* SUB (IX+dd) */
4208 adr
= IX
+ (int8
) RAM_PP(PC
);
4209 CHECK_BREAK_BYTE(adr
);
4210 temp
= GetBYTE(adr
);
4211 acu
= HIGH_REGISTER(AF
);
4213 AF
= addTable
[sum
& 0xff] | cbits2Z80Table
[(acu
^ temp
^ sum
) & 0x1ff];
4216 case 0x94: /* SUB IXH */
4217 SETFLAG(C
, 0);/* fall through, a bit less efficient but smaller code */
4219 case 0x9c: /* SBC A,IXH */
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];
4228 case 0x95: /* SUB IXL */
4229 SETFLAG(C
, 0);/* fall through, a bit less efficient but smaller code */
4231 case 0x9d: /* SBC A,IXL */
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];
4240 case 0x9e: /* SBC A,(IX+dd) */
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];
4250 case 0xa4: /* AND IXH */
4252 sim_brk_pend
[0] = FALSE
;
4253 AF
= andTable
[((AF
& IX
) >> 8) & 0xff];
4256 case 0xa5: /* AND IXL */
4258 sim_brk_pend
[0] = FALSE
;
4259 AF
= andTable
[((AF
>> 8) & IX
) & 0xff];
4262 case 0xa6: /* AND (IX+dd) */
4264 adr
= IX
+ (int8
) RAM_PP(PC
);
4265 CHECK_BREAK_BYTE(adr
);
4266 AF
= andTable
[((AF
>> 8) & GetBYTE(adr
)) & 0xff];
4269 case 0xac: /* XOR IXH */
4271 sim_brk_pend
[0] = FALSE
;
4272 AF
= xororTable
[((AF
^ IX
) >> 8) & 0xff];
4275 case 0xad: /* XOR IXL */
4277 sim_brk_pend
[0] = FALSE
;
4278 AF
= xororTable
[((AF
>> 8) ^ IX
) & 0xff];
4281 case 0xae: /* XOR (IX+dd) */
4283 adr
= IX
+ (int8
) RAM_PP(PC
);
4284 CHECK_BREAK_BYTE(adr
);
4285 AF
= xororTable
[((AF
>> 8) ^ GetBYTE(adr
)) & 0xff];
4288 case 0xb4: /* OR IXH */
4290 sim_brk_pend
[0] = FALSE
;
4291 AF
= xororTable
[((AF
| IX
) >> 8) & 0xff];
4294 case 0xb5: /* OR IXL */
4296 sim_brk_pend
[0] = FALSE
;
4297 AF
= xororTable
[((AF
>> 8) | IX
) & 0xff];
4300 case 0xb6: /* OR (IX+dd) */
4302 adr
= IX
+ (int8
) RAM_PP(PC
);
4303 CHECK_BREAK_BYTE(adr
);
4304 AF
= xororTable
[((AF
>> 8) | GetBYTE(adr
)) & 0xff];
4307 case 0xbc: /* CP IXH */
4309 sim_brk_pend
[0] = FALSE
;
4310 temp
= HIGH_REGISTER(IX
);
4311 AF
= (AF
& ~0x28) | (temp
& 0x28);
4312 acu
= HIGH_REGISTER(AF
);
4314 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
4315 cbits2Z80Table
[(acu
^ temp
^ sum
) & 0x1ff];
4318 case 0xbd: /* CP IXL */
4320 sim_brk_pend
[0] = FALSE
;
4321 temp
= LOW_REGISTER(IX
);
4322 AF
= (AF
& ~0x28) | (temp
& 0x28);
4323 acu
= HIGH_REGISTER(AF
);
4325 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
4326 cbits2Z80Table
[(acu
^ temp
^ sum
) & 0x1ff];
4329 case 0xbe: /* CP (IX+dd) */
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
);
4337 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
4338 cbits2Z80Table
[(acu
^ temp
^ sum
) & 0x1ff];
4341 case 0xcb: /* CB prefix */
4342 adr
= IX
+ (int8
) RAM_PP(PC
);
4343 switch ((op
= GetBYTE(PC
)) & 7) {
4346 sim_brk_pend
[0] = FALSE
;
4348 acu
= HIGH_REGISTER(BC
);
4352 sim_brk_pend
[0] = FALSE
;
4354 acu
= LOW_REGISTER(BC
);
4358 sim_brk_pend
[0] = FALSE
;
4360 acu
= HIGH_REGISTER(DE
);
4364 sim_brk_pend
[0] = FALSE
;
4366 acu
= LOW_REGISTER(DE
);
4370 sim_brk_pend
[0] = FALSE
;
4372 acu
= HIGH_REGISTER(HL
);
4376 sim_brk_pend
[0] = FALSE
;
4378 acu
= LOW_REGISTER(HL
);
4382 CHECK_BREAK_BYTE(adr
);
4388 sim_brk_pend
[0] = FALSE
;
4390 acu
= HIGH_REGISTER(AF
);
4393 switch (op
& 0xc0) {
4395 case 0x00: /* shift/rotate */
4397 switch (op
& 0x38) {
4399 case 0x00: /* RLC */
4400 temp
= (acu
<< 1) | (acu
>> 7);
4404 case 0x08: /* RRC */
4405 temp
= (acu
>> 1) | (acu
<< 7);
4406 cbits
= temp
& 0x80;
4410 temp
= (acu
<< 1) | TSTFLAG(C
);
4415 temp
= (acu
>> 1) | (TSTFLAG(C
) << 7);
4419 case 0x20: /* SLA */
4424 case 0x28: /* SRA */
4425 temp
= (acu
>> 1) | (acu
& 0x80);
4429 case 0x30: /* SLIA */
4430 temp
= (acu
<< 1) | 1;
4434 case 0x38: /* SRL */
4438 AF
= (AF
& ~0xff) | rotateShiftTable
[temp
& 0xff] | !!cbits
;
4439 /* !!cbits == 0 if cbits == 0 !!cbits == 1 if cbits > 0 */
4443 case 0x40: /* BIT */
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);
4452 case 0x80: /* RES */
4454 temp
= acu
& ~(1 << ((op
>> 3) & 7));
4457 case 0xc0: /* SET */
4459 temp
= acu
| (1 << ((op
>> 3) & 7));
4465 SET_HIGH_REGISTER(BC
, temp
);
4469 SET_LOW_REGISTER(BC
, temp
);
4473 SET_HIGH_REGISTER(DE
, temp
);
4477 SET_LOW_REGISTER(DE
, temp
);
4481 SET_HIGH_REGISTER(HL
, temp
);
4485 SET_LOW_REGISTER(HL
, temp
);
4493 SET_HIGH_REGISTER(AF
, temp
);
4498 case 0xe1: /* POP IX */
4500 CHECK_BREAK_WORD(SP
);
4504 case 0xe3: /* EX (SP),IX */
4506 CHECK_BREAK_WORD(SP
);
4512 case 0xe5: /* PUSH IX */
4514 CHECK_BREAK_WORD(SP
- 2);
4518 case 0xe9: /* JP (IX) */
4520 sim_brk_pend
[0] = FALSE
;
4525 case 0xf9: /* LD SP,IX */
4527 sim_brk_pend
[0] = FALSE
;
4531 default: /* ignore DD */
4532 sim_brk_pend
[0] = FALSE
;
4538 case 0xde: /* SBC A,nn */
4540 sim_brk_pend
[0] = FALSE
;
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
);
4548 case 0xdf: /* RST 18H */
4550 CHECK_BREAK_WORD(SP
- 2);
4556 case 0xe0: /* RET PO */
4558 sim_brk_pend
[0] = FALSE
;
4562 CHECK_BREAK_WORD(SP
);
4569 case 0xe1: /* POP HL */
4571 CHECK_BREAK_WORD(SP
);
4575 case 0xe2: /* JP PO,nnnn */
4576 sim_brk_pend
[0] = FALSE
;
4577 JPC(!TSTFLAG(P
)); /* also updates tStates */
4580 case 0xe3: /* EX (SP),HL */
4582 CHECK_BREAK_WORD(SP
);
4588 case 0xe4: /* CALL PO,nnnn */
4589 CALLC(!TSTFLAG(P
)); /* also updates tStates */
4592 case 0xe5: /* PUSH HL */
4594 CHECK_BREAK_WORD(SP
- 2);
4598 case 0xe6: /* AND nn */
4600 sim_brk_pend
[0] = FALSE
;
4601 AF
= andTable
[((AF
>> 8) & RAM_PP(PC
)) & 0xff];
4604 case 0xe7: /* RST 20H */
4606 CHECK_BREAK_WORD(SP
- 2);
4612 case 0xe8: /* RET PE */
4614 CHECK_BREAK_WORD(SP
);
4620 sim_brk_pend
[0] = FALSE
;
4625 case 0xe9: /* JP (HL) */
4627 sim_brk_pend
[0] = FALSE
;
4632 case 0xea: /* JP PE,nnnn */
4633 sim_brk_pend
[0] = FALSE
;
4634 JPC(TSTFLAG(P
)); /* also updates tStates */
4637 case 0xeb: /* EX DE,HL */
4639 sim_brk_pend
[0] = FALSE
;
4645 case 0xec: /* CALL PE,nnnn */
4646 CALLC(TSTFLAG(P
)); /* also updates tStates */
4649 case 0xed: /* ED prefix */
4651 switch (op
= RAM_PP(PC
)) {
4653 case 0x40: /* IN B,(C) */
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];
4661 case 0x41: /* OUT (C),B */
4663 sim_brk_pend
[0] = FALSE
;
4664 out(LOW_REGISTER(BC
), HIGH_REGISTER(BC
));
4667 case 0x42: /* SBC HL,BC */
4669 sim_brk_pend
[0] = FALSE
;
4672 sum
= HL
- BC
- TSTFLAG(C
);
4673 AF
= (AF
& ~0xff) | ((sum
>> 8) & 0xa8) | (((sum
& ADDRMASK
) == 0) << 6) |
4674 cbits2Z80Table
[((HL
^ BC
^ sum
) >> 8) & 0x1ff];
4678 case 0x43: /* LD (nnnn),BC */
4680 temp
= GET_WORD(PC
);
4681 CHECK_BREAK_WORD(temp
);
4686 case 0x44: /* NEG */
4688 case 0x4C: /* NEG, unofficial */
4690 case 0x54: /* NEG, unofficial */
4692 case 0x5C: /* NEG, unofficial */
4694 case 0x64: /* NEG, unofficial */
4696 case 0x6C: /* NEG, unofficial */
4698 case 0x74: /* NEG, unofficial */
4700 case 0x7C: /* NEG, unofficial */
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
];
4708 case 0x45: /* RETN */
4710 case 0x55: /* RETN, unofficial */
4712 case 0x5D: /* RETN, unofficial */
4714 case 0x65: /* RETN, unofficial */
4716 case 0x6D: /* RETN, unofficial */
4718 case 0x75: /* RETN, unofficial */
4720 case 0x7D: /* RETN, unofficial */
4722 IFF_S
|= IFF_S
>> 1;
4723 CHECK_BREAK_WORD(SP
);
4728 case 0x46: /* IM 0 */
4730 sim_brk_pend
[0] = FALSE
;
4731 /* interrupt mode 0 */
4734 case 0x47: /* LD I,A */
4736 sim_brk_pend
[0] = FALSE
;
4737 IR_S
= (IR_S
& 0xff) | (AF
& ~0xff);
4740 case 0x48: /* IN C,(C) */
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];
4748 case 0x49: /* OUT (C),C */
4750 sim_brk_pend
[0] = FALSE
;
4751 out(LOW_REGISTER(BC
), LOW_REGISTER(BC
));
4754 case 0x4a: /* ADC HL,BC */
4756 sim_brk_pend
[0] = FALSE
;
4759 sum
= HL
+ BC
+ TSTFLAG(C
);
4760 AF
= (AF
& ~0xff) | ((sum
>> 8) & 0xa8) | (((sum
& ADDRMASK
) == 0) << 6) |
4761 cbitsZ80Table
[(HL
^ BC
^ sum
) >> 8];
4765 case 0x4b: /* LD BC,(nnnn) */
4767 temp
= GET_WORD(PC
);
4768 CHECK_BREAK_WORD(temp
);
4769 BC
= GET_WORD(temp
);
4773 case 0x4d: /* RETI */
4775 IFF_S
|= IFF_S
>> 1;
4776 CHECK_BREAK_WORD(SP
);
4781 case 0x4f: /* LD R,A */
4783 sim_brk_pend
[0] = FALSE
;
4784 IR_S
= (IR_S
& ~0xff) | ((AF
>> 8) & 0xff);
4787 case 0x50: /* IN D,(C) */
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];
4795 case 0x51: /* OUT (C),D */
4797 sim_brk_pend
[0] = FALSE
;
4798 out(LOW_REGISTER(BC
), HIGH_REGISTER(DE
));
4801 case 0x52: /* SBC HL,DE */
4803 sim_brk_pend
[0] = FALSE
;
4806 sum
= HL
- DE
- TSTFLAG(C
);
4807 AF
= (AF
& ~0xff) | ((sum
>> 8) & 0xa8) | (((sum
& ADDRMASK
) == 0) << 6) |
4808 cbits2Z80Table
[((HL
^ DE
^ sum
) >> 8) & 0x1ff];
4812 case 0x53: /* LD (nnnn),DE */
4814 temp
= GET_WORD(PC
);
4815 CHECK_BREAK_WORD(temp
);
4820 case 0x56: /* IM 1 */
4822 sim_brk_pend
[0] = FALSE
;
4823 /* interrupt mode 1 */
4826 case 0x57: /* LD A,I */
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);
4832 case 0x58: /* IN E,(C) */
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];
4840 case 0x59: /* OUT (C),E */
4842 sim_brk_pend
[0] = FALSE
;
4843 out(LOW_REGISTER(BC
), LOW_REGISTER(DE
));
4846 case 0x5a: /* ADC HL,DE */
4848 sim_brk_pend
[0] = FALSE
;
4851 sum
= HL
+ DE
+ TSTFLAG(C
);
4852 AF
= (AF
& ~0xff) | ((sum
>> 8) & 0xa8) | (((sum
& ADDRMASK
) == 0) << 6) |
4853 cbitsZ80Table
[(HL
^ DE
^ sum
) >> 8];
4857 case 0x5b: /* LD DE,(nnnn) */
4859 temp
= GET_WORD(PC
);
4860 CHECK_BREAK_WORD(temp
);
4861 DE
= GET_WORD(temp
);
4865 case 0x5e: /* IM 2 */
4867 sim_brk_pend
[0] = FALSE
;
4868 /* interrupt mode 2 */
4871 case 0x5f: /* LD A,R */
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);
4878 case 0x60: /* IN H,(C) */
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];
4886 case 0x61: /* OUT (C),H */
4888 sim_brk_pend
[0] = FALSE
;
4889 out(LOW_REGISTER(BC
), HIGH_REGISTER(HL
));
4892 case 0x62: /* SBC HL,HL */
4894 sim_brk_pend
[0] = FALSE
;
4896 sum
= HL
- HL
- TSTFLAG(C
);
4897 AF
= (AF
& ~0xff) | (((sum
& ADDRMASK
) == 0) << 6) |
4898 cbits2Z80DupTable
[(sum
>> 8) & 0x1ff];
4902 case 0x63: /* LD (nnnn),HL */
4904 temp
= GET_WORD(PC
);
4905 CHECK_BREAK_WORD(temp
);
4910 case 0x67: /* RRD */
4912 sim_brk_pend
[0] = FALSE
;
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);
4919 case 0x68: /* IN L,(C) */
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];
4927 case 0x69: /* OUT (C),L */
4929 sim_brk_pend
[0] = FALSE
;
4930 out(LOW_REGISTER(BC
), LOW_REGISTER(HL
));
4933 case 0x6a: /* ADC HL,HL */
4935 sim_brk_pend
[0] = FALSE
;
4937 sum
= HL
+ HL
+ TSTFLAG(C
);
4938 AF
= (AF
& ~0xff) | (((sum
& ADDRMASK
) == 0) << 6) |
4939 cbitsZ80DupTable
[sum
>> 8];
4943 case 0x6b: /* LD HL,(nnnn) */
4945 temp
= GET_WORD(PC
);
4946 CHECK_BREAK_WORD(temp
);
4947 HL
= GET_WORD(temp
);
4951 case 0x6f: /* RLD */
4953 sim_brk_pend
[0] = FALSE
;
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);
4960 case 0x70: /* IN (C) */
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];
4968 case 0x71: /* OUT (C),0 */
4970 sim_brk_pend
[0] = FALSE
;
4971 out(LOW_REGISTER(BC
), 0);
4974 case 0x72: /* SBC HL,SP */
4976 sim_brk_pend
[0] = FALSE
;
4979 sum
= HL
- SP
- TSTFLAG(C
);
4980 AF
= (AF
& ~0xff) | ((sum
>> 8) & 0xa8) | (((sum
& ADDRMASK
) == 0) << 6) |
4981 cbits2Z80Table
[((HL
^ SP
^ sum
) >> 8) & 0x1ff];
4985 case 0x73: /* LD (nnnn),SP */
4987 temp
= GET_WORD(PC
);
4988 CHECK_BREAK_WORD(temp
);
4993 case 0x78: /* IN A,(C) */
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];
5001 case 0x79: /* OUT (C),A */
5003 sim_brk_pend
[0] = FALSE
;
5004 out(LOW_REGISTER(BC
), HIGH_REGISTER(AF
));
5007 case 0x7a: /* ADC HL,SP */
5009 sim_brk_pend
[0] = FALSE
;
5012 sum
= HL
+ SP
+ TSTFLAG(C
);
5013 AF
= (AF
& ~0xff) | ((sum
>> 8) & 0xa8) | (((sum
& ADDRMASK
) == 0) << 6) |
5014 cbitsZ80Table
[(HL
^ SP
^ sum
) >> 8];
5018 case 0x7b: /* LD SP,(nnnn) */
5020 temp
= GET_WORD(PC
);
5021 CHECK_BREAK_WORD(temp
);
5022 SP
= GET_WORD(temp
);
5026 case 0xa0: /* LDI */
5028 CHECK_BREAK_TWO_BYTES(HL
, DE
);
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);
5036 case 0xa1: /* CPI */
5038 CHECK_BREAK_BYTE(HL
);
5039 acu
= HIGH_REGISTER(AF
);
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;
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 */
5059 CHECK_BREAK_BYTE(HL
);
5060 acu
= in(LOW_REGISTER(BC
));
5063 temp
= HIGH_REGISTER(BC
);
5065 INOUTFLAGS_NONZERO((LOW_REGISTER(BC
) + 1) & 0xff);
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 */
5078 CHECK_BREAK_BYTE(HL
);
5080 out(LOW_REGISTER(BC
), acu
);
5082 temp
= HIGH_REGISTER(BC
);
5084 INOUTFLAGS_NONZERO(LOW_REGISTER(HL
));
5087 case 0xa8: /* LDD */
5089 CHECK_BREAK_TWO_BYTES(HL
, DE
);
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);
5097 case 0xa9: /* CPD */
5099 CHECK_BREAK_BYTE(HL
);
5100 acu
= HIGH_REGISTER(AF
);
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;
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 */
5120 CHECK_BREAK_BYTE(HL
);
5121 acu
= in(LOW_REGISTER(BC
));
5124 temp
= HIGH_REGISTER(BC
);
5126 INOUTFLAGS_NONZERO((LOW_REGISTER(BC
) - 1) & 0xff);
5129 case 0xab: /* OUTD */
5131 CHECK_BREAK_BYTE(HL
);
5133 out(LOW_REGISTER(BC
), acu
);
5135 temp
= HIGH_REGISTER(BC
);
5137 INOUTFLAGS_NONZERO(LOW_REGISTER(HL
));
5140 case 0xb0: /* LDIR */
5142 acu
= HIGH_REGISTER(AF
);
5144 if (BC
== 0) BC
= 0x10000;
5147 CHECK_BREAK_TWO_BYTES(HL
, DE
);
5149 PUT_BYTE_PP(DE
, acu
);
5151 acu
+= HIGH_REGISTER(AF
);
5152 AF
= (AF
& ~0x3e) | (acu
& 8) | ((acu
& 2) << 4);
5155 case 0xb1: /* CPIR */
5157 acu
= HIGH_REGISTER(AF
);
5159 if (BC
== 0) BC
= 0x10000;
5162 CHECK_BREAK_BYTE(HL
);
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) |
5172 if ((sum
& 15) == 8 && (cbits
& 16) != 0) AF
&= ~8;
5175 case 0xb2: /* INIR */
5177 temp
= HIGH_REGISTER(BC
);
5178 if (temp
== 0) temp
= 0x100;
5181 CHECK_BREAK_BYTE(HL
);
5182 acu
= in(LOW_REGISTER(BC
));
5186 temp
= HIGH_REGISTER(BC
);
5187 SET_HIGH_REGISTER(BC
, 0);
5188 INOUTFLAGS_ZERO((LOW_REGISTER(BC
) + 1) & 0xff);
5191 case 0xb3: /* OTIR */
5193 temp
= HIGH_REGISTER(BC
);
5194 if (temp
== 0) temp
= 0x100;
5197 CHECK_BREAK_BYTE(HL
);
5199 out(LOW_REGISTER(BC
), acu
);
5202 temp
= HIGH_REGISTER(BC
);
5203 SET_HIGH_REGISTER(BC
, 0);
5204 INOUTFLAGS_ZERO(LOW_REGISTER(HL
));
5207 case 0xb8: /* LDDR */
5210 if (BC
== 0) BC
= 0x10000;
5213 CHECK_BREAK_TWO_BYTES(HL
, DE
);
5215 PUT_BYTE_MM(DE
, acu
);
5217 acu
+= HIGH_REGISTER(AF
);
5218 AF
= (AF
& ~0x3e) | (acu
& 8) | ((acu
& 2) << 4);
5221 case 0xb9: /* CPDR */
5223 acu
= HIGH_REGISTER(AF
);
5225 if (BC
== 0) BC
= 0x10000;
5228 CHECK_BREAK_BYTE(HL
);
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) |
5238 if ((sum
& 15) == 8 && (cbits
& 16) != 0) AF
&= ~8;
5241 case 0xba: /* INDR */
5243 temp
= HIGH_REGISTER(BC
);
5244 if (temp
== 0) temp
= 0x100;
5247 CHECK_BREAK_BYTE(HL
);
5248 acu
= in(LOW_REGISTER(BC
));
5252 temp
= HIGH_REGISTER(BC
);
5253 SET_HIGH_REGISTER(BC
, 0);
5254 INOUTFLAGS_ZERO((LOW_REGISTER(BC
) - 1) & 0xff);
5257 case 0xbb: /* OTDR */
5259 temp
= HIGH_REGISTER(BC
);
5260 if (temp
== 0) temp
= 0x100;
5263 CHECK_BREAK_BYTE(HL
);
5265 out(LOW_REGISTER(BC
), acu
);
5268 temp
= HIGH_REGISTER(BC
);
5269 SET_HIGH_REGISTER(BC
, 0);
5270 INOUTFLAGS_ZERO(LOW_REGISTER(HL
));
5273 default: /* ignore ED and following byte */
5274 sim_brk_pend
[0] = FALSE
;
5279 case 0xee: /* XOR nn */
5281 sim_brk_pend
[0] = FALSE
;
5282 AF
= xororTable
[((AF
>> 8) ^ RAM_PP(PC
)) & 0xff];
5285 case 0xef: /* RST 28H */
5287 CHECK_BREAK_WORD(SP
- 2);
5293 case 0xf0: /* RET P */
5295 sim_brk_pend
[0] = FALSE
;
5299 CHECK_BREAK_WORD(SP
);
5306 case 0xf1: /* POP AF */
5308 CHECK_BREAK_WORD(SP
);
5312 case 0xf2: /* JP P,nnnn */
5313 sim_brk_pend
[0] = FALSE
;
5314 JPC(!TSTFLAG(S
)); /* also updates tStates */
5319 sim_brk_pend
[0] = FALSE
;
5323 case 0xf4: /* CALL P,nnnn */
5324 CALLC(!TSTFLAG(S
)); /* also updates tStates */
5327 case 0xf5: /* PUSH AF */
5329 CHECK_BREAK_WORD(SP
- 2);
5333 case 0xf6: /* OR nn */
5335 sim_brk_pend
[0] = FALSE
;
5336 AF
= xororTable
[((AF
>> 8) | RAM_PP(PC
)) & 0xff];
5339 case 0xf7: /* RST 30H */
5341 CHECK_BREAK_WORD(SP
- 2);
5347 case 0xf8: /* RET M */
5349 CHECK_BREAK_WORD(SP
);
5355 sim_brk_pend
[0] = FALSE
;
5360 case 0xf9: /* LD SP,HL */
5362 sim_brk_pend
[0] = FALSE
;
5366 case 0xfa: /* JP M,nnnn */
5367 sim_brk_pend
[0] = FALSE
;
5368 JPC(TSTFLAG(S
)); /* also updates tStates */
5373 sim_brk_pend
[0] = FALSE
;
5377 case 0xfc: /* CALL M,nnnn */
5378 CALLC(TSTFLAG(S
)); /* also updates tStates */
5381 case 0xfd: /* FD prefix */
5383 switch (op
= RAM_PP(PC
)) {
5385 case 0x09: /* ADD IY,BC */
5387 sim_brk_pend
[0] = FALSE
;
5391 AF
= (AF
& ~0x3b) | ((sum
>> 8) & 0x28) | cbitsTable
[(IY
^ BC
^ sum
) >> 8];
5395 case 0x19: /* ADD IY,DE */
5397 sim_brk_pend
[0] = FALSE
;
5401 AF
= (AF
& ~0x3b) | ((sum
>> 8) & 0x28) | cbitsTable
[(IY
^ DE
^ sum
) >> 8];
5405 case 0x21: /* LD IY,nnnn */
5407 sim_brk_pend
[0] = FALSE
;
5412 case 0x22: /* LD (nnnn),IY */
5414 temp
= GET_WORD(PC
);
5415 CHECK_BREAK_WORD(temp
);
5420 case 0x23: /* INC IY */
5422 sim_brk_pend
[0] = FALSE
;
5426 case 0x24: /* INC IYH */
5428 sim_brk_pend
[0] = FALSE
;
5430 AF
= (AF
& ~0xfe) | incZ80Table
[HIGH_REGISTER(IY
)];
5433 case 0x25: /* DEC IYH */
5435 sim_brk_pend
[0] = FALSE
;
5437 AF
= (AF
& ~0xfe) | decZ80Table
[HIGH_REGISTER(IY
)];
5440 case 0x26: /* LD IYH,nn */
5442 sim_brk_pend
[0] = FALSE
;
5443 SET_HIGH_REGISTER(IY
, RAM_PP(PC
));
5446 case 0x29: /* ADD IY,IY */
5448 sim_brk_pend
[0] = FALSE
;
5451 AF
= (AF
& ~0x3b) | cbitsDup16Table
[sum
>> 8];
5455 case 0x2a: /* LD IY,(nnnn) */
5457 temp
= GET_WORD(PC
);
5458 CHECK_BREAK_WORD(temp
);
5459 IY
= GET_WORD(temp
);
5463 case 0x2b: /* DEC IY */
5465 sim_brk_pend
[0] = FALSE
;
5469 case 0x2c: /* INC IYL */
5471 sim_brk_pend
[0] = FALSE
;
5472 temp
= LOW_REGISTER(IY
) + 1;
5473 SET_LOW_REGISTER(IY
, temp
);
5474 AF
= (AF
& ~0xfe) | incZ80Table
[temp
];
5477 case 0x2d: /* DEC IYL */
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];
5485 case 0x2e: /* LD IYL,nn */
5487 sim_brk_pend
[0] = FALSE
;
5488 SET_LOW_REGISTER(IY
, RAM_PP(PC
));
5491 case 0x34: /* INC (IY+dd) */
5493 adr
= IY
+ (int8
) RAM_PP(PC
);
5494 CHECK_BREAK_BYTE(adr
);
5495 temp
= GetBYTE(adr
) + 1;
5497 AF
= (AF
& ~0xfe) | incZ80Table
[temp
];
5500 case 0x35: /* DEC (IY+dd) */
5502 adr
= IY
+ (int8
) RAM_PP(PC
);
5503 CHECK_BREAK_BYTE(adr
);
5504 temp
= GetBYTE(adr
) - 1;
5506 AF
= (AF
& ~0xfe) | decZ80Table
[temp
& 0xff];
5509 case 0x36: /* LD (IY+dd),nn */
5511 adr
= IY
+ (int8
) RAM_PP(PC
);
5512 CHECK_BREAK_BYTE(adr
);
5513 PutBYTE(adr
, RAM_PP(PC
));
5516 case 0x39: /* ADD IY,SP */
5518 sim_brk_pend
[0] = FALSE
;
5522 AF
= (AF
& ~0x3b) | ((sum
>> 8) & 0x28) | cbitsTable
[(IY
^ SP
^ sum
) >> 8];
5526 case 0x44: /* LD B,IYH */
5528 sim_brk_pend
[0] = FALSE
;
5529 SET_HIGH_REGISTER(BC
, HIGH_REGISTER(IY
));
5532 case 0x45: /* LD B,IYL */
5534 sim_brk_pend
[0] = FALSE
;
5535 SET_HIGH_REGISTER(BC
, LOW_REGISTER(IY
));
5538 case 0x46: /* LD B,(IY+dd) */
5540 adr
= IY
+ (int8
) RAM_PP(PC
);
5541 CHECK_BREAK_BYTE(adr
);
5542 SET_HIGH_REGISTER(BC
, GetBYTE(adr
));
5545 case 0x4c: /* LD C,IYH */
5547 sim_brk_pend
[0] = FALSE
;
5548 SET_LOW_REGISTER(BC
, HIGH_REGISTER(IY
));
5551 case 0x4d: /* LD C,IYL */
5553 sim_brk_pend
[0] = FALSE
;
5554 SET_LOW_REGISTER(BC
, LOW_REGISTER(IY
));
5557 case 0x4e: /* LD C,(IY+dd) */
5559 adr
= IY
+ (int8
) RAM_PP(PC
);
5560 CHECK_BREAK_BYTE(adr
);
5561 SET_LOW_REGISTER(BC
, GetBYTE(adr
));
5564 case 0x54: /* LD D,IYH */
5566 sim_brk_pend
[0] = FALSE
;
5567 SET_HIGH_REGISTER(DE
, HIGH_REGISTER(IY
));
5570 case 0x55: /* LD D,IYL */
5572 sim_brk_pend
[0] = FALSE
;
5573 SET_HIGH_REGISTER(DE
, LOW_REGISTER(IY
));
5576 case 0x56: /* LD D,(IY+dd) */
5578 adr
= IY
+ (int8
) RAM_PP(PC
);
5579 CHECK_BREAK_BYTE(adr
);
5580 SET_HIGH_REGISTER(DE
, GetBYTE(adr
));
5583 case 0x5c: /* LD E,IYH */
5585 sim_brk_pend
[0] = FALSE
;
5586 SET_LOW_REGISTER(DE
, HIGH_REGISTER(IY
));
5589 case 0x5d: /* LD E,IYL */
5591 sim_brk_pend
[0] = FALSE
;
5592 SET_LOW_REGISTER(DE
, LOW_REGISTER(IY
));
5595 case 0x5e: /* LD E,(IY+dd) */
5597 adr
= IY
+ (int8
) RAM_PP(PC
);
5598 CHECK_BREAK_BYTE(adr
);
5599 SET_LOW_REGISTER(DE
, GetBYTE(adr
));
5602 case 0x60: /* LD IYH,B */
5604 sim_brk_pend
[0] = FALSE
;
5605 SET_HIGH_REGISTER(IY
, HIGH_REGISTER(BC
));
5608 case 0x61: /* LD IYH,C */
5610 sim_brk_pend
[0] = FALSE
;
5611 SET_HIGH_REGISTER(IY
, LOW_REGISTER(BC
));
5614 case 0x62: /* LD IYH,D */
5616 sim_brk_pend
[0] = FALSE
;
5617 SET_HIGH_REGISTER(IY
, HIGH_REGISTER(DE
));
5620 case 0x63: /* LD IYH,E */
5622 sim_brk_pend
[0] = FALSE
;
5623 SET_HIGH_REGISTER(IY
, LOW_REGISTER(DE
));
5626 case 0x64: /* LD IYH,IYH */
5628 sim_brk_pend
[0] = FALSE
; /* nop */
5631 case 0x65: /* LD IYH,IYL */
5633 sim_brk_pend
[0] = FALSE
;
5634 SET_HIGH_REGISTER(IY
, LOW_REGISTER(IY
));
5637 case 0x66: /* LD H,(IY+dd) */
5639 adr
= IY
+ (int8
) RAM_PP(PC
);
5640 CHECK_BREAK_BYTE(adr
);
5641 SET_HIGH_REGISTER(HL
, GetBYTE(adr
));
5644 case 0x67: /* LD IYH,A */
5646 sim_brk_pend
[0] = FALSE
;
5647 SET_HIGH_REGISTER(IY
, HIGH_REGISTER(AF
));
5650 case 0x68: /* LD IYL,B */
5652 sim_brk_pend
[0] = FALSE
;
5653 SET_LOW_REGISTER(IY
, HIGH_REGISTER(BC
));
5656 case 0x69: /* LD IYL,C */
5658 sim_brk_pend
[0] = FALSE
;
5659 SET_LOW_REGISTER(IY
, LOW_REGISTER(BC
));
5662 case 0x6a: /* LD IYL,D */
5664 sim_brk_pend
[0] = FALSE
;
5665 SET_LOW_REGISTER(IY
, HIGH_REGISTER(DE
));
5668 case 0x6b: /* LD IYL,E */
5670 sim_brk_pend
[0] = FALSE
;
5671 SET_LOW_REGISTER(IY
, LOW_REGISTER(DE
));
5674 case 0x6c: /* LD IYL,IYH */
5676 sim_brk_pend
[0] = FALSE
;
5677 SET_LOW_REGISTER(IY
, HIGH_REGISTER(IY
));
5680 case 0x6d: /* LD IYL,IYL */
5682 sim_brk_pend
[0] = FALSE
; /* nop */
5685 case 0x6e: /* LD L,(IY+dd) */
5687 adr
= IY
+ (int8
) RAM_PP(PC
);
5688 CHECK_BREAK_BYTE(adr
);
5689 SET_LOW_REGISTER(HL
, GetBYTE(adr
));
5692 case 0x6f: /* LD IYL,A */
5694 sim_brk_pend
[0] = FALSE
;
5695 SET_LOW_REGISTER(IY
, HIGH_REGISTER(AF
));
5698 case 0x70: /* LD (IY+dd),B */
5700 adr
= IY
+ (int8
) RAM_PP(PC
);
5701 CHECK_BREAK_BYTE(adr
);
5702 PutBYTE(adr
, HIGH_REGISTER(BC
));
5705 case 0x71: /* LD (IY+dd),C */
5707 adr
= IY
+ (int8
) RAM_PP(PC
);
5708 CHECK_BREAK_BYTE(adr
);
5709 PutBYTE(adr
, LOW_REGISTER(BC
));
5712 case 0x72: /* LD (IY+dd),D */
5714 adr
= IY
+ (int8
) RAM_PP(PC
);
5715 CHECK_BREAK_BYTE(adr
);
5716 PutBYTE(adr
, HIGH_REGISTER(DE
));
5719 case 0x73: /* LD (IY+dd),E */
5721 adr
= IY
+ (int8
) RAM_PP(PC
);
5722 CHECK_BREAK_BYTE(adr
);
5723 PutBYTE(adr
, LOW_REGISTER(DE
));
5726 case 0x74: /* LD (IY+dd),H */
5728 adr
= IY
+ (int8
) RAM_PP(PC
);
5729 CHECK_BREAK_BYTE(adr
);
5730 PutBYTE(adr
, HIGH_REGISTER(HL
));
5733 case 0x75: /* LD (IY+dd),L */
5735 adr
= IY
+ (int8
) RAM_PP(PC
);
5736 CHECK_BREAK_BYTE(adr
);
5737 PutBYTE(adr
, LOW_REGISTER(HL
));
5740 case 0x77: /* LD (IY+dd),A */
5742 adr
= IY
+ (int8
) RAM_PP(PC
);
5743 CHECK_BREAK_BYTE(adr
);
5744 PutBYTE(adr
, HIGH_REGISTER(AF
));
5747 case 0x7c: /* LD A,IYH */
5749 sim_brk_pend
[0] = FALSE
;
5750 SET_HIGH_REGISTER(AF
, HIGH_REGISTER(IY
));
5753 case 0x7d: /* LD A,IYL */
5755 sim_brk_pend
[0] = FALSE
;
5756 SET_HIGH_REGISTER(AF
, LOW_REGISTER(IY
));
5759 case 0x7e: /* LD A,(IY+dd) */
5761 adr
= IY
+ (int8
) RAM_PP(PC
);
5762 CHECK_BREAK_BYTE(adr
);
5763 SET_HIGH_REGISTER(AF
, GetBYTE(adr
));
5766 case 0x84: /* ADD A,IYH */
5768 sim_brk_pend
[0] = FALSE
;
5769 temp
= HIGH_REGISTER(IY
);
5770 acu
= HIGH_REGISTER(AF
);
5772 AF
= addTable
[sum
] | cbitsZ80Table
[acu
^ temp
^ sum
];
5775 case 0x85: /* ADD A,IYL */
5777 sim_brk_pend
[0] = FALSE
;
5778 temp
= LOW_REGISTER(IY
);
5779 acu
= HIGH_REGISTER(AF
);
5781 AF
= addTable
[sum
] | cbitsZ80Table
[acu
^ temp
^ sum
];
5784 case 0x86: /* ADD A,(IY+dd) */
5786 adr
= IY
+ (int8
) RAM_PP(PC
);
5787 CHECK_BREAK_BYTE(adr
);
5788 temp
= GetBYTE(adr
);
5789 acu
= HIGH_REGISTER(AF
);
5791 AF
= addTable
[sum
] | cbitsZ80Table
[acu
^ temp
^ sum
];
5794 case 0x8c: /* ADC A,IYH */
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
];
5803 case 0x8d: /* ADC A,IYL */
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
];
5812 case 0x8e: /* ADC A,(IY+dd) */
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
];
5822 case 0x96: /* SUB (IY+dd) */
5824 adr
= IY
+ (int8
) RAM_PP(PC
);
5825 CHECK_BREAK_BYTE(adr
);
5826 temp
= GetBYTE(adr
);
5827 acu
= HIGH_REGISTER(AF
);
5829 AF
= addTable
[sum
& 0xff] | cbits2Z80Table
[(acu
^ temp
^ sum
) & 0x1ff];
5832 case 0x94: /* SUB IYH */
5833 SETFLAG(C
, 0);/* fall through, a bit less efficient but smaller code */
5835 case 0x9c: /* SBC A,IYH */
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];
5844 case 0x95: /* SUB IYL */
5845 SETFLAG(C
, 0);/* fall through, a bit less efficient but smaller code */
5847 case 0x9d: /* SBC A,IYL */
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];
5856 case 0x9e: /* SBC A,(IY+dd) */
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];
5866 case 0xa4: /* AND IYH */
5868 sim_brk_pend
[0] = FALSE
;
5869 AF
= andTable
[((AF
& IY
) >> 8) & 0xff];
5872 case 0xa5: /* AND IYL */
5874 sim_brk_pend
[0] = FALSE
;
5875 AF
= andTable
[((AF
>> 8) & IY
) & 0xff];
5878 case 0xa6: /* AND (IY+dd) */
5880 adr
= IY
+ (int8
) RAM_PP(PC
);
5881 CHECK_BREAK_BYTE(adr
);
5882 AF
= andTable
[((AF
>> 8) & GetBYTE(adr
)) & 0xff];
5885 case 0xac: /* XOR IYH */
5887 sim_brk_pend
[0] = FALSE
;
5888 AF
= xororTable
[((AF
^ IY
) >> 8) & 0xff];
5891 case 0xad: /* XOR IYL */
5893 sim_brk_pend
[0] = FALSE
;
5894 AF
= xororTable
[((AF
>> 8) ^ IY
) & 0xff];
5897 case 0xae: /* XOR (IY+dd) */
5899 adr
= IY
+ (int8
) RAM_PP(PC
);
5900 CHECK_BREAK_BYTE(adr
);
5901 AF
= xororTable
[((AF
>> 8) ^ GetBYTE(adr
)) & 0xff];
5904 case 0xb4: /* OR IYH */
5906 sim_brk_pend
[0] = FALSE
;
5907 AF
= xororTable
[((AF
| IY
) >> 8) & 0xff];
5910 case 0xb5: /* OR IYL */
5912 sim_brk_pend
[0] = FALSE
;
5913 AF
= xororTable
[((AF
>> 8) | IY
) & 0xff];
5916 case 0xb6: /* OR (IY+dd) */
5918 adr
= IY
+ (int8
) RAM_PP(PC
);
5919 CHECK_BREAK_BYTE(adr
);
5920 AF
= xororTable
[((AF
>> 8) | GetBYTE(adr
)) & 0xff];
5923 case 0xbc: /* CP IYH */
5925 sim_brk_pend
[0] = FALSE
;
5926 temp
= HIGH_REGISTER(IY
);
5927 AF
= (AF
& ~0x28) | (temp
& 0x28);
5928 acu
= HIGH_REGISTER(AF
);
5930 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
5931 cbits2Z80Table
[(acu
^ temp
^ sum
) & 0x1ff];
5934 case 0xbd: /* CP IYL */
5936 sim_brk_pend
[0] = FALSE
;
5937 temp
= LOW_REGISTER(IY
);
5938 AF
= (AF
& ~0x28) | (temp
& 0x28);
5939 acu
= HIGH_REGISTER(AF
);
5941 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
5942 cbits2Z80Table
[(acu
^ temp
^ sum
) & 0x1ff];
5945 case 0xbe: /* CP (IY+dd) */
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
);
5953 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
5954 cbits2Z80Table
[(acu
^ temp
^ sum
) & 0x1ff];
5957 case 0xcb: /* CB prefix */
5958 adr
= IY
+ (int8
) RAM_PP(PC
);
5959 switch ((op
= GetBYTE(PC
)) & 7) {
5962 sim_brk_pend
[0] = FALSE
;
5964 acu
= HIGH_REGISTER(BC
);
5968 sim_brk_pend
[0] = FALSE
;
5970 acu
= LOW_REGISTER(BC
);
5974 sim_brk_pend
[0] = FALSE
;
5976 acu
= HIGH_REGISTER(DE
);
5980 sim_brk_pend
[0] = FALSE
;
5982 acu
= LOW_REGISTER(DE
);
5986 sim_brk_pend
[0] = FALSE
;
5988 acu
= HIGH_REGISTER(HL
);
5992 sim_brk_pend
[0] = FALSE
;
5994 acu
= LOW_REGISTER(HL
);
5998 CHECK_BREAK_BYTE(adr
);
6004 sim_brk_pend
[0] = FALSE
;
6006 acu
= HIGH_REGISTER(AF
);
6009 switch (op
& 0xc0) {
6011 case 0x00: /* shift/rotate */
6013 switch (op
& 0x38) {
6015 case 0x00: /* RLC */
6016 temp
= (acu
<< 1) | (acu
>> 7);
6020 case 0x08: /* RRC */
6021 temp
= (acu
>> 1) | (acu
<< 7);
6022 cbits
= temp
& 0x80;
6026 temp
= (acu
<< 1) | TSTFLAG(C
);
6031 temp
= (acu
>> 1) | (TSTFLAG(C
) << 7);
6035 case 0x20: /* SLA */
6040 case 0x28: /* SRA */
6041 temp
= (acu
>> 1) | (acu
& 0x80);
6045 case 0x30: /* SLIA */
6046 temp
= (acu
<< 1) | 1;
6050 case 0x38: /* SRL */
6054 AF
= (AF
& ~0xff) | rotateShiftTable
[temp
& 0xff] | !!cbits
;
6055 /* !!cbits == 0 if cbits == 0 !!cbits == 1 if cbits > 0 */
6059 case 0x40: /* BIT */
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);
6068 case 0x80: /* RES */
6070 temp
= acu
& ~(1 << ((op
>> 3) & 7));
6073 case 0xc0: /* SET */
6075 temp
= acu
| (1 << ((op
>> 3) & 7));
6081 SET_HIGH_REGISTER(BC
, temp
);
6085 SET_LOW_REGISTER(BC
, temp
);
6089 SET_HIGH_REGISTER(DE
, temp
);
6093 SET_LOW_REGISTER(DE
, temp
);
6097 SET_HIGH_REGISTER(HL
, temp
);
6101 SET_LOW_REGISTER(HL
, temp
);
6109 SET_HIGH_REGISTER(AF
, temp
);
6114 case 0xe1: /* POP IY */
6116 CHECK_BREAK_WORD(SP
);
6120 case 0xe3: /* EX (SP),IY */
6122 CHECK_BREAK_WORD(SP
);
6128 case 0xe5: /* PUSH IY */
6130 CHECK_BREAK_WORD(SP
- 2);
6134 case 0xe9: /* JP (IY) */
6136 sim_brk_pend
[0] = FALSE
;
6141 case 0xf9: /* LD SP,IY */
6143 sim_brk_pend
[0] = FALSE
;
6147 default: /* ignore FD */
6148 sim_brk_pend
[0] = FALSE
;
6154 case 0xfe: /* CP nn */
6156 sim_brk_pend
[0] = FALSE
;
6158 AF
= (AF
& ~0x28) | (temp
& 0x28);
6159 acu
= HIGH_REGISTER(AF
);
6161 cbits
= acu
^ temp
^ sum
;
6162 AF
= (AF
& ~0xff) | cpTable
[sum
& 0xff] | (temp
& 0x28) |
6163 (SET_PV
) | cbits2Table
[cbits
& 0x1ff];
6166 case 0xff: /* RST 38H */
6168 CHECK_BREAK_WORD(SP
- 2);
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 */
6186 executedTStates
= tStates
;
6192 static t_stat
cpu_reset(DEVICE
*dptr
) {
6193 extern uint32 sim_brk_types
, sim_brk_dflt
; /* breakpoint info */
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;
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;
6206 pcq_r
= find_reg("PCQ", NULL
, dptr
);
6207 if (pcq_r
) pcq_r
-> qptr
= 0;
6208 else return SCPE_IERR
;
6212 t_stat
install_bootrom(int32 bootrom
[], int32 size
, int32 addr
, int32 makeROM
) {
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;
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
);
6228 oldBankSelect
= getBankSelect();
6229 setBankSelect((addr
>> MAXBANKSIZELOG2
) & BANKMASK
);
6230 *vptr
= GetBYTE(addr
& ADDRMASK
);
6231 setBankSelect(oldBankSelect
);
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
);
6241 oldBankSelect
= getBankSelect();
6242 setBankSelect((addr
>> MAXBANKSIZELOG2
) & BANKMASK
);
6243 PutBYTE(addr
& ADDRMASK
, val
);
6244 setBankSelect(oldBankSelect
);
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");
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");
6262 static t_stat
cpu_show(FILE *st
, UNIT
*uptr
, int32 val
, void *desc
) {
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
));
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");
6281 static void cpu_clear(void) {
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();
6290 static t_stat
cpu_clear_command(UNIT
*uptr
, int32 value
, char *cptr
, void *desc
) {
6295 static t_stat
cpu_set_altairrom(UNIT
*uptr
, int32 value
, char *cptr
, void *desc
) {
6296 install_ALTAIRbootROM();
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
;
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");
6311 if (cpu_unit
.flags
& UNIT_CPU_BANKED
) {
6312 printf("Cannot switch off MMU for banked memory.\n");
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
);
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
;
6331 else if (chiptype
== CHIP_TYPE_8086
) {
6332 printf("Cannot use banked memory for 8086 CPU.\n");
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
;
6347 static int32
bankseldev(const int32 port
, const int32 io
, const int32 data
) {
6352 printf("HRAM: Parity %s" NLP
, data
& 1 ? "ON" : "OFF");
6354 printf("HRAM BANKSEL=%02x" NLP
, data
);
6358 /* printf("VRAM BANKSEL=%02x" NLP, data);*/
6359 switch(data
& 0xFF) {
6361 /* case 0x41: // OASIS uses this for some reason?*/
6365 /* case 0x42: // OASIS uses this for some reason?*/
6387 /* printf("Invalid bank select 0x%02x for VRAM" NLP, data);*/
6392 printf("CRAM BANKSEL=%02x" NLP
, data
);
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
)) {
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
;
6420 else if ((chiptype
== CHIP_TYPE_8080
) || (chiptype
== CHIP_TYPE_Z80
)) {
6421 MEMORYSIZE
= previousCapacity
;
6422 cpu_dev
.awidth
= MAXBANKSIZELOG2
;
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
);
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");
6443 static t_stat
cpu_set_switcher(UNIT
*uptr
, int32 value
, char *cptr
, void *desc
) {
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
);
6451 oldSwitcherDevice
= safe
;
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
);
6464 static t_stat
cpu_set_ramtype(UNIT
*uptr
, int32 value
, char *cptr
, void *desc
) {
6466 if(value
== ramtype
) {
6467 printf("RAM Selection unchanged\n");
6473 printf("Unmapping NorthStar HRAM\n");
6474 sim_map_resource(0xC0, 1, RESOURCE_TYPE_IO
, &bankseldev
, TRUE
);
6477 printf("Unmapping Vector RAM\n");
6478 sim_map_resource(0x40, 1, RESOURCE_TYPE_IO
, &bankseldev
, TRUE
);
6481 printf("Unmapping Cromemco RAM\n");
6482 /* sim_map_resource(0xC0, 1, RESOURCE_TYPE_IO, &bankseldev, TRUE);*/
6486 printf("Unmapping AltairZ80 RAM\n");
6492 printf("NorthStar HRAM Selected\n");
6493 sim_map_resource(0xC0, 1, RESOURCE_TYPE_IO
, &bankseldev
, FALSE
);
6496 printf("Vector RAM Selected\n");
6497 sim_map_resource(0x40, 1, RESOURCE_TYPE_IO
, &bankseldev
, FALSE
);
6500 printf("Cromemco RAM Selected\n");
6501 /* sim_map_resource(0xC0, 1, RESOURCE_TYPE_IO, &bankseldev, FALSE);*/
6505 printf("AltairZ80 RAM Selected\n");
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
;
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
;
6529 static t_stat
cpu_set_size(UNIT
*uptr
, int32 value
, char *cptr
, void *desc
) {
6530 return set_size(value
);
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
);
6543 /* AltairZ80 Simulator initialization */
6544 void altairz80_init(void) {
6548 void (*sim_vm_init
) (void) = &altairz80_init
;
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.
6557 #define PLURAL(x) (x), (x) == 1 ? "" : "s"
6559 t_stat
sim_load(FILE *fileref
, char *cptr
, char *fnam
, int32 flag
) {
6560 uint32 i
, addr
, cnt
= 0, org
, pagesModified
= 0, makeROM
= FALSE
;
6564 char gbuf
[CBUFSIZE
];
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
;
6573 printf("%d byte%s dumped [%x - %x].\n", PLURAL(hi
+ 1 - lo
), lo
, hi
);
6576 if (*cptr
== 0) addr
= PC_S
;
6578 get_glyph(cptr
, gbuf
, 0);
6579 if (strcmp(gbuf
, "ROM") == 0) {
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
;
6591 /* addr is start address to load to, makeROM == TRUE iff memory should become ROM */
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
;
6601 mmu_table
[addr
>> LOG2PAGESIZE
] = ROM_PAGE
;
6604 if (!m
.isRAM
&& m
.routine
) m
.routine(addr
, 1, i
);
6609 printf("%d byte%s [%d page%s] loaded at %x%s.\n", PLURAL(cnt
),
6610 PLURAL((cnt
+ 0xff) >> 8), org
, makeROM
? " [ROM]" : "");
6612 printf("Warning: %d page%s modified.\n", PLURAL(pagesModified
));