From bd09b3b68b577251db0596d62ccbed964940fdc9 Mon Sep 17 00:00:00 2001 From: Bart Trzynadlowski Date: Tue, 22 Mar 2016 01:16:46 +0000 Subject: [PATCH] Fixed warnings and whitespace --- Src/CPU/Z80/Z80.cpp | 7638 ++++++++++++++++++++++--------------------- Src/CPU/Z80/Z80.h | 451 +-- 2 files changed, 4047 insertions(+), 4042 deletions(-) diff --git a/Src/CPU/Z80/Z80.cpp b/Src/CPU/Z80/Z80.cpp index 54d6278..df0fbbb 100644 --- a/Src/CPU/Z80/Z80.cpp +++ b/Src/CPU/Z80/Z80.cpp @@ -29,9 +29,9 @@ * Please see Z80.h for a discussion of known inaccuracies. */ -#include // for NULL +#include // for NULL #include "Supermodel.h" -#include "Z80.h" // must include this first to define CZ80 +#include "Z80.h" // must include this first to define CZ80 /****************************************************************************** @@ -39,195 +39,195 @@ ******************************************************************************/ // Address space access -#define GetBYTE(a) ( Bus->Read8(a&0xFFFF) ) -#define GetBYTE_pp(a) ( Bus->Read8(((a)++)&0xFFFF) ) -#define GetBYTE_mm(a) ( Bus->Read8(((a)--)&0xFFFF) ) -#define mm_GetBYTE(a) ( Bus->Read8((--(a))&0xFFFF) ) +#define GetBYTE(a) ( Bus->Read8(a&0xFFFF) ) +#define GetBYTE_pp(a) ( Bus->Read8(((a)++)&0xFFFF) ) +#define GetBYTE_mm(a) ( Bus->Read8(((a)--)&0xFFFF) ) +#define mm_GetBYTE(a) ( Bus->Read8((--(a))&0xFFFF) ) -#define PutBYTE(a,v) Bus->Write8((a)&0xFFFF,v) -#define PutBYTE_pp(a,v) Bus->Write8(((a)++)&0xFFFF,v) -#define PutBYTE_mm(a,v) Bus->Write8(((a)--)&0xFFFF,v) -#define mm_PutBYTE(a,v) Bus->Write8((--(a))&0xFFFF,v) +#define PutBYTE(a,v) Bus->Write8((a)&0xFFFF,v) +#define PutBYTE_pp(a,v) Bus->Write8(((a)++)&0xFFFF,v) +#define PutBYTE_mm(a,v) Bus->Write8(((a)--)&0xFFFF,v) +#define mm_PutBYTE(a,v) Bus->Write8((--(a))&0xFFFF,v) -#define GetWORD(a) (Bus->Read8((a)&0xFFFF) | (Bus->Read8(((a)+1)&0xFFFF)<<8)) +#define GetWORD(a) (Bus->Read8((a)&0xFFFF) | (Bus->Read8(((a)+1)&0xFFFF)<<8)) -#define PutWORD(a, v) \ - do \ - { \ - PutBYTE((a),(v)&0xFF); \ - PutBYTE((a)+1,((v)>>8)); \ - } while (0) +#define PutWORD(a, v) \ + do \ + { \ + PutBYTE((a),(v)&0xFF); \ + PutBYTE((a)+1,((v)>>8)); \ + } while (0) -#define OUTPUT(a,v) Bus->IOWrite8((a)&0xFF,v) -#define INPUT(a) ( Bus->IORead8((a)&0xFF) ) +#define OUTPUT(a,v) Bus->IOWrite8((a)&0xFF,v) +#define INPUT(a) ( Bus->IORead8((a)&0xFF) ) // Flags -#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 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 SETFLAG(f,c) AF = (c) ? AF | FLAG_ ## f : AF & ~FLAG_ ## f +#define TSTFLAG(f) ((AF & FLAG_ ## f) != 0) + // Piecewise register access -#define ldig(x) ((x) & 0xf) -#define hdig(x) (((x)>>4)&0xf) -#define lreg(x) ((x)&0xff) -#define hreg(x) (((x)>>8)&0xff) +#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)) +#define Setlreg(x, v) x = (((x)&0xff00) | ((v)&0xff)) +#define Sethreg(x, v) x = (((x)&0xff) | (((v)&0xff) << 8)) // Parity bit calculation static const unsigned char 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, + 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, }; // Instruction cycle tables static const unsigned char cycleTables[5][256] = { - { - // Table 0: single byte instructions - 4,10,7,6,4,4,7,4,4,11,7,6,4,4,7,4, - 8,10,7,6,4,4,7,4,12,11,7,6,4,4,7,4, - 7,10,16,6,4,4,7,4,7,11,16,6,4,4,7,4, - 7,10,13,6,11,11,10,4,7,11,13,6,4,4,7,4, - 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, - 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, - 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, - 7,7,7,7,7,7,4,7,4,4,4,4,4,4,7,4, - 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, - 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, - 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, - 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, - 5,10,10,10,10,11,7,11,5,10,10,0,10,17,7,11, - 5,10,10,11,10,11,7,11,5,4,10,11,10,0,7,11, - 5,10,10,19,10,11,7,11,5,4,10,4,10,0,7,11, - 5,10,10,4,10,11,7,11,5,6,10,4,10,0,7,11 - }, { - // Table 1: two byte instructions of form CB-XX - 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, - 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, - 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, - 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, - 8,8,8,8,8,8,12,8,8,8,8,8,8,8,12,8, - 8,8,8,8,8,8,12,8,8,8,8,8,8,8,12,8, - 8,8,8,8,8,8,12,8,8,8,8,8,8,8,12,8, - 8,8,8,8,8,8,12,8,8,8,8,8,8,8,12,8, - 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, - 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, - 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, - 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, - 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, - 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, - 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, - 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8 - }, { - // Table 2: two byte instructions of form ED-XX - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 12,12,15,20,8,14,8,9,12,12,15,20,0,14,0,9, - 12,12,15,20,0,0,8,9,12,12,15,20,0,0,8,9, - 12,12,15,20,0,0,0,18,12,12,15,20,0,0,0,18, - 12,0,15,20,0,0,0,0,12,12,15,20,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 16,16,16,16,0,0,0,0,16,16,16,16,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - }, { - // Table 3: two byte instructions of form DD-XX or FD-XX - 0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0, - 0,14,20,10,9,9,9,0,0,15,20,10,9,9,9,0, - 0,0,0,0,23,23,19,0,0,15,0,0,0,0,0,0, - 0,0,0,0,9,9,19,0,0,0,0,0,9,9,19,0, - 0,0,0,0,9,9,19,0,0,0,0,0,9,9,19,0, - 9,9,9,9,9,9,19,9,9,9,9,9,9,9,19,9, - 19,19,19,19,19,19,19,19,0,0,0,0,9,9,19,0, - 0,0,0,0,9,9,19,0,0,0,0,0,9,9,19,0, - 0,0,0,0,9,9,19,0,0,0,0,0,9,9,19,0, - 0,0,0,0,9,9,19,0,0,0,0,0,9,9,19,0, - 0,0,0,0,9,9,19,0,0,0,0,0,9,9,19,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,14,0,23,0,15,0,0,0,8,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0 - }, { - // Table 4: three byte instructions of form DD-CB-XX or FD-CB-XX - 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, - 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, - 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, - 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, - 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, - 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, - 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, - 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, - 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, - 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, - 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, - 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, - 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, - 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, - 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, - 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0 - } + { + // Table 0: single byte instructions + 4,10,7,6,4,4,7,4,4,11,7,6,4,4,7,4, + 8,10,7,6,4,4,7,4,12,11,7,6,4,4,7,4, + 7,10,16,6,4,4,7,4,7,11,16,6,4,4,7,4, + 7,10,13,6,11,11,10,4,7,11,13,6,4,4,7,4, + 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, + 7,7,7,7,7,7,4,7,4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4,4,4,4,4,4,4,7,4, + 5,10,10,10,10,11,7,11,5,10,10,0,10,17,7,11, + 5,10,10,11,10,11,7,11,5,4,10,11,10,0,7,11, + 5,10,10,19,10,11,7,11,5,4,10,4,10,0,7,11, + 5,10,10,4,10,11,7,11,5,6,10,4,10,0,7,11 + }, { + // Table 1: two byte instructions of form CB-XX + 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,12,8,8,8,8,8,8,8,12,8, + 8,8,8,8,8,8,12,8,8,8,8,8,8,8,12,8, + 8,8,8,8,8,8,12,8,8,8,8,8,8,8,12,8, + 8,8,8,8,8,8,12,8,8,8,8,8,8,8,12,8, + 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8,8,8,8,8,8,8,15,8 + }, { + // Table 2: two byte instructions of form ED-XX + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 12,12,15,20,8,14,8,9,12,12,15,20,0,14,0,9, + 12,12,15,20,0,0,8,9,12,12,15,20,0,0,8,9, + 12,12,15,20,0,0,0,18,12,12,15,20,0,0,0,18, + 12,0,15,20,0,0,0,0,12,12,15,20,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 16,16,16,16,0,0,0,0,16,16,16,16,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }, { + // Table 3: two byte instructions of form DD-XX or FD-XX + 0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0, + 0,14,20,10,9,9,9,0,0,15,20,10,9,9,9,0, + 0,0,0,0,23,23,19,0,0,15,0,0,0,0,0,0, + 0,0,0,0,9,9,19,0,0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0,0,0,0,0,9,9,19,0, + 9,9,9,9,9,9,19,9,9,9,9,9,9,9,19,9, + 19,19,19,19,19,19,19,19,0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0,0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0,0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0,0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0,0,0,0,0,9,9,19,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,14,0,23,0,15,0,0,0,8,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0 + }, { + // Table 4: three byte instructions of form DD-CB-XX or FD-CB-XX + 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0,0,0,0,0,0,0,23,0 + } }; -#define parity(x) partab[(x)&0xff] +#define parity(x) partab[(x)&0xff] // Stack -#define POP(x) \ - do \ - { \ - unsigned int y = GetBYTE_pp(SP); \ - x = y + (GetBYTE_pp(SP) << 8); \ - } while (0) +#define POP(x) \ + do \ + { \ + unsigned int y = GetBYTE_pp(SP); \ + x = y + (GetBYTE_pp(SP) << 8); \ + } while (0) -#define PUSH(x) \ - do \ - { \ - mm_PutBYTE(SP,((x)>>8)); \ - mm_PutBYTE(SP,(x)&0xFF); \ - } while (0) +#define PUSH(x) \ + do \ + { \ + mm_PutBYTE(SP,((x)>>8)); \ + mm_PutBYTE(SP,(x)&0xFF); \ + } while (0) // Branching #define Jpc(cond) pc = cond ? GetWORD(pc) : pc+2 -#define CALLC(cond) \ - { \ - if (cond) \ - { \ - unsigned int adrr = GetWORD(pc); \ - PUSH(pc+2); \ - pc = adrr; \ - } \ - else \ - pc += 2; \ - } - +#define CALLC(cond) \ + { \ + if (cond) \ + { \ + unsigned int adrr = GetWORD(pc); \ + PUSH(pc+2); \ + pc = adrr; \ + } \ + else \ + pc += 2; \ + } + /******************************************************************************* Functions @@ -236,7 +236,7 @@ static const unsigned char cycleTables[5][256] = { int CZ80::Run(int numCycles) { #ifdef SUPERMODEL_DEBUGGER - // If debugging enabled, don't optimize access to registers as they need to be accesible to debugger during execution + // If debugging enabled, don't optimize access to registers as they need to be accesible to debugger during execution #define AF af[af_sel] #define BC regs[regs_sel].bc #define DE regs[regs_sel].de @@ -246,3535 +246,3539 @@ int CZ80::Run(int numCycles) #define IY iy #else // Optimization: copy registers into native word-sized local variables - unsigned int AF = af[af_sel]; - unsigned int BC = regs[regs_sel].bc; - unsigned int DE = regs[regs_sel].de; - unsigned int HL = regs[regs_sel].hl; - unsigned int SP = sp; - unsigned int IX = ix; - unsigned int IY = iy; + unsigned int AF = af[af_sel]; + unsigned int BC = regs[regs_sel].bc; + unsigned int DE = regs[regs_sel].de; + unsigned int HL = regs[regs_sel].hl; + unsigned int SP = sp; + unsigned int IX = ix; + unsigned int IY = iy; #endif - unsigned int temp, acu, sum, cbits; - unsigned int op, adr; + unsigned int temp = 0; + unsigned int acu = 0; + unsigned int sum = 0; + unsigned int cbits = 0; + unsigned int op = 0; + unsigned int adr = 0; - int cycles = numCycles; + int cycles = numCycles; #ifdef SUPERMODEL_DEBUGGER - if (Debug != NULL) - { - Debug->CPUActive(); - lastCycles += numCycles; - } + if (Debug != NULL) + { + Debug->CPUActive(); + lastCycles += numCycles; + } #endif // SUPERMODEL_DEBUGGER - while (cycles > 0) - { - op = GetBYTE_pp(pc); + while (cycles > 0) + { + op = GetBYTE_pp(pc); #ifdef SUPERMODEL_DEBUGGER - if (Debug != NULL) - { - while (Debug->CPUExecute(pc - 1, op, lastCycles - cycles)) - op = GetBYTE_pp(pc); - lastCycles = cycles; - } + if (Debug != NULL) + { + while (Debug->CPUExecute(pc - 1, op, lastCycles - cycles)) + op = GetBYTE_pp(pc); + lastCycles = cycles; + } #endif // SUPERMODEL_DEBUGGER - switch(op) { - case 0x00: /* NOP */ - cycles -= cycleTables[0][0x00]; - break; - case 0x01: /* LD BC,nnnn */ - cycles -= cycleTables[0][0x01]; - BC = GetWORD(pc); - pc += 2; - break; - case 0x02: /* LD (BC),A */ - cycles -= cycleTables[0][0x02]; - PutBYTE(BC, hreg(AF)); - break; - case 0x03: /* INC BC */ - cycles -= cycleTables[0][0x03]; - ++BC; - break; - case 0x04: /* INC B */ - cycles -= cycleTables[0][0x04]; - BC += 0x100; - temp = hreg(BC); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x05: /* DEC B */ - cycles -= cycleTables[0][0x05]; - BC -= 0x100; - temp = hreg(BC); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x06: /* LD B,nn */ - cycles -= cycleTables[0][0x06]; - Sethreg(BC, GetBYTE_pp(pc)); - break; - case 0x07: /* RLCA */ - cycles -= cycleTables[0][0x07]; - AF = ((AF >> 7) & 0x0128) | ((AF << 1) & ~0x1ff) | - (AF & 0xc4) | ((AF >> 15) & 1); - break; - case 0x08: /* EX AF,AF' */ - cycles -= cycleTables[0][0x08]; - af[af_sel] = AF; - af_sel = 1 - af_sel; - AF = af[af_sel]; - break; - case 0x09: /* ADD HL,BC */ - cycles -= cycleTables[0][0x09]; - 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) */ - cycles -= cycleTables[0][0x0A]; - Sethreg(AF, GetBYTE(BC)); - break; - case 0x0B: /* DEC BC */ - cycles -= cycleTables[0][0x0B]; - --BC; - break; - case 0x0C: /* INC C */ - cycles -= cycleTables[0][0x0C]; - temp = lreg(BC)+1; - Setlreg(BC, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x0D: /* DEC C */ - cycles -= cycleTables[0][0x0D]; - temp = lreg(BC)-1; - Setlreg(BC, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x0E: /* LD C,nn */ - cycles -= cycleTables[0][0x0E]; - Setlreg(BC, GetBYTE_pp(pc)); - break; - case 0x0F: /* RRCA */ - cycles -= cycleTables[0][0x0F]; - temp = hreg(AF); - sum = temp >> 1; - AF = ((temp & 1) << 15) | (sum << 8) | - (sum & 0x28) | (AF & 0xc4) | (temp & 1); - break; - case 0x10: /* DJNZ dd */ - cycles -= cycleTables[0][0x10]; - pc += ((BC -= 0x100) & 0xff00) ? (signed char) GetBYTE(pc) + 1 : 1; - break; - case 0x11: /* LD DE,nnnn */ - cycles -= cycleTables[0][0x11]; - DE = GetWORD(pc); - pc += 2; - break; - case 0x12: /* LD (DE),A */ - cycles -= cycleTables[0][0x12]; - PutBYTE(DE, hreg(AF)); - break; - case 0x13: /* INC DE */ - cycles -= cycleTables[0][0x13]; - ++DE; - break; - case 0x14: /* INC D */ - cycles -= cycleTables[0][0x14]; - DE += 0x100; - temp = hreg(DE); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x15: /* DEC D */ - cycles -= cycleTables[0][0x15]; - DE -= 0x100; - temp = hreg(DE); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x16: /* LD D,nn */ - cycles -= cycleTables[0][0x16]; - Sethreg(DE, GetBYTE_pp(pc)); - break; - case 0x17: /* RLA */ - cycles -= cycleTables[0][0x17]; - AF = ((AF << 8) & 0x0100) | ((AF >> 7) & 0x28) | ((AF << 1) & ~0x01ff) | - (AF & 0xc4) | ((AF >> 15) & 1); - break; - case 0x18: /* JR dd */ - cycles -= cycleTables[0][0x18]; - pc += (1) ? (signed char) GetBYTE(pc) + 1 : 1; - break; - case 0x19: /* ADD HL,DE */ - cycles -= cycleTables[0][0x19]; - 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) */ - cycles -= cycleTables[0][0x1A]; - Sethreg(AF, GetBYTE(DE)); - break; - case 0x1B: /* DEC DE */ - cycles -= cycleTables[0][0x1B]; - --DE; - break; - case 0x1C: /* INC E */ - cycles -= cycleTables[0][0x1C]; - temp = lreg(DE)+1; - Setlreg(DE, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x1D: /* DEC E */ - cycles -= cycleTables[0][0x1D]; - temp = lreg(DE)-1; - Setlreg(DE, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x1E: /* LD E,nn */ - cycles -= cycleTables[0][0x1E]; - Setlreg(DE, GetBYTE_pp(pc)); - break; - case 0x1F: /* RRA */ - cycles -= cycleTables[0][0x1F]; - temp = hreg(AF); - sum = temp >> 1; - AF = ((AF & 1) << 15) | (sum << 8) | - (sum & 0x28) | (AF & 0xc4) | (temp & 1); - break; - case 0x20: /* JR NZ,dd */ - cycles -= cycleTables[0][0x20]; - pc += (!TSTFLAG(Z)) ? (signed char) GetBYTE(pc) + 1 : 1; - break; - case 0x21: /* LD HL,nnnn */ - cycles -= cycleTables[0][0x21]; - HL = GetWORD(pc); - pc += 2; - break; - case 0x22: /* LD (nnnn),HL */ - cycles -= cycleTables[0][0x22]; - temp = GetWORD(pc); - PutWORD(temp, HL); - pc += 2; - break; - case 0x23: /* INC HL */ - cycles -= cycleTables[0][0x23]; - ++HL; - break; - case 0x24: /* INC H */ - cycles -= cycleTables[0][0x24]; - HL += 0x100; - temp = hreg(HL); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x25: /* DEC H */ - cycles -= cycleTables[0][0x25]; - HL -= 0x100; - temp = hreg(HL); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x26: /* LD H,nn */ - cycles -= cycleTables[0][0x26]; - Sethreg(HL, GetBYTE_pp(pc)); - break; - case 0x27: /* DAA */ - cycles -= cycleTables[0][0x27]; - 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 */ - cycles -= cycleTables[0][0x28]; - pc += (TSTFLAG(Z)) ? (signed char) GetBYTE(pc) + 1 : 1; - break; - case 0x29: /* ADD HL,HL */ - cycles -= cycleTables[0][0x29]; - 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) */ - cycles -= cycleTables[0][0x2A]; - temp = GetWORD(pc); - HL = GetWORD(temp); - pc += 2; - break; - case 0x2B: /* DEC HL */ - cycles -= cycleTables[0][0x2B]; - --HL; - break; - case 0x2C: /* INC L */ - cycles -= cycleTables[0][0x2C]; - temp = lreg(HL)+1; - Setlreg(HL, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x2D: /* DEC L */ - cycles -= cycleTables[0][0x2D]; - temp = lreg(HL)-1; - Setlreg(HL, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x2E: /* LD L,nn */ - cycles -= cycleTables[0][0x2E]; - Setlreg(HL, GetBYTE_pp(pc)); - break; - case 0x2F: /* CPL */ - cycles -= cycleTables[0][0x2F]; - AF = (~AF & ~0xff) | (AF & 0xc5) | ((~AF >> 8) & 0x28) | 0x12; - break; - case 0x30: /* JR NC,dd */ - cycles -= cycleTables[0][0x30]; - pc += (!TSTFLAG(C)) ? (signed char) GetBYTE(pc) + 1 : 1; - break; - case 0x31: /* LD SP,nnnn */ - cycles -= cycleTables[0][0x31]; - SP = GetWORD(pc); - pc += 2; - break; - case 0x32: /* LD (nnnn),A */ - cycles -= cycleTables[0][0x32]; - temp = GetWORD(pc); - PutBYTE(temp, hreg(AF)); - pc += 2; - break; - case 0x33: /* INC SP */ - cycles -= cycleTables[0][0x33]; - ++SP; - break; - case 0x34: /* INC (HL) */ - cycles -= cycleTables[0][0x34]; - temp = GetBYTE(HL)+1; - PutBYTE(HL, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x35: /* DEC (HL) */ - cycles -= cycleTables[0][0x35]; - temp = GetBYTE(HL)-1; - PutBYTE(HL, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x36: /* LD (HL),nn */ - cycles -= cycleTables[0][0x36]; - PutBYTE(HL, GetBYTE_pp(pc)); - break; - case 0x37: /* SCF */ - cycles -= cycleTables[0][0x37]; - AF = (AF&~0x3b)|((AF>>8)&0x28)|1; - break; - case 0x38: /* JR C,dd */ - cycles -= cycleTables[0][0x38]; - pc += (TSTFLAG(C)) ? (signed char) GetBYTE(pc) + 1 : 1; - break; - case 0x39: /* ADD HL,SP */ - cycles -= cycleTables[0][0x39]; - 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) */ - cycles -= cycleTables[0][0x3A]; - temp = GetWORD(pc); - Sethreg(AF, GetBYTE(temp)); - pc += 2; - break; - case 0x3B: /* DEC SP */ - cycles -= cycleTables[0][0x3B]; - --SP; - break; - case 0x3C: /* INC A */ - cycles -= cycleTables[0][0x3C]; - AF += 0x100; - temp = hreg(AF); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x3D: /* DEC A */ - cycles -= cycleTables[0][0x3D]; - AF -= 0x100; - temp = hreg(AF); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x3E: /* LD A,nn */ - cycles -= cycleTables[0][0x3E]; - Sethreg(AF, GetBYTE_pp(pc)); - break; - case 0x3F: /* CCF */ - cycles -= cycleTables[0][0x3F]; - AF = (AF&~0x3b)|((AF>>8)&0x28)|((AF&1)<<4)|(~AF&1); - break; - case 0x40: /* LD B,B */ - cycles -= cycleTables[0][0x40]; - /* nop */ - break; - case 0x41: /* LD B,C */ - cycles -= cycleTables[0][0x41]; - BC = (BC & 255) | ((BC & 255) << 8); - break; - case 0x42: /* LD B,D */ - cycles -= cycleTables[0][0x42]; - BC = (BC & 255) | (DE & ~255); - break; - case 0x43: /* LD B,E */ - cycles -= cycleTables[0][0x43]; - BC = (BC & 255) | ((DE & 255) << 8); - break; - case 0x44: /* LD B,H */ - cycles -= cycleTables[0][0x44]; - BC = (BC & 255) | (HL & ~255); - break; - case 0x45: /* LD B,L */ - cycles -= cycleTables[0][0x45]; - BC = (BC & 255) | ((HL & 255) << 8); - break; - case 0x46: /* LD B,(HL) */ - cycles -= cycleTables[0][0x46]; - Sethreg(BC, GetBYTE(HL)); - break; - case 0x47: /* LD B,A */ - cycles -= cycleTables[0][0x47]; - BC = (BC & 255) | (AF & ~255); - break; - case 0x48: /* LD C,B */ - cycles -= cycleTables[0][0x48]; - BC = (BC & ~255) | ((BC >> 8) & 255); - break; - case 0x49: /* LD C,C */ - cycles -= cycleTables[0][0x49]; - /* nop */ - break; - case 0x4A: /* LD C,D */ - cycles -= cycleTables[0][0x4A]; - BC = (BC & ~255) | ((DE >> 8) & 255); - break; - case 0x4B: /* LD C,E */ - cycles -= cycleTables[0][0x4B]; - BC = (BC & ~255) | (DE & 255); - break; - case 0x4C: /* LD C,H */ - cycles -= cycleTables[0][0x4C]; - BC = (BC & ~255) | ((HL >> 8) & 255); - break; - case 0x4D: /* LD C,L */ - cycles -= cycleTables[0][0x4D]; - BC = (BC & ~255) | (HL & 255); - break; - case 0x4E: /* LD C,(HL) */ - cycles -= cycleTables[0][0x4E]; - Setlreg(BC, GetBYTE(HL)); - break; - case 0x4F: /* LD C,A */ - cycles -= cycleTables[0][0x4F]; - BC = (BC & ~255) | ((AF >> 8) & 255); - break; - case 0x50: /* LD D,B */ - cycles -= cycleTables[0][0x50]; - DE = (DE & 255) | (BC & ~255); - break; - case 0x51: /* LD D,C */ - cycles -= cycleTables[0][0x51]; - DE = (DE & 255) | ((BC & 255) << 8); - break; - case 0x52: /* LD D,D */ - cycles -= cycleTables[0][0x52]; - /* nop */ - break; - case 0x53: /* LD D,E */ - cycles -= cycleTables[0][0x53]; - DE = (DE & 255) | ((DE & 255) << 8); - break; - case 0x54: /* LD D,H */ - cycles -= cycleTables[0][0x54]; - DE = (DE & 255) | (HL & ~255); - break; - case 0x55: /* LD D,L */ - cycles -= cycleTables[0][0x55]; - DE = (DE & 255) | ((HL & 255) << 8); - break; - case 0x56: /* LD D,(HL) */ - cycles -= cycleTables[0][0x56]; - Sethreg(DE, GetBYTE(HL)); - break; - case 0x57: /* LD D,A */ - cycles -= cycleTables[0][0x57]; - DE = (DE & 255) | (AF & ~255); - break; - case 0x58: /* LD E,B */ - cycles -= cycleTables[0][0x58]; - DE = (DE & ~255) | ((BC >> 8) & 255); - break; - case 0x59: /* LD E,C */ - cycles -= cycleTables[0][0x59]; - DE = (DE & ~255) | (BC & 255); - break; - case 0x5A: /* LD E,D */ - cycles -= cycleTables[0][0x5A]; - DE = (DE & ~255) | ((DE >> 8) & 255); - break; - case 0x5B: /* LD E,E */ - cycles -= cycleTables[0][0x5B]; - /* nop */ - break; - case 0x5C: /* LD E,H */ - cycles -= cycleTables[0][0x5C]; - DE = (DE & ~255) | ((HL >> 8) & 255); - break; - case 0x5D: /* LD E,L */ - cycles -= cycleTables[0][0x5D]; - DE = (DE & ~255) | (HL & 255); - break; - case 0x5E: /* LD E,(HL) */ - cycles -= cycleTables[0][0x5E]; - Setlreg(DE, GetBYTE(HL)); - break; - case 0x5F: /* LD E,A */ - cycles -= cycleTables[0][0x5F]; - DE = (DE & ~255) | ((AF >> 8) & 255); - break; - case 0x60: /* LD H,B */ - cycles -= cycleTables[0][0x60]; - HL = (HL & 255) | (BC & ~255); - break; - case 0x61: /* LD H,C */ - cycles -= cycleTables[0][0x61]; - HL = (HL & 255) | ((BC & 255) << 8); - break; - case 0x62: /* LD H,D */ - cycles -= cycleTables[0][0x62]; - HL = (HL & 255) | (DE & ~255); - break; - case 0x63: /* LD H,E */ - cycles -= cycleTables[0][0x63]; - HL = (HL & 255) | ((DE & 255) << 8); - break; - case 0x64: /* LD H,H */ - cycles -= cycleTables[0][0x64]; - /* nop */ - break; - case 0x65: /* LD H,L */ - cycles -= cycleTables[0][0x65]; - HL = (HL & 255) | ((HL & 255) << 8); - break; - case 0x66: /* LD H,(HL) */ - cycles -= cycleTables[0][0x66]; - Sethreg(HL, GetBYTE(HL)); - break; - case 0x67: /* LD H,A */ - cycles -= cycleTables[0][0x67]; - HL = (HL & 255) | (AF & ~255); - break; - case 0x68: /* LD L,B */ - cycles -= cycleTables[0][0x68]; - HL = (HL & ~255) | ((BC >> 8) & 255); - break; - case 0x69: /* LD L,C */ - cycles -= cycleTables[0][0x69]; - HL = (HL & ~255) | (BC & 255); - break; - case 0x6A: /* LD L,D */ - cycles -= cycleTables[0][0x6A]; - HL = (HL & ~255) | ((DE >> 8) & 255); - break; - case 0x6B: /* LD L,E */ - cycles -= cycleTables[0][0x6B]; - HL = (HL & ~255) | (DE & 255); - break; - case 0x6C: /* LD L,H */ - cycles -= cycleTables[0][0x6C]; - HL = (HL & ~255) | ((HL >> 8) & 255); - break; - case 0x6D: /* LD L,L */ - cycles -= cycleTables[0][0x6D]; - /* nop */ - break; - case 0x6E: /* LD L,(HL) */ - cycles -= cycleTables[0][0x6E]; - Setlreg(HL, GetBYTE(HL)); - break; - case 0x6F: /* LD L,A */ - cycles -= cycleTables[0][0x6F]; - HL = (HL & ~255) | ((AF >> 8) & 255); - break; - case 0x70: /* LD (HL),B */ - cycles -= cycleTables[0][0x70]; - PutBYTE(HL, hreg(BC)); - break; - case 0x71: /* LD (HL),C */ - cycles -= cycleTables[0][0x71]; - PutBYTE(HL, lreg(BC)); - break; - case 0x72: /* LD (HL),D */ - cycles -= cycleTables[0][0x72]; - PutBYTE(HL, hreg(DE)); - break; - case 0x73: /* LD (HL),E */ - cycles -= cycleTables[0][0x73]; - PutBYTE(HL, lreg(DE)); - break; - case 0x74: /* LD (HL),H */ - cycles -= cycleTables[0][0x74]; - PutBYTE(HL, hreg(HL)); - break; - case 0x75: /* LD (HL),L */ - cycles -= cycleTables[0][0x75]; - PutBYTE(HL, lreg(HL)); - break; - case 0x76: /* HALT */ - cycles -= cycleTables[0][0x76]; -// ErrorLog("Z80 encountered an unemulated instruction at 0x%04X", (pc-1)&0xFFFF); - goto HALTExit; - case 0x77: /* LD (HL),A */ - cycles -= cycleTables[0][0x77]; - PutBYTE(HL, hreg(AF)); - break; - case 0x78: /* LD A,B */ - cycles -= cycleTables[0][0x78]; - AF = (AF & 255) | (BC & ~255); - break; - case 0x79: /* LD A,C */ - cycles -= cycleTables[0][0x79]; - AF = (AF & 255) | ((BC & 255) << 8); - break; - case 0x7A: /* LD A,D */ - cycles -= cycleTables[0][0x7A]; - AF = (AF & 255) | (DE & ~255); - break; - case 0x7B: /* LD A,E */ - cycles -= cycleTables[0][0x7B]; - AF = (AF & 255) | ((DE & 255) << 8); - break; - case 0x7C: /* LD A,H */ - cycles -= cycleTables[0][0x7C]; - AF = (AF & 255) | (HL & ~255); - break; - case 0x7D: /* LD A,L */ - cycles -= cycleTables[0][0x7D]; - AF = (AF & 255) | ((HL & 255) << 8); - break; - case 0x7E: /* LD A,(HL) */ - cycles -= cycleTables[0][0x7E]; - Sethreg(AF, GetBYTE(HL)); - break; - case 0x7F: /* LD A,A */ - cycles -= cycleTables[0][0x7F]; - /* nop */ - break; - case 0x80: /* ADD A,B */ - cycles -= cycleTables[0][0x80]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x81: /* ADD A,C */ - cycles -= cycleTables[0][0x81]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x82: /* ADD A,D */ - cycles -= cycleTables[0][0x82]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x83: /* ADD A,E */ - cycles -= cycleTables[0][0x83]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x84: /* ADD A,H */ - cycles -= cycleTables[0][0x84]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x85: /* ADD A,L */ - cycles -= cycleTables[0][0x85]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x86: /* ADD A,(HL) */ - cycles -= cycleTables[0][0x86]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x87: /* ADD A,A */ - cycles -= cycleTables[0][0x87]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x88: /* ADC A,B */ - cycles -= cycleTables[0][0x88]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x89: /* ADC A,C */ - cycles -= cycleTables[0][0x89]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x8A: /* ADC A,D */ - cycles -= cycleTables[0][0x8A]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x8B: /* ADC A,E */ - cycles -= cycleTables[0][0x8B]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x8C: /* ADC A,H */ - cycles -= cycleTables[0][0x8C]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x8D: /* ADC A,L */ - cycles -= cycleTables[0][0x8D]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x8E: /* ADC A,(HL) */ - cycles -= cycleTables[0][0x8E]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x8F: /* ADC A,A */ - cycles -= cycleTables[0][0x8F]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x90: /* SUB B */ - cycles -= cycleTables[0][0x90]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x91: /* SUB C */ - cycles -= cycleTables[0][0x91]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x92: /* SUB D */ - cycles -= cycleTables[0][0x92]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x93: /* SUB E */ - cycles -= cycleTables[0][0x93]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x94: /* SUB H */ - cycles -= cycleTables[0][0x94]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x95: /* SUB L */ - cycles -= cycleTables[0][0x95]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x96: /* SUB (HL) */ - cycles -= cycleTables[0][0x96]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x97: /* SUB A */ - cycles -= cycleTables[0][0x97]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x98: /* SBC A,B */ - cycles -= cycleTables[0][0x98]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x99: /* SBC A,C */ - cycles -= cycleTables[0][0x99]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x9A: /* SBC A,D */ - cycles -= cycleTables[0][0x9A]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x9B: /* SBC A,E */ - cycles -= cycleTables[0][0x9B]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x9C: /* SBC A,H */ - cycles -= cycleTables[0][0x9C]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x9D: /* SBC A,L */ - cycles -= cycleTables[0][0x9D]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x9E: /* SBC A,(HL) */ - cycles -= cycleTables[0][0x9E]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x9F: /* SBC A,A */ - cycles -= cycleTables[0][0x9F]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0xA0: /* AND B */ - cycles -= cycleTables[0][0xA0]; - sum = ((AF & (BC)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | - ((sum == 0) << 6) | 0x10 | partab[sum]; - break; - case 0xA1: /* AND C */ - cycles -= cycleTables[0][0xA1]; - sum = ((AF >> 8) & BC) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xA2: /* AND D */ - cycles -= cycleTables[0][0xA2]; - sum = ((AF & (DE)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | - ((sum == 0) << 6) | 0x10 | partab[sum]; - break; - case 0xA3: /* AND E */ - cycles -= cycleTables[0][0xA3]; - sum = ((AF >> 8) & DE) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xA4: /* AND H */ - cycles -= cycleTables[0][0xA4]; - sum = ((AF & (HL)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | - ((sum == 0) << 6) | 0x10 | partab[sum]; - break; - case 0xA5: /* AND L */ - cycles -= cycleTables[0][0xA5]; - sum = ((AF >> 8) & HL) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xA6: /* AND (HL) */ - cycles -= cycleTables[0][0xA6]; - sum = ((AF >> 8) & GetBYTE(HL)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xA7: /* AND A */ - cycles -= cycleTables[0][0xA7]; - sum = ((AF & (AF)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | - ((sum == 0) << 6) | 0x10 | partab[sum]; - break; - case 0xA8: /* XOR B */ - cycles -= cycleTables[0][0xA8]; - sum = ((AF ^ (BC)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xA9: /* XOR C */ - cycles -= cycleTables[0][0xA9]; - sum = ((AF >> 8) ^ BC) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xAA: /* XOR D */ - cycles -= cycleTables[0][0xAA]; - sum = ((AF ^ (DE)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xAB: /* XOR E */ - cycles -= cycleTables[0][0xAB]; - sum = ((AF >> 8) ^ DE) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xAC: /* XOR H */ - cycles -= cycleTables[0][0xAC]; - sum = ((AF ^ (HL)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xAD: /* XOR L */ - cycles -= cycleTables[0][0xAD]; - sum = ((AF >> 8) ^ HL) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xAE: /* XOR (HL) */ - cycles -= cycleTables[0][0xAE]; - sum = ((AF >> 8) ^ GetBYTE(HL)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xAF: /* XOR A */ - cycles -= cycleTables[0][0xAF]; - sum = ((AF ^ (AF)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB0: /* OR B */ - cycles -= cycleTables[0][0xB0]; - sum = ((AF | (BC)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB1: /* OR C */ - cycles -= cycleTables[0][0xB1]; - sum = ((AF >> 8) | BC) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB2: /* OR D */ - cycles -= cycleTables[0][0xB2]; - sum = ((AF | (DE)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB3: /* OR E */ - cycles -= cycleTables[0][0xB3]; - sum = ((AF >> 8) | DE) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB4: /* OR H */ - cycles -= cycleTables[0][0xB4]; - sum = ((AF | (HL)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB5: /* OR L */ - cycles -= cycleTables[0][0xB5]; - sum = ((AF >> 8) | HL) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB6: /* OR (HL) */ - cycles -= cycleTables[0][0xB6]; - sum = ((AF >> 8) | GetBYTE(HL)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB7: /* OR A */ - cycles -= cycleTables[0][0xB7]; - sum = ((AF | (AF)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB8: /* CP B */ - cycles -= cycleTables[0][0xB8]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xB9: /* CP C */ - cycles -= cycleTables[0][0xB9]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xBA: /* CP D */ - cycles -= cycleTables[0][0xBA]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xBB: /* CP E */ - cycles -= cycleTables[0][0xBB]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xBC: /* CP H */ - cycles -= cycleTables[0][0xBC]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xBD: /* CP L */ - cycles -= cycleTables[0][0xBD]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xBE: /* CP (HL) */ - cycles -= cycleTables[0][0xBE]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xBF: /* CP A */ - cycles -= cycleTables[0][0xBF]; - 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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xC0: /* RET NZ */ - cycles -= cycleTables[0][0xC0]; - if (!TSTFLAG(Z)) POP(pc); - break; - case 0xC1: /* POP BC */ - cycles -= cycleTables[0][0xC1]; - POP(BC); - break; - case 0xC2: /* JP NZ,nnnn */ - cycles -= cycleTables[0][0xC2]; - Jpc(!TSTFLAG(Z)); - break; - case 0xC3: /* JP nnnn */ - cycles -= cycleTables[0][0xC3]; - Jpc(1); - break; - case 0xC4: /* CALL NZ,nnnn */ - cycles -= cycleTables[0][0xC4]; - CALLC(!TSTFLAG(Z)); - break; - case 0xC5: /* PUSH BC */ - cycles -= cycleTables[0][0xC5]; - PUSH(BC); - break; - case 0xC6: /* ADD A,nn */ - cycles -= cycleTables[0][0xC6]; - temp = GetBYTE_pp(pc); - 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 0xC7: /* RST 0 */ - cycles -= cycleTables[0][0xC7]; - PUSH(pc); pc = 0; - break; - case 0xC8: /* RET Z */ - cycles -= cycleTables[0][0xC8]; - if (TSTFLAG(Z)) POP(pc); - break; - case 0xC9: /* RET */ - cycles -= cycleTables[0][0xC9]; - POP(pc); - break; - case 0xCA: /* JP Z,nnnn */ - cycles -= cycleTables[0][0xCA]; - Jpc(TSTFLAG(Z)); - break; - case 0xCB: /* CB prefix */ - adr = HL; - op = GetBYTE(pc); - cycles -= cycleTables[1][op]; - switch (op & 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 */ - cycles -= cycleTables[0][0xCC]; - CALLC(TSTFLAG(Z)); - break; - case 0xCD: /* CALL nnnn */ - cycles -= cycleTables[0][0xCD]; - CALLC(1); - break; - case 0xCE: /* ADC A,nn */ - cycles -= cycleTables[0][0xCE]; - temp = GetBYTE_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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0xCF: /* RST 8 */ - cycles -= cycleTables[0][0xCF]; - PUSH(pc); pc = 8; - break; - case 0xD0: /* RET NC */ - cycles -= cycleTables[0][0xD0]; - if (!TSTFLAG(C)) POP(pc); - break; - case 0xD1: /* POP DE */ - cycles -= cycleTables[0][0xD1]; - POP(DE); - break; - case 0xD2: /* JP NC,nnnn */ - cycles -= cycleTables[0][0xD2]; - Jpc(!TSTFLAG(C)); - break; - case 0xD3: /* OUT (nn),A */ - cycles -= cycleTables[0][0xD3]; - OUTPUT(GetBYTE_pp(pc), hreg(AF)); - break; - case 0xD4: /* CALL NC,nnnn */ - cycles -= cycleTables[0][0xD4]; - CALLC(!TSTFLAG(C)); - break; - case 0xD5: /* PUSH DE */ - cycles -= cycleTables[0][0xD5]; - PUSH(DE); - break; - case 0xD6: /* SUB nn */ - cycles -= cycleTables[0][0xD6]; - temp = GetBYTE_pp(pc); - 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 0xD7: /* RST 10H */ - cycles -= cycleTables[0][0xD7]; - PUSH(pc); pc = 0x10; - break; - case 0xD8: /* RET C */ - cycles -= cycleTables[0][0xD8]; - if (TSTFLAG(C)) POP(pc); - break; - case 0xD9: /* EXX */ - cycles -= cycleTables[0][0xD9]; - 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 */ - cycles -= cycleTables[0][0xDA]; - Jpc(TSTFLAG(C)); - break; - case 0xDB: /* IN A,(nn) */ - cycles -= cycleTables[0][0xDB]; - Sethreg(AF, INPUT(GetBYTE_pp(pc))); - break; - case 0xDC: /* CALL C,nnnn */ - cycles -= cycleTables[0][0xDC]; - CALLC(TSTFLAG(C)); - break; - case 0xDD: /* DD prefix */ - op = GetBYTE_pp(pc); - switch (op) { - case 0x09: /* ADD IX,BC */ - cycles -= cycleTables[3][0x09]; - 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 */ - cycles -= cycleTables[3][0x19]; - 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 */ - cycles -= cycleTables[3][0x21]; - IX = GetWORD(pc); - pc += 2; - break; - case 0x22: /* LD (nnnn),IX */ - cycles -= cycleTables[3][0x22]; - temp = GetWORD(pc); - PutWORD(temp, IX); - pc += 2; - break; - case 0x23: /* INC IX */ - cycles -= cycleTables[3][0x23]; - ++IX; - break; - case 0x24: /* INC IXH */ - cycles -= cycleTables[3][0x24]; - 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 */ - cycles -= cycleTables[3][0x25]; - 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 */ - cycles -= cycleTables[3][0x26]; - Sethreg(IX, GetBYTE_pp(pc)); - break; - case 0x29: /* ADD IX,IX */ - cycles -= cycleTables[3][0x29]; - 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) */ - cycles -= cycleTables[3][0x2A]; - temp = GetWORD(pc); - IX = GetWORD(temp); - pc += 2; - break; - case 0x2B: /* DEC IX */ - cycles -= cycleTables[3][0x2B]; - --IX; - break; - case 0x2C: /* INC IXL */ - cycles -= cycleTables[3][0x2C]; - 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 */ - cycles -= cycleTables[3][0x2D]; - 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 */ - cycles -= cycleTables[3][0x2E]; - Setlreg(IX, GetBYTE_pp(pc)); - break; - case 0x34: /* INC (IX+dd) */ - cycles -= cycleTables[3][0x34]; - adr = IX + (signed char) GetBYTE_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) */ - cycles -= cycleTables[3][0x35]; - adr = IX + (signed char) GetBYTE_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 */ - cycles -= cycleTables[3][0x36]; - adr = IX + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, GetBYTE_pp(pc)); - break; - case 0x39: /* ADD IX,SP */ - cycles -= cycleTables[3][0x39]; - 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 */ - cycles -= cycleTables[3][0x44]; - Sethreg(BC, hreg(IX)); - break; - case 0x45: /* LD B,IXL */ - cycles -= cycleTables[3][0x45]; - Sethreg(BC, lreg(IX)); - break; - case 0x46: /* LD B,(IX+dd) */ - cycles -= cycleTables[3][0x46]; - adr = IX + (signed char) GetBYTE_pp(pc); - Sethreg(BC, GetBYTE(adr)); - break; - case 0x4C: /* LD C,IXH */ - cycles -= cycleTables[3][0x4C]; - Setlreg(BC, hreg(IX)); - break; - case 0x4D: /* LD C,IXL */ - cycles -= cycleTables[3][0x4D]; - Setlreg(BC, lreg(IX)); - break; - case 0x4E: /* LD C,(IX+dd) */ - cycles -= cycleTables[3][0x4E]; - adr = IX + (signed char) GetBYTE_pp(pc); - Setlreg(BC, GetBYTE(adr)); - break; - case 0x54: /* LD D,IXH */ - cycles -= cycleTables[3][0x54]; - Sethreg(DE, hreg(IX)); - break; - case 0x55: /* LD D,IXL */ - cycles -= cycleTables[3][0x55]; - Sethreg(DE, lreg(IX)); - break; - case 0x56: /* LD D,(IX+dd) */ - cycles -= cycleTables[3][0x56]; - adr = IX + (signed char) GetBYTE_pp(pc); - Sethreg(DE, GetBYTE(adr)); - break; - case 0x5C: /* LD E,H */ - cycles -= cycleTables[3][0x5C]; - Setlreg(DE, hreg(IX)); - break; - case 0x5D: /* LD E,L */ - cycles -= cycleTables[3][0x5D]; - Setlreg(DE, lreg(IX)); - break; - case 0x5E: /* LD E,(IX+dd) */ - cycles -= cycleTables[3][0x5E]; - adr = IX + (signed char) GetBYTE_pp(pc); - Setlreg(DE, GetBYTE(adr)); - break; - case 0x60: /* LD IXH,B */ - cycles -= cycleTables[3][0x60]; - Sethreg(IX, hreg(BC)); - break; - case 0x61: /* LD IXH,C */ - cycles -= cycleTables[3][0x61]; - Sethreg(IX, lreg(BC)); - break; - case 0x62: /* LD IXH,D */ - cycles -= cycleTables[3][0x62]; - Sethreg(IX, hreg(DE)); - break; - case 0x63: /* LD IXH,E */ - cycles -= cycleTables[3][0x63]; - Sethreg(IX, lreg(DE)); - break; - case 0x64: /* LD IXH,IXH */ - cycles -= cycleTables[3][0x64]; - /* nop */ - break; - case 0x65: /* LD IXH,IXL */ - cycles -= cycleTables[3][0x65]; - Sethreg(IX, lreg(IX)); - break; - case 0x66: /* LD H,(IX+dd) */ - cycles -= cycleTables[3][0x66]; - adr = IX + (signed char) GetBYTE_pp(pc); - Sethreg(HL, GetBYTE(adr)); - break; - case 0x67: /* LD IXH,A */ - cycles -= cycleTables[3][0x67]; - Sethreg(IX, hreg(AF)); - break; - case 0x68: /* LD IXL,B */ - cycles -= cycleTables[3][0x68]; - Setlreg(IX, hreg(BC)); - break; - case 0x69: /* LD IXL,C */ - cycles -= cycleTables[3][0x69]; - Setlreg(IX, lreg(BC)); - break; - case 0x6A: /* LD IXL,D */ - cycles -= cycleTables[3][0x6A]; - Setlreg(IX, hreg(DE)); - break; - case 0x6B: /* LD IXL,E */ - cycles -= cycleTables[3][0x6B]; - Setlreg(IX, lreg(DE)); - break; - case 0x6C: /* LD IXL,IXH */ - cycles -= cycleTables[3][0x6C]; - Setlreg(IX, hreg(IX)); - break; - case 0x6D: /* LD IXL,IXL */ - cycles -= cycleTables[3][0x6D]; - /* nop */ - break; - case 0x6E: /* LD L,(IX+dd) */ - cycles -= cycleTables[3][0x6E]; - adr = IX + (signed char) GetBYTE_pp(pc); - Setlreg(HL, GetBYTE(adr)); - break; - case 0x6F: /* LD IXL,A */ - cycles -= cycleTables[3][0x6F]; - Setlreg(IX, hreg(AF)); - break; - case 0x70: /* LD (IX+dd),B */ - cycles -= cycleTables[3][0x70]; - adr = IX + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, hreg(BC)); - break; - case 0x71: /* LD (IX+dd),C */ - cycles -= cycleTables[3][0x71]; - adr = IX + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, lreg(BC)); - break; - case 0x72: /* LD (IX+dd),D */ - cycles -= cycleTables[3][0x72]; - adr = IX + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, hreg(DE)); - break; - case 0x73: /* LD (IX+dd),E */ - cycles -= cycleTables[3][0x73]; - adr = IX + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, lreg(DE)); - break; - case 0x74: /* LD (IX+dd),H */ - cycles -= cycleTables[3][0x74]; - adr = IX + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, hreg(HL)); - break; - case 0x75: /* LD (IX+dd),L */ - cycles -= cycleTables[3][0x75]; - adr = IX + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, lreg(HL)); - break; - case 0x77: /* LD (IX+dd),A */ - cycles -= cycleTables[3][0x77]; - adr = IX + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, hreg(AF)); - break; - case 0x7C: /* LD A,IXH */ - cycles -= cycleTables[3][0x7C]; - Sethreg(AF, hreg(IX)); - break; - case 0x7D: /* LD A,IXL */ - cycles -= cycleTables[3][0x7D]; - Sethreg(AF, lreg(IX)); - break; - case 0x7E: /* LD A,(IX+dd) */ - cycles -= cycleTables[3][0x7E]; - adr = IX + (signed char) GetBYTE_pp(pc); - Sethreg(AF, GetBYTE(adr)); - break; - case 0x84: /* ADD A,IXH */ - cycles -= cycleTables[3][0x84]; - 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 */ - cycles -= cycleTables[3][0x85]; - 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) */ - cycles -= cycleTables[3][0x86]; - adr = IX + (signed char) GetBYTE_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 */ - cycles -= cycleTables[3][0x8C]; - 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 */ - cycles -= cycleTables[3][0x8D]; - 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) */ - cycles -= cycleTables[3][0x8E]; - adr = IX + (signed char) GetBYTE_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 */ - cycles -= cycleTables[3][0x94]; - 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 */ - cycles -= cycleTables[3][0x95]; - 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) */ - cycles -= cycleTables[3][0x96]; - adr = IX + (signed char) GetBYTE_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 */ - cycles -= cycleTables[3][0x9C]; - 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 */ - cycles -= cycleTables[3][0x9D]; - 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) */ - cycles -= cycleTables[3][0x9E]; - adr = IX + (signed char) GetBYTE_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 */ - cycles -= cycleTables[3][0xA4]; - sum = ((AF & (IX)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | - ((sum == 0) << 6) | 0x10 | partab[sum]; - break; - case 0xA5: /* AND IXL */ - cycles -= cycleTables[3][0xA5]; - sum = ((AF >> 8) & IX) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xA6: /* AND (IX+dd) */ - cycles -= cycleTables[3][0xA6]; - adr = IX + (signed char) GetBYTE_pp(pc); - sum = ((AF >> 8) & GetBYTE(adr)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xAC: /* XOR IXH */ - cycles -= cycleTables[3][0xAC]; - sum = ((AF ^ (IX)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xAD: /* XOR IXL */ - cycles -= cycleTables[3][0xAD]; - sum = ((AF >> 8) ^ IX) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xAE: /* XOR (IX+dd) */ - cycles -= cycleTables[3][0xAE]; - adr = IX + (signed char) GetBYTE_pp(pc); - sum = ((AF >> 8) ^ GetBYTE(adr)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB4: /* OR IXH */ - cycles -= cycleTables[3][0xB4]; - sum = ((AF | (IX)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB5: /* OR IXL */ - cycles -= cycleTables[3][0xB5]; - sum = ((AF >> 8) | IX) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB6: /* OR (IX+dd) */ - cycles -= cycleTables[3][0xB6]; - adr = IX + (signed char) GetBYTE_pp(pc); - sum = ((AF >> 8) | GetBYTE(adr)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xBC: /* CP IXH */ - cycles -= cycleTables[3][0xBC]; - 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 */ - cycles -= cycleTables[3][0xBD]; - 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) */ - cycles -= cycleTables[3][0xBE]; - adr = IX + (signed char) GetBYTE_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) GetBYTE_pp(pc); - adr = adr; - op = GetBYTE(pc); - cycles -= cycleTables[4][op]; - switch (op & 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 */ - cycles -= cycleTables[3][0xE1]; - POP(IX); - break; - case 0xE3: /* EX (SP),IX */ - cycles -= cycleTables[3][0xE3]; - temp = IX; POP(IX); PUSH(temp); - break; - case 0xE5: /* PUSH IX */ - cycles -= cycleTables[3][0xE5]; - PUSH(IX); - break; - case 0xE9: /* JP (IX) */ - cycles -= cycleTables[3][0xE9]; - pc = IX; - break; - case 0xF9: /* LD SP,IX */ - cycles -= cycleTables[3][0xF9]; - SP = IX; - break; - default: pc--; /* ignore DD */ - } - break; - case 0xDE: /* SBC A,nn */ - cycles -= cycleTables[0][0xDE]; - temp = GetBYTE_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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0xDF: /* RST 18H */ - cycles -= cycleTables[0][0xDF]; - PUSH(pc); pc = 0x18; - break; - case 0xE0: /* RET PO */ - cycles -= cycleTables[0][0xE0]; - if (!TSTFLAG(P)) POP(pc); - break; - case 0xE1: /* POP HL */ - cycles -= cycleTables[0][0xE1]; - POP(HL); - break; - case 0xE2: /* JP PO,nnnn */ - cycles -= cycleTables[0][0xE2]; - Jpc(!TSTFLAG(P)); - break; - case 0xE3: /* EX (SP),HL */ - cycles -= cycleTables[0][0xE3]; - temp = HL; POP(HL); PUSH(temp); - break; - case 0xE4: /* CALL PO,nnnn */ - cycles -= cycleTables[0][0xE4]; - CALLC(!TSTFLAG(P)); - break; - case 0xE5: /* PUSH HL */ - cycles -= cycleTables[0][0xE5]; - PUSH(HL); - break; - case 0xE6: /* AND nn */ - cycles -= cycleTables[0][0xE6]; - sum = ((AF >> 8) & GetBYTE_pp(pc)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xE7: /* RST 20H */ - cycles -= cycleTables[0][0xE7]; - PUSH(pc); pc = 0x20; - break; - case 0xE8: /* RET PE */ - cycles -= cycleTables[0][0xE8]; - if (TSTFLAG(P)) POP(pc); - break; - case 0xE9: /* JP (HL) */ - cycles -= cycleTables[0][0xE9]; - pc = HL; - break; - case 0xEA: /* JP PE,nnnn */ - cycles -= cycleTables[0][0xEA]; - Jpc(TSTFLAG(P)); - break; - case 0xEB: /* EX DE,HL */ - cycles -= cycleTables[0][0xEB]; - temp = HL; HL = DE; DE = temp; - break; - case 0xEC: /* CALL PE,nnnn */ - cycles -= cycleTables[0][0xEC]; - CALLC(TSTFLAG(P)); - break; - case 0xED: /* ED prefix */ - op = GetBYTE_pp(pc); - switch (op) { - case 0x40: /* IN B,(C) */ - cycles -= cycleTables[2][0x40]; - temp = INPUT(lreg(BC)); - Sethreg(BC, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x41: /* OUT (C),B */ - cycles -= cycleTables[2][0x41]; - OUTPUT(lreg(BC), BC); - break; - case 0x42: /* SBC HL,BC */ - cycles -= cycleTables[2][0x42]; - 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 */ - cycles -= cycleTables[2][0x43]; - temp = GetWORD(pc); - PutWORD(temp, BC); - pc += 2; - break; - case 0x44: /* NEG */ - cycles -= cycleTables[2][0x44]; - 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 */ - cycles -= cycleTables[2][0x45]; - iff |= iff >> 1; - POP(pc); - break; - case 0x46: /* IM 0 */ - cycles -= cycleTables[2][0x46]; - im = 0; // interrupt mode 0 - break; - case 0x47: /* LD I,A */ - cycles -= cycleTables[2][0x47]; - ir = (ir & 255) | (AF & ~255); - break; - case 0x48: /* IN C,(C) */ - cycles -= cycleTables[2][0x48]; - temp = INPUT(lreg(BC)); - Setlreg(BC, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x49: /* OUT (C),C */ - cycles -= cycleTables[2][0x49]; - OUTPUT(lreg(BC), BC); - break; - case 0x4A: /* ADC HL,BC */ - cycles -= cycleTables[2][0x4A]; - 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) */ - cycles -= cycleTables[2][0x4B]; - temp = GetWORD(pc); - BC = GetWORD(temp); - pc += 2; - break; - case 0x4D: /* RETI */ - cycles -= cycleTables[2][0x4D]; - iff |= iff >> 1; - POP(pc); - break; - case 0x4F: /* LD R,A */ - cycles -= cycleTables[2][0x4F]; - ir = (ir & ~255) | ((AF >> 8) & 255); - break; - case 0x50: /* IN D,(C) */ - cycles -= cycleTables[2][0x50]; - temp = INPUT(lreg(BC)); - Sethreg(DE, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x51: /* OUT (C),D */ - cycles -= cycleTables[2][0x51]; - OUTPUT(lreg(BC), DE); - break; - case 0x52: /* SBC HL,DE */ - cycles -= cycleTables[2][0x52]; - 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 */ - cycles -= cycleTables[2][0x53]; - temp = GetWORD(pc); - PutWORD(temp, DE); - pc += 2; - break; - case 0x56: /* IM 1 */ - cycles -= cycleTables[2][0x56]; - im = 1; // interrupt mode 1 - break; - case 0x57: /* LD A,I */ - cycles -= cycleTables[2][0x57]; - AF = (AF & 0x29) | (ir & ~255) | ((ir >> 8) & 0x80) | (((ir & ~255) == 0) << 6) | ((iff & 2) << 1); - break; - case 0x58: /* IN E,(C) */ - cycles -= cycleTables[2][0x58]; - temp = INPUT(lreg(BC)); - Setlreg(DE, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x59: /* OUT (C),E */ - cycles -= cycleTables[2][0x59]; - OUTPUT(lreg(BC), DE); - break; - case 0x5A: /* ADC HL,DE */ - cycles -= cycleTables[2][0x5A]; - 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) */ - cycles -= cycleTables[2][0x5B]; - temp = GetWORD(pc); - DE = GetWORD(temp); - pc += 2; - break; - case 0x5E: /* IM 2 */ - cycles -= cycleTables[2][0x5E]; - im = 2; // interrupt mode 2 - break; - case 0x5F: /* LD A,R */ - cycles -= cycleTables[2][0x5F]; - AF = (AF & 0x29) | ((ir & 255) << 8) | (ir & 0x80) | (((ir & 255) == 0) << 6) | ((iff & 2) << 1); - break; - case 0x60: /* IN H,(C) */ - cycles -= cycleTables[2][0x60]; - temp = INPUT(lreg(BC)); - Sethreg(HL, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x61: /* OUT (C),H */ - cycles -= cycleTables[2][0x61]; - OUTPUT(lreg(BC), HL); - break; - case 0x62: /* SBC HL,HL */ - cycles -= cycleTables[2][0x62]; - 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 */ - cycles -= cycleTables[2][0x63]; - temp = GetWORD(pc); - PutWORD(temp, HL); - pc += 2; - break; - case 0x67: /* RRD */ - cycles -= cycleTables[2][0x67]; - 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) */ - cycles -= cycleTables[2][0x68]; - temp = INPUT(lreg(BC)); - Setlreg(HL, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x69: /* OUT (C),L */ - cycles -= cycleTables[2][0x69]; - OUTPUT(lreg(BC), HL); - break; - case 0x6A: /* ADC HL,HL */ - cycles -= cycleTables[2][0x6A]; - 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) */ - cycles -= cycleTables[2][0x6B]; - temp = GetWORD(pc); - HL = GetWORD(temp); - pc += 2; - break; - case 0x6F: /* RLD */ - cycles -= cycleTables[2][0x6F]; - 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) */ - cycles -= cycleTables[2][0x70]; - temp = INPUT(lreg(BC)); - Setlreg(temp, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x71: /* OUT (C),0 */ - cycles -= cycleTables[2][0x71]; - OUTPUT(lreg(BC), 0); - break; - case 0x72: /* SBC HL,SP */ - cycles -= cycleTables[2][0x72]; - 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 */ - cycles -= cycleTables[2][0x73]; - temp = GetWORD(pc); - PutWORD(temp, SP); - pc += 2; - break; - case 0x78: /* IN A,(C) */ - cycles -= cycleTables[2][0x78]; - temp = INPUT(lreg(BC)); - Sethreg(AF, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x79: /* OUT (C),A */ - cycles -= cycleTables[2][0x79]; - OUTPUT(lreg(BC), AF); - break; - case 0x7A: /* ADC HL,SP */ - cycles -= cycleTables[2][0x7A]; - 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) */ - cycles -= cycleTables[2][0x7B]; - temp = GetWORD(pc); - SP = GetWORD(temp); - pc += 2; - break; - case 0xA0: /* LDI */ - cycles -= cycleTables[2][0xA0]; - acu = GetBYTE_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 */ - cycles -= cycleTables[2][0xA1]; - acu = hreg(AF); - temp = GetBYTE_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 */ - cycles -= cycleTables[2][0xA2]; - PutBYTE(HL, INPUT(lreg(BC))); ++HL; - SETFLAG(N, 1); - SETFLAG(P, (--BC & 0xffff) != 0); - break; - case 0xA3: /* OUTI */ - cycles -= cycleTables[2][0xA3]; - OUTPUT(lreg(BC), GetBYTE(HL)); ++HL; - SETFLAG(N, 1); - Sethreg(BC, hreg(BC) - 1); - SETFLAG(Z, hreg(BC) == 0); - break; - case 0xA8: /* LDD */ - cycles -= cycleTables[2][0xA8]; - acu = GetBYTE_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 */ - cycles -= cycleTables[2][0xA9]; - acu = hreg(AF); - temp = GetBYTE_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 */ - cycles -= cycleTables[2][0xAA]; - PutBYTE(HL, INPUT(lreg(BC))); --HL; - SETFLAG(N, 1); - Sethreg(BC, lreg(BC) - 1); - SETFLAG(Z, lreg(BC) == 0); - break; - case 0xAB: /* OUTD */ - cycles -= cycleTables[2][0xAB]; - OUTPUT(lreg(BC), GetBYTE(HL)); --HL; - SETFLAG(N, 1); - Sethreg(BC, hreg(BC) - 1); - SETFLAG(Z, hreg(BC) == 0); - break; - case 0xB0: /* LDIR */ - cycles -= cycleTables[2][0xB0]; - acu = hreg(AF); - BC &= 0xffff; - do { - acu = GetBYTE_pp(HL); - PutBYTE_pp(DE, acu); - } while (--BC); - acu += hreg(AF); - AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4); - break; - case 0xB1: /* CPIR */ - cycles -= cycleTables[2][0xB1]; - acu = hreg(AF); - BC &= 0xffff; - do { - temp = GetBYTE_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 */ - cycles -= cycleTables[2][0xB2]; - temp = hreg(BC); - do { - PutBYTE(HL, INPUT(lreg(BC))); ++HL; - } while (--temp); - Sethreg(BC, 0); - SETFLAG(N, 1); - SETFLAG(Z, 1); - break; - case 0xB3: /* OTIR */ - cycles -= cycleTables[2][0xB3]; - temp = hreg(BC); - do { - OUTPUT(lreg(BC), GetBYTE(HL)); ++HL; - } while (--temp); - Sethreg(BC, 0); - SETFLAG(N, 1); - SETFLAG(Z, 1); - break; - case 0xB8: /* LDDR */ - cycles -= cycleTables[2][0xB8]; - BC &= 0xffff; - do { - acu = GetBYTE_mm(HL); - PutBYTE_mm(DE, acu); - } while (--BC); - acu += hreg(AF); - AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4); - break; - case 0xB9: /* CPDR */ - cycles -= cycleTables[2][0xB9]; - acu = hreg(AF); - BC &= 0xffff; - do { - temp = GetBYTE_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 */ - cycles -= cycleTables[2][0xBA]; - temp = hreg(BC); - do { - PutBYTE(HL, INPUT(lreg(BC))); --HL; - } while (--temp); - Sethreg(BC, 0); - SETFLAG(N, 1); - SETFLAG(Z, 1); - break; - case 0xBB: /* OTDR */ - cycles -= cycleTables[2][0xBB]; - temp = hreg(BC); - do { - OUTPUT(lreg(BC), GetBYTE(HL)); --HL; - } while (--temp); - Sethreg(BC, 0); - SETFLAG(N, 1); - SETFLAG(Z, 1); - break; - default: if (0x40 <= op && op <= 0x7f) pc--; /* ignore ED */ - } - break; - case 0xEE: /* XOR nn */ - cycles -= cycleTables[0][0xEE]; - sum = ((AF >> 8) ^ GetBYTE_pp(pc)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xEF: /* RST 28H */ - cycles -= cycleTables[0][0xEF]; - PUSH(pc); pc = 0x28; - break; - case 0xF0: /* RET P */ - cycles -= cycleTables[0][0xF0]; - if (!TSTFLAG(S)) POP(pc); - break; - case 0xF1: /* POP AF */ - cycles -= cycleTables[0][0xF1]; - POP(AF); - break; - case 0xF2: /* JP P,nnnn */ - cycles -= cycleTables[0][0xF2]; - Jpc(!TSTFLAG(S)); - break; - case 0xF3: /* DI */ - cycles -= cycleTables[0][0xF3]; - iff = 0; - break; - case 0xF4: /* CALL P,nnnn */ - cycles -= cycleTables[0][0xF4]; - CALLC(!TSTFLAG(S)); - break; - case 0xF5: /* PUSH AF */ - cycles -= cycleTables[0][0xF5]; - PUSH(AF); - break; - case 0xF6: /* OR nn */ - cycles -= cycleTables[0][0xF6]; - sum = ((AF >> 8) | GetBYTE_pp(pc)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xF7: /* RST 30H */ - cycles -= cycleTables[0][0xF7]; - PUSH(pc); pc = 0x30; - break; - case 0xF8: /* RET M */ - cycles -= cycleTables[0][0xF8]; - if (TSTFLAG(S)) POP(pc); - break; - case 0xF9: /* LD SP,HL */ - cycles -= cycleTables[0][0xF9]; - SP = HL; - break; - case 0xFA: /* JP M,nnnn */ - cycles -= cycleTables[0][0xFA]; - Jpc(TSTFLAG(S)); - break; - case 0xFB: /* EI */ - cycles -= cycleTables[0][0xFB]; - iff = 3; - break; - case 0xFC: /* CALL M,nnnn */ - cycles -= cycleTables[0][0xFC]; - CALLC(TSTFLAG(S)); - break; - case 0xFD: /* FD prefix */ - op = GetBYTE_pp(pc); - switch (op) { - case 0x09: /* ADD IY,BC */ - cycles -= cycleTables[3][0x09]; - 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 */ - cycles -= cycleTables[3][0x19]; - 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 */ - cycles -= cycleTables[3][0x21]; - IY = GetWORD(pc); - pc += 2; - break; - case 0x22: /* LD (nnnn),IY */ - cycles -= cycleTables[3][0x22]; - temp = GetWORD(pc); - PutWORD(temp, IY); - pc += 2; - break; - case 0x23: /* INC IY */ - cycles -= cycleTables[3][0x23]; - ++IY; - break; - case 0x24: /* INC IYH */ - cycles -= cycleTables[3][0x24]; - 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 */ - cycles -= cycleTables[3][0x25]; - 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 */ - cycles -= cycleTables[3][0x26]; - Sethreg(IY, GetBYTE_pp(pc)); - break; - case 0x29: /* ADD IY,IY */ - cycles -= cycleTables[3][0x29]; - 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) */ - cycles -= cycleTables[3][0x2A]; - temp = GetWORD(pc); - IY = GetWORD(temp); - pc += 2; - break; - case 0x2B: /* DEC IY */ - cycles -= cycleTables[3][0x2B]; - --IY; - break; - case 0x2C: /* INC IYL */ - cycles -= cycleTables[3][0x2C]; - 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 */ - cycles -= cycleTables[3][0x2D]; - 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 */ - cycles -= cycleTables[3][0x2E]; - Setlreg(IY, GetBYTE_pp(pc)); - break; - case 0x34: /* INC (IY+dd) */ - cycles -= cycleTables[3][0x34]; - adr = IY + (signed char) GetBYTE_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) */ - cycles -= cycleTables[3][0x35]; - adr = IY + (signed char) GetBYTE_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 */ - cycles -= cycleTables[3][0x36]; - adr = IY + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, GetBYTE_pp(pc)); - break; - case 0x39: /* ADD IY,SP */ - cycles -= cycleTables[3][0x39]; - 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 */ - cycles -= cycleTables[3][0x44]; - Sethreg(BC, hreg(IY)); - break; - case 0x45: /* LD B,IYL */ - cycles -= cycleTables[3][0x45]; - Sethreg(BC, lreg(IY)); - break; - case 0x46: /* LD B,(IY+dd) */ - cycles -= cycleTables[3][0x46]; - adr = IY + (signed char) GetBYTE_pp(pc); - Sethreg(BC, GetBYTE(adr)); - break; - case 0x4C: /* LD C,IYH */ - cycles -= cycleTables[3][0x4C]; - Setlreg(BC, hreg(IY)); - break; - case 0x4D: /* LD C,IYL */ - cycles -= cycleTables[3][0x4D]; - Setlreg(BC, lreg(IY)); - break; - case 0x4E: /* LD C,(IY+dd) */ - cycles -= cycleTables[3][0x4E]; - adr = IY + (signed char) GetBYTE_pp(pc); - Setlreg(BC, GetBYTE(adr)); - break; - case 0x54: /* LD D,IYH */ - cycles -= cycleTables[3][0x54]; - Sethreg(DE, hreg(IY)); - break; - case 0x55: /* LD D,IYL */ - cycles -= cycleTables[3][0x55]; - Sethreg(DE, lreg(IY)); - break; - case 0x56: /* LD D,(IY+dd) */ - cycles -= cycleTables[3][0x56]; - adr = IY + (signed char) GetBYTE_pp(pc); - Sethreg(DE, GetBYTE(adr)); - break; - case 0x5C: /* LD E,H */ - cycles -= cycleTables[3][0x5C]; - Setlreg(DE, hreg(IY)); - break; - case 0x5D: /* LD E,L */ - cycles -= cycleTables[3][0x5D]; - Setlreg(DE, lreg(IY)); - break; - case 0x5E: /* LD E,(IY+dd) */ - cycles -= cycleTables[3][0x5E]; - adr = IY + (signed char) GetBYTE_pp(pc); - Setlreg(DE, GetBYTE(adr)); - break; - case 0x60: /* LD IYH,B */ - cycles -= cycleTables[3][0x60]; - Sethreg(IY, hreg(BC)); - break; - case 0x61: /* LD IYH,C */ - cycles -= cycleTables[3][0x61]; - Sethreg(IY, lreg(BC)); - break; - case 0x62: /* LD IYH,D */ - cycles -= cycleTables[3][0x62]; - Sethreg(IY, hreg(DE)); - break; - case 0x63: /* LD IYH,E */ - cycles -= cycleTables[3][0x63]; - Sethreg(IY, lreg(DE)); - break; - case 0x64: /* LD IYH,IYH */ - cycles -= cycleTables[3][0x64]; - /* nop */ - break; - case 0x65: /* LD IYH,IYL */ - cycles -= cycleTables[3][0x65]; - Sethreg(IY, lreg(IY)); - break; - case 0x66: /* LD H,(IY+dd) */ - cycles -= cycleTables[3][0x66]; - adr = IY + (signed char) GetBYTE_pp(pc); - Sethreg(HL, GetBYTE(adr)); - break; - case 0x67: /* LD IYH,A */ - cycles -= cycleTables[3][0x67]; - Sethreg(IY, hreg(AF)); - break; - case 0x68: /* LD IYL,B */ - cycles -= cycleTables[3][0x68]; - Setlreg(IY, hreg(BC)); - break; - case 0x69: /* LD IYL,C */ - cycles -= cycleTables[3][0x69]; - Setlreg(IY, lreg(BC)); - break; - case 0x6A: /* LD IYL,D */ - cycles -= cycleTables[3][0x6A]; - Setlreg(IY, hreg(DE)); - break; - case 0x6B: /* LD IYL,E */ - cycles -= cycleTables[3][0x6B]; - Setlreg(IY, lreg(DE)); - break; - case 0x6C: /* LD IYL,IYH */ - cycles -= cycleTables[3][0x6C]; - Setlreg(IY, hreg(IY)); - break; - case 0x6D: /* LD IYL,IYL */ - cycles -= cycleTables[3][0x6D]; - /* nop */ - break; - case 0x6E: /* LD L,(IY+dd) */ - cycles -= cycleTables[3][0x6E]; - adr = IY + (signed char) GetBYTE_pp(pc); - Setlreg(HL, GetBYTE(adr)); - break; - case 0x6F: /* LD IYL,A */ - cycles -= cycleTables[3][0x6F]; - Setlreg(IY, hreg(AF)); - break; - case 0x70: /* LD (IY+dd),B */ - cycles -= cycleTables[3][0x70]; - adr = IY + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, hreg(BC)); - break; - case 0x71: /* LD (IY+dd),C */ - cycles -= cycleTables[3][0x71]; - adr = IY + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, lreg(BC)); - break; - case 0x72: /* LD (IY+dd),D */ - cycles -= cycleTables[3][0x72]; - adr = IY + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, hreg(DE)); - break; - case 0x73: /* LD (IY+dd),E */ - cycles -= cycleTables[3][0x73]; - adr = IY + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, lreg(DE)); - break; - case 0x74: /* LD (IY+dd),H */ - cycles -= cycleTables[3][0x74]; - adr = IY + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, hreg(HL)); - break; - case 0x75: /* LD (IY+dd),L */ - cycles -= cycleTables[3][0x75]; - adr = IY + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, lreg(HL)); - break; - case 0x77: /* LD (IY+dd),A */ - cycles -= cycleTables[3][0x77]; - adr = IY + (signed char) GetBYTE_pp(pc); - PutBYTE(adr, hreg(AF)); - break; - case 0x7C: /* LD A,IYH */ - cycles -= cycleTables[3][0x7C]; - Sethreg(AF, hreg(IY)); - break; - case 0x7D: /* LD A,IYL */ - cycles -= cycleTables[3][0x7D]; - Sethreg(AF, lreg(IY)); - break; - case 0x7E: /* LD A,(IY+dd) */ - cycles -= cycleTables[3][0x7E]; - adr = IY + (signed char) GetBYTE_pp(pc); - Sethreg(AF, GetBYTE(adr)); - break; - case 0x84: /* ADD A,IYH */ - cycles -= cycleTables[3][0x84]; - 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 */ - cycles -= cycleTables[3][0x85]; - 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) */ - cycles -= cycleTables[3][0x86]; - adr = IY + (signed char) GetBYTE_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 */ - cycles -= cycleTables[3][0x8C]; - 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 */ - cycles -= cycleTables[3][0x8D]; - 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) */ - cycles -= cycleTables[3][0x8E]; - adr = IY + (signed char) GetBYTE_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 */ - cycles -= cycleTables[3][0x94]; - 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 */ - cycles -= cycleTables[3][0x95]; - 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) */ - cycles -= cycleTables[3][0x96]; - adr = IY + (signed char) GetBYTE_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 */ - cycles -= cycleTables[3][0x9C]; - 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 */ - cycles -= cycleTables[3][0x9D]; - 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) */ - cycles -= cycleTables[3][0x9E]; - adr = IY + (signed char) GetBYTE_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 */ - cycles -= cycleTables[3][0xA4]; - sum = ((AF & (IY)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | - ((sum == 0) << 6) | 0x10 | partab[sum]; - break; - case 0xA5: /* AND IYL */ - cycles -= cycleTables[3][0xA5]; - sum = ((AF >> 8) & IY) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xA6: /* AND (IY+dd) */ - cycles -= cycleTables[3][0xA6]; - adr = IY + (signed char) GetBYTE_pp(pc); - sum = ((AF >> 8) & GetBYTE(adr)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xAC: /* XOR IYH */ - cycles -= cycleTables[3][0xAC]; - sum = ((AF ^ (IY)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xAD: /* XOR IYL */ - cycles -= cycleTables[3][0xAD]; - sum = ((AF >> 8) ^ IY) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xAE: /* XOR (IY+dd) */ - cycles -= cycleTables[3][0xAE]; - adr = IY + (signed char) GetBYTE_pp(pc); - sum = ((AF >> 8) ^ GetBYTE(adr)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB4: /* OR IYH */ - cycles -= cycleTables[3][0xB4]; - sum = ((AF | (IY)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB5: /* OR IYL */ - cycles -= cycleTables[3][0xB5]; - sum = ((AF >> 8) | IY) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xB6: /* OR (IY+dd) */ - cycles -= cycleTables[3][0xB6]; - adr = IY + (signed char) GetBYTE_pp(pc); - sum = ((AF >> 8) | GetBYTE(adr)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xBC: /* CP IYH */ - cycles -= cycleTables[3][0xBC]; - 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 */ - cycles -= cycleTables[3][0xBD]; - 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) */ - cycles -= cycleTables[3][0xBE]; - adr = IY + (signed char) GetBYTE_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) GetBYTE_pp(pc); - adr = adr; - op = GetBYTE(pc); - cycles -= cycleTables[4][op]; - switch (op & 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 */ - cycles -= cycleTables[3][0xE1]; - POP(IY); - break; - case 0xE3: /* EX (SP),IY */ - cycles -= cycleTables[3][0xE3]; - temp = IY; POP(IY); PUSH(temp); - break; - case 0xE5: /* PUSH IY */ - cycles -= cycleTables[3][0xE5]; - PUSH(IY); - break; - case 0xE9: /* JP (IY) */ - cycles -= cycleTables[3][0xE9]; - pc = IY; - break; - case 0xF9: /* LD SP,IY */ - cycles -= cycleTables[3][0xF9]; - SP = IY; - break; - default: pc--; /* ignore DD */ - } - break; - case 0xFE: /* CP nn */ - cycles -= cycleTables[0][0xFE]; - temp = GetBYTE_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) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xFF: /* RST 38H */ - cycles -= cycleTables[0][0xFF]; - PUSH(pc); pc = 0x38; - break; + switch(op) { + case 0x00: /* NOP */ + cycles -= cycleTables[0][0x00]; + break; + case 0x01: /* LD BC,nnnn */ + cycles -= cycleTables[0][0x01]; + BC = GetWORD(pc); + pc += 2; + break; + case 0x02: /* LD (BC),A */ + cycles -= cycleTables[0][0x02]; + PutBYTE(BC, hreg(AF)); + break; + case 0x03: /* INC BC */ + cycles -= cycleTables[0][0x03]; + ++BC; + break; + case 0x04: /* INC B */ + cycles -= cycleTables[0][0x04]; + BC += 0x100; + temp = hreg(BC); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0) << 4) | + ((temp == 0x80) << 2); + break; + case 0x05: /* DEC B */ + cycles -= cycleTables[0][0x05]; + BC -= 0x100; + temp = hreg(BC); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0xf) << 4) | + ((temp == 0x7f) << 2) | 2; + break; + case 0x06: /* LD B,nn */ + cycles -= cycleTables[0][0x06]; + Sethreg(BC, GetBYTE_pp(pc)); + break; + case 0x07: /* RLCA */ + cycles -= cycleTables[0][0x07]; + AF = ((AF >> 7) & 0x0128) | ((AF << 1) & ~0x1ff) | + (AF & 0xc4) | ((AF >> 15) & 1); + break; + case 0x08: /* EX AF,AF' */ + cycles -= cycleTables[0][0x08]; + af[af_sel] = AF; + af_sel = 1 - af_sel; + AF = af[af_sel]; + break; + case 0x09: /* ADD HL,BC */ + cycles -= cycleTables[0][0x09]; + 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) */ + cycles -= cycleTables[0][0x0A]; + Sethreg(AF, GetBYTE(BC)); + break; + case 0x0B: /* DEC BC */ + cycles -= cycleTables[0][0x0B]; + --BC; + break; + case 0x0C: /* INC C */ + cycles -= cycleTables[0][0x0C]; + temp = lreg(BC)+1; + Setlreg(BC, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0) << 4) | + ((temp == 0x80) << 2); + break; + case 0x0D: /* DEC C */ + cycles -= cycleTables[0][0x0D]; + temp = lreg(BC)-1; + Setlreg(BC, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0xf) << 4) | + ((temp == 0x7f) << 2) | 2; + break; + case 0x0E: /* LD C,nn */ + cycles -= cycleTables[0][0x0E]; + Setlreg(BC, GetBYTE_pp(pc)); + break; + case 0x0F: /* RRCA */ + cycles -= cycleTables[0][0x0F]; + temp = hreg(AF); + sum = temp >> 1; + AF = ((temp & 1) << 15) | (sum << 8) | + (sum & 0x28) | (AF & 0xc4) | (temp & 1); + break; + case 0x10: /* DJNZ dd */ + cycles -= cycleTables[0][0x10]; + pc += ((BC -= 0x100) & 0xff00) ? (signed char) GetBYTE(pc) + 1 : 1; + break; + case 0x11: /* LD DE,nnnn */ + cycles -= cycleTables[0][0x11]; + DE = GetWORD(pc); + pc += 2; + break; + case 0x12: /* LD (DE),A */ + cycles -= cycleTables[0][0x12]; + PutBYTE(DE, hreg(AF)); + break; + case 0x13: /* INC DE */ + cycles -= cycleTables[0][0x13]; + ++DE; + break; + case 0x14: /* INC D */ + cycles -= cycleTables[0][0x14]; + DE += 0x100; + temp = hreg(DE); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0) << 4) | + ((temp == 0x80) << 2); + break; + case 0x15: /* DEC D */ + cycles -= cycleTables[0][0x15]; + DE -= 0x100; + temp = hreg(DE); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0xf) << 4) | + ((temp == 0x7f) << 2) | 2; + break; + case 0x16: /* LD D,nn */ + cycles -= cycleTables[0][0x16]; + Sethreg(DE, GetBYTE_pp(pc)); + break; + case 0x17: /* RLA */ + cycles -= cycleTables[0][0x17]; + AF = ((AF << 8) & 0x0100) | ((AF >> 7) & 0x28) | ((AF << 1) & ~0x01ff) | + (AF & 0xc4) | ((AF >> 15) & 1); + break; + case 0x18: /* JR dd */ + cycles -= cycleTables[0][0x18]; + pc += (1) ? (signed char) GetBYTE(pc) + 1 : 1; + break; + case 0x19: /* ADD HL,DE */ + cycles -= cycleTables[0][0x19]; + 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) */ + cycles -= cycleTables[0][0x1A]; + Sethreg(AF, GetBYTE(DE)); + break; + case 0x1B: /* DEC DE */ + cycles -= cycleTables[0][0x1B]; + --DE; + break; + case 0x1C: /* INC E */ + cycles -= cycleTables[0][0x1C]; + temp = lreg(DE)+1; + Setlreg(DE, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0) << 4) | + ((temp == 0x80) << 2); + break; + case 0x1D: /* DEC E */ + cycles -= cycleTables[0][0x1D]; + temp = lreg(DE)-1; + Setlreg(DE, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0xf) << 4) | + ((temp == 0x7f) << 2) | 2; + break; + case 0x1E: /* LD E,nn */ + cycles -= cycleTables[0][0x1E]; + Setlreg(DE, GetBYTE_pp(pc)); + break; + case 0x1F: /* RRA */ + cycles -= cycleTables[0][0x1F]; + temp = hreg(AF); + sum = temp >> 1; + AF = ((AF & 1) << 15) | (sum << 8) | + (sum & 0x28) | (AF & 0xc4) | (temp & 1); + break; + case 0x20: /* JR NZ,dd */ + cycles -= cycleTables[0][0x20]; + pc += (!TSTFLAG(Z)) ? (signed char) GetBYTE(pc) + 1 : 1; + break; + case 0x21: /* LD HL,nnnn */ + cycles -= cycleTables[0][0x21]; + HL = GetWORD(pc); + pc += 2; + break; + case 0x22: /* LD (nnnn),HL */ + cycles -= cycleTables[0][0x22]; + temp = GetWORD(pc); + PutWORD(temp, HL); + pc += 2; + break; + case 0x23: /* INC HL */ + cycles -= cycleTables[0][0x23]; + ++HL; + break; + case 0x24: /* INC H */ + cycles -= cycleTables[0][0x24]; + HL += 0x100; + temp = hreg(HL); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0) << 4) | + ((temp == 0x80) << 2); + break; + case 0x25: /* DEC H */ + cycles -= cycleTables[0][0x25]; + HL -= 0x100; + temp = hreg(HL); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0xf) << 4) | + ((temp == 0x7f) << 2) | 2; + break; + case 0x26: /* LD H,nn */ + cycles -= cycleTables[0][0x26]; + Sethreg(HL, GetBYTE_pp(pc)); + break; + case 0x27: /* DAA */ + cycles -= cycleTables[0][0x27]; + 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 */ + cycles -= cycleTables[0][0x28]; + pc += (TSTFLAG(Z)) ? (signed char) GetBYTE(pc) + 1 : 1; + break; + case 0x29: /* ADD HL,HL */ + cycles -= cycleTables[0][0x29]; + 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) */ + cycles -= cycleTables[0][0x2A]; + temp = GetWORD(pc); + HL = GetWORD(temp); + pc += 2; + break; + case 0x2B: /* DEC HL */ + cycles -= cycleTables[0][0x2B]; + --HL; + break; + case 0x2C: /* INC L */ + cycles -= cycleTables[0][0x2C]; + temp = lreg(HL)+1; + Setlreg(HL, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0) << 4) | + ((temp == 0x80) << 2); + break; + case 0x2D: /* DEC L */ + cycles -= cycleTables[0][0x2D]; + temp = lreg(HL)-1; + Setlreg(HL, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0xf) << 4) | + ((temp == 0x7f) << 2) | 2; + break; + case 0x2E: /* LD L,nn */ + cycles -= cycleTables[0][0x2E]; + Setlreg(HL, GetBYTE_pp(pc)); + break; + case 0x2F: /* CPL */ + cycles -= cycleTables[0][0x2F]; + AF = (~AF & ~0xff) | (AF & 0xc5) | ((~AF >> 8) & 0x28) | 0x12; + break; + case 0x30: /* JR NC,dd */ + cycles -= cycleTables[0][0x30]; + pc += (!TSTFLAG(C)) ? (signed char) GetBYTE(pc) + 1 : 1; + break; + case 0x31: /* LD SP,nnnn */ + cycles -= cycleTables[0][0x31]; + SP = GetWORD(pc); + pc += 2; + break; + case 0x32: /* LD (nnnn),A */ + cycles -= cycleTables[0][0x32]; + temp = GetWORD(pc); + PutBYTE(temp, hreg(AF)); + pc += 2; + break; + case 0x33: /* INC SP */ + cycles -= cycleTables[0][0x33]; + ++SP; + break; + case 0x34: /* INC (HL) */ + cycles -= cycleTables[0][0x34]; + temp = GetBYTE(HL)+1; + PutBYTE(HL, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0) << 4) | + ((temp == 0x80) << 2); + break; + case 0x35: /* DEC (HL) */ + cycles -= cycleTables[0][0x35]; + temp = GetBYTE(HL)-1; + PutBYTE(HL, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0xf) << 4) | + ((temp == 0x7f) << 2) | 2; + break; + case 0x36: /* LD (HL),nn */ + cycles -= cycleTables[0][0x36]; + PutBYTE(HL, GetBYTE_pp(pc)); + break; + case 0x37: /* SCF */ + cycles -= cycleTables[0][0x37]; + AF = (AF&~0x3b)|((AF>>8)&0x28)|1; + break; + case 0x38: /* JR C,dd */ + cycles -= cycleTables[0][0x38]; + pc += (TSTFLAG(C)) ? (signed char) GetBYTE(pc) + 1 : 1; + break; + case 0x39: /* ADD HL,SP */ + cycles -= cycleTables[0][0x39]; + 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) */ + cycles -= cycleTables[0][0x3A]; + temp = GetWORD(pc); + Sethreg(AF, GetBYTE(temp)); + pc += 2; + break; + case 0x3B: /* DEC SP */ + cycles -= cycleTables[0][0x3B]; + --SP; + break; + case 0x3C: /* INC A */ + cycles -= cycleTables[0][0x3C]; + AF += 0x100; + temp = hreg(AF); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0) << 4) | + ((temp == 0x80) << 2); + break; + case 0x3D: /* DEC A */ + cycles -= cycleTables[0][0x3D]; + AF -= 0x100; + temp = hreg(AF); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0xf) << 4) | + ((temp == 0x7f) << 2) | 2; + break; + case 0x3E: /* LD A,nn */ + cycles -= cycleTables[0][0x3E]; + Sethreg(AF, GetBYTE_pp(pc)); + break; + case 0x3F: /* CCF */ + cycles -= cycleTables[0][0x3F]; + AF = (AF&~0x3b)|((AF>>8)&0x28)|((AF&1)<<4)|(~AF&1); + break; + case 0x40: /* LD B,B */ + cycles -= cycleTables[0][0x40]; + /* nop */ + break; + case 0x41: /* LD B,C */ + cycles -= cycleTables[0][0x41]; + BC = (BC & 255) | ((BC & 255) << 8); + break; + case 0x42: /* LD B,D */ + cycles -= cycleTables[0][0x42]; + BC = (BC & 255) | (DE & ~255); + break; + case 0x43: /* LD B,E */ + cycles -= cycleTables[0][0x43]; + BC = (BC & 255) | ((DE & 255) << 8); + break; + case 0x44: /* LD B,H */ + cycles -= cycleTables[0][0x44]; + BC = (BC & 255) | (HL & ~255); + break; + case 0x45: /* LD B,L */ + cycles -= cycleTables[0][0x45]; + BC = (BC & 255) | ((HL & 255) << 8); + break; + case 0x46: /* LD B,(HL) */ + cycles -= cycleTables[0][0x46]; + Sethreg(BC, GetBYTE(HL)); + break; + case 0x47: /* LD B,A */ + cycles -= cycleTables[0][0x47]; + BC = (BC & 255) | (AF & ~255); + break; + case 0x48: /* LD C,B */ + cycles -= cycleTables[0][0x48]; + BC = (BC & ~255) | ((BC >> 8) & 255); + break; + case 0x49: /* LD C,C */ + cycles -= cycleTables[0][0x49]; + /* nop */ + break; + case 0x4A: /* LD C,D */ + cycles -= cycleTables[0][0x4A]; + BC = (BC & ~255) | ((DE >> 8) & 255); + break; + case 0x4B: /* LD C,E */ + cycles -= cycleTables[0][0x4B]; + BC = (BC & ~255) | (DE & 255); + break; + case 0x4C: /* LD C,H */ + cycles -= cycleTables[0][0x4C]; + BC = (BC & ~255) | ((HL >> 8) & 255); + break; + case 0x4D: /* LD C,L */ + cycles -= cycleTables[0][0x4D]; + BC = (BC & ~255) | (HL & 255); + break; + case 0x4E: /* LD C,(HL) */ + cycles -= cycleTables[0][0x4E]; + Setlreg(BC, GetBYTE(HL)); + break; + case 0x4F: /* LD C,A */ + cycles -= cycleTables[0][0x4F]; + BC = (BC & ~255) | ((AF >> 8) & 255); + break; + case 0x50: /* LD D,B */ + cycles -= cycleTables[0][0x50]; + DE = (DE & 255) | (BC & ~255); + break; + case 0x51: /* LD D,C */ + cycles -= cycleTables[0][0x51]; + DE = (DE & 255) | ((BC & 255) << 8); + break; + case 0x52: /* LD D,D */ + cycles -= cycleTables[0][0x52]; + /* nop */ + break; + case 0x53: /* LD D,E */ + cycles -= cycleTables[0][0x53]; + DE = (DE & 255) | ((DE & 255) << 8); + break; + case 0x54: /* LD D,H */ + cycles -= cycleTables[0][0x54]; + DE = (DE & 255) | (HL & ~255); + break; + case 0x55: /* LD D,L */ + cycles -= cycleTables[0][0x55]; + DE = (DE & 255) | ((HL & 255) << 8); + break; + case 0x56: /* LD D,(HL) */ + cycles -= cycleTables[0][0x56]; + Sethreg(DE, GetBYTE(HL)); + break; + case 0x57: /* LD D,A */ + cycles -= cycleTables[0][0x57]; + DE = (DE & 255) | (AF & ~255); + break; + case 0x58: /* LD E,B */ + cycles -= cycleTables[0][0x58]; + DE = (DE & ~255) | ((BC >> 8) & 255); + break; + case 0x59: /* LD E,C */ + cycles -= cycleTables[0][0x59]; + DE = (DE & ~255) | (BC & 255); + break; + case 0x5A: /* LD E,D */ + cycles -= cycleTables[0][0x5A]; + DE = (DE & ~255) | ((DE >> 8) & 255); + break; + case 0x5B: /* LD E,E */ + cycles -= cycleTables[0][0x5B]; + /* nop */ + break; + case 0x5C: /* LD E,H */ + cycles -= cycleTables[0][0x5C]; + DE = (DE & ~255) | ((HL >> 8) & 255); + break; + case 0x5D: /* LD E,L */ + cycles -= cycleTables[0][0x5D]; + DE = (DE & ~255) | (HL & 255); + break; + case 0x5E: /* LD E,(HL) */ + cycles -= cycleTables[0][0x5E]; + Setlreg(DE, GetBYTE(HL)); + break; + case 0x5F: /* LD E,A */ + cycles -= cycleTables[0][0x5F]; + DE = (DE & ~255) | ((AF >> 8) & 255); + break; + case 0x60: /* LD H,B */ + cycles -= cycleTables[0][0x60]; + HL = (HL & 255) | (BC & ~255); + break; + case 0x61: /* LD H,C */ + cycles -= cycleTables[0][0x61]; + HL = (HL & 255) | ((BC & 255) << 8); + break; + case 0x62: /* LD H,D */ + cycles -= cycleTables[0][0x62]; + HL = (HL & 255) | (DE & ~255); + break; + case 0x63: /* LD H,E */ + cycles -= cycleTables[0][0x63]; + HL = (HL & 255) | ((DE & 255) << 8); + break; + case 0x64: /* LD H,H */ + cycles -= cycleTables[0][0x64]; + /* nop */ + break; + case 0x65: /* LD H,L */ + cycles -= cycleTables[0][0x65]; + HL = (HL & 255) | ((HL & 255) << 8); + break; + case 0x66: /* LD H,(HL) */ + cycles -= cycleTables[0][0x66]; + Sethreg(HL, GetBYTE(HL)); + break; + case 0x67: /* LD H,A */ + cycles -= cycleTables[0][0x67]; + HL = (HL & 255) | (AF & ~255); + break; + case 0x68: /* LD L,B */ + cycles -= cycleTables[0][0x68]; + HL = (HL & ~255) | ((BC >> 8) & 255); + break; + case 0x69: /* LD L,C */ + cycles -= cycleTables[0][0x69]; + HL = (HL & ~255) | (BC & 255); + break; + case 0x6A: /* LD L,D */ + cycles -= cycleTables[0][0x6A]; + HL = (HL & ~255) | ((DE >> 8) & 255); + break; + case 0x6B: /* LD L,E */ + cycles -= cycleTables[0][0x6B]; + HL = (HL & ~255) | (DE & 255); + break; + case 0x6C: /* LD L,H */ + cycles -= cycleTables[0][0x6C]; + HL = (HL & ~255) | ((HL >> 8) & 255); + break; + case 0x6D: /* LD L,L */ + cycles -= cycleTables[0][0x6D]; + /* nop */ + break; + case 0x6E: /* LD L,(HL) */ + cycles -= cycleTables[0][0x6E]; + Setlreg(HL, GetBYTE(HL)); + break; + case 0x6F: /* LD L,A */ + cycles -= cycleTables[0][0x6F]; + HL = (HL & ~255) | ((AF >> 8) & 255); + break; + case 0x70: /* LD (HL),B */ + cycles -= cycleTables[0][0x70]; + PutBYTE(HL, hreg(BC)); + break; + case 0x71: /* LD (HL),C */ + cycles -= cycleTables[0][0x71]; + PutBYTE(HL, lreg(BC)); + break; + case 0x72: /* LD (HL),D */ + cycles -= cycleTables[0][0x72]; + PutBYTE(HL, hreg(DE)); + break; + case 0x73: /* LD (HL),E */ + cycles -= cycleTables[0][0x73]; + PutBYTE(HL, lreg(DE)); + break; + case 0x74: /* LD (HL),H */ + cycles -= cycleTables[0][0x74]; + PutBYTE(HL, hreg(HL)); + break; + case 0x75: /* LD (HL),L */ + cycles -= cycleTables[0][0x75]; + PutBYTE(HL, lreg(HL)); + break; + case 0x76: /* HALT */ + cycles -= cycleTables[0][0x76]; +// ErrorLog("Z80 encountered an unemulated instruction at 0x%04X", (pc-1)&0xFFFF); + goto HALTExit; + case 0x77: /* LD (HL),A */ + cycles -= cycleTables[0][0x77]; + PutBYTE(HL, hreg(AF)); + break; + case 0x78: /* LD A,B */ + cycles -= cycleTables[0][0x78]; + AF = (AF & 255) | (BC & ~255); + break; + case 0x79: /* LD A,C */ + cycles -= cycleTables[0][0x79]; + AF = (AF & 255) | ((BC & 255) << 8); + break; + case 0x7A: /* LD A,D */ + cycles -= cycleTables[0][0x7A]; + AF = (AF & 255) | (DE & ~255); + break; + case 0x7B: /* LD A,E */ + cycles -= cycleTables[0][0x7B]; + AF = (AF & 255) | ((DE & 255) << 8); + break; + case 0x7C: /* LD A,H */ + cycles -= cycleTables[0][0x7C]; + AF = (AF & 255) | (HL & ~255); + break; + case 0x7D: /* LD A,L */ + cycles -= cycleTables[0][0x7D]; + AF = (AF & 255) | ((HL & 255) << 8); + break; + case 0x7E: /* LD A,(HL) */ + cycles -= cycleTables[0][0x7E]; + Sethreg(AF, GetBYTE(HL)); + break; + case 0x7F: /* LD A,A */ + cycles -= cycleTables[0][0x7F]; + /* nop */ + break; + case 0x80: /* ADD A,B */ + cycles -= cycleTables[0][0x80]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x81: /* ADD A,C */ + cycles -= cycleTables[0][0x81]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x82: /* ADD A,D */ + cycles -= cycleTables[0][0x82]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x83: /* ADD A,E */ + cycles -= cycleTables[0][0x83]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x84: /* ADD A,H */ + cycles -= cycleTables[0][0x84]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x85: /* ADD A,L */ + cycles -= cycleTables[0][0x85]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x86: /* ADD A,(HL) */ + cycles -= cycleTables[0][0x86]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x87: /* ADD A,A */ + cycles -= cycleTables[0][0x87]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x88: /* ADC A,B */ + cycles -= cycleTables[0][0x88]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x89: /* ADC A,C */ + cycles -= cycleTables[0][0x89]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x8A: /* ADC A,D */ + cycles -= cycleTables[0][0x8A]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x8B: /* ADC A,E */ + cycles -= cycleTables[0][0x8B]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x8C: /* ADC A,H */ + cycles -= cycleTables[0][0x8C]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x8D: /* ADC A,L */ + cycles -= cycleTables[0][0x8D]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x8E: /* ADC A,(HL) */ + cycles -= cycleTables[0][0x8E]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x8F: /* ADC A,A */ + cycles -= cycleTables[0][0x8F]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0x90: /* SUB B */ + cycles -= cycleTables[0][0x90]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x91: /* SUB C */ + cycles -= cycleTables[0][0x91]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x92: /* SUB D */ + cycles -= cycleTables[0][0x92]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x93: /* SUB E */ + cycles -= cycleTables[0][0x93]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x94: /* SUB H */ + cycles -= cycleTables[0][0x94]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x95: /* SUB L */ + cycles -= cycleTables[0][0x95]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x96: /* SUB (HL) */ + cycles -= cycleTables[0][0x96]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x97: /* SUB A */ + cycles -= cycleTables[0][0x97]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x98: /* SBC A,B */ + cycles -= cycleTables[0][0x98]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x99: /* SBC A,C */ + cycles -= cycleTables[0][0x99]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x9A: /* SBC A,D */ + cycles -= cycleTables[0][0x9A]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x9B: /* SBC A,E */ + cycles -= cycleTables[0][0x9B]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x9C: /* SBC A,H */ + cycles -= cycleTables[0][0x9C]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x9D: /* SBC A,L */ + cycles -= cycleTables[0][0x9D]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x9E: /* SBC A,(HL) */ + cycles -= cycleTables[0][0x9E]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0x9F: /* SBC A,A */ + cycles -= cycleTables[0][0x9F]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0xA0: /* AND B */ + cycles -= cycleTables[0][0xA0]; + sum = ((AF & (BC)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | + ((sum == 0) << 6) | 0x10 | partab[sum]; + break; + case 0xA1: /* AND C */ + cycles -= cycleTables[0][0xA1]; + sum = ((AF >> 8) & BC) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | 0x10 | + ((sum == 0) << 6) | partab[sum]; + break; + case 0xA2: /* AND D */ + cycles -= cycleTables[0][0xA2]; + sum = ((AF & (DE)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | + ((sum == 0) << 6) | 0x10 | partab[sum]; + break; + case 0xA3: /* AND E */ + cycles -= cycleTables[0][0xA3]; + sum = ((AF >> 8) & DE) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | 0x10 | + ((sum == 0) << 6) | partab[sum]; + break; + case 0xA4: /* AND H */ + cycles -= cycleTables[0][0xA4]; + sum = ((AF & (HL)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | + ((sum == 0) << 6) | 0x10 | partab[sum]; + break; + case 0xA5: /* AND L */ + cycles -= cycleTables[0][0xA5]; + sum = ((AF >> 8) & HL) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | 0x10 | + ((sum == 0) << 6) | partab[sum]; + break; + case 0xA6: /* AND (HL) */ + cycles -= cycleTables[0][0xA6]; + sum = ((AF >> 8) & GetBYTE(HL)) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | 0x10 | + ((sum == 0) << 6) | partab[sum]; + break; + case 0xA7: /* AND A */ + cycles -= cycleTables[0][0xA7]; + sum = ((AF & (AF)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | + ((sum == 0) << 6) | 0x10 | partab[sum]; + break; + case 0xA8: /* XOR B */ + cycles -= cycleTables[0][0xA8]; + sum = ((AF ^ (BC)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xA9: /* XOR C */ + cycles -= cycleTables[0][0xA9]; + sum = ((AF >> 8) ^ BC) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xAA: /* XOR D */ + cycles -= cycleTables[0][0xAA]; + sum = ((AF ^ (DE)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xAB: /* XOR E */ + cycles -= cycleTables[0][0xAB]; + sum = ((AF >> 8) ^ DE) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xAC: /* XOR H */ + cycles -= cycleTables[0][0xAC]; + sum = ((AF ^ (HL)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xAD: /* XOR L */ + cycles -= cycleTables[0][0xAD]; + sum = ((AF >> 8) ^ HL) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xAE: /* XOR (HL) */ + cycles -= cycleTables[0][0xAE]; + sum = ((AF >> 8) ^ GetBYTE(HL)) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xAF: /* XOR A */ + cycles -= cycleTables[0][0xAF]; + sum = ((AF ^ (AF)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB0: /* OR B */ + cycles -= cycleTables[0][0xB0]; + sum = ((AF | (BC)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB1: /* OR C */ + cycles -= cycleTables[0][0xB1]; + sum = ((AF >> 8) | BC) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB2: /* OR D */ + cycles -= cycleTables[0][0xB2]; + sum = ((AF | (DE)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB3: /* OR E */ + cycles -= cycleTables[0][0xB3]; + sum = ((AF >> 8) | DE) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB4: /* OR H */ + cycles -= cycleTables[0][0xB4]; + sum = ((AF | (HL)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB5: /* OR L */ + cycles -= cycleTables[0][0xB5]; + sum = ((AF >> 8) | HL) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB6: /* OR (HL) */ + cycles -= cycleTables[0][0xB6]; + sum = ((AF >> 8) | GetBYTE(HL)) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB7: /* OR A */ + cycles -= cycleTables[0][0xB7]; + sum = ((AF | (AF)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB8: /* CP B */ + cycles -= cycleTables[0][0xB8]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + (cbits & 0x10) | ((cbits >> 8) & 1); + break; + case 0xB9: /* CP C */ + cycles -= cycleTables[0][0xB9]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + (cbits & 0x10) | ((cbits >> 8) & 1); + break; + case 0xBA: /* CP D */ + cycles -= cycleTables[0][0xBA]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + (cbits & 0x10) | ((cbits >> 8) & 1); + break; + case 0xBB: /* CP E */ + cycles -= cycleTables[0][0xBB]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + (cbits & 0x10) | ((cbits >> 8) & 1); + break; + case 0xBC: /* CP H */ + cycles -= cycleTables[0][0xBC]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + (cbits & 0x10) | ((cbits >> 8) & 1); + break; + case 0xBD: /* CP L */ + cycles -= cycleTables[0][0xBD]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + (cbits & 0x10) | ((cbits >> 8) & 1); + break; + case 0xBE: /* CP (HL) */ + cycles -= cycleTables[0][0xBE]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + (cbits & 0x10) | ((cbits >> 8) & 1); + break; + case 0xBF: /* CP A */ + cycles -= cycleTables[0][0xBF]; + 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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + (cbits & 0x10) | ((cbits >> 8) & 1); + break; + case 0xC0: /* RET NZ */ + cycles -= cycleTables[0][0xC0]; + if (!TSTFLAG(Z)) POP(pc); + break; + case 0xC1: /* POP BC */ + cycles -= cycleTables[0][0xC1]; + POP(BC); + break; + case 0xC2: /* JP NZ,nnnn */ + cycles -= cycleTables[0][0xC2]; + Jpc(!TSTFLAG(Z)); + break; + case 0xC3: /* JP nnnn */ + cycles -= cycleTables[0][0xC3]; + Jpc(1); + break; + case 0xC4: /* CALL NZ,nnnn */ + cycles -= cycleTables[0][0xC4]; + CALLC(!TSTFLAG(Z)); + break; + case 0xC5: /* PUSH BC */ + cycles -= cycleTables[0][0xC5]; + PUSH(BC); + break; + case 0xC6: /* ADD A,nn */ + cycles -= cycleTables[0][0xC6]; + temp = GetBYTE_pp(pc); + 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 0xC7: /* RST 0 */ + cycles -= cycleTables[0][0xC7]; + PUSH(pc); pc = 0; + break; + case 0xC8: /* RET Z */ + cycles -= cycleTables[0][0xC8]; + if (TSTFLAG(Z)) POP(pc); + break; + case 0xC9: /* RET */ + cycles -= cycleTables[0][0xC9]; + POP(pc); + break; + case 0xCA: /* JP Z,nnnn */ + cycles -= cycleTables[0][0xCA]; + Jpc(TSTFLAG(Z)); + break; + case 0xCB: /* CB prefix */ + adr = HL; + op = GetBYTE(pc); + cycles -= cycleTables[1][op]; + switch (op & 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 */ + cycles -= cycleTables[0][0xCC]; + CALLC(TSTFLAG(Z)); + break; + case 0xCD: /* CALL nnnn */ + cycles -= cycleTables[0][0xCD]; + CALLC(1); + break; + case 0xCE: /* ADC A,nn */ + cycles -= cycleTables[0][0xCE]; + temp = GetBYTE_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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + break; + case 0xCF: /* RST 8 */ + cycles -= cycleTables[0][0xCF]; + PUSH(pc); pc = 8; + break; + case 0xD0: /* RET NC */ + cycles -= cycleTables[0][0xD0]; + if (!TSTFLAG(C)) POP(pc); + break; + case 0xD1: /* POP DE */ + cycles -= cycleTables[0][0xD1]; + POP(DE); + break; + case 0xD2: /* JP NC,nnnn */ + cycles -= cycleTables[0][0xD2]; + Jpc(!TSTFLAG(C)); + break; + case 0xD3: /* OUT (nn),A */ + cycles -= cycleTables[0][0xD3]; + OUTPUT(GetBYTE_pp(pc), hreg(AF)); + break; + case 0xD4: /* CALL NC,nnnn */ + cycles -= cycleTables[0][0xD4]; + CALLC(!TSTFLAG(C)); + break; + case 0xD5: /* PUSH DE */ + cycles -= cycleTables[0][0xD5]; + PUSH(DE); + break; + case 0xD6: /* SUB nn */ + cycles -= cycleTables[0][0xD6]; + temp = GetBYTE_pp(pc); + 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 0xD7: /* RST 10H */ + cycles -= cycleTables[0][0xD7]; + PUSH(pc); pc = 0x10; + break; + case 0xD8: /* RET C */ + cycles -= cycleTables[0][0xD8]; + if (TSTFLAG(C)) POP(pc); + break; + case 0xD9: /* EXX */ + cycles -= cycleTables[0][0xD9]; + 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 */ + cycles -= cycleTables[0][0xDA]; + Jpc(TSTFLAG(C)); + break; + case 0xDB: /* IN A,(nn) */ + cycles -= cycleTables[0][0xDB]; + Sethreg(AF, INPUT(GetBYTE_pp(pc))); + break; + case 0xDC: /* CALL C,nnnn */ + cycles -= cycleTables[0][0xDC]; + CALLC(TSTFLAG(C)); + break; + case 0xDD: /* DD prefix */ + op = GetBYTE_pp(pc); + switch (op) { + case 0x09: /* ADD IX,BC */ + cycles -= cycleTables[3][0x09]; + 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 */ + cycles -= cycleTables[3][0x19]; + 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 */ + cycles -= cycleTables[3][0x21]; + IX = GetWORD(pc); + pc += 2; + break; + case 0x22: /* LD (nnnn),IX */ + cycles -= cycleTables[3][0x22]; + temp = GetWORD(pc); + PutWORD(temp, IX); + pc += 2; + break; + case 0x23: /* INC IX */ + cycles -= cycleTables[3][0x23]; + ++IX; + break; + case 0x24: /* INC IXH */ + cycles -= cycleTables[3][0x24]; + 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 */ + cycles -= cycleTables[3][0x25]; + 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 */ + cycles -= cycleTables[3][0x26]; + Sethreg(IX, GetBYTE_pp(pc)); + break; + case 0x29: /* ADD IX,IX */ + cycles -= cycleTables[3][0x29]; + 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) */ + cycles -= cycleTables[3][0x2A]; + temp = GetWORD(pc); + IX = GetWORD(temp); + pc += 2; + break; + case 0x2B: /* DEC IX */ + cycles -= cycleTables[3][0x2B]; + --IX; + break; + case 0x2C: /* INC IXL */ + cycles -= cycleTables[3][0x2C]; + 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 */ + cycles -= cycleTables[3][0x2D]; + 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 */ + cycles -= cycleTables[3][0x2E]; + Setlreg(IX, GetBYTE_pp(pc)); + break; + case 0x34: /* INC (IX+dd) */ + cycles -= cycleTables[3][0x34]; + adr = IX + (signed char) GetBYTE_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) */ + cycles -= cycleTables[3][0x35]; + adr = IX + (signed char) GetBYTE_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 */ + cycles -= cycleTables[3][0x36]; + adr = IX + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, GetBYTE_pp(pc)); + break; + case 0x39: /* ADD IX,SP */ + cycles -= cycleTables[3][0x39]; + 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 */ + cycles -= cycleTables[3][0x44]; + Sethreg(BC, hreg(IX)); + break; + case 0x45: /* LD B,IXL */ + cycles -= cycleTables[3][0x45]; + Sethreg(BC, lreg(IX)); + break; + case 0x46: /* LD B,(IX+dd) */ + cycles -= cycleTables[3][0x46]; + adr = IX + (signed char) GetBYTE_pp(pc); + Sethreg(BC, GetBYTE(adr)); + break; + case 0x4C: /* LD C,IXH */ + cycles -= cycleTables[3][0x4C]; + Setlreg(BC, hreg(IX)); + break; + case 0x4D: /* LD C,IXL */ + cycles -= cycleTables[3][0x4D]; + Setlreg(BC, lreg(IX)); + break; + case 0x4E: /* LD C,(IX+dd) */ + cycles -= cycleTables[3][0x4E]; + adr = IX + (signed char) GetBYTE_pp(pc); + Setlreg(BC, GetBYTE(adr)); + break; + case 0x54: /* LD D,IXH */ + cycles -= cycleTables[3][0x54]; + Sethreg(DE, hreg(IX)); + break; + case 0x55: /* LD D,IXL */ + cycles -= cycleTables[3][0x55]; + Sethreg(DE, lreg(IX)); + break; + case 0x56: /* LD D,(IX+dd) */ + cycles -= cycleTables[3][0x56]; + adr = IX + (signed char) GetBYTE_pp(pc); + Sethreg(DE, GetBYTE(adr)); + break; + case 0x5C: /* LD E,H */ + cycles -= cycleTables[3][0x5C]; + Setlreg(DE, hreg(IX)); + break; + case 0x5D: /* LD E,L */ + cycles -= cycleTables[3][0x5D]; + Setlreg(DE, lreg(IX)); + break; + case 0x5E: /* LD E,(IX+dd) */ + cycles -= cycleTables[3][0x5E]; + adr = IX + (signed char) GetBYTE_pp(pc); + Setlreg(DE, GetBYTE(adr)); + break; + case 0x60: /* LD IXH,B */ + cycles -= cycleTables[3][0x60]; + Sethreg(IX, hreg(BC)); + break; + case 0x61: /* LD IXH,C */ + cycles -= cycleTables[3][0x61]; + Sethreg(IX, lreg(BC)); + break; + case 0x62: /* LD IXH,D */ + cycles -= cycleTables[3][0x62]; + Sethreg(IX, hreg(DE)); + break; + case 0x63: /* LD IXH,E */ + cycles -= cycleTables[3][0x63]; + Sethreg(IX, lreg(DE)); + break; + case 0x64: /* LD IXH,IXH */ + cycles -= cycleTables[3][0x64]; + /* nop */ + break; + case 0x65: /* LD IXH,IXL */ + cycles -= cycleTables[3][0x65]; + Sethreg(IX, lreg(IX)); + break; + case 0x66: /* LD H,(IX+dd) */ + cycles -= cycleTables[3][0x66]; + adr = IX + (signed char) GetBYTE_pp(pc); + Sethreg(HL, GetBYTE(adr)); + break; + case 0x67: /* LD IXH,A */ + cycles -= cycleTables[3][0x67]; + Sethreg(IX, hreg(AF)); + break; + case 0x68: /* LD IXL,B */ + cycles -= cycleTables[3][0x68]; + Setlreg(IX, hreg(BC)); + break; + case 0x69: /* LD IXL,C */ + cycles -= cycleTables[3][0x69]; + Setlreg(IX, lreg(BC)); + break; + case 0x6A: /* LD IXL,D */ + cycles -= cycleTables[3][0x6A]; + Setlreg(IX, hreg(DE)); + break; + case 0x6B: /* LD IXL,E */ + cycles -= cycleTables[3][0x6B]; + Setlreg(IX, lreg(DE)); + break; + case 0x6C: /* LD IXL,IXH */ + cycles -= cycleTables[3][0x6C]; + Setlreg(IX, hreg(IX)); + break; + case 0x6D: /* LD IXL,IXL */ + cycles -= cycleTables[3][0x6D]; + /* nop */ + break; + case 0x6E: /* LD L,(IX+dd) */ + cycles -= cycleTables[3][0x6E]; + adr = IX + (signed char) GetBYTE_pp(pc); + Setlreg(HL, GetBYTE(adr)); + break; + case 0x6F: /* LD IXL,A */ + cycles -= cycleTables[3][0x6F]; + Setlreg(IX, hreg(AF)); + break; + case 0x70: /* LD (IX+dd),B */ + cycles -= cycleTables[3][0x70]; + adr = IX + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, hreg(BC)); + break; + case 0x71: /* LD (IX+dd),C */ + cycles -= cycleTables[3][0x71]; + adr = IX + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, lreg(BC)); + break; + case 0x72: /* LD (IX+dd),D */ + cycles -= cycleTables[3][0x72]; + adr = IX + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, hreg(DE)); + break; + case 0x73: /* LD (IX+dd),E */ + cycles -= cycleTables[3][0x73]; + adr = IX + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, lreg(DE)); + break; + case 0x74: /* LD (IX+dd),H */ + cycles -= cycleTables[3][0x74]; + adr = IX + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, hreg(HL)); + break; + case 0x75: /* LD (IX+dd),L */ + cycles -= cycleTables[3][0x75]; + adr = IX + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, lreg(HL)); + break; + case 0x77: /* LD (IX+dd),A */ + cycles -= cycleTables[3][0x77]; + adr = IX + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, hreg(AF)); + break; + case 0x7C: /* LD A,IXH */ + cycles -= cycleTables[3][0x7C]; + Sethreg(AF, hreg(IX)); + break; + case 0x7D: /* LD A,IXL */ + cycles -= cycleTables[3][0x7D]; + Sethreg(AF, lreg(IX)); + break; + case 0x7E: /* LD A,(IX+dd) */ + cycles -= cycleTables[3][0x7E]; + adr = IX + (signed char) GetBYTE_pp(pc); + Sethreg(AF, GetBYTE(adr)); + break; + case 0x84: /* ADD A,IXH */ + cycles -= cycleTables[3][0x84]; + 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 */ + cycles -= cycleTables[3][0x85]; + 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) */ + cycles -= cycleTables[3][0x86]; + adr = IX + (signed char) GetBYTE_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 */ + cycles -= cycleTables[3][0x8C]; + 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 */ + cycles -= cycleTables[3][0x8D]; + 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) */ + cycles -= cycleTables[3][0x8E]; + adr = IX + (signed char) GetBYTE_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 */ + cycles -= cycleTables[3][0x94]; + 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 */ + cycles -= cycleTables[3][0x95]; + 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) */ + cycles -= cycleTables[3][0x96]; + adr = IX + (signed char) GetBYTE_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 */ + cycles -= cycleTables[3][0x9C]; + 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 */ + cycles -= cycleTables[3][0x9D]; + 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) */ + cycles -= cycleTables[3][0x9E]; + adr = IX + (signed char) GetBYTE_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 */ + cycles -= cycleTables[3][0xA4]; + sum = ((AF & (IX)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | + ((sum == 0) << 6) | 0x10 | partab[sum]; + break; + case 0xA5: /* AND IXL */ + cycles -= cycleTables[3][0xA5]; + sum = ((AF >> 8) & IX) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | 0x10 | + ((sum == 0) << 6) | partab[sum]; + break; + case 0xA6: /* AND (IX+dd) */ + cycles -= cycleTables[3][0xA6]; + adr = IX + (signed char) GetBYTE_pp(pc); + sum = ((AF >> 8) & GetBYTE(adr)) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | 0x10 | + ((sum == 0) << 6) | partab[sum]; + break; + case 0xAC: /* XOR IXH */ + cycles -= cycleTables[3][0xAC]; + sum = ((AF ^ (IX)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xAD: /* XOR IXL */ + cycles -= cycleTables[3][0xAD]; + sum = ((AF >> 8) ^ IX) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xAE: /* XOR (IX+dd) */ + cycles -= cycleTables[3][0xAE]; + adr = IX + (signed char) GetBYTE_pp(pc); + sum = ((AF >> 8) ^ GetBYTE(adr)) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB4: /* OR IXH */ + cycles -= cycleTables[3][0xB4]; + sum = ((AF | (IX)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB5: /* OR IXL */ + cycles -= cycleTables[3][0xB5]; + sum = ((AF >> 8) | IX) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB6: /* OR (IX+dd) */ + cycles -= cycleTables[3][0xB6]; + adr = IX + (signed char) GetBYTE_pp(pc); + sum = ((AF >> 8) | GetBYTE(adr)) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xBC: /* CP IXH */ + cycles -= cycleTables[3][0xBC]; + 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 */ + cycles -= cycleTables[3][0xBD]; + 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) */ + cycles -= cycleTables[3][0xBE]; + adr = IX + (signed char) GetBYTE_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) GetBYTE_pp(pc); + adr = adr; + op = GetBYTE(pc); + cycles -= cycleTables[4][op]; + switch (op & 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 */ + cycles -= cycleTables[3][0xE1]; + POP(IX); + break; + case 0xE3: /* EX (SP),IX */ + cycles -= cycleTables[3][0xE3]; + temp = IX; POP(IX); PUSH(temp); + break; + case 0xE5: /* PUSH IX */ + cycles -= cycleTables[3][0xE5]; + PUSH(IX); + break; + case 0xE9: /* JP (IX) */ + cycles -= cycleTables[3][0xE9]; + pc = IX; + break; + case 0xF9: /* LD SP,IX */ + cycles -= cycleTables[3][0xF9]; + SP = IX; + break; + default: pc--; /* ignore DD */ + } + break; + case 0xDE: /* SBC A,nn */ + cycles -= cycleTables[0][0xDE]; + temp = GetBYTE_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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + ((cbits >> 8) & 1); + break; + case 0xDF: /* RST 18H */ + cycles -= cycleTables[0][0xDF]; + PUSH(pc); pc = 0x18; + break; + case 0xE0: /* RET PO */ + cycles -= cycleTables[0][0xE0]; + if (!TSTFLAG(P)) POP(pc); + break; + case 0xE1: /* POP HL */ + cycles -= cycleTables[0][0xE1]; + POP(HL); + break; + case 0xE2: /* JP PO,nnnn */ + cycles -= cycleTables[0][0xE2]; + Jpc(!TSTFLAG(P)); + break; + case 0xE3: /* EX (SP),HL */ + cycles -= cycleTables[0][0xE3]; + temp = HL; POP(HL); PUSH(temp); + break; + case 0xE4: /* CALL PO,nnnn */ + cycles -= cycleTables[0][0xE4]; + CALLC(!TSTFLAG(P)); + break; + case 0xE5: /* PUSH HL */ + cycles -= cycleTables[0][0xE5]; + PUSH(HL); + break; + case 0xE6: /* AND nn */ + cycles -= cycleTables[0][0xE6]; + sum = ((AF >> 8) & GetBYTE_pp(pc)) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | 0x10 | + ((sum == 0) << 6) | partab[sum]; + break; + case 0xE7: /* RST 20H */ + cycles -= cycleTables[0][0xE7]; + PUSH(pc); pc = 0x20; + break; + case 0xE8: /* RET PE */ + cycles -= cycleTables[0][0xE8]; + if (TSTFLAG(P)) POP(pc); + break; + case 0xE9: /* JP (HL) */ + cycles -= cycleTables[0][0xE9]; + pc = HL; + break; + case 0xEA: /* JP PE,nnnn */ + cycles -= cycleTables[0][0xEA]; + Jpc(TSTFLAG(P)); + break; + case 0xEB: /* EX DE,HL */ + cycles -= cycleTables[0][0xEB]; + temp = HL; HL = DE; DE = temp; + break; + case 0xEC: /* CALL PE,nnnn */ + cycles -= cycleTables[0][0xEC]; + CALLC(TSTFLAG(P)); + break; + case 0xED: /* ED prefix */ + op = GetBYTE_pp(pc); + switch (op) { + case 0x40: /* IN B,(C) */ + cycles -= cycleTables[2][0x40]; + temp = INPUT(lreg(BC)); + Sethreg(BC, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + parity(temp); + break; + case 0x41: /* OUT (C),B */ + cycles -= cycleTables[2][0x41]; + OUTPUT(lreg(BC), BC); + break; + case 0x42: /* SBC HL,BC */ + cycles -= cycleTables[2][0x42]; + 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 */ + cycles -= cycleTables[2][0x43]; + temp = GetWORD(pc); + PutWORD(temp, BC); + pc += 2; + break; + case 0x44: /* NEG */ + cycles -= cycleTables[2][0x44]; + 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 */ + cycles -= cycleTables[2][0x45]; + iff |= iff >> 1; + POP(pc); + break; + case 0x46: /* IM 0 */ + cycles -= cycleTables[2][0x46]; + im = 0; // interrupt mode 0 + break; + case 0x47: /* LD I,A */ + cycles -= cycleTables[2][0x47]; + ir = (ir & 255) | (AF & ~255); + break; + case 0x48: /* IN C,(C) */ + cycles -= cycleTables[2][0x48]; + temp = INPUT(lreg(BC)); + Setlreg(BC, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + parity(temp); + break; + case 0x49: /* OUT (C),C */ + cycles -= cycleTables[2][0x49]; + OUTPUT(lreg(BC), BC); + break; + case 0x4A: /* ADC HL,BC */ + cycles -= cycleTables[2][0x4A]; + 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) */ + cycles -= cycleTables[2][0x4B]; + temp = GetWORD(pc); + BC = GetWORD(temp); + pc += 2; + break; + case 0x4D: /* RETI */ + cycles -= cycleTables[2][0x4D]; + iff |= iff >> 1; + POP(pc); + break; + case 0x4F: /* LD R,A */ + cycles -= cycleTables[2][0x4F]; + ir = (ir & ~255) | ((AF >> 8) & 255); + break; + case 0x50: /* IN D,(C) */ + cycles -= cycleTables[2][0x50]; + temp = INPUT(lreg(BC)); + Sethreg(DE, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + parity(temp); + break; + case 0x51: /* OUT (C),D */ + cycles -= cycleTables[2][0x51]; + OUTPUT(lreg(BC), DE); + break; + case 0x52: /* SBC HL,DE */ + cycles -= cycleTables[2][0x52]; + 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 */ + cycles -= cycleTables[2][0x53]; + temp = GetWORD(pc); + PutWORD(temp, DE); + pc += 2; + break; + case 0x56: /* IM 1 */ + cycles -= cycleTables[2][0x56]; + im = 1; // interrupt mode 1 + break; + case 0x57: /* LD A,I */ + cycles -= cycleTables[2][0x57]; + AF = (AF & 0x29) | (ir & ~255) | ((ir >> 8) & 0x80) | (((ir & ~255) == 0) << 6) | ((iff & 2) << 1); + break; + case 0x58: /* IN E,(C) */ + cycles -= cycleTables[2][0x58]; + temp = INPUT(lreg(BC)); + Setlreg(DE, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + parity(temp); + break; + case 0x59: /* OUT (C),E */ + cycles -= cycleTables[2][0x59]; + OUTPUT(lreg(BC), DE); + break; + case 0x5A: /* ADC HL,DE */ + cycles -= cycleTables[2][0x5A]; + 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) */ + cycles -= cycleTables[2][0x5B]; + temp = GetWORD(pc); + DE = GetWORD(temp); + pc += 2; + break; + case 0x5E: /* IM 2 */ + cycles -= cycleTables[2][0x5E]; + im = 2; // interrupt mode 2 + break; + case 0x5F: /* LD A,R */ + cycles -= cycleTables[2][0x5F]; + AF = (AF & 0x29) | ((ir & 255) << 8) | (ir & 0x80) | (((ir & 255) == 0) << 6) | ((iff & 2) << 1); + break; + case 0x60: /* IN H,(C) */ + cycles -= cycleTables[2][0x60]; + temp = INPUT(lreg(BC)); + Sethreg(HL, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + parity(temp); + break; + case 0x61: /* OUT (C),H */ + cycles -= cycleTables[2][0x61]; + OUTPUT(lreg(BC), HL); + break; + case 0x62: /* SBC HL,HL */ + cycles -= cycleTables[2][0x62]; + 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 */ + cycles -= cycleTables[2][0x63]; + temp = GetWORD(pc); + PutWORD(temp, HL); + pc += 2; + break; + case 0x67: /* RRD */ + cycles -= cycleTables[2][0x67]; + 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) */ + cycles -= cycleTables[2][0x68]; + temp = INPUT(lreg(BC)); + Setlreg(HL, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + parity(temp); + break; + case 0x69: /* OUT (C),L */ + cycles -= cycleTables[2][0x69]; + OUTPUT(lreg(BC), HL); + break; + case 0x6A: /* ADC HL,HL */ + cycles -= cycleTables[2][0x6A]; + 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) */ + cycles -= cycleTables[2][0x6B]; + temp = GetWORD(pc); + HL = GetWORD(temp); + pc += 2; + break; + case 0x6F: /* RLD */ + cycles -= cycleTables[2][0x6F]; + 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) */ + cycles -= cycleTables[2][0x70]; + temp = INPUT(lreg(BC)); + Setlreg(temp, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + parity(temp); + break; + case 0x71: /* OUT (C),0 */ + cycles -= cycleTables[2][0x71]; + OUTPUT(lreg(BC), 0); + break; + case 0x72: /* SBC HL,SP */ + cycles -= cycleTables[2][0x72]; + 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 */ + cycles -= cycleTables[2][0x73]; + temp = GetWORD(pc); + PutWORD(temp, SP); + pc += 2; + break; + case 0x78: /* IN A,(C) */ + cycles -= cycleTables[2][0x78]; + temp = INPUT(lreg(BC)); + Sethreg(AF, temp); + AF = (AF & ~0xfe) | (temp & 0xa8) | + (((temp & 0xff) == 0) << 6) | + parity(temp); + break; + case 0x79: /* OUT (C),A */ + cycles -= cycleTables[2][0x79]; + OUTPUT(lreg(BC), AF); + break; + case 0x7A: /* ADC HL,SP */ + cycles -= cycleTables[2][0x7A]; + 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) */ + cycles -= cycleTables[2][0x7B]; + temp = GetWORD(pc); + SP = GetWORD(temp); + pc += 2; + break; + case 0xA0: /* LDI */ + cycles -= cycleTables[2][0xA0]; + acu = GetBYTE_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 */ + cycles -= cycleTables[2][0xA1]; + acu = hreg(AF); + temp = GetBYTE_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 */ + cycles -= cycleTables[2][0xA2]; + PutBYTE(HL, INPUT(lreg(BC))); ++HL; + SETFLAG(N, 1); + SETFLAG(P, (--BC & 0xffff) != 0); + break; + case 0xA3: /* OUTI */ + cycles -= cycleTables[2][0xA3]; + OUTPUT(lreg(BC), GetBYTE(HL)); ++HL; + SETFLAG(N, 1); + Sethreg(BC, hreg(BC) - 1); + SETFLAG(Z, hreg(BC) == 0); + break; + case 0xA8: /* LDD */ + cycles -= cycleTables[2][0xA8]; + acu = GetBYTE_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 */ + cycles -= cycleTables[2][0xA9]; + acu = hreg(AF); + temp = GetBYTE_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 */ + cycles -= cycleTables[2][0xAA]; + PutBYTE(HL, INPUT(lreg(BC))); --HL; + SETFLAG(N, 1); + Sethreg(BC, lreg(BC) - 1); + SETFLAG(Z, lreg(BC) == 0); + break; + case 0xAB: /* OUTD */ + cycles -= cycleTables[2][0xAB]; + OUTPUT(lreg(BC), GetBYTE(HL)); --HL; + SETFLAG(N, 1); + Sethreg(BC, hreg(BC) - 1); + SETFLAG(Z, hreg(BC) == 0); + break; + case 0xB0: /* LDIR */ + cycles -= cycleTables[2][0xB0]; + acu = hreg(AF); + BC &= 0xffff; + do { + acu = GetBYTE_pp(HL); + PutBYTE_pp(DE, acu); + } while (--BC); + acu += hreg(AF); + AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4); + break; + case 0xB1: /* CPIR */ + cycles -= cycleTables[2][0xB1]; + acu = hreg(AF); + BC &= 0xffff; + do { + temp = GetBYTE_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 */ + cycles -= cycleTables[2][0xB2]; + temp = hreg(BC); + do { + PutBYTE(HL, INPUT(lreg(BC))); ++HL; + } while (--temp); + Sethreg(BC, 0); + SETFLAG(N, 1); + SETFLAG(Z, 1); + break; + case 0xB3: /* OTIR */ + cycles -= cycleTables[2][0xB3]; + temp = hreg(BC); + do { + OUTPUT(lreg(BC), GetBYTE(HL)); ++HL; + } while (--temp); + Sethreg(BC, 0); + SETFLAG(N, 1); + SETFLAG(Z, 1); + break; + case 0xB8: /* LDDR */ + cycles -= cycleTables[2][0xB8]; + BC &= 0xffff; + do { + acu = GetBYTE_mm(HL); + PutBYTE_mm(DE, acu); + } while (--BC); + acu += hreg(AF); + AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4); + break; + case 0xB9: /* CPDR */ + cycles -= cycleTables[2][0xB9]; + acu = hreg(AF); + BC &= 0xffff; + do { + temp = GetBYTE_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 */ + cycles -= cycleTables[2][0xBA]; + temp = hreg(BC); + do { + PutBYTE(HL, INPUT(lreg(BC))); --HL; + } while (--temp); + Sethreg(BC, 0); + SETFLAG(N, 1); + SETFLAG(Z, 1); + break; + case 0xBB: /* OTDR */ + cycles -= cycleTables[2][0xBB]; + temp = hreg(BC); + do { + OUTPUT(lreg(BC), GetBYTE(HL)); --HL; + } while (--temp); + Sethreg(BC, 0); + SETFLAG(N, 1); + SETFLAG(Z, 1); + break; + default: if (0x40 <= op && op <= 0x7f) pc--; /* ignore ED */ + } + break; + case 0xEE: /* XOR nn */ + cycles -= cycleTables[0][0xEE]; + sum = ((AF >> 8) ^ GetBYTE_pp(pc)) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xEF: /* RST 28H */ + cycles -= cycleTables[0][0xEF]; + PUSH(pc); pc = 0x28; + break; + case 0xF0: /* RET P */ + cycles -= cycleTables[0][0xF0]; + if (!TSTFLAG(S)) POP(pc); + break; + case 0xF1: /* POP AF */ + cycles -= cycleTables[0][0xF1]; + POP(AF); + break; + case 0xF2: /* JP P,nnnn */ + cycles -= cycleTables[0][0xF2]; + Jpc(!TSTFLAG(S)); + break; + case 0xF3: /* DI */ + cycles -= cycleTables[0][0xF3]; + iff = 0; + break; + case 0xF4: /* CALL P,nnnn */ + cycles -= cycleTables[0][0xF4]; + CALLC(!TSTFLAG(S)); + break; + case 0xF5: /* PUSH AF */ + cycles -= cycleTables[0][0xF5]; + PUSH(AF); + break; + case 0xF6: /* OR nn */ + cycles -= cycleTables[0][0xF6]; + sum = ((AF >> 8) | GetBYTE_pp(pc)) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xF7: /* RST 30H */ + cycles -= cycleTables[0][0xF7]; + PUSH(pc); pc = 0x30; + break; + case 0xF8: /* RET M */ + cycles -= cycleTables[0][0xF8]; + if (TSTFLAG(S)) POP(pc); + break; + case 0xF9: /* LD SP,HL */ + cycles -= cycleTables[0][0xF9]; + SP = HL; + break; + case 0xFA: /* JP M,nnnn */ + cycles -= cycleTables[0][0xFA]; + Jpc(TSTFLAG(S)); + break; + case 0xFB: /* EI */ + cycles -= cycleTables[0][0xFB]; + iff = 3; + break; + case 0xFC: /* CALL M,nnnn */ + cycles -= cycleTables[0][0xFC]; + CALLC(TSTFLAG(S)); + break; + case 0xFD: /* FD prefix */ + op = GetBYTE_pp(pc); + switch (op) { + case 0x09: /* ADD IY,BC */ + cycles -= cycleTables[3][0x09]; + 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 */ + cycles -= cycleTables[3][0x19]; + 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 */ + cycles -= cycleTables[3][0x21]; + IY = GetWORD(pc); + pc += 2; + break; + case 0x22: /* LD (nnnn),IY */ + cycles -= cycleTables[3][0x22]; + temp = GetWORD(pc); + PutWORD(temp, IY); + pc += 2; + break; + case 0x23: /* INC IY */ + cycles -= cycleTables[3][0x23]; + ++IY; + break; + case 0x24: /* INC IYH */ + cycles -= cycleTables[3][0x24]; + 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 */ + cycles -= cycleTables[3][0x25]; + 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 */ + cycles -= cycleTables[3][0x26]; + Sethreg(IY, GetBYTE_pp(pc)); + break; + case 0x29: /* ADD IY,IY */ + cycles -= cycleTables[3][0x29]; + 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) */ + cycles -= cycleTables[3][0x2A]; + temp = GetWORD(pc); + IY = GetWORD(temp); + pc += 2; + break; + case 0x2B: /* DEC IY */ + cycles -= cycleTables[3][0x2B]; + --IY; + break; + case 0x2C: /* INC IYL */ + cycles -= cycleTables[3][0x2C]; + 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 */ + cycles -= cycleTables[3][0x2D]; + 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 */ + cycles -= cycleTables[3][0x2E]; + Setlreg(IY, GetBYTE_pp(pc)); + break; + case 0x34: /* INC (IY+dd) */ + cycles -= cycleTables[3][0x34]; + adr = IY + (signed char) GetBYTE_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) */ + cycles -= cycleTables[3][0x35]; + adr = IY + (signed char) GetBYTE_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 */ + cycles -= cycleTables[3][0x36]; + adr = IY + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, GetBYTE_pp(pc)); + break; + case 0x39: /* ADD IY,SP */ + cycles -= cycleTables[3][0x39]; + 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 */ + cycles -= cycleTables[3][0x44]; + Sethreg(BC, hreg(IY)); + break; + case 0x45: /* LD B,IYL */ + cycles -= cycleTables[3][0x45]; + Sethreg(BC, lreg(IY)); + break; + case 0x46: /* LD B,(IY+dd) */ + cycles -= cycleTables[3][0x46]; + adr = IY + (signed char) GetBYTE_pp(pc); + Sethreg(BC, GetBYTE(adr)); + break; + case 0x4C: /* LD C,IYH */ + cycles -= cycleTables[3][0x4C]; + Setlreg(BC, hreg(IY)); + break; + case 0x4D: /* LD C,IYL */ + cycles -= cycleTables[3][0x4D]; + Setlreg(BC, lreg(IY)); + break; + case 0x4E: /* LD C,(IY+dd) */ + cycles -= cycleTables[3][0x4E]; + adr = IY + (signed char) GetBYTE_pp(pc); + Setlreg(BC, GetBYTE(adr)); + break; + case 0x54: /* LD D,IYH */ + cycles -= cycleTables[3][0x54]; + Sethreg(DE, hreg(IY)); + break; + case 0x55: /* LD D,IYL */ + cycles -= cycleTables[3][0x55]; + Sethreg(DE, lreg(IY)); + break; + case 0x56: /* LD D,(IY+dd) */ + cycles -= cycleTables[3][0x56]; + adr = IY + (signed char) GetBYTE_pp(pc); + Sethreg(DE, GetBYTE(adr)); + break; + case 0x5C: /* LD E,H */ + cycles -= cycleTables[3][0x5C]; + Setlreg(DE, hreg(IY)); + break; + case 0x5D: /* LD E,L */ + cycles -= cycleTables[3][0x5D]; + Setlreg(DE, lreg(IY)); + break; + case 0x5E: /* LD E,(IY+dd) */ + cycles -= cycleTables[3][0x5E]; + adr = IY + (signed char) GetBYTE_pp(pc); + Setlreg(DE, GetBYTE(adr)); + break; + case 0x60: /* LD IYH,B */ + cycles -= cycleTables[3][0x60]; + Sethreg(IY, hreg(BC)); + break; + case 0x61: /* LD IYH,C */ + cycles -= cycleTables[3][0x61]; + Sethreg(IY, lreg(BC)); + break; + case 0x62: /* LD IYH,D */ + cycles -= cycleTables[3][0x62]; + Sethreg(IY, hreg(DE)); + break; + case 0x63: /* LD IYH,E */ + cycles -= cycleTables[3][0x63]; + Sethreg(IY, lreg(DE)); + break; + case 0x64: /* LD IYH,IYH */ + cycles -= cycleTables[3][0x64]; + /* nop */ + break; + case 0x65: /* LD IYH,IYL */ + cycles -= cycleTables[3][0x65]; + Sethreg(IY, lreg(IY)); + break; + case 0x66: /* LD H,(IY+dd) */ + cycles -= cycleTables[3][0x66]; + adr = IY + (signed char) GetBYTE_pp(pc); + Sethreg(HL, GetBYTE(adr)); + break; + case 0x67: /* LD IYH,A */ + cycles -= cycleTables[3][0x67]; + Sethreg(IY, hreg(AF)); + break; + case 0x68: /* LD IYL,B */ + cycles -= cycleTables[3][0x68]; + Setlreg(IY, hreg(BC)); + break; + case 0x69: /* LD IYL,C */ + cycles -= cycleTables[3][0x69]; + Setlreg(IY, lreg(BC)); + break; + case 0x6A: /* LD IYL,D */ + cycles -= cycleTables[3][0x6A]; + Setlreg(IY, hreg(DE)); + break; + case 0x6B: /* LD IYL,E */ + cycles -= cycleTables[3][0x6B]; + Setlreg(IY, lreg(DE)); + break; + case 0x6C: /* LD IYL,IYH */ + cycles -= cycleTables[3][0x6C]; + Setlreg(IY, hreg(IY)); + break; + case 0x6D: /* LD IYL,IYL */ + cycles -= cycleTables[3][0x6D]; + /* nop */ + break; + case 0x6E: /* LD L,(IY+dd) */ + cycles -= cycleTables[3][0x6E]; + adr = IY + (signed char) GetBYTE_pp(pc); + Setlreg(HL, GetBYTE(adr)); + break; + case 0x6F: /* LD IYL,A */ + cycles -= cycleTables[3][0x6F]; + Setlreg(IY, hreg(AF)); + break; + case 0x70: /* LD (IY+dd),B */ + cycles -= cycleTables[3][0x70]; + adr = IY + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, hreg(BC)); + break; + case 0x71: /* LD (IY+dd),C */ + cycles -= cycleTables[3][0x71]; + adr = IY + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, lreg(BC)); + break; + case 0x72: /* LD (IY+dd),D */ + cycles -= cycleTables[3][0x72]; + adr = IY + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, hreg(DE)); + break; + case 0x73: /* LD (IY+dd),E */ + cycles -= cycleTables[3][0x73]; + adr = IY + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, lreg(DE)); + break; + case 0x74: /* LD (IY+dd),H */ + cycles -= cycleTables[3][0x74]; + adr = IY + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, hreg(HL)); + break; + case 0x75: /* LD (IY+dd),L */ + cycles -= cycleTables[3][0x75]; + adr = IY + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, lreg(HL)); + break; + case 0x77: /* LD (IY+dd),A */ + cycles -= cycleTables[3][0x77]; + adr = IY + (signed char) GetBYTE_pp(pc); + PutBYTE(adr, hreg(AF)); + break; + case 0x7C: /* LD A,IYH */ + cycles -= cycleTables[3][0x7C]; + Sethreg(AF, hreg(IY)); + break; + case 0x7D: /* LD A,IYL */ + cycles -= cycleTables[3][0x7D]; + Sethreg(AF, lreg(IY)); + break; + case 0x7E: /* LD A,(IY+dd) */ + cycles -= cycleTables[3][0x7E]; + adr = IY + (signed char) GetBYTE_pp(pc); + Sethreg(AF, GetBYTE(adr)); + break; + case 0x84: /* ADD A,IYH */ + cycles -= cycleTables[3][0x84]; + 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 */ + cycles -= cycleTables[3][0x85]; + 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) */ + cycles -= cycleTables[3][0x86]; + adr = IY + (signed char) GetBYTE_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 */ + cycles -= cycleTables[3][0x8C]; + 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 */ + cycles -= cycleTables[3][0x8D]; + 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) */ + cycles -= cycleTables[3][0x8E]; + adr = IY + (signed char) GetBYTE_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 */ + cycles -= cycleTables[3][0x94]; + 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 */ + cycles -= cycleTables[3][0x95]; + 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) */ + cycles -= cycleTables[3][0x96]; + adr = IY + (signed char) GetBYTE_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 */ + cycles -= cycleTables[3][0x9C]; + 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 */ + cycles -= cycleTables[3][0x9D]; + 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) */ + cycles -= cycleTables[3][0x9E]; + adr = IY + (signed char) GetBYTE_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 */ + cycles -= cycleTables[3][0xA4]; + sum = ((AF & (IY)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | + ((sum == 0) << 6) | 0x10 | partab[sum]; + break; + case 0xA5: /* AND IYL */ + cycles -= cycleTables[3][0xA5]; + sum = ((AF >> 8) & IY) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | 0x10 | + ((sum == 0) << 6) | partab[sum]; + break; + case 0xA6: /* AND (IY+dd) */ + cycles -= cycleTables[3][0xA6]; + adr = IY + (signed char) GetBYTE_pp(pc); + sum = ((AF >> 8) & GetBYTE(adr)) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | 0x10 | + ((sum == 0) << 6) | partab[sum]; + break; + case 0xAC: /* XOR IYH */ + cycles -= cycleTables[3][0xAC]; + sum = ((AF ^ (IY)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xAD: /* XOR IYL */ + cycles -= cycleTables[3][0xAD]; + sum = ((AF >> 8) ^ IY) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xAE: /* XOR (IY+dd) */ + cycles -= cycleTables[3][0xAE]; + adr = IY + (signed char) GetBYTE_pp(pc); + sum = ((AF >> 8) ^ GetBYTE(adr)) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB4: /* OR IYH */ + cycles -= cycleTables[3][0xB4]; + sum = ((AF | (IY)) >> 8) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB5: /* OR IYL */ + cycles -= cycleTables[3][0xB5]; + sum = ((AF >> 8) | IY) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xB6: /* OR (IY+dd) */ + cycles -= cycleTables[3][0xB6]; + adr = IY + (signed char) GetBYTE_pp(pc); + sum = ((AF >> 8) | GetBYTE(adr)) & 0xff; + AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + break; + case 0xBC: /* CP IYH */ + cycles -= cycleTables[3][0xBC]; + 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 */ + cycles -= cycleTables[3][0xBD]; + 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) */ + cycles -= cycleTables[3][0xBE]; + adr = IY + (signed char) GetBYTE_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) GetBYTE_pp(pc); + adr = adr; + op = GetBYTE(pc); + cycles -= cycleTables[4][op]; + switch (op & 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 */ + cycles -= cycleTables[3][0xE1]; + POP(IY); + break; + case 0xE3: /* EX (SP),IY */ + cycles -= cycleTables[3][0xE3]; + temp = IY; POP(IY); PUSH(temp); + break; + case 0xE5: /* PUSH IY */ + cycles -= cycleTables[3][0xE5]; + PUSH(IY); + break; + case 0xE9: /* JP (IY) */ + cycles -= cycleTables[3][0xE9]; + pc = IY; + break; + case 0xF9: /* LD SP,IY */ + cycles -= cycleTables[3][0xF9]; + SP = IY; + break; + default: pc--; /* ignore DD */ + } + break; + case 0xFE: /* CP nn */ + cycles -= cycleTables[0][0xFE]; + temp = GetBYTE_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) | + (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | + (cbits & 0x10) | ((cbits >> 8) & 1); + break; + case 0xFF: /* RST 38H */ + cycles -= cycleTables[0][0xFF]; + PUSH(pc); pc = 0x38; + break; } - // Interrupts + // Interrupts - if (nmiTrigger) // NMI triggered (higher priority than INT) - { - /* - * NMI sequence: - * - * - Push pc on stack - * - Set pc to NMI vector (0x0066) - * - Copy IFF1 to IFF2 (save interrupt enable status) - * - Clear IFF1 (disable interrupts) - * - Un-halt CPU (if in HALT state) - */ + if (nmiTrigger) // NMI triggered (higher priority than INT) + { + /* + * NMI sequence: + * + * - Push pc on stack + * - Set pc to NMI vector (0x0066) + * - Copy IFF1 to IFF2 (save interrupt enable status) + * - Clear IFF1 (disable interrupts) + * - Un-halt CPU (if in HALT state) + */ #ifdef SUPERMODEL_DEBUGGER - if (Debug != NULL) - Debug->CPUException(Z80_EX_NMI); + if (Debug != NULL) + Debug->CPUException(Z80_EX_NMI); #endif // SUPERMODEL_DEBUGGER - PUSH(pc); - pc = 0x0066; - iff = (iff&~2) | ((iff&1)<<1); - iff &= ~1; - nmiTrigger = false; // clear NMI - // TODO: if in HALTed state, un-halt + PUSH(pc); + pc = 0x0066; + iff = (iff&~2) | ((iff&1)<<1); + iff &= ~1; + nmiTrigger = false; // clear NMI + // TODO: if in HALTed state, un-halt } - else if (intLine) // INT asserted + else if (intLine) // INT asserted { - // If interrupts are enabled (IFF1 != 0) - if ((iff&1)) - { - int v; - - /* - * INT sequence: - * - * - Disable interrupts (clear IFF1 and IFF2) - * - Push pc on stack - * - Un-halt CPU (if in HALT state) - * - Set pc to vector (which depends on mode) - * - * If no callback is provided when required, nothing happens and - * the interrupt line is cleared. Otherwise, callbacks are - * responsible for clearing the lines themselves. - */ - // TODO: if in HALTed state, un-halt - switch (im) // interrupt mode (0, 1, or 2 only!) - { - case 0: - /* - * Mode 0: - * - * Fetches up 3 bytes from bus and executes them directly. - * Usually, this will just be an RST instruction, so this is - * all that we accept here. - */ - if (NULL != INTCallback) - { - v = INTCallback(this); + // If interrupts are enabled (IFF1 != 0) + if ((iff&1)) + { + int v; + + /* + * INT sequence: + * + * - Disable interrupts (clear IFF1 and IFF2) + * - Push pc on stack + * - Un-halt CPU (if in HALT state) + * - Set pc to vector (which depends on mode) + * + * If no callback is provided when required, nothing happens and + * the interrupt line is cleared. Otherwise, callbacks are + * responsible for clearing the lines themselves. + */ + // TODO: if in HALTed state, un-halt + switch (im) // interrupt mode (0, 1, or 2 only!) + { + case 0: + /* + * Mode 0: + * + * Fetches up 3 bytes from bus and executes them directly. + * Usually, this will just be an RST instruction, so this is + * all that we accept here. + */ + if (NULL != INTCallback) + { + v = INTCallback(this); #ifdef SUPERMODEL_DEBUGGER - if (Debug != NULL) - Debug->CPUException(v); + if (Debug != NULL) + Debug->CPUException(v); #endif // SUPERMODEL_DEBUGGER - switch (v) - { - case Z80_INT_RST_00: v = 0x0000; break; - case Z80_INT_RST_08: v = 0x0008; break; - case Z80_INT_RST_10: v = 0x0010; break; - case Z80_INT_RST_18: v = 0x0018; break; - case Z80_INT_RST_20: v = 0x0020; break; - case Z80_INT_RST_28: v = 0x0028; break; - case Z80_INT_RST_30: v = 0x0030; break; - case Z80_INT_RST_38: v = 0x0038; break; - default: v = -1; break; // invalid, do nothing - } - - if (v >= 0) // valid vector - { - PUSH(pc); - pc = (UINT16) v; - iff = 0; - } - } - else // if no callback, do nothing, clear INT line - intLine = false; - break; - case 1: - /* - * Mode 1: - * - * Vector is 0x0038. - */ + switch (v) + { + case Z80_INT_RST_00: v = 0x0000; break; + case Z80_INT_RST_08: v = 0x0008; break; + case Z80_INT_RST_10: v = 0x0010; break; + case Z80_INT_RST_18: v = 0x0018; break; + case Z80_INT_RST_20: v = 0x0020; break; + case Z80_INT_RST_28: v = 0x0028; break; + case Z80_INT_RST_30: v = 0x0030; break; + case Z80_INT_RST_38: v = 0x0038; break; + default: v = -1; break; // invalid, do nothing + } + + if (v >= 0) // valid vector + { + PUSH(pc); + pc = (UINT16) v; + iff = 0; + } + } + else // if no callback, do nothing, clear INT line + intLine = false; + break; + case 1: + /* + * Mode 1: + * + * Vector is 0x0038. + */ #ifdef SUPERMODEL_DEBUGGER - if (Debug != NULL) - Debug->CPUException(Z80_IM1_IRQ); + if (Debug != NULL) + Debug->CPUException(Z80_IM1_IRQ); #endif // SUPERMODEL_DEBUGGER - PUSH(pc); - pc = 0x0038; - iff = 0; - if (NULL != INTCallback) - INTCallback(this); - else // no callback, clear INT line automatically - intLine = false; - break; - case 2: - /* - * Mode 2: - * - * A 16-bit address is formed by concatenating the I register - * and 8 bits read from the bus (with bit 0 cleared). The final - * 16-bit vector is read from this address. - */ + PUSH(pc); + pc = 0x0038; + iff = 0; + if (NULL != INTCallback) + INTCallback(this); + else // no callback, clear INT line automatically + intLine = false; + break; + case 2: + /* + * Mode 2: + * + * A 16-bit address is formed by concatenating the I register + * and 8 bits read from the bus (with bit 0 cleared). The final + * 16-bit vector is read from this address. + */ #ifdef SUPERMODEL_DEBUGGER - if (Debug != NULL) - Debug->CPUException(Z80_IM2_VECTOR); + if (Debug != NULL) + Debug->CPUException(Z80_IM2_VECTOR); #endif // SUPERMODEL_DEBUGGER - if (NULL != INTCallback) - { - v = INTCallback(this); - v = (ir&0xFF00) | (v&0xFE); - PUSH(pc); - pc = GetWORD(v); - iff = 0; - } - else // if no callback, do nothing, clear INT line - intLine = false; - break; - default: // should never happen (nothing will be done) - intLine = false; - break; - } - } + if (NULL != INTCallback) + { + v = INTCallback(this); + v = (ir&0xFF00) | (v&0xFE); + PUSH(pc); + pc = GetWORD(v); + iff = 0; + } + else // if no callback, do nothing, clear INT line + intLine = false; + break; + default: // should never happen (nothing will be done) + intLine = false; + break; + } + } } - } // end while + } // end while - // write registers back to context -HALTExit: + // write registers back to context +HALTExit: #ifdef SUPERMODEL_DEBUGGER - if (Debug != NULL) - { - Debug->CPUInactive(); - lastCycles -= cycles; - } + if (Debug != NULL) + { + Debug->CPUInactive(); + lastCycles -= cycles; + } #else - // Save local copies of Z80 registers back to context - af[af_sel] = AF; + // Save local copies of Z80 registers back to context + af[af_sel] = AF; regs[regs_sel].bc = BC; regs[regs_sel].de = DE; regs[regs_sel].hl = HL; @@ -3783,229 +3787,229 @@ HALTExit: sp = SP; #endif // SUPERMODEL_DEBUGGER - // Return number of cycles actually executed + // Return number of cycles actually executed return numCycles - cycles; } void CZ80::TriggerNMI(void) { - nmiTrigger = true; + nmiTrigger = true; } void CZ80::SetINT(bool state) { - intLine = state; + intLine = state; } UINT16 CZ80::GetPC(void) { - return pc; + return pc; } #ifdef SUPERMODEL_DEBUGGER UINT8 CZ80::GetReg8(unsigned reg8) { - switch (reg8) - { - case Z80_REG8_IFF: return iff; - case Z80_REG8_IM: return im; - case Z80_REG8_I: return ir>>8; - case Z80_REG8_R: return ir&0xFF; - case Z80_REG8_A: return af[0]>>8; - case Z80_REG8_F: return af[0]&0xFF; - case Z80_REG8_B: return regs[0].bc>>8; - case Z80_REG8_C: return regs[0].bc&0xFF; - case Z80_REG8_D: return regs[0].de>>8; - case Z80_REG8_E: return regs[0].de&0xFF; - case Z80_REG8_H: return regs[0].hl>>8; - case Z80_REG8_L: return regs[0].hl&0xFF; - default: return 0; - } + switch (reg8) + { + case Z80_REG8_IFF: return iff; + case Z80_REG8_IM: return im; + case Z80_REG8_I: return ir>>8; + case Z80_REG8_R: return ir&0xFF; + case Z80_REG8_A: return af[0]>>8; + case Z80_REG8_F: return af[0]&0xFF; + case Z80_REG8_B: return regs[0].bc>>8; + case Z80_REG8_C: return regs[0].bc&0xFF; + case Z80_REG8_D: return regs[0].de>>8; + case Z80_REG8_E: return regs[0].de&0xFF; + case Z80_REG8_H: return regs[0].hl>>8; + case Z80_REG8_L: return regs[0].hl&0xFF; + default: return 0; + } } bool CZ80::SetReg8(unsigned reg8, UINT8 value) { - switch (reg8) - { - case Z80_REG8_IFF: iff = value; return true; - case Z80_REG8_IM: im = value; return true; - case Z80_REG8_I: ir |= value<<8; return true; - case Z80_REG8_R: ir |= value; return true; - case Z80_REG8_A: af[0] |= value<<8; return true; - case Z80_REG8_F: af[0] |= value; return true; - case Z80_REG8_B: regs[0].bc |= value<<8; return true; - case Z80_REG8_C: regs[0].bc |= value; return true; - case Z80_REG8_D: regs[0].de |= value<<8; return true; - case Z80_REG8_E: regs[0].de |= value; return true; - case Z80_REG8_H: regs[0].hl |= value<<8; return true; - case Z80_REG8_L: regs[0].hl |= value; return true; - default: return false; - } + switch (reg8) + { + case Z80_REG8_IFF: iff = value; return true; + case Z80_REG8_IM: im = value; return true; + case Z80_REG8_I: ir |= value<<8; return true; + case Z80_REG8_R: ir |= value; return true; + case Z80_REG8_A: af[0] |= value<<8; return true; + case Z80_REG8_F: af[0] |= value; return true; + case Z80_REG8_B: regs[0].bc |= value<<8; return true; + case Z80_REG8_C: regs[0].bc |= value; return true; + case Z80_REG8_D: regs[0].de |= value<<8; return true; + case Z80_REG8_E: regs[0].de |= value; return true; + case Z80_REG8_H: regs[0].hl |= value<<8; return true; + case Z80_REG8_L: regs[0].hl |= value; return true; + default: return false; + } } UINT16 CZ80::GetReg16(unsigned reg16) { - switch (reg16) - { - case Z80_REG16_SP: return sp; - case Z80_REG16_PC: return pc; - case Z80_REG16_IR: return ir; - case Z80_REG16_AF: return af[0]; - case Z80_REG16_BC: return regs[0].bc; - case Z80_REG16_DE: return regs[0].de; - case Z80_REG16_HL: return regs[0].hl; - case Z80_REG16_IX: return ix; - case Z80_REG16_IY: return iy; - case Z80_REG16_AF_: return af[1]; - case Z80_REG16_BC_: return regs[1].bc; - case Z80_REG16_DE_: return regs[1].de; - case Z80_REG16_HL_: return regs[1].hl; - default: return 0; - } + switch (reg16) + { + case Z80_REG16_SP: return sp; + case Z80_REG16_PC: return pc; + case Z80_REG16_IR: return ir; + case Z80_REG16_AF: return af[0]; + case Z80_REG16_BC: return regs[0].bc; + case Z80_REG16_DE: return regs[0].de; + case Z80_REG16_HL: return regs[0].hl; + case Z80_REG16_IX: return ix; + case Z80_REG16_IY: return iy; + case Z80_REG16_AF_: return af[1]; + case Z80_REG16_BC_: return regs[1].bc; + case Z80_REG16_DE_: return regs[1].de; + case Z80_REG16_HL_: return regs[1].hl; + default: return 0; + } } bool CZ80::SetReg16(unsigned reg16, UINT16 value) { - switch (reg16) - { - case Z80_REG16_SP: sp = value; return true; - case Z80_REG16_PC: pc = value; return true; - case Z80_REG16_IR: ir = value; return true; - case Z80_REG16_AF: af[0] = value; return true; - case Z80_REG16_BC: regs[0].bc = value; return true; - case Z80_REG16_DE: regs[0].de = value; return true; - case Z80_REG16_HL: regs[0].hl = value; return true; - case Z80_REG16_IX: ix = value; return true; - case Z80_REG16_IY: iy = value; return true; - case Z80_REG16_AF_: af[1] = value; return true; - case Z80_REG16_BC_: regs[1].bc = value; return true; - case Z80_REG16_DE_: regs[1].de = value; return true; - case Z80_REG16_HL_: regs[1].hl = value; return true; - default: return false; - } + switch (reg16) + { + case Z80_REG16_SP: sp = value; return true; + case Z80_REG16_PC: pc = value; return true; + case Z80_REG16_IR: ir = value; return true; + case Z80_REG16_AF: af[0] = value; return true; + case Z80_REG16_BC: regs[0].bc = value; return true; + case Z80_REG16_DE: regs[0].de = value; return true; + case Z80_REG16_HL: regs[0].hl = value; return true; + case Z80_REG16_IX: ix = value; return true; + case Z80_REG16_IY: iy = value; return true; + case Z80_REG16_AF_: af[1] = value; return true; + case Z80_REG16_BC_: regs[1].bc = value; return true; + case Z80_REG16_DE_: regs[1].de = value; return true; + case Z80_REG16_HL_: regs[1].hl = value; return true; + default: return false; + } } #endif // SUPERMODEL_DEBUGGER void CZ80::Reset(void) { - pc = 0x0000; - sp = 0xF000; - af[0] = 0x0000; - af[1] = 0x0000; - regs[0].bc = 0x0000; - regs[0].de = 0x0000; - regs[0].hl = 0x0000; - regs[1].bc = 0x0000; - regs[1].de = 0x0000; - regs[1].hl = 0x0000; - ix = 0x0000; - iy = 0x0000; - ir = 0x0000; - iff = 0; - im = 0; - - af_sel = 0; - regs_sel = 0; - - intLine = false; - nmiTrigger = false; + pc = 0x0000; + sp = 0xF000; + af[0] = 0x0000; + af[1] = 0x0000; + regs[0].bc = 0x0000; + regs[0].de = 0x0000; + regs[0].hl = 0x0000; + regs[1].bc = 0x0000; + regs[1].de = 0x0000; + regs[1].hl = 0x0000; + ix = 0x0000; + iy = 0x0000; + ir = 0x0000; + iff = 0; + im = 0; + + af_sel = 0; + regs_sel = 0; + + intLine = false; + nmiTrigger = false; #ifdef SUPERMODEL_DEBUGGER - lastCycles = 0; + lastCycles = 0; #endif // SUPERMODEL_DEBUGGER } void CZ80::SaveState(CBlockFile *StateFile, const char *name) { - StateFile->NewBlock(name, __FILE__); - - for (int i = 0; i < 2; i++) - { - StateFile->Write(®s[i].bc, sizeof(regs[i].bc)); - StateFile->Write(®s[i].de, sizeof(regs[i].de)); - StateFile->Write(®s[i].hl, sizeof(regs[i].hl)); - } - - StateFile->Write(af, sizeof(af)); - StateFile->Write(&ir, sizeof(ir)); - StateFile->Write(&ix, sizeof(ix)); - StateFile->Write(&iy, sizeof(iy)); - StateFile->Write(&sp, sizeof(sp)); - StateFile->Write(&pc, sizeof(pc)); - StateFile->Write(&iff, sizeof(iff)); - StateFile->Write(&im, sizeof(im)); - StateFile->Write(®s_sel, sizeof(regs_sel)); - StateFile->Write(&af_sel, sizeof(af_sel)); - StateFile->Write(&nmiTrigger, sizeof(nmiTrigger)); - StateFile->Write(&intLine, sizeof(intLine)); + StateFile->NewBlock(name, __FILE__); + + for (int i = 0; i < 2; i++) + { + StateFile->Write(®s[i].bc, sizeof(regs[i].bc)); + StateFile->Write(®s[i].de, sizeof(regs[i].de)); + StateFile->Write(®s[i].hl, sizeof(regs[i].hl)); + } + + StateFile->Write(af, sizeof(af)); + StateFile->Write(&ir, sizeof(ir)); + StateFile->Write(&ix, sizeof(ix)); + StateFile->Write(&iy, sizeof(iy)); + StateFile->Write(&sp, sizeof(sp)); + StateFile->Write(&pc, sizeof(pc)); + StateFile->Write(&iff, sizeof(iff)); + StateFile->Write(&im, sizeof(im)); + StateFile->Write(®s_sel, sizeof(regs_sel)); + StateFile->Write(&af_sel, sizeof(af_sel)); + StateFile->Write(&nmiTrigger, sizeof(nmiTrigger)); + StateFile->Write(&intLine, sizeof(intLine)); } void CZ80::LoadState(CBlockFile *StateFile, const char *name) { - if (OKAY != StateFile->FindBlock(name)) - { - ErrorLog("Unable to load Z80 state. Save state file is corrupt."); - return; - } - - for (int i = 0; i < 2; i++) - { - StateFile->Read(®s[i].bc, sizeof(regs[i].bc)); - StateFile->Read(®s[i].de, sizeof(regs[i].de)); - StateFile->Read(®s[i].hl, sizeof(regs[i].hl)); - } - - StateFile->Read(af, sizeof(af)); - StateFile->Read(&ir, sizeof(ir)); - StateFile->Read(&ix, sizeof(ix)); - StateFile->Read(&iy, sizeof(iy)); - StateFile->Read(&sp, sizeof(sp)); - StateFile->Read(&pc, sizeof(pc)); - StateFile->Read(&iff, sizeof(iff)); - StateFile->Read(&im, sizeof(im)); - StateFile->Read(®s_sel, sizeof(regs_sel)); - StateFile->Read(&af_sel, sizeof(af_sel)); - StateFile->Read(&nmiTrigger, sizeof(nmiTrigger)); - StateFile->Read(&intLine, sizeof(intLine)); + if (OKAY != StateFile->FindBlock(name)) + { + ErrorLog("Unable to load Z80 state. Save state file is corrupt."); + return; + } + + for (int i = 0; i < 2; i++) + { + StateFile->Read(®s[i].bc, sizeof(regs[i].bc)); + StateFile->Read(®s[i].de, sizeof(regs[i].de)); + StateFile->Read(®s[i].hl, sizeof(regs[i].hl)); + } + + StateFile->Read(af, sizeof(af)); + StateFile->Read(&ir, sizeof(ir)); + StateFile->Read(&ix, sizeof(ix)); + StateFile->Read(&iy, sizeof(iy)); + StateFile->Read(&sp, sizeof(sp)); + StateFile->Read(&pc, sizeof(pc)); + StateFile->Read(&iff, sizeof(iff)); + StateFile->Read(&im, sizeof(im)); + StateFile->Read(®s_sel, sizeof(regs_sel)); + StateFile->Read(&af_sel, sizeof(af_sel)); + StateFile->Read(&nmiTrigger, sizeof(nmiTrigger)); + StateFile->Read(&intLine, sizeof(intLine)); } -void CZ80::Init(CBus *BusPtr, int (*INTF)(CZ80 *Z80)) +void mCZ80::Init(CBus *BusPtr, int (*INTF)(CZ80 *Z80)) { - Bus = BusPtr; - INTCallback = INTF; + Bus = BusPtr; + INTCallback = INTF; } #ifdef SUPERMODEL_DEBUGGER void CZ80::AttachDebugger(Debugger::CZ80Debug *DebugPtr) { - if (Debug != NULL) - DetachDebugger(); - Debug = DebugPtr; - Bus = Debug->AttachBus(Bus); + if (Debug != NULL) + DetachDebugger(); + Debug = DebugPtr; + Bus = Debug->AttachBus(Bus); } void CZ80::DetachDebugger() { - if (Debug == NULL) - return; - Bus = Debug->DetachBus(); - Debug = NULL; + if (Debug == NULL) + return; + Bus = Debug->DetachBus(); + Debug = NULL; } #endif //SUPERMODEL_DEBUGGER CZ80::CZ80(void) { - INTCallback = NULL; // so we can later check to see if one has been installed - Bus = NULL; + INTCallback = NULL; // so we can later check to see if one has been installed + Bus = NULL; #ifdef SUPERMODEL_DEBUGGER - Debug = NULL; + Debug = NULL; #endif //SUPERMODEL_DEBUGGER } CZ80::~CZ80(void) { - INTCallback = NULL; - Bus = NULL; + INTCallback = NULL; + Bus = NULL; #ifdef SUPERMODEL_DEBUGGER - Debug = NULL; + Debug = NULL; #endif //SUPERMODEL_DEBUGGER } \ No newline at end of file diff --git a/Src/CPU/Z80/Z80.h b/Src/CPU/Z80/Z80.h index 752de69..7a49e0b 100644 --- a/Src/CPU/Z80/Z80.h +++ b/Src/CPU/Z80/Z80.h @@ -27,17 +27,17 @@ * * Known inaccuracies: * - * - Interrupts are accepted immediately after EI instruction. In reality, - * interrupts become enabled after the instruction following EI. This - * could be implemented with a state machine in Run() if needed. - * This feature exists to prevent interrupts from occuring before a RETI - * instruction executes in the interrupt handler. Interrupt callbacks - * should take care to immediately clear the interrupt line, otherwise, - * an improperly timed interrupt may occur right after an EI instruction - * but before the service routine has a chance to return. - * - HALT instruction is not implemented (it just exits). - * - 16-bit words are read as two bytes but these reads may not occur in - * the exact same order as the real device. Needs to be checked. + * - Interrupts are accepted immediately after EI instruction. In reality, + * interrupts become enabled after the instruction following EI. This + * could be implemented with a state machine in Run() if needed. + * This feature exists to prevent interrupts from occuring before a RETI + * instruction executes in the interrupt handler. Interrupt callbacks + * should take care to immediately clear the interrupt line, otherwise, + * an improperly timed interrupt may occur right after an EI instruction + * but before the service routine has a chance to return. + * - HALT instruction is not implemented (it just exits). + * - 16-bit words are read as two bytes but these reads may not occur in + * the exact same order as the real device. Needs to be checked. */ #ifndef INCLUDED_Z80_H @@ -55,14 +55,14 @@ * supplied, and this is the only supported behavior here. The interrupt * callback must return one of these values when the Z80 is in mode 0. */ -#define Z80_INT_RST_00 0xC7 // RST 0x00 (jumps to 0x0000) -#define Z80_INT_RST_08 0xCF // RST 0x08 (jumps to 0x0008) -#define Z80_INT_RST_10 0xD7 // RST 0x10 (...) -#define Z80_INT_RST_18 0xDF // RST 0x18 -#define Z80_INT_RST_20 0xE7 // RST 0x20 -#define Z80_INT_RST_28 0xEF // RST 0x28 -#define Z80_INT_RST_30 0xF7 // RST 0x30 -#define Z80_INT_RST_38 0xFF // RST 0x38 +#define Z80_INT_RST_00 0xC7 // RST 0x00 (jumps to 0x0000) +#define Z80_INT_RST_08 0xCF // RST 0x08 (jumps to 0x0008) +#define Z80_INT_RST_10 0xD7 // RST 0x10 (...) +#define Z80_INT_RST_18 0xDF // RST 0x18 +#define Z80_INT_RST_20 0xE7 // RST 0x20 +#define Z80_INT_RST_28 0xEF // RST 0x28 +#define Z80_INT_RST_30 0xF7 // RST 0x30 +#define Z80_INT_RST_38 0xFF // RST 0x38 #ifdef SUPERMODEL_DEBUGGER // Extra interrupt types @@ -99,7 +99,9 @@ #define Z80_REG16_DE_ 11 #define Z80_REG16_HL_ 12 -class Debugger::CZ80Debug; +namespace Debugger { + class CZ80Debug; +} #endif // SUPERMODEL_DEBUGGER /* @@ -110,229 +112,228 @@ class Debugger::CZ80Debug; class CZ80 { public: - /* - * Run(numCycles): - * - * Runs the Z80 for the specified number of instruction cycles. - * - * Parameters: - * numCycles Number of instruction cycles to execute. - * - * Returns: - * Number of instruction cycles actually executed. - */ - int Run(int numCycles); - - /* - * TriggerNMI(void): - * - * Triggers a non-maskable interrupt. This is equivalent to a high-to-low - * transition on the NMI pin (NMI pin is triggered on falling edges). This - * may be called while the Z80 is running. NMIs are always higher priority - * than interrupts and are taken first. - */ - void TriggerNMI(void); - - /* - * SetINT(state): - * - * Set or clear the interrupt request. This may be called from memory - * handlers while the Z80 is running and should be used by interrupt - * callbacks to clear interrupts. - * - * Parameters: - * state If TRUE, this is equivalent to /INT being asserted on the - * Z80 (INT line low, which triggers an interrupt). If FALSE, - * this deasserts /INT (INT line high, no interrupt pending). - */ - void SetINT(bool state); + /* + * Run(numCycles): + * + * Runs the Z80 for the specified number of instruction cycles. + * + * Parameters: + * numCycles Number of instruction cycles to execute. + * + * Returns: + * Number of instruction cycles actually executed. + */ + int Run(int numCycles); + + /* + * TriggerNMI(void): + * + * Triggers a non-maskable interrupt. This is equivalent to a high-to-low + * transition on the NMI pin (NMI pin is triggered on falling edges). This + * may be called while the Z80 is running. NMIs are always higher priority + * than interrupts and are taken first. + */ + void TriggerNMI(void); + + /* + * SetINT(state): + * + * Set or clear the interrupt request. This may be called from memory + * handlers while the Z80 is running and should be used by interrupt + * callbacks to clear interrupts. + * + * Parameters: + * state If TRUE, this is equivalent to /INT being asserted on the + * Z80 (INT line low, which triggers an interrupt). If FALSE, + * this deasserts /INT (INT line high, no interrupt pending). + */ + void SetINT(bool state); - /* - * GetPC(void): - * - * Returns the current PC value. - * - * Returns: - * Current value of PC register. - */ - UINT16 GetPC(void); + /* + * GetPC(void): + * + * Returns the current PC value. + * + * Returns: + * Current value of PC register. + */ + UINT16 GetPC(void); #ifdef SUPERMODEL_DEBUGGER - /* - * GetReg8(reg8): - * - * Reads an 8-bit register. - * - * Parameters: - * reg8 Register number (use Z80_REG8_* macros). - * - * Returns: - * Value of given 8-bit register. - */ - UINT8 GetReg8(unsigned reg8); + /* + * GetReg8(reg8): + * + * Reads an 8-bit register. + * + * Parameters: + * reg8 Register number (use Z80_REG8_* macros). + * + * Returns: + * Value of given 8-bit register. + */ + UINT8 GetReg8(unsigned reg8); - /* - * SetReg8(reg8, value): - * - * Sets value of given 8-bit register. - * - * Parameters: - * reg8 Register number. - * value Value to write. - * - * Returns: - * True if succeeded, false if invalid register. - */ - bool SetReg8(unsigned reg8, UINT8 value); + /* + * SetReg8(reg8, value): + * + * Sets value of given 8-bit register. + * + * Parameters: + * reg8 Register number. + * value Value to write. + * + * Returns: + * True if succeeded, false if invalid register. + */ + bool SetReg8(unsigned reg8, UINT8 value); - /* - * GetReg16(reg16, value): - * - * Reads a 16-bit register. - * - * Parameters: - * reg16 Register number (use Z80_REG16_* macros). - * - * Returns: - * Value of given 16-bit register. - */ - UINT16 GetReg16(unsigned reg16); + /* + * GetReg16(reg16, value): + * + * Reads a 16-bit register. + * + * Parameters: + * reg16 Register number (use Z80_REG16_* macros). + * + * Returns: + * Value of given 16-bit register. + */ + UINT16 GetReg16(unsigned reg16); - /* - * SetReg16(state): - * - * Sets value of given 16-bit register. - * - * Parameters: - * reg16 Register. - * value Value to write. - * - * Returns: - * True if succeeded, false if invalid register. - */ - bool SetReg16(unsigned reg16, UINT16 value); + /* + * SetReg16(state): + * + * Sets value of given 16-bit register. + * + * Parameters: + * reg16 Register. + * value Value to write. + * + * Returns: + * True if succeeded, false if invalid register. + */ + bool SetReg16(unsigned reg16, UINT16 value); #endif // SUPERMODEL_DEBUGGER - /* - * Reset(void): - * - * Resets the Z80, clearing all registers and pending interrupt requests. - */ - void Reset(void); - - /* - * SaveState(StateFile, name): - * - * Saves the CPU state to the block file. - * - * Parameters: - * StateFile Block file. - * name Name of block to create (e.g. "Main Z80"), to facilitate - * multiple Z80 states in the same file. - */ - void SaveState(CBlockFile *StateFile, const char *name); + /* + * Reset(void): + * + * Resets the Z80, clearing all registers and pending interrupt requests. + */ + void Reset(void); + + /* + * SaveState(StateFile, name): + * + * Saves the CPU state to the block file. + * + * Parameters: + * StateFile Block file. + * name Name of block to create (e.g. "Main Z80"), to facilitate + * multiple Z80 states in the same file. + */ + void SaveState(CBlockFile *StateFile, const char *name); - /* - * LoadState(StateFile, name): - * - * Loads the CPU state. - * - * Parameters: - * StateFile Block file. - * name Name of block to load. - */ - void LoadState(CBlockFile *StateFile, const char *name); + /* + * LoadState(StateFile, name): + * + * Loads the CPU state. + * + * Parameters: + * StateFile Block file. + * name Name of block to load. + */ + void LoadState(CBlockFile *StateFile, const char *name); - /* - * Init(BusPtr, INTF): - * - * One-time initialization of the Z80 emulator. Must be called first. - * - * A bus object must be supplied which will be used to handle all memory - * and IO accesses. The Read8, Write8, IORead8, and IOWrite8 members need - * to be defined. Addresses are automatically clamped to 16 bits for memory - * and 8 bits for IO accesses. - * - * An interrupt callback, which is called each time an interrupt occurs, - * should also be supplied. The interrupt callback should explicitly clear - * the INT status (using SetINT(FALSE)) and then return the appropriate - * vector depending on the interrupt mode that is used by the system. - * - * For mode 0, only Z80_INT_RST_* values are acceptable. For mode 1, the - * return value is discarded because the Z80 will always use vector 0x0038. - * In mode 2, an 8-bit value supplying the lower 8-bits of the interrupt - * vector address must be returned. Bit 0 will be ignored in this case (0 - * is used). - * - * If a callback is not installed, the interrupt status will automatically - * be cleared and interrupts will not be taken when the Z80 is in a mode - * that requires vector data from the callback. In mode 1, the interrupt - * callback (if one is provided) should explicitly clear the interrupt. The - * value returned will be unused. - * - * Parameters: - * BusPtr Pointer to a bus object. - * INTF Pointer to callback function. The function accepts a - * a pointer to the Z80 object that received the interrupt. - */ - void Init(CBus *BusPtr, int (*INTF)(CZ80 *Z80)); + /* + * Init(BusPtr, INTF): + * + * One-time initialization of the Z80 emulator. Must be called first. + * + * A bus object must be supplied which will be used to handle all memory + * and IO accesses. The Read8, Write8, IORead8, and IOWrite8 members need + * to be defined. Addresses are automatically clamped to 16 bits for memory + * and 8 bits for IO accesses. + * + * An interrupt callback, which is called each time an interrupt occurs, + * should also be supplied. The interrupt callback should explicitly clear + * the INT status (using SetINT(FALSE)) and then return the appropriate + * vector depending on the interrupt mode that is used by the system. + * + * For mode 0, only Z80_INT_RST_* values are acceptable. For mode 1, the + * return value is discarded because the Z80 will always use vector 0x0038. + * In mode 2, an 8-bit value supplying the lower 8-bits of the interrupt + * vector address must be returned. Bit 0 will be ignored in this case (0 + * is used). + * + * If a callback is not installed, the interrupt status will automatically + * be cleared and interrupts will not be taken when the Z80 is in a mode + * that requires vector data from the callback. In mode 1, the interrupt + * callback (if one is provided) should explicitly clear the interrupt. The + * value returned will be unused. + * + * Parameters: + * BusPtr Pointer to a bus object. + * INTF Pointer to callback function. The function accepts a + * a pointer to the Z80 object that received the interrupt. + */ + void Init(CBus *BusPtr, int (*INTF)(CZ80 *Z80)); #ifdef SUPERMODEL_DEBUGGER - /* - * AttachDebugger(DebugPtr): - * - * Attaches debugger to CPU. - */ - void AttachDebugger(Debugger::CZ80Debug *DebugPtr); + /* + * AttachDebugger(DebugPtr): + * + * Attaches debugger to CPU. + */ + void AttachDebugger(Debugger::CZ80Debug *DebugPtr); - /* - * DetachDebugger(): - * - * Detaches debugger from CPU. - */ - void DetachDebugger(); + /* + * DetachDebugger(): + * + * Detaches debugger from CPU. + */ + void DetachDebugger(); #endif // SUPERMODEL_DEBUGGER - - /* - * CZ80(void): - * ~CZ80(void): - * - * Constructor and destructor. - */ - CZ80(void); - ~CZ80(void); + + /* + * CZ80(void): + * ~CZ80(void): + * + * Constructor and destructor. + */ + CZ80(void); + ~CZ80(void); private: - // Registers - struct GPR { // general purpose registers - UINT16 bc; - UINT16 de; - UINT16 hl; - } regs[2]; // two sets: primary (0) and alternate (1) - UINT16 af[2]; // AF (primary and alternate) - UINT16 ir; // interrupt vector (I) and memory refresh (R) - UINT16 ix; // index register X - UINT16 iy; // index register Y - UINT16 sp; // stack pointer - UINT16 pc; // program counter - UINT8 iff; // interrupt flip flops (bit 1: IFF2, 0: IFF1) - UINT8 im; // interrupt mode (0, 1, or 2 only) - int regs_sel; // active register set (primary or alternate) - int af_sel; // active AF - - // Memory and IO bus - CBus *Bus; - - // Interrupts - bool nmiTrigger; - bool intLine; - int (*INTCallback)(CZ80 *Z80); + // Registers + struct GPR { // general purpose registers + UINT16 bc; + UINT16 de; + UINT16 hl; + } regs[2]; // two sets: primary (0) and alternate (1) + UINT16 af[2]; // AF (primary and alternate) + UINT16 ir; // interrupt vector (I) and memory refresh (R) + UINT16 ix; // index register X + UINT16 iy; // index register Y + UINT16 sp; // stack pointer + UINT16 pc; // program counter + UINT8 iff; // interrupt flip flops (bit 1: IFF2, 0: IFF1) + UINT8 im; // interrupt mode (0, 1, or 2 only) + int regs_sel; // active register set (primary or alternate) + int af_sel; // active AF + + // Memory and IO bus + CBus *Bus; + + // Interrupts + bool nmiTrigger; + bool intLine; + int (*INTCallback)(CZ80 *Z80); #ifdef SUPERMODEL_DEBUGGER - int lastCycles; - - Debugger::CZ80Debug *Debug; + int lastCycles; + Debugger::CZ80Debug *Debug; #endif // SUPERMODEL_DEBUGGER }; -#endif // INCLUDED_Z80_H \ No newline at end of file +#endif // INCLUDED_Z80_H