/**
 ** Supermodel
 ** A Sega Model 3 Arcade Emulator.
 ** Copyright 2011 Bart Trzynadlowski, Nik Henson
 **
 ** This file is part of Supermodel.
 **
 ** Supermodel is free software: you can redistribute it and/or modify it under
 ** the terms of the GNU General Public License as published by the Free 
 ** Software Foundation, either version 3 of the License, or (at your option)
 ** any later version.
 **
 ** Supermodel is distributed in the hope that it will be useful, but WITHOUT
 ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 ** FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 ** more details.
 **
 ** You should have received a copy of the GNU General Public License along
 ** with Supermodel.  If not, see <http://www.gnu.org/licenses/>.
 **/
 
/*
 * Z80.cpp
 *
 * Z80 instruction set simulator.
 * Copyright (C) 1995  Frank D. Cringle.
 * Adapted for use in Supermodel by Bart Trzynadlowski (July 15, 2011).
 *
 * Please see Z80.h for a discussion of known inaccuracies.
 */

#include <cstdio>	// for NULL
#include "Z80.h"	// must include this first to define CZ80
#include "Supermodel.h"


/******************************************************************************
 Internal Helper Macros
******************************************************************************/

// 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 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 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) )

// 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 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 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,
};

// 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
	}
};

#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 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;							\
	}
	
// Save local copies of Z80 registers back to context
#define SAVE_TO_CONTEXT()	\
    af[af_sel] = AF;		\
    regs[regs_sel].bc = BC;	\
    regs[regs_sel].de = DE;	\
    regs[regs_sel].hl = HL;	\
    ix = IX;				\
    iy = IY;				\
    sp = SP


/*******************************************************************************
 Functions
*******************************************************************************/

int CZ80::Run(int numCycles)
{
    // 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 temp, acu, sum, cbits;
    unsigned int op, adr;
    
	int cycles = numCycles;
	while (cycles > 0)
	{
	op = GetBYTE_pp(pc);
	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
    
    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)
    	 */
    	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
    {
    	// 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);
    				
    				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.
    			 */
    			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.
    			 */
    			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
    
	// write registers back to context
HALTExit:
    SAVE_TO_CONTEXT();

	// Return number of cycles actually executed
    return numCycles - cycles;
}

void CZ80::TriggerNMI(void)
{
	nmiTrigger = true;
}

void CZ80::SetINT(bool state)
{
	intLine = state;
}

UINT16 CZ80::GetPC(void)
{
	return pc;
}

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;
}

void CZ80::SaveState(CBlockFile *StateFile, const char *name)
{
	StateFile->NewBlock(name, __FILE__);
	
	for (int i = 0; i < 2; i++)
	{
		StateFile->Write(&regs[i].bc, sizeof(regs[i].bc));
		StateFile->Write(&regs[i].de, sizeof(regs[i].de));
		StateFile->Write(&regs[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(&regs_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 corrupted.");
		return;
	}
	
	for (int i = 0; i < 2; i++)
	{
		StateFile->Read(&regs[i].bc, sizeof(regs[i].bc));
		StateFile->Read(&regs[i].de, sizeof(regs[i].de));
		StateFile->Read(&regs[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(&regs_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))
{
	Bus 		= BusPtr;
	INTCallback	= INTF;
}

CZ80::CZ80(void)
{
	INTCallback	= NULL;	// so we can later check to see if one has been installed
	Bus 		= NULL;
}

CZ80::~CZ80(void)
{
	INTCallback	= NULL;
	Bus			= NULL;
}