/* altairz80_cpu.c: MITS Altair CPU (8080 and Z80) | |
Written by Peter Schorn, 2001 | |
Based on work by Charles E Owen ((c) 1997 - Commercial use prohibited) | |
Code for Z80 CPU from Frank D. Cringle ((c) 1995 under GNU license) | |
*/ | |
#include <stdio.h> | |
#include "altairZ80_defs.h" | |
/*-------------------------------- definitions for memory space --------*/ | |
uint8 M[MAXMEMSIZE]; /* RAM which is present */ | |
/* two sets of accumulator / flags */ | |
uint16 af[2]; | |
int af_sel; | |
/* two sets of 16-bit registers */ | |
struct ddregs { | |
uint16 bc; | |
uint16 de; | |
uint16 hl; | |
} regs[2]; | |
int regs_sel; | |
uint16 ir; | |
uint16 ix; | |
uint16 iy; | |
uint16 sp; | |
uint16 pc; | |
uint16 IFF; | |
#define FLAG_C 1 | |
#define FLAG_N 2 | |
#define FLAG_P 4 | |
#define FLAG_H 16 | |
#define FLAG_Z 64 | |
#define FLAG_S 128 | |
#define SETFLAG(f,c) AF = (c) ? AF | FLAG_ ## f : AF & ~FLAG_ ## f | |
#define TSTFLAG(f) ((AF & FLAG_ ## f) != 0) | |
#define ldig(x) ((x) & 0xf) | |
#define hdig(x) (((x)>>4)&0xf) | |
#define lreg(x) ((x)&0xff) | |
#define hreg(x) (((x)>>8)&0xff) | |
#define Setlreg(x, v) x = (((x)&0xff00) | ((v)&0xff)) | |
#define Sethreg(x, v) x = (((x)&0xff) | (((v)&0xff) << 8)) | |
/* SetPV and SetPV2 are used to provide correct parity flag semantics for the 8080 in cases | |
where the Z80 uses the overflow flag | |
*/ | |
#define SetPV ((cpu_unit.flags & UNIT_CHIP) ? (((cbits >> 6) ^ (cbits >> 5)) & 4) : (parity(sum))) | |
#define SetPV2(x) ((cpu_unit.flags & UNIT_CHIP) ? (((temp == (x)) << 2)) : (parity(temp))) | |
/* checkCPU must be invoked whenever a Z80 only instruction is executed */ | |
#define checkCPU if ((cpu_unit.flags & UNIT_CHIP) == 0) { Bad8080OpOccured = 1; break; } | |
static const uint8 partab[256] = { | |
4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, | |
0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, | |
0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, | |
4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, | |
0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, | |
4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, | |
4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, | |
0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, | |
0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, | |
4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, | |
4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, | |
0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, | |
4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, | |
0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, | |
0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, | |
4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, | |
}; | |
#define parity(x) partab[(x)&0xff] | |
#define POP(x) do { \ | |
register uint32 y = RAM_pp(SP); \ | |
x = y + (RAM_pp(SP) << 8); \ | |
} while (0) | |
#define JPC(cond) PC = cond ? GetWORD(PC) : PC+2 | |
#define CALLC(cond) { \ | |
if (cond) { \ | |
register uint32 adrr = GetWORD(PC); \ | |
PUSH(PC+2); \ | |
PC = adrr; \ | |
} \ | |
else \ | |
PC += 2; \ | |
} | |
int32 saved_PC = 0; /* program counter */ | |
int32 SR = 0; /* switch register */ | |
int32 PCX; /* External view of PC */ | |
extern int32 sim_int_char; | |
extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ | |
/* function prototypes */ | |
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); | |
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); | |
t_stat cpu_reset (DEVICE *dptr); | |
t_stat cpu_svc (UNIT *uptr); | |
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); | |
void clear_memory(int32 starting); | |
extern int32 sio0s(int32 io, int32 data); | |
extern int32 sio0d(int32 io, int32 data); | |
extern int32 sio1s(int32 io, int32 data); | |
extern int32 sio1d(int32 io, int32 data); | |
extern int32 dsk10(int32 io, int32 data); | |
extern int32 dsk11(int32 io, int32 data); | |
extern int32 dsk12(int32 io, int32 data); | |
extern int32 nulldev(int32 io, int32 data); | |
extern int32 simh_dev(int32 io, int32 data); | |
extern int32 markTimeSP; | |
/* This is the I/O configuration table. There are 255 possible | |
device addresses, if a device is plugged to a port it's routine | |
address is here, 'nulldev' means no device is available | |
*/ | |
struct idev { | |
int32 (*routine)(); | |
}; | |
struct idev dev_table[256] = { | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 00 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 04 */ | |
{&dsk10}, {&dsk11}, {&dsk12}, {&nulldev}, /* 08 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C */ | |
{&sio0s}, {&sio0d}, {&sio1s}, {&sio1d}, /* 10 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 14 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 18 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 20 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 24 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 28 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 30 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 34 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 38 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 40 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 44 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 48 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 4C */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 50 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 54 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 58 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 5C */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 60 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 64 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 68 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 6C */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 70 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 74 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 78 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 7C */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 80 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 84 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 88 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 8C */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 90 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 94 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 98 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 9C */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* A0 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* A4 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* A8 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* AC */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* B0 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* B4 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* B8 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* BC */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* C0 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* C4 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* C8 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* CC */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D0 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D4 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D8 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* DC */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D0 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* E4 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* E8 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* EC */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* F0 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* F4 */ | |
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* F8 */ | |
{&nulldev}, {&nulldev}, {&simh_dev}, {&nulldev} }; /* FC */ | |
/* Altair MITS modified BOOT EPROM, fits in upper 256 byte of memory */ | |
int32 bootrom[bootrom_size] = { | |
0x21, 0x00, 0x5c, 0x11, 0x13, 0xff, 0x0e, 0xb9, /* ff00-ff07 */ | |
0x1a, 0x77, 0x13, 0x23, 0x0d, 0xc2, 0x08, 0xff, /* ff08-ff0f */ | |
0xc3, 0x00, 0x5c, 0x31, 0xa6, 0x5d, 0xaf, 0xd3, /* ff10-ff17 */ | |
0x08, 0x3e, 0x04, 0xd3, 0x09, 0xc3, 0x18, 0x5c, /* ff18-ff1f */ | |
0xdb, 0x08, 0xe6, 0x02, 0xc2, 0x0d, 0x5c, 0x3e, /* ff20-ff27 */ | |
0x02, 0xd3, 0x09, 0xdb, 0x08, 0xe6, 0x40, 0xc2, /* ff28-ff2f */ | |
0x0d, 0x5c, 0x11, 0x00, 0x00, 0x06, 0x08, 0xc3, /* ff30-ff37 */ | |
0x29, 0x5c, 0x06, 0x00, 0x3e, 0x10, 0xf5, 0xd5, /* ff38-ff3f */ | |
0xc5, 0xd5, 0x11, 0x86, 0x80, 0x21, 0xb9, 0x5c, /* ff40-ff47 */ | |
0xdb, 0x09, 0x1f, 0xda, 0x35, 0x5c, 0xe6, 0x1f, /* ff48-ff4f */ | |
0xb8, 0xc2, 0x35, 0x5c, 0xdb, 0x08, 0xb7, 0xfa, /* ff50-ff57 */ | |
0x41, 0x5c, 0xdb, 0x0a, 0x77, 0x23, 0x1d, 0xca, /* ff58-ff5f */ | |
0x57, 0x5c, 0x1d, 0xdb, 0x0a, 0x77, 0x23, 0xc2, /* ff60-ff67 */ | |
0x41, 0x5c, 0xe1, 0x11, 0xbc, 0x5c, 0x01, 0x80, /* ff68-ff6f */ | |
0x00, 0x1a, 0x77, 0xbe, 0x80, 0x47, 0x13, 0x23, /* ff70-ff77 */ | |
0x0d, 0xc2, 0x5e, 0x5c, 0x1a, 0xfe, 0xff, 0xc2, /* ff78-ff7f */ | |
0x72, 0x5c, 0x13, 0x1a, 0xb8, 0xc1, 0xeb, 0xc2, /* ff80-ff87 */ | |
0xac, 0x5c, 0xf1, 0xf1, 0x2a, 0xba, 0x5c, 0xd5, /* ff88-ff8f */ | |
0x11, 0x00, 0x5c, 0xcd, 0xb3, 0x5c, 0xd1, 0xcd, /* ff90-ff97 */ | |
0xb3, 0x5c, 0xd2, 0xa5, 0x5c, 0x04, 0x04, 0x78, /* ff98-ff9f */ | |
0xfe, 0x20, 0xda, 0x29, 0x5c, 0x06, 0x01, 0xca, /* ffa0-ffa7 */ | |
0x29, 0x5c, 0xdb, 0x08, 0xe6, 0x02, 0xc2, 0x97, /* ffa8-ffaf */ | |
0x5c, 0x3e, 0x01, 0xd3, 0x09, 0xc3, 0x27, 0x5c, /* ffb0-ffb7 */ | |
0x3e, 0x80, 0xd3, 0x08, 0xc3, 0x00, 0x00, 0xd1, /* ffb8-ffbf */ | |
0xf1, 0x3d, 0xc2, 0x2b, 0x5c, 0x76, 0x7a, 0xbc, /* ffc0-ffc7 */ | |
0xc0, 0x7b, 0xbd, 0xc9, 0x00, 0x00, 0x00, 0x00, /* ffc8-ffcf */ | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ffd0-ffd7 */ | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ffd8-ffdf */ | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ffe0-ffe7 */ | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ffe8-ffef */ | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* fff0-fff7 */ | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* fff8-ffff */ | |
}; | |
/* CPU data structures | |
cpu_dev CPU device descriptor | |
cpu_unit CPU unit descriptor | |
cpu_reg CPU register list | |
cpu_mod CPU modifiers list | |
*/ | |
UNIT cpu_unit = { UDATA (NULL, UNIT_FIX + UNIT_BINK, MAXMEMSIZE) }; | |
int32 AF_S; | |
int32 BC_S; | |
int32 DE_S; | |
int32 HL_S; | |
int32 IX_S; | |
int32 IY_S; | |
int32 SP_S; | |
int32 AF1_S; | |
int32 BC1_S; | |
int32 DE1_S; | |
int32 HL1_S; | |
int32 IFF_S; | |
int32 INT_S; | |
REG cpu_reg[] = { | |
{ HRDATA (PC, saved_PC, 16) }, | |
{ HRDATA (AF, AF_S, 16) }, | |
{ HRDATA (BC, BC_S, 16) }, | |
{ HRDATA (DE, DE_S, 16) }, | |
{ HRDATA (HL, HL_S, 16) }, | |
{ HRDATA (IX, IX_S, 16) }, | |
{ HRDATA (IY, IY_S, 16) }, | |
{ HRDATA (SP, SP_S, 16) }, | |
{ HRDATA (AF1, AF1_S, 16) }, | |
{ HRDATA (BC1, BC1_S, 16) }, | |
{ HRDATA (DE1, DE1_S, 16) }, | |
{ HRDATA (HL1, HL1_S, 16) }, | |
{ FLDATA (IFF, IFF_S, 8) }, | |
{ FLDATA (INT, INT_S, 8) }, | |
{ FLDATA (Z80, cpu_unit.flags, UNIT_V_CHIP), REG_HRO }, | |
{ FLDATA (OPSTOP, cpu_unit.flags, UNIT_V_OPSTOP), REG_HRO }, | |
{ HRDATA (SR, SR, 8) }, | |
{ HRDATA (WRU, sim_int_char, 8) }, | |
{ DRDATA (MARK, markTimeSP, 3), REG_RO }, | |
{ NULL } }; | |
MTAB cpu_mod[] = { | |
{ UNIT_CHIP, UNIT_CHIP, "Z80", "Z80", NULL }, | |
{ UNIT_CHIP, 0, "8080", "8080", NULL }, | |
{ UNIT_OPSTOP, UNIT_OPSTOP, "ITRAP", "ITRAP", NULL }, | |
{ UNIT_OPSTOP, 0, "NOITRAP", "NOITRAP", NULL }, | |
{ UNIT_MSIZE, 4*KB, NULL, "4K", &cpu_set_size }, | |
{ UNIT_MSIZE, 8*KB, NULL, "8K", &cpu_set_size }, | |
{ UNIT_MSIZE, 12*KB, NULL, "12K", &cpu_set_size }, | |
{ UNIT_MSIZE, 16*KB, NULL, "16K", &cpu_set_size }, | |
{ UNIT_MSIZE, 20*KB, NULL, "20K", &cpu_set_size }, | |
{ UNIT_MSIZE, 24*KB, NULL, "24K", &cpu_set_size }, | |
{ UNIT_MSIZE, 28*KB, NULL, "28K", &cpu_set_size }, | |
{ UNIT_MSIZE, 32*KB, NULL, "32K", &cpu_set_size }, | |
{ UNIT_MSIZE, 48*KB, NULL, "48K", &cpu_set_size }, | |
{ UNIT_MSIZE, 64*KB, NULL, "64K", &cpu_set_size }, | |
{ 0 } }; | |
DEVICE cpu_dev = { | |
"CPU", &cpu_unit, cpu_reg, cpu_mod, | |
1, 16, 16, 1, 16, 8, | |
&cpu_ex, &cpu_dep, &cpu_reset, | |
NULL, NULL, NULL }; | |
void out(uint32 Port, uint8 Value) { | |
dev_table[Port].routine(1, Value); | |
} | |
int in(uint32 Port) { | |
return Port == 0xFF ? SR & 0xFF : dev_table[Port].routine(0, 0); | |
} | |
inline uint8 GetBYTE(register uint16 a) { | |
return a < MEMSIZE ? M[a] : 0xff; | |
} | |
#define RAM_mm(a) GetBYTE(a--) | |
#define RAM_pp(a) GetBYTE(a++) | |
inline void PutBYTE(register uint16 Addr, register uint8 Value) { | |
if ((Addr < MEMSIZE) && (Addr < bootrom_origin)) { | |
M[Addr] = Value; | |
} | |
/* | |
else { | |
printf("R/O M[%x]:=%x\n", Addr, Value); | |
} | |
*/ | |
} | |
#define PutBYTE_pp(a,v) PutBYTE(a++, v) | |
#define PutBYTE_mm(a,v) PutBYTE(a--, v) | |
#define mm_PutBYTE(a,v) PutBYTE(--a, v) | |
inline uint16 GetWORD(register uint16 a) {return (GetBYTE(a) | (GetBYTE((a)+1) << 8));} | |
inline void PutWORD(register uint16 a, register uint16 v) { | |
PutBYTE(a, (uint8)(v)); | |
PutBYTE(a+1, v>>8); | |
} | |
#define PUSH(x) do { \ | |
mm_PutBYTE(SP, (x) >> 8); \ | |
mm_PutBYTE(SP, x); \ | |
} while (0) | |
int32 sim_instr (void) { | |
extern int32 sim_interval; | |
int32 reason = 0; | |
register uint32 AF; | |
register uint32 BC; | |
register uint32 DE; | |
register uint32 HL; | |
register uint32 PC; | |
register uint32 SP; | |
register uint32 IX; | |
register uint32 IY; | |
register uint32 temp, acu, sum, cbits; | |
register uint32 op, adr; | |
int32 BadZ80OpOccured = 0; | |
int32 Bad8080OpOccured = 0; | |
pc = saved_PC & ADDRMASK; /* load local PC */ | |
af[af_sel] = AF_S; | |
regs[regs_sel].bc = BC_S; | |
regs[regs_sel].de = DE_S; | |
regs[regs_sel].hl = HL_S; | |
ix = IX_S; | |
iy = IY_S; | |
sp = SP_S; | |
af[1-af_sel] = AF1_S; | |
regs[1-regs_sel].bc = BC1_S; | |
regs[1-regs_sel].de = DE1_S; | |
regs[1-regs_sel].hl = HL1_S; | |
IFF = IFF_S; | |
ir = INT_S; | |
AF = af[af_sel]; | |
BC = regs[regs_sel].bc; | |
DE = regs[regs_sel].de; | |
HL = regs[regs_sel].hl; | |
PC = pc; | |
SP = sp; | |
IX = ix; | |
IY = iy; | |
/* Main instruction fetch/decode loop */ | |
while (reason == 0) { /* loop until halted */ | |
if (sim_interval <= 0) { /* check clock queue */ | |
if (reason = sim_process_event ()) { | |
break; | |
} | |
} | |
if (sim_brk_summ && | |
sim_brk_test (PC, SWMASK ('E'))) { /* breakpoint? */ | |
reason = STOP_IBKPT; /* stop simulation */ | |
break; | |
} | |
PCX = PC; | |
sim_interval--; | |
switch(RAM_pp(PC)) { | |
case 0x00: /* NOP */ | |
break; | |
case 0x01: /* LD BC,nnnn */ | |
BC = GetWORD(PC); | |
PC += 2; | |
break; | |
case 0x02: /* LD (BC),A */ | |
PutBYTE(BC, hreg(AF)); | |
break; | |
case 0x03: /* INC BC */ | |
++BC; | |
break; | |
case 0x04: /* INC B */ | |
BC += 0x100; | |
temp = hreg(BC); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
SetPV2(0x80); | |
break; | |
case 0x05: /* DEC B */ | |
BC -= 0x100; | |
temp = hreg(BC); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
SetPV2(0x7f) | 2; | |
break; | |
case 0x06: /* LD B,nn */ | |
Sethreg(BC, RAM_pp(PC)); | |
break; | |
case 0x07: /* RLCA */ | |
AF = ((AF >> 7) & 0x0128) | ((AF << 1) & ~0x1ff) | | |
(AF & 0xc4) | ((AF >> 15) & 1); | |
break; | |
case 0x08: /* EX AF,AF' */ | |
checkCPU | |
af[af_sel] = AF; | |
af_sel = 1 - af_sel; | |
AF = af[af_sel]; | |
break; | |
case 0x09: /* ADD HL,BC */ | |
HL &= 0xffff; | |
BC &= 0xffff; | |
sum = HL + BC; | |
cbits = (HL ^ BC ^ sum) >> 8; | |
HL = sum; | |
AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x0A: /* LD A,(BC) */ | |
Sethreg(AF, GetBYTE(BC)); | |
break; | |
case 0x0B: /* DEC BC */ | |
--BC; | |
break; | |
case 0x0C: /* INC C */ | |
temp = lreg(BC)+1; | |
Setlreg(BC, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
SetPV2(0x80); | |
break; | |
case 0x0D: /* DEC C */ | |
temp = lreg(BC)-1; | |
Setlreg(BC, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
SetPV2(0x7f) | 2; | |
break; | |
case 0x0E: /* LD C,nn */ | |
Setlreg(BC, RAM_pp(PC)); | |
break; | |
case 0x0F: /* RRCA */ | |
temp = hreg(AF); | |
sum = temp >> 1; | |
AF = ((temp & 1) << 15) | (sum << 8) | | |
(sum & 0x28) | (AF & 0xc4) | (temp & 1); | |
break; | |
case 0x10: /* DJNZ dd */ | |
checkCPU | |
PC += ((BC -= 0x100) & 0xff00) ? (signed char) GetBYTE(PC) + 1 : 1; | |
break; | |
case 0x11: /* LD DE,nnnn */ | |
DE = GetWORD(PC); | |
PC += 2; | |
break; | |
case 0x12: /* LD (DE),A */ | |
PutBYTE(DE, hreg(AF)); | |
break; | |
case 0x13: /* INC DE */ | |
++DE; | |
break; | |
case 0x14: /* INC D */ | |
DE += 0x100; | |
temp = hreg(DE); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
SetPV2(0x80); | |
break; | |
case 0x15: /* DEC D */ | |
DE -= 0x100; | |
temp = hreg(DE); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
SetPV2(0x7f) | 2; | |
break; | |
case 0x16: /* LD D,nn */ | |
Sethreg(DE, RAM_pp(PC)); | |
break; | |
case 0x17: /* RLA */ | |
AF = ((AF << 8) & 0x0100) | ((AF >> 7) & 0x28) | ((AF << 1) & ~0x01ff) | | |
(AF & 0xc4) | ((AF >> 15) & 1); | |
break; | |
case 0x18: /* JR dd */ | |
checkCPU | |
PC += (1) ? (signed char) GetBYTE(PC) + 1 : 1; | |
break; | |
case 0x19: /* ADD HL,DE */ | |
HL &= 0xffff; | |
DE &= 0xffff; | |
sum = HL + DE; | |
cbits = (HL ^ DE ^ sum) >> 8; | |
HL = sum; | |
AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x1A: /* LD A,(DE) */ | |
Sethreg(AF, GetBYTE(DE)); | |
break; | |
case 0x1B: /* DEC DE */ | |
--DE; | |
break; | |
case 0x1C: /* INC E */ | |
temp = lreg(DE)+1; | |
Setlreg(DE, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
SetPV2(0x80); | |
break; | |
case 0x1D: /* DEC E */ | |
temp = lreg(DE)-1; | |
Setlreg(DE, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
SetPV2(0x7f) | 2; | |
break; | |
case 0x1E: /* LD E,nn */ | |
Setlreg(DE, RAM_pp(PC)); | |
break; | |
case 0x1F: /* RRA */ | |
temp = hreg(AF); | |
sum = temp >> 1; | |
AF = ((AF & 1) << 15) | (sum << 8) | | |
(sum & 0x28) | (AF & 0xc4) | (temp & 1); | |
break; | |
case 0x20: /* JR NZ,dd */ | |
checkCPU | |
PC += (!TSTFLAG(Z)) ? (signed char) GetBYTE(PC) + 1 : 1; | |
break; | |
case 0x21: /* LD HL,nnnn */ | |
HL = GetWORD(PC); | |
PC += 2; | |
break; | |
case 0x22: /* LD (nnnn),HL */ | |
temp = GetWORD(PC); | |
PutWORD(temp, HL); | |
PC += 2; | |
break; | |
case 0x23: /* INC HL */ | |
++HL; | |
break; | |
case 0x24: /* INC H */ | |
HL += 0x100; | |
temp = hreg(HL); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
SetPV2(0x80); | |
break; | |
case 0x25: /* DEC H */ | |
HL -= 0x100; | |
temp = hreg(HL); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
SetPV2(0x7f) | 2; | |
break; | |
case 0x26: /* LD H,nn */ | |
Sethreg(HL, RAM_pp(PC)); | |
break; | |
case 0x27: /* DAA */ | |
acu = hreg(AF); | |
temp = ldig(acu); | |
cbits = TSTFLAG(C); | |
if (TSTFLAG(N)) { /* last operation was a subtract */ | |
int hd = cbits || acu > 0x99; | |
if (TSTFLAG(H) || (temp > 9)) { /* adjust low digit */ | |
if (temp > 5) | |
SETFLAG(H, 0); | |
acu -= 6; | |
acu &= 0xff; | |
} | |
if (hd) /* adjust high digit */ | |
acu -= 0x160; | |
} | |
else { /* last operation was an add */ | |
if (TSTFLAG(H) || (temp > 9)) { /* adjust low digit */ | |
SETFLAG(H, (temp > 9)); | |
acu += 6; | |
} | |
if (cbits || ((acu & 0x1f0) > 0x90)) /* adjust high digit */ | |
acu += 0x60; | |
} | |
cbits |= (acu >> 8) & 1; | |
acu &= 0xff; | |
AF = (acu << 8) | (acu & 0xa8) | ((acu == 0) << 6) | | |
(AF & 0x12) | partab[acu] | cbits; | |
break; | |
case 0x28: /* JR Z,dd */ | |
checkCPU | |
PC += (TSTFLAG(Z)) ? (signed char) GetBYTE(PC) + 1 : 1; | |
break; | |
case 0x29: /* ADD HL,HL */ | |
HL &= 0xffff; | |
sum = HL + HL; | |
cbits = (HL ^ HL ^ sum) >> 8; | |
HL = sum; | |
AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x2A: /* LD HL,(nnnn) */ | |
temp = GetWORD(PC); | |
HL = GetWORD(temp); | |
PC += 2; | |
break; | |
case 0x2B: /* DEC HL */ | |
--HL; | |
break; | |
case 0x2C: /* INC L */ | |
temp = lreg(HL)+1; | |
Setlreg(HL, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
SetPV2(0x80); | |
break; | |
case 0x2D: /* DEC L */ | |
temp = lreg(HL)-1; | |
Setlreg(HL, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
SetPV2(0x7f) | 2; | |
break; | |
case 0x2E: /* LD L,nn */ | |
Setlreg(HL, RAM_pp(PC)); | |
break; | |
case 0x2F: /* CPL */ | |
AF = (~AF & ~0xff) | (AF & 0xc5) | ((~AF >> 8) & 0x28) | 0x12; | |
break; | |
case 0x30: /* JR NC,dd */ | |
checkCPU | |
PC += (!TSTFLAG(C)) ? (signed char) GetBYTE(PC) + 1 : 1; | |
break; | |
case 0x31: /* LD SP,nnnn */ | |
SP = GetWORD(PC); | |
PC += 2; | |
break; | |
case 0x32: /* LD (nnnn),A */ | |
temp = GetWORD(PC); | |
PutBYTE(temp, hreg(AF)); | |
PC += 2; | |
break; | |
case 0x33: /* INC SP */ | |
++SP; | |
break; | |
case 0x34: /* INC (HL) */ | |
temp = GetBYTE(HL)+1; | |
PutBYTE(HL, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
SetPV2(0x80); | |
break; | |
case 0x35: /* DEC (HL) */ | |
temp = GetBYTE(HL)-1; | |
PutBYTE(HL, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
SetPV2(0x7f) | 2; | |
break; | |
case 0x36: /* LD (HL),nn */ | |
PutBYTE(HL, RAM_pp(PC)); | |
break; | |
case 0x37: /* SCF */ | |
AF = (AF&~0x3b)|((AF>>8)&0x28)|1; | |
break; | |
case 0x38: /* JR C,dd */ | |
checkCPU | |
PC += (TSTFLAG(C)) ? (signed char) GetBYTE(PC) + 1 : 1; | |
break; | |
case 0x39: /* ADD HL,SP */ | |
HL &= 0xffff; | |
SP &= 0xffff; | |
sum = HL + SP; | |
cbits = (HL ^ SP ^ sum) >> 8; | |
HL = sum; | |
AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x3A: /* LD A,(nnnn) */ | |
temp = GetWORD(PC); | |
Sethreg(AF, GetBYTE(temp)); | |
PC += 2; | |
break; | |
case 0x3B: /* DEC SP */ | |
--SP; | |
break; | |
case 0x3C: /* INC A */ | |
AF += 0x100; | |
temp = hreg(AF); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
SetPV2(0x80); | |
break; | |
case 0x3D: /* DEC A */ | |
AF -= 0x100; | |
temp = hreg(AF); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
SetPV2(0x7f) | 2; | |
break; | |
case 0x3E: /* LD A,nn */ | |
Sethreg(AF, RAM_pp(PC)); | |
break; | |
case 0x3F: /* CCF */ | |
AF = (AF&~0x3b)|((AF>>8)&0x28)|((AF&1)<<4)|(~AF&1); | |
break; | |
case 0x40: /* LD B,B */ | |
/* nop */ | |
break; | |
case 0x41: /* LD B,C */ | |
BC = (BC & 255) | ((BC & 255) << 8); | |
break; | |
case 0x42: /* LD B,D */ | |
BC = (BC & 255) | (DE & ~255); | |
break; | |
case 0x43: /* LD B,E */ | |
BC = (BC & 255) | ((DE & 255) << 8); | |
break; | |
case 0x44: /* LD B,H */ | |
BC = (BC & 255) | (HL & ~255); | |
break; | |
case 0x45: /* LD B,L */ | |
BC = (BC & 255) | ((HL & 255) << 8); | |
break; | |
case 0x46: /* LD B,(HL) */ | |
Sethreg(BC, GetBYTE(HL)); | |
break; | |
case 0x47: /* LD B,A */ | |
BC = (BC & 255) | (AF & ~255); | |
break; | |
case 0x48: /* LD C,B */ | |
BC = (BC & ~255) | ((BC >> 8) & 255); | |
break; | |
case 0x49: /* LD C,C */ | |
/* nop */ | |
break; | |
case 0x4A: /* LD C,D */ | |
BC = (BC & ~255) | ((DE >> 8) & 255); | |
break; | |
case 0x4B: /* LD C,E */ | |
BC = (BC & ~255) | (DE & 255); | |
break; | |
case 0x4C: /* LD C,H */ | |
BC = (BC & ~255) | ((HL >> 8) & 255); | |
break; | |
case 0x4D: /* LD C,L */ | |
BC = (BC & ~255) | (HL & 255); | |
break; | |
case 0x4E: /* LD C,(HL) */ | |
Setlreg(BC, GetBYTE(HL)); | |
break; | |
case 0x4F: /* LD C,A */ | |
BC = (BC & ~255) | ((AF >> 8) & 255); | |
break; | |
case 0x50: /* LD D,B */ | |
DE = (DE & 255) | (BC & ~255); | |
break; | |
case 0x51: /* LD D,C */ | |
DE = (DE & 255) | ((BC & 255) << 8); | |
break; | |
case 0x52: /* LD D,D */ | |
/* nop */ | |
break; | |
case 0x53: /* LD D,E */ | |
DE = (DE & 255) | ((DE & 255) << 8); | |
break; | |
case 0x54: /* LD D,H */ | |
DE = (DE & 255) | (HL & ~255); | |
break; | |
case 0x55: /* LD D,L */ | |
DE = (DE & 255) | ((HL & 255) << 8); | |
break; | |
case 0x56: /* LD D,(HL) */ | |
Sethreg(DE, GetBYTE(HL)); | |
break; | |
case 0x57: /* LD D,A */ | |
DE = (DE & 255) | (AF & ~255); | |
break; | |
case 0x58: /* LD E,B */ | |
DE = (DE & ~255) | ((BC >> 8) & 255); | |
break; | |
case 0x59: /* LD E,C */ | |
DE = (DE & ~255) | (BC & 255); | |
break; | |
case 0x5A: /* LD E,D */ | |
DE = (DE & ~255) | ((DE >> 8) & 255); | |
break; | |
case 0x5B: /* LD E,E */ | |
/* nop */ | |
break; | |
case 0x5C: /* LD E,H */ | |
DE = (DE & ~255) | ((HL >> 8) & 255); | |
break; | |
case 0x5D: /* LD E,L */ | |
DE = (DE & ~255) | (HL & 255); | |
break; | |
case 0x5E: /* LD E,(HL) */ | |
Setlreg(DE, GetBYTE(HL)); | |
break; | |
case 0x5F: /* LD E,A */ | |
DE = (DE & ~255) | ((AF >> 8) & 255); | |
break; | |
case 0x60: /* LD H,B */ | |
HL = (HL & 255) | (BC & ~255); | |
break; | |
case 0x61: /* LD H,C */ | |
HL = (HL & 255) | ((BC & 255) << 8); | |
break; | |
case 0x62: /* LD H,D */ | |
HL = (HL & 255) | (DE & ~255); | |
break; | |
case 0x63: /* LD H,E */ | |
HL = (HL & 255) | ((DE & 255) << 8); | |
break; | |
case 0x64: /* LD H,H */ | |
/* nop */ | |
break; | |
case 0x65: /* LD H,L */ | |
HL = (HL & 255) | ((HL & 255) << 8); | |
break; | |
case 0x66: /* LD H,(HL) */ | |
Sethreg(HL, GetBYTE(HL)); | |
break; | |
case 0x67: /* LD H,A */ | |
HL = (HL & 255) | (AF & ~255); | |
break; | |
case 0x68: /* LD L,B */ | |
HL = (HL & ~255) | ((BC >> 8) & 255); | |
break; | |
case 0x69: /* LD L,C */ | |
HL = (HL & ~255) | (BC & 255); | |
break; | |
case 0x6A: /* LD L,D */ | |
HL = (HL & ~255) | ((DE >> 8) & 255); | |
break; | |
case 0x6B: /* LD L,E */ | |
HL = (HL & ~255) | (DE & 255); | |
break; | |
case 0x6C: /* LD L,H */ | |
HL = (HL & ~255) | ((HL >> 8) & 255); | |
break; | |
case 0x6D: /* LD L,L */ | |
/* nop */ | |
break; | |
case 0x6E: /* LD L,(HL) */ | |
Setlreg(HL, GetBYTE(HL)); | |
break; | |
case 0x6F: /* LD L,A */ | |
HL = (HL & ~255) | ((AF >> 8) & 255); | |
break; | |
case 0x70: /* LD (HL),B */ | |
PutBYTE(HL, hreg(BC)); | |
break; | |
case 0x71: /* LD (HL),C */ | |
PutBYTE(HL, lreg(BC)); | |
break; | |
case 0x72: /* LD (HL),D */ | |
PutBYTE(HL, hreg(DE)); | |
break; | |
case 0x73: /* LD (HL),E */ | |
PutBYTE(HL, lreg(DE)); | |
break; | |
case 0x74: /* LD (HL),H */ | |
PutBYTE(HL, hreg(HL)); | |
break; | |
case 0x75: /* LD (HL),L */ | |
PutBYTE(HL, lreg(HL)); | |
break; | |
case 0x76: /* HALT */ | |
reason = STOP_HALT; | |
PC--; | |
continue; | |
case 0x77: /* LD (HL),A */ | |
PutBYTE(HL, hreg(AF)); | |
break; | |
case 0x78: /* LD A,B */ | |
AF = (AF & 255) | (BC & ~255); | |
break; | |
case 0x79: /* LD A,C */ | |
AF = (AF & 255) | ((BC & 255) << 8); | |
break; | |
case 0x7A: /* LD A,D */ | |
AF = (AF & 255) | (DE & ~255); | |
break; | |
case 0x7B: /* LD A,E */ | |
AF = (AF & 255) | ((DE & 255) << 8); | |
break; | |
case 0x7C: /* LD A,H */ | |
AF = (AF & 255) | (HL & ~255); | |
break; | |
case 0x7D: /* LD A,L */ | |
AF = (AF & 255) | ((HL & 255) << 8); | |
break; | |
case 0x7E: /* LD A,(HL) */ | |
Sethreg(AF, GetBYTE(HL)); | |
break; | |
case 0x7F: /* LD A,A */ | |
/* nop */ | |
break; | |
case 0x80: /* ADD A,B */ | |
temp = hreg(BC); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x81: /* ADD A,C */ | |
temp = lreg(BC); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x82: /* ADD A,D */ | |
temp = hreg(DE); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x83: /* ADD A,E */ | |
temp = lreg(DE); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x84: /* ADD A,H */ | |
temp = hreg(HL); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x85: /* ADD A,L */ | |
temp = lreg(HL); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x86: /* ADD A,(HL) */ | |
temp = GetBYTE(HL); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x87: /* ADD A,A */ | |
temp = hreg(AF); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x88: /* ADC A,B */ | |
temp = hreg(BC); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x89: /* ADC A,C */ | |
temp = lreg(BC); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x8A: /* ADC A,D */ | |
temp = hreg(DE); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x8B: /* ADC A,E */ | |
temp = lreg(DE); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x8C: /* ADC A,H */ | |
temp = hreg(HL); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x8D: /* ADC A,L */ | |
temp = lreg(HL); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x8E: /* ADC A,(HL) */ | |
temp = GetBYTE(HL); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x8F: /* ADC A,A */ | |
temp = hreg(AF); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x90: /* SUB B */ | |
temp = hreg(BC); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x91: /* SUB C */ | |
temp = lreg(BC); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x92: /* SUB D */ | |
temp = hreg(DE); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x93: /* SUB E */ | |
temp = lreg(DE); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x94: /* SUB H */ | |
temp = hreg(HL); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x95: /* SUB L */ | |
temp = lreg(HL); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x96: /* SUB (HL) */ | |
temp = GetBYTE(HL); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x97: /* SUB A */ | |
temp = hreg(AF); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x98: /* SBC A,B */ | |
temp = hreg(BC); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x99: /* SBC A,C */ | |
temp = lreg(BC); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x9A: /* SBC A,D */ | |
temp = hreg(DE); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x9B: /* SBC A,E */ | |
temp = lreg(DE); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x9C: /* SBC A,H */ | |
temp = hreg(HL); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x9D: /* SBC A,L */ | |
temp = lreg(HL); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x9E: /* SBC A,(HL) */ | |
temp = GetBYTE(HL); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x9F: /* SBC A,A */ | |
temp = hreg(AF); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0xA0: /* AND B */ | |
sum = ((AF & (BC)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | | |
((sum == 0) << 6) | 0x10 | partab[sum]; | |
break; | |
case 0xA1: /* AND C */ | |
sum = ((AF >> 8) & BC) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | 0x10 | | |
((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xA2: /* AND D */ | |
sum = ((AF & (DE)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | | |
((sum == 0) << 6) | 0x10 | partab[sum]; | |
break; | |
case 0xA3: /* AND E */ | |
sum = ((AF >> 8) & DE) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | 0x10 | | |
((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xA4: /* AND H */ | |
sum = ((AF & (HL)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | | |
((sum == 0) << 6) | 0x10 | partab[sum]; | |
break; | |
case 0xA5: /* AND L */ | |
sum = ((AF >> 8) & HL) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | 0x10 | | |
((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xA6: /* AND (HL) */ | |
sum = ((AF >> 8) & GetBYTE(HL)) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | 0x10 | | |
((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xA7: /* AND A */ | |
sum = ((AF & (AF)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | | |
((sum == 0) << 6) | 0x10 | partab[sum]; | |
break; | |
case 0xA8: /* XOR B */ | |
sum = ((AF ^ (BC)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xA9: /* XOR C */ | |
sum = ((AF >> 8) ^ BC) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xAA: /* XOR D */ | |
sum = ((AF ^ (DE)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xAB: /* XOR E */ | |
sum = ((AF >> 8) ^ DE) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xAC: /* XOR H */ | |
sum = ((AF ^ (HL)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xAD: /* XOR L */ | |
sum = ((AF >> 8) ^ HL) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xAE: /* XOR (HL) */ | |
sum = ((AF >> 8) ^ GetBYTE(HL)) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xAF: /* XOR A */ | |
sum = ((AF ^ (AF)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB0: /* OR B */ | |
sum = ((AF | (BC)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB1: /* OR C */ | |
sum = ((AF >> 8) | BC) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB2: /* OR D */ | |
sum = ((AF | (DE)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB3: /* OR E */ | |
sum = ((AF >> 8) | DE) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB4: /* OR H */ | |
sum = ((AF | (HL)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB5: /* OR L */ | |
sum = ((AF >> 8) | HL) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB6: /* OR (HL) */ | |
sum = ((AF >> 8) | GetBYTE(HL)) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB7: /* OR A */ | |
sum = ((AF | (AF)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB8: /* CP B */ | |
temp = hreg(BC); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(SetPV) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xB9: /* CP C */ | |
temp = lreg(BC); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(SetPV) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xBA: /* CP D */ | |
temp = hreg(DE); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(SetPV) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xBB: /* CP E */ | |
temp = lreg(DE); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(SetPV) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xBC: /* CP H */ | |
temp = hreg(HL); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(SetPV) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xBD: /* CP L */ | |
temp = lreg(HL); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(SetPV) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xBE: /* CP (HL) */ | |
temp = GetBYTE(HL); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(SetPV) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xBF: /* CP A */ | |
temp = hreg(AF); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(SetPV) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xC0: /* RET NZ */ | |
if (!TSTFLAG(Z)) POP(PC); | |
break; | |
case 0xC1: /* POP BC */ | |
POP(BC); | |
break; | |
case 0xC2: /* JP NZ,nnnn */ | |
JPC(!TSTFLAG(Z)); | |
break; | |
case 0xC3: /* JP nnnn */ | |
JPC(1); | |
break; | |
case 0xC4: /* CALL NZ,nnnn */ | |
CALLC(!TSTFLAG(Z)); | |
break; | |
case 0xC5: /* PUSH BC */ | |
PUSH(BC); | |
break; | |
case 0xC6: /* ADD A,nn */ | |
temp = RAM_pp(PC); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0xC7: /* RST 0 */ | |
PUSH(PC); PC = 0; | |
break; | |
case 0xC8: /* RET Z */ | |
if (TSTFLAG(Z)) POP(PC); | |
break; | |
case 0xC9: /* RET */ | |
POP(PC); | |
break; | |
case 0xCA: /* JP Z,nnnn */ | |
JPC(TSTFLAG(Z)); | |
break; | |
case 0xCB: /* CB prefix */ | |
checkCPU | |
adr = HL; | |
switch ((op = GetBYTE(PC)) & 7) { | |
case 0: ++PC; acu = hreg(BC); break; | |
case 1: ++PC; acu = lreg(BC); break; | |
case 2: ++PC; acu = hreg(DE); break; | |
case 3: ++PC; acu = lreg(DE); break; | |
case 4: ++PC; acu = hreg(HL); break; | |
case 5: ++PC; acu = lreg(HL); break; | |
case 6: ++PC; acu = GetBYTE(adr); break; | |
case 7: ++PC; acu = hreg(AF); break; | |
} | |
switch (op & 0xc0) { | |
case 0x00: /* shift/rotate */ | |
switch (op & 0x38) { | |
case 0x00: /* RLC */ | |
temp = (acu << 1) | (acu >> 7); | |
cbits = temp & 1; | |
goto cbshflg1; | |
case 0x08: /* RRC */ | |
temp = (acu >> 1) | (acu << 7); | |
cbits = temp & 0x80; | |
goto cbshflg1; | |
case 0x10: /* RL */ | |
temp = (acu << 1) | TSTFLAG(C); | |
cbits = acu & 0x80; | |
goto cbshflg1; | |
case 0x18: /* RR */ | |
temp = (acu >> 1) | (TSTFLAG(C) << 7); | |
cbits = acu & 1; | |
goto cbshflg1; | |
case 0x20: /* SLA */ | |
temp = acu << 1; | |
cbits = acu & 0x80; | |
goto cbshflg1; | |
case 0x28: /* SRA */ | |
temp = (acu >> 1) | (acu & 0x80); | |
cbits = acu & 1; | |
goto cbshflg1; | |
case 0x30: /* SLIA */ | |
temp = (acu << 1) | 1; | |
cbits = acu & 0x80; | |
goto cbshflg1; | |
case 0x38: /* SRL */ | |
temp = acu >> 1; | |
cbits = acu & 1; | |
cbshflg1: | |
AF = (AF & ~0xff) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
parity(temp) | !!cbits; | |
} | |
break; | |
case 0x40: /* BIT */ | |
if (acu & (1 << ((op >> 3) & 7))) | |
AF = (AF & ~0xfe) | 0x10 | | |
(((op & 0x38) == 0x38) << 7); | |
else | |
AF = (AF & ~0xfe) | 0x54; | |
if ((op&7) != 6) | |
AF |= (acu & 0x28); | |
temp = acu; | |
break; | |
case 0x80: /* RES */ | |
temp = acu & ~(1 << ((op >> 3) & 7)); | |
break; | |
case 0xc0: /* SET */ | |
temp = acu | (1 << ((op >> 3) & 7)); | |
break; | |
} | |
switch (op & 7) { | |
case 0: Sethreg(BC, temp); break; | |
case 1: Setlreg(BC, temp); break; | |
case 2: Sethreg(DE, temp); break; | |
case 3: Setlreg(DE, temp); break; | |
case 4: Sethreg(HL, temp); break; | |
case 5: Setlreg(HL, temp); break; | |
case 6: PutBYTE(adr, temp); break; | |
case 7: Sethreg(AF, temp); break; | |
} | |
break; | |
case 0xCC: /* CALL Z,nnnn */ | |
CALLC(TSTFLAG(Z)); | |
break; | |
case 0xCD: /* CALL nnnn */ | |
CALLC(1); | |
break; | |
case 0xCE: /* ADC A,nn */ | |
temp = RAM_pp(PC); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | | |
((cbits >> 8) & 1); | |
break; | |
case 0xCF: /* RST 8 */ | |
PUSH(PC); PC = 8; | |
break; | |
case 0xD0: /* RET NC */ | |
if (!TSTFLAG(C)) POP(PC); | |
break; | |
case 0xD1: /* POP DE */ | |
POP(DE); | |
break; | |
case 0xD2: /* JP NC,nnnn */ | |
JPC(!TSTFLAG(C)); | |
break; | |
case 0xD3: /* OUT (nn),A */ | |
out(RAM_pp(PC), hreg(AF)); | |
break; | |
case 0xD4: /* CALL NC,nnnn */ | |
CALLC(!TSTFLAG(C)); | |
break; | |
case 0xD5: /* PUSH DE */ | |
PUSH(DE); | |
break; | |
case 0xD6: /* SUB nn */ | |
temp = RAM_pp(PC); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0xD7: /* RST 10H */ | |
PUSH(PC); PC = 0x10; | |
break; | |
case 0xD8: /* RET C */ | |
if (TSTFLAG(C)) POP(PC); | |
break; | |
case 0xD9: /* EXX */ | |
checkCPU | |
regs[regs_sel].bc = BC; | |
regs[regs_sel].de = DE; | |
regs[regs_sel].hl = HL; | |
regs_sel = 1 - regs_sel; | |
BC = regs[regs_sel].bc; | |
DE = regs[regs_sel].de; | |
HL = regs[regs_sel].hl; | |
break; | |
case 0xDA: /* JP C,nnnn */ | |
JPC(TSTFLAG(C)); | |
break; | |
case 0xDB: /* IN A,(nn) */ | |
Sethreg(AF, in(RAM_pp(PC))); | |
break; | |
case 0xDC: /* CALL C,nnnn */ | |
CALLC(TSTFLAG(C)); | |
break; | |
case 0xDD: /* DD prefix */ | |
checkCPU | |
switch (op = RAM_pp(PC)) { | |
case 0x09: /* ADD IX,BC */ | |
IX &= 0xffff; | |
BC &= 0xffff; | |
sum = IX + BC; | |
cbits = (IX ^ BC ^ sum) >> 8; | |
IX = sum; | |
AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x19: /* ADD IX,DE */ | |
IX &= 0xffff; | |
DE &= 0xffff; | |
sum = IX + DE; | |
cbits = (IX ^ DE ^ sum) >> 8; | |
IX = sum; | |
AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x21: /* LD IX,nnnn */ | |
IX = GetWORD(PC); | |
PC += 2; | |
break; | |
case 0x22: /* LD (nnnn),IX */ | |
temp = GetWORD(PC); | |
PutWORD(temp, IX); | |
PC += 2; | |
break; | |
case 0x23: /* INC IX */ | |
++IX; | |
break; | |
case 0x24: /* INC IXH */ | |
IX += 0x100; | |
temp = hreg(IX); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
((temp == 0x80) << 2); | |
break; | |
case 0x25: /* DEC IXH */ | |
IX -= 0x100; | |
temp = hreg(IX); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
((temp == 0x7f) << 2) | 2; | |
break; | |
case 0x26: /* LD IXH,nn */ | |
Sethreg(IX, RAM_pp(PC)); | |
break; | |
case 0x29: /* ADD IX,IX */ | |
IX &= 0xffff; | |
sum = IX + IX; | |
cbits = (IX ^ IX ^ sum) >> 8; | |
IX = sum; | |
AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x2A: /* LD IX,(nnnn) */ | |
temp = GetWORD(PC); | |
IX = GetWORD(temp); | |
PC += 2; | |
break; | |
case 0x2B: /* DEC IX */ | |
--IX; | |
break; | |
case 0x2C: /* INC IXL */ | |
temp = lreg(IX)+1; | |
Setlreg(IX, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
((temp == 0x80) << 2); | |
break; | |
case 0x2D: /* DEC IXL */ | |
temp = lreg(IX)-1; | |
Setlreg(IX, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
((temp == 0x7f) << 2) | 2; | |
break; | |
case 0x2E: /* LD IXL,nn */ | |
Setlreg(IX, RAM_pp(PC)); | |
break; | |
case 0x34: /* INC (IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr)+1; | |
PutBYTE(adr, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
((temp == 0x80) << 2); | |
break; | |
case 0x35: /* DEC (IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr)-1; | |
PutBYTE(adr, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
((temp == 0x7f) << 2) | 2; | |
break; | |
case 0x36: /* LD (IX+dd),nn */ | |
adr = IX + (signed char) RAM_pp(PC); | |
PutBYTE(adr, RAM_pp(PC)); | |
break; | |
case 0x39: /* ADD IX,SP */ | |
IX &= 0xffff; | |
SP &= 0xffff; | |
sum = IX + SP; | |
cbits = (IX ^ SP ^ sum) >> 8; | |
IX = sum; | |
AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x44: /* LD B,IXH */ | |
Sethreg(BC, hreg(IX)); | |
break; | |
case 0x45: /* LD B,IXL */ | |
Sethreg(BC, lreg(IX)); | |
break; | |
case 0x46: /* LD B,(IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
Sethreg(BC, GetBYTE(adr)); | |
break; | |
case 0x4C: /* LD C,IXH */ | |
Setlreg(BC, hreg(IX)); | |
break; | |
case 0x4D: /* LD C,IXL */ | |
Setlreg(BC, lreg(IX)); | |
break; | |
case 0x4E: /* LD C,(IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
Setlreg(BC, GetBYTE(adr)); | |
break; | |
case 0x54: /* LD D,IXH */ | |
Sethreg(DE, hreg(IX)); | |
break; | |
case 0x55: /* LD D,IXL */ | |
Sethreg(DE, lreg(IX)); | |
break; | |
case 0x56: /* LD D,(IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
Sethreg(DE, GetBYTE(adr)); | |
break; | |
case 0x5C: /* LD E,H */ | |
Setlreg(DE, hreg(IX)); | |
break; | |
case 0x5D: /* LD E,L */ | |
Setlreg(DE, lreg(IX)); | |
break; | |
case 0x5E: /* LD E,(IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
Setlreg(DE, GetBYTE(adr)); | |
break; | |
case 0x60: /* LD IXH,B */ | |
Sethreg(IX, hreg(BC)); | |
break; | |
case 0x61: /* LD IXH,C */ | |
Sethreg(IX, lreg(BC)); | |
break; | |
case 0x62: /* LD IXH,D */ | |
Sethreg(IX, hreg(DE)); | |
break; | |
case 0x63: /* LD IXH,E */ | |
Sethreg(IX, lreg(DE)); | |
break; | |
case 0x64: /* LD IXH,IXH */ | |
/* nop */ | |
break; | |
case 0x65: /* LD IXH,IXL */ | |
Sethreg(IX, lreg(IX)); | |
break; | |
case 0x66: /* LD H,(IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
Sethreg(HL, GetBYTE(adr)); | |
break; | |
case 0x67: /* LD IXH,A */ | |
Sethreg(IX, hreg(AF)); | |
break; | |
case 0x68: /* LD IXL,B */ | |
Setlreg(IX, hreg(BC)); | |
break; | |
case 0x69: /* LD IXL,C */ | |
Setlreg(IX, lreg(BC)); | |
break; | |
case 0x6A: /* LD IXL,D */ | |
Setlreg(IX, hreg(DE)); | |
break; | |
case 0x6B: /* LD IXL,E */ | |
Setlreg(IX, lreg(DE)); | |
break; | |
case 0x6C: /* LD IXL,IXH */ | |
Setlreg(IX, hreg(IX)); | |
break; | |
case 0x6D: /* LD IXL,IXL */ | |
/* nop */ | |
break; | |
case 0x6E: /* LD L,(IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
Setlreg(HL, GetBYTE(adr)); | |
break; | |
case 0x6F: /* LD IXL,A */ | |
Setlreg(IX, hreg(AF)); | |
break; | |
case 0x70: /* LD (IX+dd),B */ | |
adr = IX + (signed char) RAM_pp(PC); | |
PutBYTE(adr, hreg(BC)); | |
break; | |
case 0x71: /* LD (IX+dd),C */ | |
adr = IX + (signed char) RAM_pp(PC); | |
PutBYTE(adr, lreg(BC)); | |
break; | |
case 0x72: /* LD (IX+dd),D */ | |
adr = IX + (signed char) RAM_pp(PC); | |
PutBYTE(adr, hreg(DE)); | |
break; | |
case 0x73: /* LD (IX+dd),E */ | |
adr = IX + (signed char) RAM_pp(PC); | |
PutBYTE(adr, lreg(DE)); | |
break; | |
case 0x74: /* LD (IX+dd),H */ | |
adr = IX + (signed char) RAM_pp(PC); | |
PutBYTE(adr, hreg(HL)); | |
break; | |
case 0x75: /* LD (IX+dd),L */ | |
adr = IX + (signed char) RAM_pp(PC); | |
PutBYTE(adr, lreg(HL)); | |
break; | |
case 0x77: /* LD (IX+dd),A */ | |
adr = IX + (signed char) RAM_pp(PC); | |
PutBYTE(adr, hreg(AF)); | |
break; | |
case 0x7C: /* LD A,IXH */ | |
Sethreg(AF, hreg(IX)); | |
break; | |
case 0x7D: /* LD A,IXL */ | |
Sethreg(AF, lreg(IX)); | |
break; | |
case 0x7E: /* LD A,(IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
Sethreg(AF, GetBYTE(adr)); | |
break; | |
case 0x84: /* ADD A,IXH */ | |
temp = hreg(IX); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x85: /* ADD A,IXL */ | |
temp = lreg(IX); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x86: /* ADD A,(IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x8C: /* ADC A,IXH */ | |
temp = hreg(IX); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x8D: /* ADC A,IXL */ | |
temp = lreg(IX); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x8E: /* ADC A,(IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x94: /* SUB IXH */ | |
temp = hreg(IX); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x95: /* SUB IXL */ | |
temp = lreg(IX); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x96: /* SUB (IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x9C: /* SBC A,IXH */ | |
temp = hreg(IX); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x9D: /* SBC A,IXL */ | |
temp = lreg(IX); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x9E: /* SBC A,(IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0xA4: /* AND IXH */ | |
sum = ((AF & (IX)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | | |
((sum == 0) << 6) | 0x10 | partab[sum]; | |
break; | |
case 0xA5: /* AND IXL */ | |
sum = ((AF >> 8) & IX) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | 0x10 | | |
((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xA6: /* AND (IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
sum = ((AF >> 8) & GetBYTE(adr)) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | 0x10 | | |
((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xAC: /* XOR IXH */ | |
sum = ((AF ^ (IX)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xAD: /* XOR IXL */ | |
sum = ((AF >> 8) ^ IX) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xAE: /* XOR (IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
sum = ((AF >> 8) ^ GetBYTE(adr)) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB4: /* OR IXH */ | |
sum = ((AF | (IX)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB5: /* OR IXL */ | |
sum = ((AF >> 8) | IX) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB6: /* OR (IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
sum = ((AF >> 8) | GetBYTE(adr)) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xBC: /* CP IXH */ | |
temp = hreg(IX); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xBD: /* CP IXL */ | |
temp = lreg(IX); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xBE: /* CP (IX+dd) */ | |
adr = IX + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xCB: /* CB prefix */ | |
adr = IX + (signed char) RAM_pp(PC); | |
adr = adr; | |
switch ((op = GetBYTE(PC)) & 7) { | |
case 0: ++PC; acu = hreg(BC); break; | |
case 1: ++PC; acu = lreg(BC); break; | |
case 2: ++PC; acu = hreg(DE); break; | |
case 3: ++PC; acu = lreg(DE); break; | |
case 4: ++PC; acu = hreg(HL); break; | |
case 5: ++PC; acu = lreg(HL); break; | |
case 6: ++PC; acu = GetBYTE(adr); break; | |
case 7: ++PC; acu = hreg(AF); break; | |
} | |
switch (op & 0xc0) { | |
case 0x00: /* shift/rotate */ | |
switch (op & 0x38) { | |
case 0x00: /* RLC */ | |
temp = (acu << 1) | (acu >> 7); | |
cbits = temp & 1; | |
goto cbshflg2; | |
case 0x08: /* RRC */ | |
temp = (acu >> 1) | (acu << 7); | |
cbits = temp & 0x80; | |
goto cbshflg2; | |
case 0x10: /* RL */ | |
temp = (acu << 1) | TSTFLAG(C); | |
cbits = acu & 0x80; | |
goto cbshflg2; | |
case 0x18: /* RR */ | |
temp = (acu >> 1) | (TSTFLAG(C) << 7); | |
cbits = acu & 1; | |
goto cbshflg2; | |
case 0x20: /* SLA */ | |
temp = acu << 1; | |
cbits = acu & 0x80; | |
goto cbshflg2; | |
case 0x28: /* SRA */ | |
temp = (acu >> 1) | (acu & 0x80); | |
cbits = acu & 1; | |
goto cbshflg2; | |
case 0x30: /* SLIA */ | |
temp = (acu << 1) | 1; | |
cbits = acu & 0x80; | |
goto cbshflg2; | |
case 0x38: /* SRL */ | |
temp = acu >> 1; | |
cbits = acu & 1; | |
cbshflg2: | |
AF = (AF & ~0xff) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
parity(temp) | !!cbits; | |
} | |
break; | |
case 0x40: /* BIT */ | |
if (acu & (1 << ((op >> 3) & 7))) | |
AF = (AF & ~0xfe) | 0x10 | | |
(((op & 0x38) == 0x38) << 7); | |
else | |
AF = (AF & ~0xfe) | 0x54; | |
if ((op&7) != 6) | |
AF |= (acu & 0x28); | |
temp = acu; | |
break; | |
case 0x80: /* RES */ | |
temp = acu & ~(1 << ((op >> 3) & 7)); | |
break; | |
case 0xc0: /* SET */ | |
temp = acu | (1 << ((op >> 3) & 7)); | |
break; | |
} | |
switch (op & 7) { | |
case 0: Sethreg(BC, temp); break; | |
case 1: Setlreg(BC, temp); break; | |
case 2: Sethreg(DE, temp); break; | |
case 3: Setlreg(DE, temp); break; | |
case 4: Sethreg(HL, temp); break; | |
case 5: Setlreg(HL, temp); break; | |
case 6: PutBYTE(adr, temp); break; | |
case 7: Sethreg(AF, temp); break; | |
} | |
break; | |
case 0xE1: /* POP IX */ | |
POP(IX); | |
break; | |
case 0xE3: /* EX (SP),IX */ | |
temp = IX; POP(IX); PUSH(temp); | |
break; | |
case 0xE5: /* PUSH IX */ | |
PUSH(IX); | |
break; | |
case 0xE9: /* JP (IX) */ | |
PC = IX; | |
break; | |
case 0xF9: /* LD SP,IX */ | |
SP = IX; | |
break; | |
default: /* ignore DD */ | |
BadZ80OpOccured = 1; | |
PC--; | |
} | |
break; | |
case 0xDE: /* SBC A,nn */ | |
temp = RAM_pp(PC); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(SetPV) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0xDF: /* RST 18H */ | |
PUSH(PC); PC = 0x18; | |
break; | |
case 0xE0: /* RET PO */ | |
if (!TSTFLAG(P)) POP(PC); | |
break; | |
case 0xE1: /* POP HL */ | |
POP(HL); | |
break; | |
case 0xE2: /* JP PO,nnnn */ | |
JPC(!TSTFLAG(P)); | |
break; | |
case 0xE3: /* EX (SP),HL */ | |
temp = HL; POP(HL); PUSH(temp); | |
break; | |
case 0xE4: /* CALL PO,nnnn */ | |
CALLC(!TSTFLAG(P)); | |
break; | |
case 0xE5: /* PUSH HL */ | |
PUSH(HL); | |
break; | |
case 0xE6: /* AND nn */ | |
sum = ((AF >> 8) & RAM_pp(PC)) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | 0x10 | | |
((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xE7: /* RST 20H */ | |
PUSH(PC); PC = 0x20; | |
break; | |
case 0xE8: /* RET PE */ | |
if (TSTFLAG(P)) POP(PC); | |
break; | |
case 0xE9: /* JP (HL) */ | |
PC = HL; | |
break; | |
case 0xEA: /* JP PE,nnnn */ | |
JPC(TSTFLAG(P)); | |
break; | |
case 0xEB: /* EX DE,HL */ | |
temp = HL; HL = DE; DE = temp; | |
break; | |
case 0xEC: /* CALL PE,nnnn */ | |
CALLC(TSTFLAG(P)); | |
break; | |
case 0xED: /* ED prefix */ | |
checkCPU | |
switch (op = RAM_pp(PC)) { | |
case 0x40: /* IN B,(C) */ | |
temp = in(lreg(BC)); | |
Sethreg(BC, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
parity(temp); | |
break; | |
case 0x41: /* OUT (C),B */ | |
out(lreg(BC), hreg(BC)); | |
break; | |
case 0x42: /* SBC HL,BC */ | |
HL &= 0xffff; | |
BC &= 0xffff; | |
sum = HL - BC - TSTFLAG(C); | |
cbits = (HL ^ BC ^ sum) >> 8; | |
HL = sum; | |
AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | | |
(((sum & 0xffff) == 0) << 6) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
(cbits & 0x10) | 2 | ((cbits >> 8) & 1); | |
break; | |
case 0x43: /* LD (nnnn),BC */ | |
temp = GetWORD(PC); | |
PutWORD(temp, BC); | |
PC += 2; | |
break; | |
case 0x44: /* NEG */ | |
temp = hreg(AF); | |
AF = (-(AF & 0xff00) & 0xff00); | |
AF |= ((AF >> 8) & 0xa8) | (((AF & 0xff00) == 0) << 6) | | |
(((temp & 0x0f) != 0) << 4) | | |
((temp == 0x80) << 2) | | |
2 | (temp != 0); | |
break; | |
case 0x45: /* RETN */ | |
IFF |= IFF >> 1; | |
POP(PC); | |
break; | |
case 0x46: /* IM 0 */ | |
/* interrupt mode 0 */ | |
break; | |
case 0x47: /* LD I,A */ | |
ir = (ir & 255) | (AF & ~255); | |
break; | |
case 0x48: /* IN C,(C) */ | |
temp = in(lreg(BC)); | |
Setlreg(BC, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
parity(temp); | |
break; | |
case 0x49: /* OUT (C),C */ | |
out(lreg(BC), lreg(BC)); | |
break; | |
case 0x4A: /* ADC HL,BC */ | |
HL &= 0xffff; | |
BC &= 0xffff; | |
sum = HL + BC + TSTFLAG(C); | |
cbits = (HL ^ BC ^ sum) >> 8; | |
HL = sum; | |
AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | | |
(((sum & 0xffff) == 0) << 6) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x4B: /* LD BC,(nnnn) */ | |
temp = GetWORD(PC); | |
BC = GetWORD(temp); | |
PC += 2; | |
break; | |
case 0x4D: /* RETI */ | |
IFF |= IFF >> 1; | |
POP(PC); | |
break; | |
case 0x4F: /* LD R,A */ | |
ir = (ir & ~255) | ((AF >> 8) & 255); | |
break; | |
case 0x50: /* IN D,(C) */ | |
temp = in(lreg(BC)); | |
Sethreg(DE, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
parity(temp); | |
break; | |
case 0x51: /* OUT (C),D */ | |
out(lreg(BC), hreg(DE)); | |
break; | |
case 0x52: /* SBC HL,DE */ | |
HL &= 0xffff; | |
DE &= 0xffff; | |
sum = HL - DE - TSTFLAG(C); | |
cbits = (HL ^ DE ^ sum) >> 8; | |
HL = sum; | |
AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | | |
(((sum & 0xffff) == 0) << 6) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
(cbits & 0x10) | 2 | ((cbits >> 8) & 1); | |
break; | |
case 0x53: /* LD (nnnn),DE */ | |
temp = GetWORD(PC); | |
PutWORD(temp, DE); | |
PC += 2; | |
break; | |
case 0x56: /* IM 1 */ | |
/* interrupt mode 1 */ | |
break; | |
case 0x57: /* LD A,I */ | |
AF = (AF & 0x29) | (ir & ~255) | ((ir >> 8) & 0x80) | (((ir & ~255) == 0) << 6) | ((IFF & 2) << 1); | |
break; | |
case 0x58: /* IN E,(C) */ | |
temp = in(lreg(BC)); | |
Setlreg(DE, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
parity(temp); | |
break; | |
case 0x59: /* OUT (C),E */ | |
out(lreg(BC), lreg(DE)); | |
break; | |
case 0x5A: /* ADC HL,DE */ | |
HL &= 0xffff; | |
DE &= 0xffff; | |
sum = HL + DE + TSTFLAG(C); | |
cbits = (HL ^ DE ^ sum) >> 8; | |
HL = sum; | |
AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | | |
(((sum & 0xffff) == 0) << 6) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x5B: /* LD DE,(nnnn) */ | |
temp = GetWORD(PC); | |
DE = GetWORD(temp); | |
PC += 2; | |
break; | |
case 0x5E: /* IM 2 */ | |
/* interrupt mode 2 */ | |
break; | |
case 0x5F: /* LD A,R */ | |
AF = (AF & 0x29) | ((ir & 255) << 8) | (ir & 0x80) | (((ir & 255) == 0) << 6) | ((IFF & 2) << 1); | |
break; | |
case 0x60: /* IN H,(C) */ | |
temp = in(lreg(BC)); | |
Sethreg(HL, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
parity(temp); | |
break; | |
case 0x61: /* OUT (C),H */ | |
out(lreg(BC), hreg(HL)); | |
break; | |
case 0x62: /* SBC HL,HL */ | |
HL &= 0xffff; | |
sum = HL - HL - TSTFLAG(C); | |
cbits = (HL ^ HL ^ sum) >> 8; | |
HL = sum; | |
AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | | |
(((sum & 0xffff) == 0) << 6) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
(cbits & 0x10) | 2 | ((cbits >> 8) & 1); | |
break; | |
case 0x63: /* LD (nnnn),HL */ | |
temp = GetWORD(PC); | |
PutWORD(temp, HL); | |
PC += 2; | |
break; | |
case 0x67: /* RRD */ | |
temp = GetBYTE(HL); | |
acu = hreg(AF); | |
PutBYTE(HL, hdig(temp) | (ldig(acu) << 4)); | |
acu = (acu & 0xf0) | ldig(temp); | |
AF = (acu << 8) | (acu & 0xa8) | (((acu & 0xff) == 0) << 6) | | |
partab[acu] | (AF & 1); | |
break; | |
case 0x68: /* IN L,(C) */ | |
temp = in(lreg(BC)); | |
Setlreg(HL, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
parity(temp); | |
break; | |
case 0x69: /* OUT (C),L */ | |
out(lreg(BC), lreg(HL)); | |
break; | |
case 0x6A: /* ADC HL,HL */ | |
HL &= 0xffff; | |
sum = HL + HL + TSTFLAG(C); | |
cbits = (HL ^ HL ^ sum) >> 8; | |
HL = sum; | |
AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | | |
(((sum & 0xffff) == 0) << 6) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x6B: /* LD HL,(nnnn) */ | |
temp = GetWORD(PC); | |
HL = GetWORD(temp); | |
PC += 2; | |
break; | |
case 0x6F: /* RLD */ | |
temp = GetBYTE(HL); | |
acu = hreg(AF); | |
PutBYTE(HL, (ldig(temp) << 4) | ldig(acu)); | |
acu = (acu & 0xf0) | hdig(temp); | |
AF = (acu << 8) | (acu & 0xa8) | (((acu & 0xff) == 0) << 6) | | |
partab[acu] | (AF & 1); | |
break; | |
case 0x70: /* IN (C) */ | |
temp = in(lreg(BC)); | |
Setlreg(temp, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
parity(temp); | |
break; | |
case 0x71: /* OUT (C),0 */ | |
out(lreg(BC), 0); | |
break; | |
case 0x72: /* SBC HL,SP */ | |
HL &= 0xffff; | |
SP &= 0xffff; | |
sum = HL - SP - TSTFLAG(C); | |
cbits = (HL ^ SP ^ sum) >> 8; | |
HL = sum; | |
AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | | |
(((sum & 0xffff) == 0) << 6) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
(cbits & 0x10) | 2 | ((cbits >> 8) & 1); | |
break; | |
case 0x73: /* LD (nnnn),SP */ | |
temp = GetWORD(PC); | |
PutWORD(temp, SP); | |
PC += 2; | |
break; | |
case 0x78: /* IN A,(C) */ | |
temp = in(lreg(BC)); | |
Sethreg(AF, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
parity(temp); | |
break; | |
case 0x79: /* OUT (C),A */ | |
out(lreg(BC), hreg(AF)); | |
break; | |
case 0x7A: /* ADC HL,SP */ | |
HL &= 0xffff; | |
SP &= 0xffff; | |
sum = HL + SP + TSTFLAG(C); | |
cbits = (HL ^ SP ^ sum) >> 8; | |
HL = sum; | |
AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | | |
(((sum & 0xffff) == 0) << 6) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x7B: /* LD SP,(nnnn) */ | |
temp = GetWORD(PC); | |
SP = GetWORD(temp); | |
PC += 2; | |
break; | |
case 0xA0: /* LDI */ | |
acu = RAM_pp(HL); | |
PutBYTE_pp(DE, acu); | |
acu += hreg(AF); | |
AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) | | |
(((--BC & 0xffff) != 0) << 2); | |
break; | |
case 0xA1: /* CPI */ | |
acu = hreg(AF); | |
temp = RAM_pp(HL); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) | | |
(((sum - ((cbits&16)>>4))&2) << 4) | (cbits & 16) | | |
((sum - ((cbits >> 4) & 1)) & 8) | | |
((--BC & 0xffff) != 0) << 2 | 2; | |
if ((sum & 15) == 8 && (cbits & 16) != 0) | |
AF &= ~8; | |
break; | |
case 0xA2: /* INI */ | |
PutBYTE(HL, in(lreg(BC))); ++HL; | |
SETFLAG(N, 1); | |
SETFLAG(P, (--BC & 0xffff) != 0); | |
break; | |
case 0xA3: /* OUTI */ | |
out(lreg(BC), GetBYTE(HL)); ++HL; | |
SETFLAG(N, 1); | |
Sethreg(BC, lreg(BC) - 1); | |
SETFLAG(Z, lreg(BC) == 0); | |
break; | |
case 0xA8: /* LDD */ | |
acu = RAM_mm(HL); | |
PutBYTE_mm(DE, acu); | |
acu += hreg(AF); | |
AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) | | |
(((--BC & 0xffff) != 0) << 2); | |
break; | |
case 0xA9: /* CPD */ | |
acu = hreg(AF); | |
temp = RAM_mm(HL); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) | | |
(((sum - ((cbits&16)>>4))&2) << 4) | (cbits & 16) | | |
((sum - ((cbits >> 4) & 1)) & 8) | | |
((--BC & 0xffff) != 0) << 2 | 2; | |
if ((sum & 15) == 8 && (cbits & 16) != 0) | |
AF &= ~8; | |
break; | |
case 0xAA: /* IND */ | |
PutBYTE(HL, in(lreg(BC))); --HL; | |
SETFLAG(N, 1); | |
Sethreg(BC, lreg(BC) - 1); | |
SETFLAG(Z, lreg(BC) == 0); | |
break; | |
case 0xAB: /* OUTD */ | |
out(lreg(BC), GetBYTE(HL)); --HL; | |
SETFLAG(N, 1); | |
Sethreg(BC, lreg(BC) - 1); | |
SETFLAG(Z, lreg(BC) == 0); | |
break; | |
case 0xB0: /* LDIR */ | |
acu = hreg(AF); | |
BC &= 0xffff; | |
do { | |
acu = RAM_pp(HL); | |
PutBYTE_pp(DE, acu); | |
} while (--BC); | |
acu += hreg(AF); | |
AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4); | |
break; | |
case 0xB1: /* CPIR */ | |
acu = hreg(AF); | |
BC &= 0xffff; | |
do { | |
temp = RAM_pp(HL); | |
op = --BC != 0; | |
sum = acu - temp; | |
} while (op && sum != 0); | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) | | |
(((sum - ((cbits&16)>>4))&2) << 4) | | |
(cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) | | |
op << 2 | 2; | |
if ((sum & 15) == 8 && (cbits & 16) != 0) | |
AF &= ~8; | |
break; | |
case 0xB2: /* INIR */ | |
temp = hreg(BC); | |
do { | |
PutBYTE(HL, in(lreg(BC))); ++HL; | |
} while (--temp); | |
Sethreg(BC, 0); | |
SETFLAG(N, 1); | |
SETFLAG(Z, 1); | |
break; | |
case 0xB3: /* OTIR */ | |
temp = hreg(BC); | |
do { | |
out(lreg(BC), GetBYTE(HL)); ++HL; | |
} while (--temp); | |
Sethreg(BC, 0); | |
SETFLAG(N, 1); | |
SETFLAG(Z, 1); | |
break; | |
case 0xB8: /* LDDR */ | |
BC &= 0xffff; | |
do { | |
acu = RAM_mm(HL); | |
PutBYTE_mm(DE, acu); | |
} while (--BC); | |
acu += hreg(AF); | |
AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4); | |
break; | |
case 0xB9: /* CPDR */ | |
acu = hreg(AF); | |
BC &= 0xffff; | |
do { | |
temp = RAM_mm(HL); | |
op = --BC != 0; | |
sum = acu - temp; | |
} while (op && sum != 0); | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) | | |
(((sum - ((cbits&16)>>4))&2) << 4) | | |
(cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) | | |
op << 2 | 2; | |
if ((sum & 15) == 8 && (cbits & 16) != 0) | |
AF &= ~8; | |
break; | |
case 0xBA: /* INDR */ | |
temp = hreg(BC); | |
do { | |
PutBYTE(HL, in(lreg(BC))); --HL; | |
} while (--temp); | |
Sethreg(BC, 0); | |
SETFLAG(N, 1); | |
SETFLAG(Z, 1); | |
break; | |
case 0xBB: /* OTDR */ | |
temp = hreg(BC); | |
do { | |
out(lreg(BC), GetBYTE(HL)); --HL; | |
} while (--temp); | |
Sethreg(BC, 0); | |
SETFLAG(N, 1); | |
SETFLAG(Z, 1); | |
break; | |
default: /* ignore ED and following byte */ | |
BadZ80OpOccured = 1; | |
} | |
break; | |
case 0xEE: /* XOR nn */ | |
sum = ((AF >> 8) ^ RAM_pp(PC)) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xEF: /* RST 28H */ | |
PUSH(PC); PC = 0x28; | |
break; | |
case 0xF0: /* RET P */ | |
if (!TSTFLAG(S)) POP(PC); | |
break; | |
case 0xF1: /* POP AF */ | |
POP(AF); | |
break; | |
case 0xF2: /* JP P,nnnn */ | |
JPC(!TSTFLAG(S)); | |
break; | |
case 0xF3: /* DI */ | |
IFF = 0; | |
break; | |
case 0xF4: /* CALL P,nnnn */ | |
CALLC(!TSTFLAG(S)); | |
break; | |
case 0xF5: /* PUSH AF */ | |
PUSH(AF); | |
break; | |
case 0xF6: /* OR nn */ | |
sum = ((AF >> 8) | RAM_pp(PC)) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xF7: /* RST 30H */ | |
PUSH(PC); PC = 0x30; | |
break; | |
case 0xF8: /* RET M */ | |
if (TSTFLAG(S)) POP(PC); | |
break; | |
case 0xF9: /* LD SP,HL */ | |
SP = HL; | |
break; | |
case 0xFA: /* JP M,nnnn */ | |
JPC(TSTFLAG(S)); | |
break; | |
case 0xFB: /* EI */ | |
IFF = 3; | |
break; | |
case 0xFC: /* CALL M,nnnn */ | |
CALLC(TSTFLAG(S)); | |
break; | |
case 0xFD: /* FD prefix */ | |
checkCPU | |
switch (op = RAM_pp(PC)) { | |
case 0x09: /* ADD IY,BC */ | |
IY &= 0xffff; | |
BC &= 0xffff; | |
sum = IY + BC; | |
cbits = (IY ^ BC ^ sum) >> 8; | |
IY = sum; | |
AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x19: /* ADD IY,DE */ | |
IY &= 0xffff; | |
DE &= 0xffff; | |
sum = IY + DE; | |
cbits = (IY ^ DE ^ sum) >> 8; | |
IY = sum; | |
AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x21: /* LD IY,nnnn */ | |
IY = GetWORD(PC); | |
PC += 2; | |
break; | |
case 0x22: /* LD (nnnn),IY */ | |
temp = GetWORD(PC); | |
PutWORD(temp, IY); | |
PC += 2; | |
break; | |
case 0x23: /* INC IY */ | |
++IY; | |
break; | |
case 0x24: /* INC IYH */ | |
IY += 0x100; | |
temp = hreg(IY); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
((temp == 0x80) << 2); | |
break; | |
case 0x25: /* DEC IYH */ | |
IY -= 0x100; | |
temp = hreg(IY); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
((temp == 0x7f) << 2) | 2; | |
break; | |
case 0x26: /* LD IYH,nn */ | |
Sethreg(IY, RAM_pp(PC)); | |
break; | |
case 0x29: /* ADD IY,IY */ | |
IY &= 0xffff; | |
sum = IY + IY; | |
cbits = (IY ^ IY ^ sum) >> 8; | |
IY = sum; | |
AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x2A: /* LD IY,(nnnn) */ | |
temp = GetWORD(PC); | |
IY = GetWORD(temp); | |
PC += 2; | |
break; | |
case 0x2B: /* DEC IY */ | |
--IY; | |
break; | |
case 0x2C: /* INC IYL */ | |
temp = lreg(IY)+1; | |
Setlreg(IY, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
((temp == 0x80) << 2); | |
break; | |
case 0x2D: /* DEC IYL */ | |
temp = lreg(IY)-1; | |
Setlreg(IY, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
((temp == 0x7f) << 2) | 2; | |
break; | |
case 0x2E: /* LD IYL,nn */ | |
Setlreg(IY, RAM_pp(PC)); | |
break; | |
case 0x34: /* INC (IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr)+1; | |
PutBYTE(adr, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0) << 4) | | |
((temp == 0x80) << 2); | |
break; | |
case 0x35: /* DEC (IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr)-1; | |
PutBYTE(adr, temp); | |
AF = (AF & ~0xfe) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
(((temp & 0xf) == 0xf) << 4) | | |
((temp == 0x7f) << 2) | 2; | |
break; | |
case 0x36: /* LD (IY+dd),nn */ | |
adr = IY + (signed char) RAM_pp(PC); | |
PutBYTE(adr, RAM_pp(PC)); | |
break; | |
case 0x39: /* ADD IY,SP */ | |
IY &= 0xffff; | |
SP &= 0xffff; | |
sum = IY + SP; | |
cbits = (IY ^ SP ^ sum) >> 8; | |
IY = sum; | |
AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0x44: /* LD B,IYH */ | |
Sethreg(BC, hreg(IY)); | |
break; | |
case 0x45: /* LD B,IYL */ | |
Sethreg(BC, lreg(IY)); | |
break; | |
case 0x46: /* LD B,(IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
Sethreg(BC, GetBYTE(adr)); | |
break; | |
case 0x4C: /* LD C,IYH */ | |
Setlreg(BC, hreg(IY)); | |
break; | |
case 0x4D: /* LD C,IYL */ | |
Setlreg(BC, lreg(IY)); | |
break; | |
case 0x4E: /* LD C,(IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
Setlreg(BC, GetBYTE(adr)); | |
break; | |
case 0x54: /* LD D,IYH */ | |
Sethreg(DE, hreg(IY)); | |
break; | |
case 0x55: /* LD D,IYL */ | |
Sethreg(DE, lreg(IY)); | |
break; | |
case 0x56: /* LD D,(IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
Sethreg(DE, GetBYTE(adr)); | |
break; | |
case 0x5C: /* LD E,H */ | |
Setlreg(DE, hreg(IY)); | |
break; | |
case 0x5D: /* LD E,L */ | |
Setlreg(DE, lreg(IY)); | |
break; | |
case 0x5E: /* LD E,(IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
Setlreg(DE, GetBYTE(adr)); | |
break; | |
case 0x60: /* LD IYH,B */ | |
Sethreg(IY, hreg(BC)); | |
break; | |
case 0x61: /* LD IYH,C */ | |
Sethreg(IY, lreg(BC)); | |
break; | |
case 0x62: /* LD IYH,D */ | |
Sethreg(IY, hreg(DE)); | |
break; | |
case 0x63: /* LD IYH,E */ | |
Sethreg(IY, lreg(DE)); | |
break; | |
case 0x64: /* LD IYH,IYH */ | |
/* nop */ | |
break; | |
case 0x65: /* LD IYH,IYL */ | |
Sethreg(IY, lreg(IY)); | |
break; | |
case 0x66: /* LD H,(IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
Sethreg(HL, GetBYTE(adr)); | |
break; | |
case 0x67: /* LD IYH,A */ | |
Sethreg(IY, hreg(AF)); | |
break; | |
case 0x68: /* LD IYL,B */ | |
Setlreg(IY, hreg(BC)); | |
break; | |
case 0x69: /* LD IYL,C */ | |
Setlreg(IY, lreg(BC)); | |
break; | |
case 0x6A: /* LD IYL,D */ | |
Setlreg(IY, hreg(DE)); | |
break; | |
case 0x6B: /* LD IYL,E */ | |
Setlreg(IY, lreg(DE)); | |
break; | |
case 0x6C: /* LD IYL,IYH */ | |
Setlreg(IY, hreg(IY)); | |
break; | |
case 0x6D: /* LD IYL,IYL */ | |
/* nop */ | |
break; | |
case 0x6E: /* LD L,(IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
Setlreg(HL, GetBYTE(adr)); | |
break; | |
case 0x6F: /* LD IYL,A */ | |
Setlreg(IY, hreg(AF)); | |
break; | |
case 0x70: /* LD (IY+dd),B */ | |
adr = IY + (signed char) RAM_pp(PC); | |
PutBYTE(adr, hreg(BC)); | |
break; | |
case 0x71: /* LD (IY+dd),C */ | |
adr = IY + (signed char) RAM_pp(PC); | |
PutBYTE(adr, lreg(BC)); | |
break; | |
case 0x72: /* LD (IY+dd),D */ | |
adr = IY + (signed char) RAM_pp(PC); | |
PutBYTE(adr, hreg(DE)); | |
break; | |
case 0x73: /* LD (IY+dd),E */ | |
adr = IY + (signed char) RAM_pp(PC); | |
PutBYTE(adr, lreg(DE)); | |
break; | |
case 0x74: /* LD (IY+dd),H */ | |
adr = IY + (signed char) RAM_pp(PC); | |
PutBYTE(adr, hreg(HL)); | |
break; | |
case 0x75: /* LD (IY+dd),L */ | |
adr = IY + (signed char) RAM_pp(PC); | |
PutBYTE(adr, lreg(HL)); | |
break; | |
case 0x77: /* LD (IY+dd),A */ | |
adr = IY + (signed char) RAM_pp(PC); | |
PutBYTE(adr, hreg(AF)); | |
break; | |
case 0x7C: /* LD A,IYH */ | |
Sethreg(AF, hreg(IY)); | |
break; | |
case 0x7D: /* LD A,IYL */ | |
Sethreg(AF, lreg(IY)); | |
break; | |
case 0x7E: /* LD A,(IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
Sethreg(AF, GetBYTE(adr)); | |
break; | |
case 0x84: /* ADD A,IYH */ | |
temp = hreg(IY); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x85: /* ADD A,IYL */ | |
temp = lreg(IY); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x86: /* ADD A,(IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr); | |
acu = hreg(AF); | |
sum = acu + temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x8C: /* ADC A,IYH */ | |
temp = hreg(IY); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x8D: /* ADC A,IYL */ | |
temp = lreg(IY); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x8E: /* ADC A,(IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr); | |
acu = hreg(AF); | |
sum = acu + temp + TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | | |
((cbits >> 8) & 1); | |
break; | |
case 0x94: /* SUB IYH */ | |
temp = hreg(IY); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x95: /* SUB IYL */ | |
temp = lreg(IY); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x96: /* SUB (IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x9C: /* SBC A,IYH */ | |
temp = hreg(IY); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x9D: /* SBC A,IYL */ | |
temp = lreg(IY); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0x9E: /* SBC A,(IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr); | |
acu = hreg(AF); | |
sum = acu - temp - TSTFLAG(C); | |
cbits = acu ^ temp ^ sum; | |
AF = ((sum & 0xff) << 8) | (sum & 0xa8) | | |
(((sum & 0xff) == 0) << 6) | (cbits & 0x10) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
((cbits >> 8) & 1); | |
break; | |
case 0xA4: /* AND IYH */ | |
sum = ((AF & (IY)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | | |
((sum == 0) << 6) | 0x10 | partab[sum]; | |
break; | |
case 0xA5: /* AND IYL */ | |
sum = ((AF >> 8) & IY) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | 0x10 | | |
((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xA6: /* AND (IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
sum = ((AF >> 8) & GetBYTE(adr)) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | 0x10 | | |
((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xAC: /* XOR IYH */ | |
sum = ((AF ^ (IY)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xAD: /* XOR IYL */ | |
sum = ((AF >> 8) ^ IY) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xAE: /* XOR (IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
sum = ((AF >> 8) ^ GetBYTE(adr)) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB4: /* OR IYH */ | |
sum = ((AF | (IY)) >> 8) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB5: /* OR IYL */ | |
sum = ((AF >> 8) | IY) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xB6: /* OR (IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
sum = ((AF >> 8) | GetBYTE(adr)) & 0xff; | |
AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; | |
break; | |
case 0xBC: /* CP IYH */ | |
temp = hreg(IY); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xBD: /* CP IYL */ | |
temp = lreg(IY); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xBE: /* CP (IY+dd) */ | |
adr = IY + (signed char) RAM_pp(PC); | |
temp = GetBYTE(adr); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xCB: /* CB prefix */ | |
adr = IY + (signed char) RAM_pp(PC); | |
adr = adr; | |
switch ((op = GetBYTE(PC)) & 7) { | |
case 0: ++PC; acu = hreg(BC); break; | |
case 1: ++PC; acu = lreg(BC); break; | |
case 2: ++PC; acu = hreg(DE); break; | |
case 3: ++PC; acu = lreg(DE); break; | |
case 4: ++PC; acu = hreg(HL); break; | |
case 5: ++PC; acu = lreg(HL); break; | |
case 6: ++PC; acu = GetBYTE(adr); break; | |
case 7: ++PC; acu = hreg(AF); break; | |
} | |
switch (op & 0xc0) { | |
case 0x00: /* shift/rotate */ | |
switch (op & 0x38) { | |
case 0x00: /* RLC */ | |
temp = (acu << 1) | (acu >> 7); | |
cbits = temp & 1; | |
goto cbshflg3; | |
case 0x08: /* RRC */ | |
temp = (acu >> 1) | (acu << 7); | |
cbits = temp & 0x80; | |
goto cbshflg3; | |
case 0x10: /* RL */ | |
temp = (acu << 1) | TSTFLAG(C); | |
cbits = acu & 0x80; | |
goto cbshflg3; | |
case 0x18: /* RR */ | |
temp = (acu >> 1) | (TSTFLAG(C) << 7); | |
cbits = acu & 1; | |
goto cbshflg3; | |
case 0x20: /* SLA */ | |
temp = acu << 1; | |
cbits = acu & 0x80; | |
goto cbshflg3; | |
case 0x28: /* SRA */ | |
temp = (acu >> 1) | (acu & 0x80); | |
cbits = acu & 1; | |
goto cbshflg3; | |
case 0x30: /* SLIA */ | |
temp = (acu << 1) | 1; | |
cbits = acu & 0x80; | |
goto cbshflg3; | |
case 0x38: /* SRL */ | |
temp = acu >> 1; | |
cbits = acu & 1; | |
cbshflg3: | |
AF = (AF & ~0xff) | (temp & 0xa8) | | |
(((temp & 0xff) == 0) << 6) | | |
parity(temp) | !!cbits; | |
} | |
break; | |
case 0x40: /* BIT */ | |
if (acu & (1 << ((op >> 3) & 7))) | |
AF = (AF & ~0xfe) | 0x10 | | |
(((op & 0x38) == 0x38) << 7); | |
else | |
AF = (AF & ~0xfe) | 0x54; | |
if ((op&7) != 6) | |
AF |= (acu & 0x28); | |
temp = acu; | |
break; | |
case 0x80: /* RES */ | |
temp = acu & ~(1 << ((op >> 3) & 7)); | |
break; | |
case 0xc0: /* SET */ | |
temp = acu | (1 << ((op >> 3) & 7)); | |
break; | |
} | |
switch (op & 7) { | |
case 0: Sethreg(BC, temp); break; | |
case 1: Setlreg(BC, temp); break; | |
case 2: Sethreg(DE, temp); break; | |
case 3: Setlreg(DE, temp); break; | |
case 4: Sethreg(HL, temp); break; | |
case 5: Setlreg(HL, temp); break; | |
case 6: PutBYTE(adr, temp); break; | |
case 7: Sethreg(AF, temp); break; | |
} | |
break; | |
case 0xE1: /* POP IY */ | |
POP(IY); | |
break; | |
case 0xE3: /* EX (SP),IY */ | |
temp = IY; POP(IY); PUSH(temp); | |
break; | |
case 0xE5: /* PUSH IY */ | |
PUSH(IY); | |
break; | |
case 0xE9: /* JP (IY) */ | |
PC = IY; | |
break; | |
case 0xF9: /* LD SP,IY */ | |
SP = IY; | |
break; | |
default: /* ignore FD */ | |
BadZ80OpOccured = 1; | |
PC--; | |
} | |
break; | |
case 0xFE: /* CP nn */ | |
temp = RAM_pp(PC); | |
AF = (AF & ~0x28) | (temp & 0x28); | |
acu = hreg(AF); | |
sum = acu - temp; | |
cbits = acu ^ temp ^ sum; | |
AF = (AF & ~0xff) | (sum & 0x80) | | |
(((sum & 0xff) == 0) << 6) | (temp & 0x28) | | |
(SetPV) | 2 | | |
(cbits & 0x10) | ((cbits >> 8) & 1); | |
break; | |
case 0xFF: /* RST 38H */ | |
PUSH(PC); PC = 0x38; | |
} | |
if ((BadZ80OpOccured || Bad8080OpOccured) && (cpu_unit.flags & UNIT_OPSTOP)) { | |
reason = STOP_OPCODE; | |
} | |
} | |
pc = PC; | |
af[af_sel] = AF; | |
regs[regs_sel].bc = BC; | |
regs[regs_sel].de = DE; | |
regs[regs_sel].hl = HL; | |
ix = IX; | |
iy = IY; | |
sp = SP; | |
/* Simulation halted */ | |
saved_PC = (reason == STOP_OPCODE) ? PCX : pc; | |
AF_S = af[af_sel]; | |
BC_S = regs[regs_sel].bc; | |
DE_S = regs[regs_sel].de; | |
HL_S = regs[regs_sel].hl; | |
IX_S = ix; | |
IY_S = iy; | |
SP_S = sp; | |
AF1_S = af[1-af_sel]; | |
BC1_S = regs[1-regs_sel].bc; | |
DE1_S = regs[1-regs_sel].de; | |
HL1_S = regs[1-regs_sel].hl; | |
IFF_S = IFF; | |
INT_S = ir; | |
return reason; | |
} | |
void clear_memory(int32 starting) { | |
int32 i; | |
for (i = starting; i < MAXMEMSIZE; i++) { | |
M[i] = 0; | |
} | |
for (i = 0; i < bootrom_size; i++) { | |
M[i + bootrom_origin] = bootrom[i] & 0xFF; | |
} | |
} | |
/* Reset routine */ | |
t_stat cpu_reset (DEVICE *dptr) | |
{ | |
af[0] = af[1] = 0; | |
af_sel = 0; | |
regs[0].bc = regs[0].de = regs[0].hl = 0; | |
regs_sel = 0; | |
regs[1].bc = regs[1].de = regs[1].hl = 0; | |
ir = ix = iy = sp = pc = IFF = 0; | |
saved_PC = 0; | |
clear_memory(0); | |
markTimeSP = 0; | |
sim_brk_types = sim_brk_dflt = SWMASK ('E'); | |
return SCPE_OK; | |
} | |
/* Memory examine */ | |
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) | |
{ | |
if ((addr >= MEMSIZE) && (addr < bootrom_origin)) { | |
return SCPE_NXM; | |
} | |
if (vptr != NULL) { | |
*vptr = M[addr] & 0xff; | |
} | |
return SCPE_OK; | |
} | |
/* Memory deposit */ | |
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw) | |
{ | |
if ((addr >= MEMSIZE) || (addr >= bootrom_origin)) { | |
return SCPE_NXM; | |
} | |
M[addr] = val & 0xff; | |
return SCPE_OK; | |
} | |
t_stat cpu_set_size (UNIT *uptr, int32 value, char *cptr, void *desc) | |
{ | |
int32 mc = 0; | |
t_addr i; | |
int32 limit; | |
if ((value <= 0) || (value > MAXMEMSIZE) || ((value & 0xFFF) != 0)) { | |
return SCPE_ARG; | |
} | |
limit = (bootrom_origin < MEMSIZE) ? bootrom_origin : MEMSIZE; | |
for (i = value; i < limit; i++) { | |
mc |= M[i]; | |
} | |
if (mc && (!get_yn ("Really truncate memory [N]?", FALSE))) { | |
return SCPE_OK; | |
} | |
MEMSIZE = value; | |
clear_memory(value); | |
return SCPE_OK; | |
} |