blob: 575771c5e41227d6b7e85d38bf38918267e9c772 [file] [log] [blame]
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Pacbox - a Pacman Emulator for Rockbox
*
* Based on PIE - Pacman Instructional Emulator
*
* Copyright (c) 1997-2003,2004 Alessandro Scotti
* http://www.ascotti.org/
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "plugin.h"
#include "hardware.h"
#include "z80.h"
#include "z80_internal.h"
// Table with parity, sign and zero flags precomputed for each byte value
unsigned char PSZ_[256] IDATA_ATTR = {
Zero|Parity, 0, 0, Parity, 0, Parity, Parity, 0, 0, Parity, Parity, 0, Parity, 0, 0, Parity,
0, Parity, Parity, 0, Parity, 0, 0, Parity, Parity, 0, 0, Parity, 0, Parity, Parity, 0,
0, Parity, Parity, 0, Parity, 0, 0, Parity, Parity, 0, 0, Parity, 0, Parity, Parity, 0,
Parity, 0, 0, Parity, 0, Parity, Parity, 0, 0, Parity, Parity, 0, Parity, 0, 0, Parity,
0, Parity, Parity, 0, Parity, 0, 0, Parity, Parity, 0, 0, Parity, 0, Parity, Parity, 0,
Parity, 0, 0, Parity, 0, Parity, Parity, 0, 0, Parity, Parity, 0, Parity, 0, 0, Parity,
Parity, 0, 0, Parity, 0, Parity, Parity, 0, 0, Parity, Parity, 0, Parity, 0, 0, Parity,
0, Parity, Parity, 0, Parity, 0, 0, Parity, Parity, 0, 0, Parity, 0, Parity, Parity, 0,
Sign, Sign|Parity, Sign|Parity, Sign, Sign|Parity, Sign, Sign, Sign|Parity, Sign|Parity, Sign, Sign, Sign|Parity, Sign, Sign|Parity, Sign|Parity, Sign,
Sign|Parity, Sign, Sign, Sign|Parity, Sign, Sign|Parity, Sign|Parity, Sign, Sign, Sign|Parity, Sign|Parity, Sign, Sign|Parity, Sign, Sign, Sign|Parity,
Sign|Parity, Sign, Sign, Sign|Parity, Sign, Sign|Parity, Sign|Parity, Sign, Sign, Sign|Parity, Sign|Parity, Sign, Sign|Parity, Sign, Sign, Sign|Parity,
Sign, Sign|Parity, Sign|Parity, Sign, Sign|Parity, Sign, Sign, Sign|Parity, Sign|Parity, Sign, Sign, Sign|Parity, Sign, Sign|Parity, Sign|Parity, Sign,
Sign|Parity, Sign, Sign, Sign|Parity, Sign, Sign|Parity, Sign|Parity, Sign, Sign, Sign|Parity, Sign|Parity, Sign, Sign|Parity, Sign, Sign, Sign|Parity,
Sign, Sign|Parity, Sign|Parity, Sign, Sign|Parity, Sign, Sign, Sign|Parity, Sign|Parity, Sign, Sign, Sign|Parity, Sign, Sign|Parity, Sign|Parity, Sign,
Sign, Sign|Parity, Sign|Parity, Sign, Sign|Parity, Sign, Sign, Sign|Parity, Sign|Parity, Sign, Sign, Sign|Parity, Sign, Sign|Parity, Sign|Parity, Sign,
Sign|Parity, Sign, Sign, Sign|Parity, Sign, Sign|Parity, Sign|Parity, Sign, Sign, Sign|Parity, Sign|Parity, Sign, Sign|Parity, Sign, Sign, Sign|Parity
};
// Interrupt flags
enum {
IFF1 = 0x40, // Interrupts enabled/disabled
IFF2 = 0x20, // Copy of IFF1 (used by non-maskable interrupts)
Halted = 0x10 // Internal use: signals that the CPU is halted
};
// Implements an opcode
typedef void (OpcodeHandler)(void);
typedef struct {
OpcodeHandler* handler;
unsigned cycles;
} OpcodeInfo;
// Implements an opcode for instructions that use the form (IX/IY + b)
typedef void (OpcodeHandlerXY)( unsigned );
typedef struct {
OpcodeHandlerXY* handler;
unsigned cycles;
} OpcodeInfoXY;
/** */
void do_opcode_xy( OpcodeInfo * );
/** */
unsigned do_opcode_xycb( unsigned xy );
unsigned iflags_ IBSS_ATTR; // Interrupt mode (bits 0 and 1) and flags
unsigned cycles_ IBSS_ATTR; // Number of CPU cycles elapsed so far
// Registers
unsigned char B IBSS_ATTR; //@- B register
unsigned char C IBSS_ATTR; //@- C register
unsigned char D IBSS_ATTR; //@- D register
unsigned char E IBSS_ATTR; //@- E register
unsigned char H IBSS_ATTR; //@- H register
unsigned char L IBSS_ATTR; //@- L register
unsigned char A IBSS_ATTR; //@- A register (accumulator)
unsigned char F IBSS_ATTR; //@- Flags register
unsigned char B1 IBSS_ATTR; //@- Alternate B register (B')
unsigned char C1 IBSS_ATTR; //@- Alternate C register (C')
unsigned char D1 IBSS_ATTR; //@- Alternate D register (D')
unsigned char E1 IBSS_ATTR; //@- Alternate E register (E')
unsigned char H1 IBSS_ATTR; //@- Alternate H register (H')
unsigned char L1 IBSS_ATTR; //@- Alternate L register (L')
unsigned char A1 IBSS_ATTR; //@- Alternate A register (A')
unsigned char F1 IBSS_ATTR; //@- Alternate flags register (F')
unsigned IX IBSS_ATTR; //@- Index register X
unsigned IY IBSS_ATTR; //@- Index register Y
unsigned PC IBSS_ATTR; //@- Program counter
unsigned SP IBSS_ATTR; //@- Stack pointer
unsigned char I IBSS_ATTR; //@- Interrupt register
unsigned char R IBSS_ATTR; //@- Refresh register
/** Returns the 16 bit register BC. */
#define BC() (((unsigned)B << 8) | C)
#define DE() (((unsigned)D << 8) | E)
#define HL() (((unsigned)H << 8) | L)
/**
Returns the number of Z80 CPU cycles elapsed so far.
The cycle count is reset to zero when reset() is called, or
it can be set to any value with setCycles(). It is updated after
a CPU instruction is executed, for example by calling step()
or interrupt().
*/
unsigned getCycles(void) {
return cycles_;
}
/** Sets the CPU cycle counter to the specified value. */
void setCycles( unsigned value ) {
cycles_ = value;
}
/** Returns the current interrupt mode. */
unsigned getInterruptMode(void) {
return iflags_ & 0x03;
}
/** Sets the interrupt mode to the specified value. */
void setInterruptMode( unsigned mode );
/** Returns non-zero if the CPU is halted, otherwise zero. */
int isHalted(void) {
return iflags_ & Halted;
}
/*
Sets the interrupt mode to IM0, IM1 or IM2.
*/
void setInterruptMode( unsigned mode )
{
if( mode <= 2 ) {
iflags_ = (iflags_ & ~0x03) | mode;
}
}
/*
Calls a subroutine at the specified address.
*/
void callSub( unsigned addr )
{
SP -= 2;
writeWord( SP, PC ); // Save current program counter in the stack
PC = addr & 0xFFFF; // Jump to the specified address
}
/*
Decrements a byte value by one.
Note that this is different from subtracting one from the byte value,
because flags behave differently.
*/
static inline unsigned char decByte( unsigned char b )
{
F = Subtraction | (F & Carry); // Preserve the carry flag
if( (b & 0x0F) == 0 ) F |= Halfcarry;
--b;
if( b == 0x7F ) F |= Overflow;
if( b & 0x80 ) F |= Sign;
if( b == 0 ) F |= Zero;
return b;
}
/*
Increments a byte value by one.
Note that this is different from adding one to the byte value,
because flags behave differently.
*/
static inline unsigned char incByte( unsigned char b )
{
++b;
F &= Carry; // Preserve the carry flag
if( ! (b & 0x0F) ) F |= Halfcarry;
if( b == 0x80 ) F |= Overflow;
if( b & 0x80 ) F |= Sign;
if( b == 0 ) F |= Zero;
return b;
}
/*
Reads one byte from port C, updating flags according to the rules of "IN r,(C)".
*/
static inline unsigned char inpReg(void)
{
unsigned char r = readPort( C );
F = (F & Carry) | PSZ_[r];
return r;
}
/*
Performs a relative jump to the specified offset.
*/
static inline void relJump( unsigned char o )
{
int offset = (int)((signed char)o);
PC = (unsigned)((int)PC + offset) & 0xFFFF;
cycles_++;
}
/*
Returns from a subroutine, popping the saved Program Counter from the stack.
*/
static inline void retFromSub(void)
{
PC = readWord( SP );
SP += 2;
}
/*
Rotates left one byte thru the carry flag.
*/
static inline unsigned char rotateLeft( unsigned char op )
{
unsigned char f = F;
F = 0;
if( op & 0x80 ) F |= Carry;
op <<= 1;
if( f & Carry ) op |= 0x01;
F |= PSZ_[op];
return op;
}
/*
Rotates left one byte copying the most significant bit (bit 7) in the carry flag.
*/
static inline unsigned char rotateLeftCarry( unsigned char op )
{
F = 0;
if( op & 0x80 ) F |= Carry;
op = (op << 1) | (op >> 7);
F |= PSZ_[op];
return op;
}
/*
Rotates right one byte thru the carry flag.
*/
static inline unsigned char rotateRight( unsigned char op )
{
unsigned char f = F;
F = 0;
if( op & 0x01 ) F |= Carry;
op >>= 1;
if( f & Carry ) op |= 0x80;
F |= PSZ_[op];
return op;
}
/*
Rotates right one byte copying the least significant bit (bit 0) in the carry flag.
*/
static inline unsigned char rotateRightCarry( unsigned char op )
{
F = 0;
if( op & 0x01 ) F |= Carry;
op = (op >> 1) | (op << 7);
F |= PSZ_[op];
return op;
}
/*
Shifts left one byte.
*/
static inline unsigned char shiftLeft( unsigned char op )
{
F = 0;
if( op & 0x80 ) F |= Carry;
op <<= 1;
F |= PSZ_[op];
return op;
}
/*
Shifts right one byte, preserving its sign (most significant bit).
*/
static inline unsigned char shiftRightArith( unsigned char op )
{
F = 0;
if( op & 0x01 ) F |= Carry;
op = (op >> 1) | (op & 0x80);
F |= PSZ_[op];
return op;
}
/*
Shifts right one byte.
*/
static inline unsigned char shiftRightLogical( unsigned char op )
{
F = 0;
if( op & 0x01 ) F |= Carry;
op >>= 1;
F |= PSZ_[op];
return op;
}
/*
Tests whether the specified bit of op is set.
*/
static inline void testBit( unsigned char bit, unsigned char op )
{
// Flags for a bit test operation are:
// S, P: unknown
// Z: set if bit is zero, reset otherwise
// N: reset
// H: set
// C: unaffected
// However, it seems that parity is always set like Z, so we emulate that as well.
F = (F & (Carry | Sign)) | Halfcarry;
if( (op & (1 << bit)) == 0 ) {
// Bit is not set, so set the zero flag
F |= Zero | Parity;
}
}
/*
Adds the specified byte op to the accumulator, adding
carry.
*/
static inline void addByte( unsigned char op, unsigned char cf )
{
unsigned x = A + op;
if( cf ) x++; // Add carry
F = 0;
if( !(x & 0xFF) ) F |= Zero;
if( x & 0x80 ) F |= Sign;
if( x >= 0x100 ) F |= Carry;
/*
Halfcarry is set on carry from the low order four bits.
To see how to compute it, let's take a look at the following table, which
shows the binary addition of two binary numbers:
A B A+B
-----------
0 0 0
0 1 1
1 0 1
1 1 0
Note that if only the lowest bit is used, then A+B, A-B and A^B yield the same
value. If we know A, B and the sum A+B+C, then C is easily derived:
C = A+B+C - A - B, that is
C = A+B+C ^ A ^ B.
For the halfcarry, A and B above are the fifth bit of a byte, which corresponds
to the value 0x10. So:
Halfcarry = ((accumulator+operand+halfcarry) ^ accumulator ^ operand) & 0x10
Note that masking off all bits but one is important because we have worked all
the math by using one bit only.
*/
if( (A ^ op ^ x) & 0x10 ) F |= Halfcarry;
/*
The overflow bit is set when the result is too large to fit into the destination
register, causing a change in the sign bit.
For a sum, we can only have overflow when adding two numbers that are both positive
or both negative. For example 0x5E + 0x4B (94 + 75) yields 0xA9 (169), which fits
into an 8-bit register only if it is interpreted as an unsigned number. If we
consider the result as a signed integer, then 0xA9 corresponds to decimal -87 and
we have overflow.
Note that if we add two signed numbers of opposite sign then we cannot overflow
the destination register, because the absolute value of the result will always fit
in 7 bits, leaving the most significant bit free for use as a sign bit.
We can code all the above concisely by noting that:
~(A ^ op) & 0x80
is true if and only if A and op have the same sign. Also:
(x ^ op) & 0x80
is true if and only if the sum of A and op has taken a sign opposite to that
of its operands.
Thus the expression:
~(A ^ op) & (x ^ op) & 0x80
reads "A has the same sign as op, and the opposite as x", where x is the sum of
A and op (and an optional carry).
*/
if( ~(A ^ op) & (x ^ op) & 0x80 ) F |= Overflow;
A = x;
}
/*
Subtracts the specified byte op from the accumulator, using carry as
borrow from a previous operation.
*/
static inline unsigned char subByte( unsigned char op, unsigned char cf )
{
unsigned char x = A - op;
if( cf ) x--;
F = Subtraction;
if( x == 0 ) F |= Zero;
if( x & 0x80 ) F |= Sign;
if( (x >= A) && (op | cf)) F |= Carry;
// See addByte() for an explanation of the halfcarry bit
if( (A ^ op ^ x) & 0x10 ) F |= Halfcarry;
// See addByte() for an explanation of the overflow bit. The only difference here
// is that for a subtraction we must check that the two operands have different
// sign, because in fact A-B is A+(-B). Note however that since subtraction is not
// symmetric, we have to use (x ^ A) to get the correct result, whereas for the
// addition (x ^ A) is equivalent to (x ^ op)
if( (A ^ op) & (x ^ A) & 0x80 ) F |= Overflow;
return x;
}
static inline unsigned addDispl( unsigned addr, unsigned char displ ) {
return (unsigned)((int)addr + (int)(signed char)displ);
}
/** Compares the accumulator and the specified operand (CP op) */
static inline void cmpByte( unsigned char op ) {
subByte( op, 0 );
}
/** Fetches a byte from the program counter location */
static inline unsigned char fetchByte(void) {
return readByte( PC++ );
}
/** Fetches a 16 bit word from the program counter location */
static inline unsigned fetchWord(void) {
unsigned x = readWord( PC );
PC += 2;
return x;
}
/** Sets the parity, sign and zero flags from the accumulator value */
static inline void setFlagsPSZ(void) {
F = Halfcarry | PSZ_[A];
}
/** Sets the parity, sign, zero, 3rd and 5th flag bits from the accumulator value */
static inline void setFlags35PSZ(void) {
F = (F & (Carry | Halfcarry | Subtraction)) | PSZ_[A];
}
/** */
static inline void setFlags35PSZ000(void) {
F = PSZ_[A];
}
/* Resets the CPU */
void z80_reset()
{
PC = 0; // Program counter is zero
I = 0; // Interrupt register cleared
R = 0; // Memory refresh register cleared
iflags_ = 0; // IFF1 and IFF2 cleared, IM0 enabled
cycles_ = 0; // Could that be 2 (according to some Zilog docs)?
// There is no official documentation for the following!
B = B1 = 0;
C = C1 = 0;
D = D1 = 0;
E = E1 = 0;
H = H1 = 0;
L = L1 = 0;
A = A1 = 0;
F = F1 = 0;
IX = 0;
IY = 0;
SP = 0xF000;
}
unsigned z80_getSizeOfSnapshotBuffer(void)
{
unsigned result =
8*2 + // 8-bit registers
1 + // I
1 + // R
2 + // IX
2 + // IY
2 + // PC
2 + // SP
4 + // iflags_
4; // cycles_
return result;
}
static unsigned saveUint16( unsigned char * buffer, unsigned u )
{
*buffer++ = (unsigned char) (u >> 8);
*buffer = (unsigned char) (u);
return 2;
}
unsigned z80_takeSnapshot( unsigned char * buffer )
{
unsigned char * buf = buffer;
*buf++ = A; *buf++ = A1;
*buf++ = B; *buf++ = B1;
*buf++ = C; *buf++ = C1;
*buf++ = D; *buf++ = D1;
*buf++ = E; *buf++ = E1;
*buf++ = H; *buf++ = H1;
*buf++ = L; *buf++ = L1;
*buf++ = F; *buf++ = F1;
*buf++ = I;
*buf++ = R;
buf += saveUint16( buf, IX );
buf += saveUint16( buf, IY );
buf += saveUint16( buf, PC );
buf += saveUint16( buf, SP );
buf += saveUint16( buf, iflags_ >> 16 );
buf += saveUint16( buf, iflags_ );
buf += saveUint16( buf, cycles_ >> 16 );
buf += saveUint16( buf, cycles_ );
return buffer - buf;
}
static unsigned loadUint16( unsigned char ** buffer )
{
unsigned char * buf = *buffer;
unsigned result = *buf++;
result = (result << 8) | *buf++;
*buffer = buf;
return result;
}
unsigned z80_restoreSnapshot( unsigned char * buffer )
{
unsigned char * buf = buffer;
A = *buf++; A1 = *buf++;
B = *buf++; B1 = *buf++;
C = *buf++; C1 = *buf++;
D = *buf++; D1 = *buf++;
E = *buf++; E1 = *buf++;
H = *buf++; H1 = *buf++;
L = *buf++; L1 = *buf++;
F = *buf++; F1 = *buf++;
I = *buf++;
R = *buf++;
IX = loadUint16( &buf );
IY = loadUint16( &buf );
PC = loadUint16( &buf );
SP = loadUint16( &buf );
iflags_ = loadUint16( &buf );
iflags_ = (iflags_ << 16) | loadUint16(&buf);
cycles_ = loadUint16( &buf );
cycles_ = (cycles_ << 16) | loadUint16(&buf);
return buf - buffer;
}
OpcodeInfo OpInfoCB_[256] = {
{ &opcode_cb_00, 8 }, // RLC B
{ &opcode_cb_01, 8 }, // RLC C
{ &opcode_cb_02, 8 }, // RLC D
{ &opcode_cb_03, 8 }, // RLC E
{ &opcode_cb_04, 8 }, // RLC H
{ &opcode_cb_05, 8 }, // RLC L
{ &opcode_cb_06, 15 }, // RLC (HL)
{ &opcode_cb_07, 8 }, // RLC A
{ &opcode_cb_08, 8 }, // RRC B
{ &opcode_cb_09, 8 }, // RRC C
{ &opcode_cb_0a, 8 }, // RRC D
{ &opcode_cb_0b, 8 }, // RRC E
{ &opcode_cb_0c, 8 }, // RRC H
{ &opcode_cb_0d, 8 }, // RRC L
{ &opcode_cb_0e, 15 }, // RRC (HL)
{ &opcode_cb_0f, 8 }, // RRC A
{ &opcode_cb_10, 8 }, // RL B
{ &opcode_cb_11, 8 }, // RL C
{ &opcode_cb_12, 8 }, // RL D
{ &opcode_cb_13, 8 }, // RL E
{ &opcode_cb_14, 8 }, // RL H
{ &opcode_cb_15, 8 }, // RL L
{ &opcode_cb_16, 15 }, // RL (HL)
{ &opcode_cb_17, 8 }, // RL A
{ &opcode_cb_18, 8 }, // RR B
{ &opcode_cb_19, 8 }, // RR C
{ &opcode_cb_1a, 8 }, // RR D
{ &opcode_cb_1b, 8 }, // RR E
{ &opcode_cb_1c, 8 }, // RR H
{ &opcode_cb_1d, 8 }, // RR L
{ &opcode_cb_1e, 15 }, // RR (HL)
{ &opcode_cb_1f, 8 }, // RR A
{ &opcode_cb_20, 8 }, // SLA B
{ &opcode_cb_21, 8 }, // SLA C
{ &opcode_cb_22, 8 }, // SLA D
{ &opcode_cb_23, 8 }, // SLA E
{ &opcode_cb_24, 8 }, // SLA H
{ &opcode_cb_25, 8 }, // SLA L
{ &opcode_cb_26, 15 }, // SLA (HL)
{ &opcode_cb_27, 8 }, // SLA A
{ &opcode_cb_28, 8 }, // SRA B
{ &opcode_cb_29, 8 }, // SRA C
{ &opcode_cb_2a, 8 }, // SRA D
{ &opcode_cb_2b, 8 }, // SRA E
{ &opcode_cb_2c, 8 }, // SRA H
{ &opcode_cb_2d, 8 }, // SRA L
{ &opcode_cb_2e, 15 }, // SRA (HL)
{ &opcode_cb_2f, 8 }, // SRA A
{ &opcode_cb_30, 8 }, // SLL B
{ &opcode_cb_31, 8 }, // SLL C
{ &opcode_cb_32, 8 }, // SLL D
{ &opcode_cb_33, 8 }, // SLL E
{ &opcode_cb_34, 8 }, // SLL H
{ &opcode_cb_35, 8 }, // SLL L
{ &opcode_cb_36, 15 }, // SLL (HL)
{ &opcode_cb_37, 8 }, // SLL A
{ &opcode_cb_38, 8 }, // SRL B
{ &opcode_cb_39, 8 }, // SRL C
{ &opcode_cb_3a, 8 }, // SRL D
{ &opcode_cb_3b, 8 }, // SRL E
{ &opcode_cb_3c, 8 }, // SRL H
{ &opcode_cb_3d, 8 }, // SRL L
{ &opcode_cb_3e, 15 }, // SRL (HL)
{ &opcode_cb_3f, 8 }, // SRL A
{ &opcode_cb_40, 8 }, // BIT 0, B
{ &opcode_cb_41, 8 }, // BIT 0, C
{ &opcode_cb_42, 8 }, // BIT 0, D
{ &opcode_cb_43, 8 }, // BIT 0, E
{ &opcode_cb_44, 8 }, // BIT 0, H
{ &opcode_cb_45, 8 }, // BIT 0, L
{ &opcode_cb_46, 12 }, // BIT 0, (HL)
{ &opcode_cb_47, 8 }, // BIT 0, A
{ &opcode_cb_48, 8 }, // BIT 1, B
{ &opcode_cb_49, 8 }, // BIT 1, C
{ &opcode_cb_4a, 8 }, // BIT 1, D
{ &opcode_cb_4b, 8 }, // BIT 1, E
{ &opcode_cb_4c, 8 }, // BIT 1, H
{ &opcode_cb_4d, 8 }, // BIT 1, L
{ &opcode_cb_4e, 12 }, // BIT 1, (HL)
{ &opcode_cb_4f, 8 }, // BIT 1, A
{ &opcode_cb_50, 8 }, // BIT 2, B
{ &opcode_cb_51, 8 }, // BIT 2, C
{ &opcode_cb_52, 8 }, // BIT 2, D
{ &opcode_cb_53, 8 }, // BIT 2, E
{ &opcode_cb_54, 8 }, // BIT 2, H
{ &opcode_cb_55, 8 }, // BIT 2, L
{ &opcode_cb_56, 12 }, // BIT 2, (HL)
{ &opcode_cb_57, 8 }, // BIT 2, A
{ &opcode_cb_58, 8 }, // BIT 3, B
{ &opcode_cb_59, 8 }, // BIT 3, C
{ &opcode_cb_5a, 8 }, // BIT 3, D
{ &opcode_cb_5b, 8 }, // BIT 3, E
{ &opcode_cb_5c, 8 }, // BIT 3, H
{ &opcode_cb_5d, 8 }, // BIT 3, L
{ &opcode_cb_5e, 12 }, // BIT 3, (HL)
{ &opcode_cb_5f, 8 }, // BIT 3, A
{ &opcode_cb_60, 8 }, // BIT 4, B
{ &opcode_cb_61, 8 }, // BIT 4, C
{ &opcode_cb_62, 8 }, // BIT 4, D
{ &opcode_cb_63, 8 }, // BIT 4, E
{ &opcode_cb_64, 8 }, // BIT 4, H
{ &opcode_cb_65, 8 }, // BIT 4, L
{ &opcode_cb_66, 12 }, // BIT 4, (HL)
{ &opcode_cb_67, 8 }, // BIT 4, A
{ &opcode_cb_68, 8 }, // BIT 5, B
{ &opcode_cb_69, 8 }, // BIT 5, C
{ &opcode_cb_6a, 8 }, // BIT 5, D
{ &opcode_cb_6b, 8 }, // BIT 5, E
{ &opcode_cb_6c, 8 }, // BIT 5, H
{ &opcode_cb_6d, 8 }, // BIT 5, L
{ &opcode_cb_6e, 12 }, // BIT 5, (HL)
{ &opcode_cb_6f, 8 }, // BIT 5, A
{ &opcode_cb_70, 8 }, // BIT 6, B
{ &opcode_cb_71, 8 }, // BIT 6, C
{ &opcode_cb_72, 8 }, // BIT 6, D
{ &opcode_cb_73, 8 }, // BIT 6, E
{ &opcode_cb_74, 8 }, // BIT 6, H
{ &opcode_cb_75, 8 }, // BIT 6, L
{ &opcode_cb_76, 12 }, // BIT 6, (HL)
{ &opcode_cb_77, 8 }, // BIT 6, A
{ &opcode_cb_78, 8 }, // BIT 7, B
{ &opcode_cb_79, 8 }, // BIT 7, C
{ &opcode_cb_7a, 8 }, // BIT 7, D
{ &opcode_cb_7b, 8 }, // BIT 7, E
{ &opcode_cb_7c, 8 }, // BIT 7, H
{ &opcode_cb_7d, 8 }, // BIT 7, L
{ &opcode_cb_7e, 12 }, // BIT 7, (HL)
{ &opcode_cb_7f, 8 }, // BIT 7, A
{ &opcode_cb_80, 8 }, // RES 0, B
{ &opcode_cb_81, 8 }, // RES 0, C
{ &opcode_cb_82, 8 }, // RES 0, D
{ &opcode_cb_83, 8 }, // RES 0, E
{ &opcode_cb_84, 8 }, // RES 0, H
{ &opcode_cb_85, 8 }, // RES 0, L
{ &opcode_cb_86, 15 }, // RES 0, (HL)
{ &opcode_cb_87, 8 }, // RES 0, A
{ &opcode_cb_88, 8 }, // RES 1, B
{ &opcode_cb_89, 8 }, // RES 1, C
{ &opcode_cb_8a, 8 }, // RES 1, D
{ &opcode_cb_8b, 8 }, // RES 1, E
{ &opcode_cb_8c, 8 }, // RES 1, H
{ &opcode_cb_8d, 8 }, // RES 1, L
{ &opcode_cb_8e, 15 }, // RES 1, (HL)
{ &opcode_cb_8f, 8 }, // RES 1, A
{ &opcode_cb_90, 8 }, // RES 2, B
{ &opcode_cb_91, 8 }, // RES 2, C
{ &opcode_cb_92, 8 }, // RES 2, D
{ &opcode_cb_93, 8 }, // RES 2, E
{ &opcode_cb_94, 8 }, // RES 2, H
{ &opcode_cb_95, 8 }, // RES 2, L
{ &opcode_cb_96, 15 }, // RES 2, (HL)
{ &opcode_cb_97, 8 }, // RES 2, A
{ &opcode_cb_98, 8 }, // RES 3, B
{ &opcode_cb_99, 8 }, // RES 3, C
{ &opcode_cb_9a, 8 }, // RES 3, D
{ &opcode_cb_9b, 8 }, // RES 3, E
{ &opcode_cb_9c, 8 }, // RES 3, H
{ &opcode_cb_9d, 8 }, // RES 3, L
{ &opcode_cb_9e, 15 }, // RES 3, (HL)
{ &opcode_cb_9f, 8 }, // RES 3, A
{ &opcode_cb_a0, 8 }, // RES 4, B
{ &opcode_cb_a1, 8 }, // RES 4, C
{ &opcode_cb_a2, 8 }, // RES 4, D
{ &opcode_cb_a3, 8 }, // RES 4, E
{ &opcode_cb_a4, 8 }, // RES 4, H
{ &opcode_cb_a5, 8 }, // RES 4, L
{ &opcode_cb_a6, 15 }, // RES 4, (HL)
{ &opcode_cb_a7, 8 }, // RES 4, A
{ &opcode_cb_a8, 8 }, // RES 5, B
{ &opcode_cb_a9, 8 }, // RES 5, C
{ &opcode_cb_aa, 8 }, // RES 5, D
{ &opcode_cb_ab, 8 }, // RES 5, E
{ &opcode_cb_ac, 8 }, // RES 5, H
{ &opcode_cb_ad, 8 }, // RES 5, L
{ &opcode_cb_ae, 15 }, // RES 5, (HL)
{ &opcode_cb_af, 8 }, // RES 5, A
{ &opcode_cb_b0, 8 }, // RES 6, B
{ &opcode_cb_b1, 8 }, // RES 6, C
{ &opcode_cb_b2, 8 }, // RES 6, D
{ &opcode_cb_b3, 8 }, // RES 6, E
{ &opcode_cb_b4, 8 }, // RES 6, H
{ &opcode_cb_b5, 8 }, // RES 6, L
{ &opcode_cb_b6, 15 }, // RES 6, (HL)
{ &opcode_cb_b7, 8 }, // RES 6, A
{ &opcode_cb_b8, 8 }, // RES 7, B
{ &opcode_cb_b9, 8 }, // RES 7, C
{ &opcode_cb_ba, 8 }, // RES 7, D
{ &opcode_cb_bb, 8 }, // RES 7, E
{ &opcode_cb_bc, 8 }, // RES 7, H
{ &opcode_cb_bd, 8 }, // RES 7, L
{ &opcode_cb_be, 15 }, // RES 7, (HL)
{ &opcode_cb_bf, 8 }, // RES 7, A
{ &opcode_cb_c0, 8 }, // SET 0, B
{ &opcode_cb_c1, 8 }, // SET 0, C
{ &opcode_cb_c2, 8 }, // SET 0, D
{ &opcode_cb_c3, 8 }, // SET 0, E
{ &opcode_cb_c4, 8 }, // SET 0, H
{ &opcode_cb_c5, 8 }, // SET 0, L
{ &opcode_cb_c6, 15 }, // SET 0, (HL)
{ &opcode_cb_c7, 8 }, // SET 0, A
{ &opcode_cb_c8, 8 }, // SET 1, B
{ &opcode_cb_c9, 8 }, // SET 1, C
{ &opcode_cb_ca, 8 }, // SET 1, D
{ &opcode_cb_cb, 8 }, // SET 1, E
{ &opcode_cb_cc, 8 }, // SET 1, H
{ &opcode_cb_cd, 8 }, // SET 1, L
{ &opcode_cb_ce, 15 }, // SET 1, (HL)
{ &opcode_cb_cf, 8 }, // SET 1, A
{ &opcode_cb_d0, 8 }, // SET 2, B
{ &opcode_cb_d1, 8 }, // SET 2, C
{ &opcode_cb_d2, 8 }, // SET 2, D
{ &opcode_cb_d3, 8 }, // SET 2, E
{ &opcode_cb_d4, 8 }, // SET 2, H
{ &opcode_cb_d5, 8 }, // SET 2, L
{ &opcode_cb_d6, 15 }, // SET 2, (HL)
{ &opcode_cb_d7, 8 }, // SET 2, A
{ &opcode_cb_d8, 8 }, // SET 3, B
{ &opcode_cb_d9, 8 }, // SET 3, C
{ &opcode_cb_da, 8 }, // SET 3, D
{ &opcode_cb_db, 8 }, // SET 3, E
{ &opcode_cb_dc, 8 }, // SET 3, H
{ &opcode_cb_dd, 8 }, // SET 3, L
{ &opcode_cb_de, 15 }, // SET 3, (HL)
{ &opcode_cb_df, 8 }, // SET 3, A
{ &opcode_cb_e0, 8 }, // SET 4, B
{ &opcode_cb_e1, 8 }, // SET 4, C
{ &opcode_cb_e2, 8 }, // SET 4, D
{ &opcode_cb_e3, 8 }, // SET 4, E
{ &opcode_cb_e4, 8 }, // SET 4, H
{ &opcode_cb_e5, 8 }, // SET 4, L
{ &opcode_cb_e6, 15 }, // SET 4, (HL)
{ &opcode_cb_e7, 8 }, // SET 4, A
{ &opcode_cb_e8, 8 }, // SET 5, B
{ &opcode_cb_e9, 8 }, // SET 5, C
{ &opcode_cb_ea, 8 }, // SET 5, D
{ &opcode_cb_eb, 8 }, // SET 5, E
{ &opcode_cb_ec, 8 }, // SET 5, H
{ &opcode_cb_ed, 8 }, // SET 5, L
{ &opcode_cb_ee, 15 }, // SET 5, (HL)
{ &opcode_cb_ef, 8 }, // SET 5, A
{ &opcode_cb_f0, 8 }, // SET 6, B
{ &opcode_cb_f1, 8 }, // SET 6, C
{ &opcode_cb_f2, 8 }, // SET 6, D
{ &opcode_cb_f3, 8 }, // SET 6, E
{ &opcode_cb_f4, 8 }, // SET 6, H
{ &opcode_cb_f5, 8 }, // SET 6, L
{ &opcode_cb_f6, 15 }, // SET 6, (HL)
{ &opcode_cb_f7, 8 }, // SET 6, A
{ &opcode_cb_f8, 8 }, // SET 7, B
{ &opcode_cb_f9, 8 }, // SET 7, C
{ &opcode_cb_fa, 8 }, // SET 7, D
{ &opcode_cb_fb, 8 }, // SET 7, E
{ &opcode_cb_fc, 8 }, // SET 7, H
{ &opcode_cb_fd, 8 }, // SET 7, L
{ &opcode_cb_fe, 15 }, // SET 7, (HL)
{ &opcode_cb_ff, 8 } // SET 7, A
};
void opcode_cb_00() // RLC B
{
B = rotateLeftCarry( B );
}
void opcode_cb_01() // RLC C
{
C = rotateLeftCarry( C );
}
void opcode_cb_02() // RLC D
{
D = rotateLeftCarry( D );
}
void opcode_cb_03() // RLC E
{
E = rotateLeftCarry( E );
}
void opcode_cb_04() // RLC H
{
H = rotateLeftCarry( H );
}
void opcode_cb_05() // RLC L
{
L = rotateLeftCarry( L );
}
void opcode_cb_06() // RLC (HL)
{
writeByte( HL(), rotateLeftCarry( readByte( HL() ) ) );
}
void opcode_cb_07() // RLC A
{
A = rotateLeftCarry( A );
}
void opcode_cb_08() // RRC B
{
B = rotateRightCarry( B );
}
void opcode_cb_09() // RRC C
{
C = rotateLeftCarry( C );
}
void opcode_cb_0a() // RRC D
{
D = rotateLeftCarry( D );
}
void opcode_cb_0b() // RRC E
{
E = rotateLeftCarry( E );
}
void opcode_cb_0c() // RRC H
{
H = rotateLeftCarry( H );
}
void opcode_cb_0d() // RRC L
{
L = rotateLeftCarry( L );
}
void opcode_cb_0e() // RRC (HL)
{
writeByte( HL(), rotateRightCarry( readByte( HL() ) ) );
}
void opcode_cb_0f() // RRC A
{
A = rotateLeftCarry( A );
}
void opcode_cb_10() // RL B
{
B = rotateLeft( B );
}
void opcode_cb_11() // RL C
{
C = rotateLeft( C );
}
void opcode_cb_12() // RL D
{
D = rotateLeft( D );
}
void opcode_cb_13() // RL E
{
E = rotateLeft( E );
}
void opcode_cb_14() // RL H
{
H = rotateLeft( H );
}
void opcode_cb_15() // RL L
{
L = rotateLeft( L );
}
void opcode_cb_16() // RL (HL)
{
writeByte( HL(), rotateLeft( readByte( HL() ) ) );
}
void opcode_cb_17() // RL A
{
A = rotateLeft( A );
}
void opcode_cb_18() // RR B
{
B = rotateRight( B );
}
void opcode_cb_19() // RR C
{
C = rotateRight( C );
}
void opcode_cb_1a() // RR D
{
D = rotateRight( D );
}
void opcode_cb_1b() // RR E
{
E = rotateRight( E );
}
void opcode_cb_1c() // RR H
{
H = rotateRight( H );
}
void opcode_cb_1d() // RR L
{
L = rotateRight( L );
}
void opcode_cb_1e() // RR (HL)
{
writeByte( HL(), rotateRight( readByte( HL() ) ) );
}
void opcode_cb_1f() // RR A
{
A = rotateRight( A );
}
void opcode_cb_20() // SLA B
{
B = shiftLeft( B );
}
void opcode_cb_21() // SLA C
{
C = shiftLeft( C );
}
void opcode_cb_22() // SLA D
{
D = shiftLeft( D );
}
void opcode_cb_23() // SLA E
{
E = shiftLeft( E );
}
void opcode_cb_24() // SLA H
{
H = shiftLeft( H );
}
void opcode_cb_25() // SLA L
{
L = shiftLeft( L );
}
void opcode_cb_26() // SLA (HL)
{
writeByte( HL(), shiftLeft( readByte( HL() ) ) );
}
void opcode_cb_27() // SLA A
{
A = shiftLeft( A );
}
void opcode_cb_28() // SRA B
{
B = shiftRightArith( B );
}
void opcode_cb_29() // SRA C
{
C = shiftRightArith( C );
}
void opcode_cb_2a() // SRA D
{
D = shiftRightArith( D );
}
void opcode_cb_2b() // SRA E
{
E = shiftRightArith( E );
}
void opcode_cb_2c() // SRA H
{
H = shiftRightArith( H );
}
void opcode_cb_2d() // SRA L
{
L = shiftRightArith( L );
}
void opcode_cb_2e() // SRA (HL)
{
writeByte( HL(), shiftRightArith( readByte( HL() ) ) );
}
void opcode_cb_2f() // SRA A
{
A = shiftRightArith( A );
}
void opcode_cb_30() // SLL B
{
B = shiftLeft( B ) | 0x01;
}
void opcode_cb_31() // SLL C
{
C = shiftLeft( C ) | 0x01;
}
void opcode_cb_32() // SLL D
{
D = shiftLeft( D ) | 0x01;
}
void opcode_cb_33() // SLL E
{
E = shiftLeft( E ) | 0x01;
}
void opcode_cb_34() // SLL H
{
H = shiftLeft( H ) | 0x01;
}
void opcode_cb_35() // SLL L
{
L = shiftLeft( L ) | 0x01;
}
void opcode_cb_36() // SLL (HL)
{
writeByte( HL(), shiftLeft( readByte( HL() ) ) | 0x01 );
}
void opcode_cb_37() // SLL A
{
A = shiftLeft( A ) | 0x01;
}
void opcode_cb_38() // SRL B
{
B = shiftRightLogical( B );
}
void opcode_cb_39() // SRL C
{
C = shiftRightLogical( C );
}
void opcode_cb_3a() // SRL D
{
D = shiftRightLogical( D );
}
void opcode_cb_3b() // SRL E
{
E = shiftRightLogical( E );
}
void opcode_cb_3c() // SRL H
{
H = shiftRightLogical( H );
}
void opcode_cb_3d() // SRL L
{
L = shiftRightLogical( L );
}
void opcode_cb_3e() // SRL (HL)
{
writeByte( HL(), shiftRightLogical( readByte( HL() ) ) );
}
void opcode_cb_3f() // SRL A
{
A = shiftRightLogical( A );
}
void opcode_cb_40() // BIT 0, B
{
testBit( 0, B );
}
void opcode_cb_41() // BIT 0, C
{
testBit( 0, C );
}
void opcode_cb_42() // BIT 0, D
{
testBit( 0, D );
}
void opcode_cb_43() // BIT 0, E
{
testBit( 0, E );
}
void opcode_cb_44() // BIT 0, H
{
testBit( 0, H );
}
void opcode_cb_45() // BIT 0, L
{
testBit( 0, L );
}
void opcode_cb_46() // BIT 0, (HL)
{
testBit( 0, readByte( HL() ) );
}
void opcode_cb_47() // BIT 0, A
{
testBit( 0, A );
}
void opcode_cb_48() // BIT 1, B
{
testBit( 1, B );
}
void opcode_cb_49() // BIT 1, C
{
testBit( 1, C );
}
void opcode_cb_4a() // BIT 1, D
{
testBit( 1, D );
}
void opcode_cb_4b() // BIT 1, E
{
testBit( 1, E );
}
void opcode_cb_4c() // BIT 1, H
{
testBit( 1, H );
}
void opcode_cb_4d() // BIT 1, L
{
testBit( 1, L );
}
void opcode_cb_4e() // BIT 1, (HL)
{
testBit( 1, readByte( HL() ) );
}
void opcode_cb_4f() // BIT 1, A
{
testBit( 1, A );
}
void opcode_cb_50() // BIT 2, B
{
testBit( 2, B );
}
void opcode_cb_51() // BIT 2, C
{
testBit( 2, C );
}
void opcode_cb_52() // BIT 2, D
{
testBit( 2, D );
}
void opcode_cb_53() // BIT 2, E
{
testBit( 2, E );
}
void opcode_cb_54() // BIT 2, H
{
testBit( 2, H );
}
void opcode_cb_55() // BIT 2, L
{
testBit( 2, L );
}
void opcode_cb_56() // BIT 2, (HL)
{
testBit( 2, readByte( HL() ) );
}
void opcode_cb_57() // BIT 2, A
{
testBit( 2, A );
}
void opcode_cb_58() // BIT 3, B
{
testBit( 3, B );
}
void opcode_cb_59() // BIT 3, C
{
testBit( 3, C );
}
void opcode_cb_5a() // BIT 3, D
{
testBit( 3, D );
}
void opcode_cb_5b() // BIT 3, E
{
testBit( 3, E );
}
void opcode_cb_5c() // BIT 3, H
{
testBit( 3, H );
}
void opcode_cb_5d() // BIT 3, L
{
testBit( 3, L );
}
void opcode_cb_5e() // BIT 3, (HL)
{
testBit( 3, readByte( HL() ) );
}
void opcode_cb_5f() // BIT 3, A
{
testBit( 3, A );
}
void opcode_cb_60() // BIT 4, B
{
testBit( 4, B );
}
void opcode_cb_61() // BIT 4, C
{
testBit( 4, C );
}
void opcode_cb_62() // BIT 4, D
{
testBit( 4, D );
}
void opcode_cb_63() // BIT 4, E
{
testBit( 4, E );
}
void opcode_cb_64() // BIT 4, H
{
testBit( 4, H );
}
void opcode_cb_65() // BIT 4, L
{
testBit( 4, L );
}
void opcode_cb_66() // BIT 4, (HL)
{
testBit( 4, readByte( HL() ) );
}
void opcode_cb_67() // BIT 4, A
{
testBit( 4, A );
}
void opcode_cb_68() // BIT 5, B
{
testBit( 5, B );
}
void opcode_cb_69() // BIT 5, C
{
testBit( 5, C );
}
void opcode_cb_6a() // BIT 5, D
{
testBit( 5, D );
}
void opcode_cb_6b() // BIT 5, E
{
testBit( 5, E );
}
void opcode_cb_6c() // BIT 5, H
{
testBit( 5, H );
}
void opcode_cb_6d() // BIT 5, L
{
testBit( 5, L );
}
void opcode_cb_6e() // BIT 5, (HL)
{
testBit( 5, readByte( HL() ) );
}
void opcode_cb_6f() // BIT 5, A
{
testBit( 5, A );
}
void opcode_cb_70() // BIT 6, B
{
testBit( 6, B );
}
void opcode_cb_71() // BIT 6, C
{
testBit( 6, C );
}
void opcode_cb_72() // BIT 6, D
{
testBit( 6, D );
}
void opcode_cb_73() // BIT 6, E
{
testBit( 6, E );
}
void opcode_cb_74() // BIT 6, H
{
testBit( 6, H );
}
void opcode_cb_75() // BIT 6, L
{
testBit( 6, L );
}
void opcode_cb_76() // BIT 6, (HL)
{
testBit( 6, readByte( HL() ) );
}
void opcode_cb_77() // BIT 6, A
{
testBit( 6, A );
}
void opcode_cb_78() // BIT 7, B
{
testBit( 7, B );
}
void opcode_cb_79() // BIT 7, C
{
testBit( 7, C );
}
void opcode_cb_7a() // BIT 7, D
{
testBit( 7, D );
}
void opcode_cb_7b() // BIT 7, E
{
testBit( 7, E );
}
void opcode_cb_7c() // BIT 7, H
{
testBit( 7, H );
}
void opcode_cb_7d() // BIT 7, L
{
testBit( 7, L );
}
void opcode_cb_7e() // BIT 7, (HL)
{
testBit( 7, readByte( HL() ) );
}
void opcode_cb_7f() // BIT 7, A
{
testBit( 7, A );
}
void opcode_cb_80() // RES 0, B
{
B &= ~(unsigned char) (1 << 0);
}
void opcode_cb_81() // RES 0, C
{
C &= ~(unsigned char) (1 << 0);
}
void opcode_cb_82() // RES 0, D
{
D &= ~(unsigned char) (1 << 0);
}
void opcode_cb_83() // RES 0, E
{
E &= ~(unsigned char) (1 << 0);
}
void opcode_cb_84() // RES 0, H
{
H &= ~(unsigned char) (1 << 0);
}
void opcode_cb_85() // RES 0, L
{
L &= ~(unsigned char) (1 << 0);
}
void opcode_cb_86() // RES 0, (HL)
{
writeByte( HL(), readByte( HL() ) & (unsigned char) ~(unsigned char) (1 << 0) );
}
void opcode_cb_87() // RES 0, A
{
A &= ~(unsigned char) (1 << 0);
}
void opcode_cb_88() // RES 1, B
{
B &= ~(unsigned char) (1 << 1);
}
void opcode_cb_89() // RES 1, C
{
C &= ~(unsigned char) (1 << 1);
}
void opcode_cb_8a() // RES 1, D
{
D &= ~(unsigned char) (1 << 1);
}
void opcode_cb_8b() // RES 1, E
{
E &= ~(unsigned char) (1 << 1);
}
void opcode_cb_8c() // RES 1, H
{
H &= ~(unsigned char) (1 << 1);
}
void opcode_cb_8d() // RES 1, L
{
L &= ~(unsigned char) (1 << 1);
}
void opcode_cb_8e() // RES 1, (HL)
{
writeByte( HL(), readByte( HL() ) & (unsigned char) ~(unsigned char) (1 << 1) );
}
void opcode_cb_8f() // RES 1, A
{
A &= ~(unsigned char) (1 << 1);
}
void opcode_cb_90() // RES 2, B
{
B &= ~(unsigned char) (1 << 2);
}
void opcode_cb_91() // RES 2, C
{
C &= ~(unsigned char) (1 << 2);
}
void opcode_cb_92() // RES 2, D
{
D &= ~(unsigned char) (1 << 2);
}
void opcode_cb_93() // RES 2, E
{
E &= ~(unsigned char) (1 << 2);
}
void opcode_cb_94() // RES 2, H
{
H &= ~(unsigned char) (1 << 2);
}
void opcode_cb_95() // RES 2, L
{
L &= ~(unsigned char) (1 << 2);
}
void opcode_cb_96() // RES 2, (HL)
{
writeByte( HL(), readByte( HL() ) & (unsigned char) ~(unsigned char) (1 << 2) );
}
void opcode_cb_97() // RES 2, A
{
A &= ~(unsigned char) (1 << 2);
}
void opcode_cb_98() // RES 3, B
{
B &= ~(unsigned char) (1 << 3);
}
void opcode_cb_99() // RES 3, C
{
C &= ~(unsigned char) (1 << 3);
}
void opcode_cb_9a() // RES 3, D
{
D &= ~(unsigned char) (1 << 3);
}
void opcode_cb_9b() // RES 3, E
{
E &= ~(unsigned char) (1 << 3);
}
void opcode_cb_9c() // RES 3, H
{
H &= ~(unsigned char) (1 << 3);
}
void opcode_cb_9d() // RES 3, L
{
L &= ~(unsigned char) (1 << 3);
}
void opcode_cb_9e() // RES 3, (HL)
{
writeByte( HL(), readByte( HL() ) & (unsigned char) ~(unsigned char) (1 << 3) );
}
void opcode_cb_9f() // RES 3, A
{
A &= ~(unsigned char) (1 << 3);
}
void opcode_cb_a0() // RES 4, B
{
B &= ~(unsigned char) (1 << 4);
}
void opcode_cb_a1() // RES 4, C
{
C &= ~(unsigned char) (1 << 4);
}
void opcode_cb_a2() // RES 4, D
{
D &= ~(unsigned char) (1 << 4);
}
void opcode_cb_a3() // RES 4, E
{
E &= ~(unsigned char) (1 << 4);
}
void opcode_cb_a4() // RES 4, H
{
H &= ~(unsigned char) (1 << 4);
}
void opcode_cb_a5() // RES 4, L
{
L &= ~(unsigned char) (1 << 4);
}
void opcode_cb_a6() // RES 4, (HL)
{
writeByte( HL(), readByte( HL() ) & (unsigned char) ~(unsigned char) (1 << 4) );
}
void opcode_cb_a7() // RES 4, A
{
A &= ~(unsigned char) (1 << 4);
}
void opcode_cb_a8() // RES 5, B
{
B &= ~(unsigned char) (1 << 5);
}
void opcode_cb_a9() // RES 5, C
{
C &= ~(unsigned char) (1 << 5);
}
void opcode_cb_aa() // RES 5, D
{
D &= ~(unsigned char) (1 << 5);
}
void opcode_cb_ab() // RES 5, E
{
E &= ~(unsigned char) (1 << 5);
}
void opcode_cb_ac() // RES 5, H
{
H &= ~(unsigned char) (1 << 5);
}
void opcode_cb_ad() // RES 5, L
{
L &= ~(unsigned char) (1 << 5);
}
void opcode_cb_ae() // RES 5, (HL)
{
writeByte( HL(), readByte( HL() ) & (unsigned char) ~(unsigned char) (1 << 5) );
}
void opcode_cb_af() // RES 5, A
{
A &= ~(unsigned char) (1 << 5);
}
void opcode_cb_b0() // RES 6, B
{
B &= ~(unsigned char) (1 << 6);
}
void opcode_cb_b1() // RES 6, C
{
C &= ~(unsigned char) (1 << 6);
}
void opcode_cb_b2() // RES 6, D
{
D &= ~(unsigned char) (1 << 6);
}
void opcode_cb_b3() // RES 6, E
{
E &= ~(unsigned char) (1 << 6);
}
void opcode_cb_b4() // RES 6, H
{
H &= ~(unsigned char) (1 << 6);
}
void opcode_cb_b5() // RES 6, L
{
L &= ~(unsigned char) (1 << 6);
}
void opcode_cb_b6() // RES 6, (HL)
{
writeByte( HL(), readByte( HL() ) & (unsigned char) ~(unsigned char) (1 << 6) );
}
void opcode_cb_b7() // RES 6, A
{
A &= ~(unsigned char) (1 << 6);
}
void opcode_cb_b8() // RES 7, B
{
B &= ~(unsigned char) (1 << 7);
}
void opcode_cb_b9() // RES 7, C
{
C &= ~(unsigned char) (1 << 7);
}
void opcode_cb_ba() // RES 7, D
{
D &= ~(unsigned char) (1 << 7);
}
void opcode_cb_bb() // RES 7, E
{
E &= ~(unsigned char) (1 << 7);
}
void opcode_cb_bc() // RES 7, H
{
H &= ~(unsigned char) (1 << 7);
}
void opcode_cb_bd() // RES 7, L
{
L &= ~(unsigned char) (1 << 7);
}
void opcode_cb_be() // RES 7, (HL)
{
writeByte( HL(), readByte( HL() ) & (unsigned char) ~(unsigned char) (1 << 7) );
}
void opcode_cb_bf() // RES 7, A
{
A &= ~(unsigned char) (1 << 7);
}
void opcode_cb_c0() // SET 0, B
{
B |= (unsigned char) (1 << 0);
}
void opcode_cb_c1() // SET 0, C
{
C |= (unsigned char) (1 << 0);
}
void opcode_cb_c2() // SET 0, D
{
D |= (unsigned char) (1 << 0);
}
void opcode_cb_c3() // SET 0, E
{
E |= (unsigned char) (1 << 0);
}
void opcode_cb_c4() // SET 0, H
{
H |= (unsigned char) (1 << 0);
}
void opcode_cb_c5() // SET 0, L
{
L |= (unsigned char) (1 << 0);
}
void opcode_cb_c6() // SET 0, (HL)
{
writeByte( HL(), readByte( HL() ) | (unsigned char) (1 << 0) );
}
void opcode_cb_c7() // SET 0, A
{
A |= (unsigned char) (1 << 0);
}
void opcode_cb_c8() // SET 1, B
{
B |= (unsigned char) (1 << 1);
}
void opcode_cb_c9() // SET 1, C
{
C |= (unsigned char) (1 << 1);
}
void opcode_cb_ca() // SET 1, D
{
D |= (unsigned char) (1 << 1);
}
void opcode_cb_cb() // SET 1, E
{
E |= (unsigned char) (1 << 1);
}
void opcode_cb_cc() // SET 1, H
{
H |= (unsigned char) (1 << 1);
}
void opcode_cb_cd() // SET 1, L
{
L |= (unsigned char) (1 << 1);
}
void opcode_cb_ce() // SET 1, (HL)
{
writeByte( HL(), readByte( HL() ) | (unsigned char) (1 << 1) );
}
void opcode_cb_cf() // SET 1, A
{
A |= (unsigned char) (1 << 1);
}
void opcode_cb_d0() // SET 2, B
{
B |= (unsigned char) (1 << 2);
}
void opcode_cb_d1() // SET 2, C
{
C |= (unsigned char) (1 << 2);
}
void opcode_cb_d2() // SET 2, D
{
D |= (unsigned char) (1 << 2);
}
void opcode_cb_d3() // SET 2, E
{
E |= (unsigned char) (1 << 2);
}
void opcode_cb_d4() // SET 2, H
{
H |= (unsigned char) (1 << 2);
}
void opcode_cb_d5() // SET 2, L
{
L |= (unsigned char) (1 << 2);
}
void opcode_cb_d6() // SET 2, (HL)
{
writeByte( HL(), readByte( HL() ) | (unsigned char) (1 << 2) );
}
void opcode_cb_d7() // SET 2, A
{
A |= (unsigned char) (1 << 2);
}
void opcode_cb_d8() // SET 3, B
{
B |= (unsigned char) (1 << 3);
}
void opcode_cb_d9() // SET 3, C
{
C |= (unsigned char) (1 << 3);
}
void opcode_cb_da() // SET 3, D
{
D |= (unsigned char) (1 << 3);
}
void opcode_cb_db() // SET 3, E
{
E |= (unsigned char) (1 << 3);
}
void opcode_cb_dc() // SET 3, H
{
H |= (unsigned char) (1 << 3);
}
void opcode_cb_dd() // SET 3, L
{
L |= (unsigned char) (1 << 3);
}
void opcode_cb_de() // SET 3, (HL)
{
writeByte( HL(), readByte( HL() ) | (unsigned char) (1 << 3) );
}
void opcode_cb_df() // SET 3, A
{
A |= (unsigned char) (1 << 3);
}
void opcode_cb_e0() // SET 4, B
{
B |= (unsigned char) (1 << 4);
}
void opcode_cb_e1() // SET 4, C
{
C |= (unsigned char) (1 << 4);
}
void opcode_cb_e2() // SET 4, D
{
D |= (unsigned char) (1 << 4);
}
void opcode_cb_e3() // SET 4, E
{
E |= (unsigned char) (1 << 4);
}
void opcode_cb_e4() // SET 4, H
{
H |= (unsigned char) (1 << 4);
}
void opcode_cb_e5() // SET 4, L
{
L |= (unsigned char) (1 << 4);
}
void opcode_cb_e6() // SET 4, (HL)
{
writeByte( HL(), readByte( HL() ) | (unsigned char) (1 << 4) );
}
void opcode_cb_e7() // SET 4, A
{
A |= (unsigned char) (1 << 4);
}
void opcode_cb_e8() // SET 5, B
{
B |= (unsigned char) (1 << 5);
}
void opcode_cb_e9() // SET 5, C
{
C |= (unsigned char) (1 << 5);
}
void opcode_cb_ea() // SET 5, D
{
D |= (unsigned char) (1 << 5);
}
void opcode_cb_eb() // SET 5, E
{
E |= (unsigned char) (1 << 5);
}
void opcode_cb_ec() // SET 5, H
{
H |= (unsigned char) (1 << 5);
}
void opcode_cb_ed() // SET 5, L
{
L |= (unsigned char) (1 << 5);
}
void opcode_cb_ee() // SET 5, (HL)
{
writeByte( HL(), readByte( HL() ) | (unsigned char) (1 << 5) );
}
void opcode_cb_ef() // SET 5, A
{
A |= (unsigned char) (1 << 5);
}
void opcode_cb_f0() // SET 6, B
{
B |= (unsigned char) (1 << 6);
}
void opcode_cb_f1() // SET 6, C
{
C |= (unsigned char) (1 << 6);
}
void opcode_cb_f2() // SET 6, D
{
D |= (unsigned char) (1 << 6);
}
void opcode_cb_f3() // SET 6, E
{
E |= (unsigned char) (1 << 6);
}
void opcode_cb_f4() // SET 6, H
{
H |= (unsigned char) (1 << 6);
}
void opcode_cb_f5() // SET 6, L
{
L |= (unsigned char) (1 << 6);
}
void opcode_cb_f6() // SET 6, (HL)
{
writeByte( HL(), readByte( HL() ) | (unsigned char) (1 << 6) );
}
void opcode_cb_f7() // SET 6, A
{
A |= (unsigned char) (1 << 6);
}
void opcode_cb_f8() // SET 7, B
{
B |= (unsigned char) (1 << 7);
}
void opcode_cb_f9() // SET 7, C
{
C |= (unsigned char) (1 << 7);
}
void opcode_cb_fa() // SET 7, D
{
D |= (unsigned char) (1 << 7);
}
void opcode_cb_fb() // SET 7, E
{
E |= (unsigned char) (1 << 7);
}
void opcode_cb_fc() // SET 7, H
{
H |= (unsigned char) (1 << 7);
}
void opcode_cb_fd() // SET 7, L
{
L |= (unsigned char) (1 << 7);
}
void opcode_cb_fe() // SET 7, (HL)
{
writeByte( HL(), readByte( HL() ) | (unsigned char) (1 << 7) );
}
void opcode_cb_ff() // SET 7, A
{
A |= (unsigned char) (1 << 7);
}
OpcodeInfo OpInfoDD_[256] = {
{ 0, 0 }, // 0x00
{ 0, 0 }, // 0x01
{ 0, 0 }, // 0x02
{ 0, 0 }, // 0x03
{ 0, 0 }, // 0x04
{ 0, 0 }, // 0x05
{ 0, 0 }, // 0x06
{ 0, 0 }, // 0x07
{ 0, 0 }, // 0x08
{ &opcode_dd_09, 15 }, // ADD IX, BC
{ 0, 0 }, // 0x0A
{ 0, 0 }, // 0x0B
{ 0, 0 }, // 0x0C
{ 0, 0 }, // 0x0D
{ 0, 0 }, // 0x0E
{ 0, 0 }, // 0x0F
{ 0, 0 }, // 0x10
{ 0, 0 }, // 0x11
{ 0, 0 }, // 0x12
{ 0, 0 }, // 0x13
{ 0, 0 }, // 0x14
{ 0, 0 }, // 0x15
{ 0, 0 }, // 0x16
{ 0, 0 }, // 0x17
{ 0, 0 }, // 0x18
{ &opcode_dd_19, 15 }, // ADD IX, DE
{ 0, 0 }, // 0x1A
{ 0, 0 }, // 0x1B
{ 0, 0 }, // 0x1C
{ 0, 0 }, // 0x1D
{ 0, 0 }, // 0x1E
{ 0, 0 }, // 0x1F
{ 0, 0 }, // 0x20
{ &opcode_dd_21, 14 }, // LD IX, nn
{ &opcode_dd_22, 20 }, // LD (nn), IX
{ &opcode_dd_23, 10 }, // INC IX
{ &opcode_dd_24, 9 }, // INC IXH
{ &opcode_dd_25, 9 }, // DEC IXH
{ &opcode_dd_26, 9 }, // LD IXH, n
{ 0, 0 }, // 0x27
{ 0, 0 }, // 0x28
{ &opcode_dd_29, 15 }, // ADD IX, IX
{ &opcode_dd_2a, 20 }, // LD IX, (nn)
{ &opcode_dd_2b, 10 }, // DEC IX
{ &opcode_dd_2c, 9 }, // INC IXL
{ &opcode_dd_2d, 9 }, // DEC IXL
{ &opcode_dd_2e, 9 }, // LD IXL, n
{ 0, 0 }, // 0x2F
{ 0, 0 }, // 0x30
{ 0, 0 }, // 0x31
{ 0, 0 }, // 0x32
{ 0, 0 }, // 0x33
{ &opcode_dd_34, 23 }, // INC (IX + d)
{ &opcode_dd_35, 23 }, // DEC (IX + d)
{ &opcode_dd_36, 19 }, // LD (IX + d), n
{ 0, 0 }, // 0x37
{ 0, 0 }, // 0x38
{ &opcode_dd_39, 15 }, // ADD IX, SP
{ 0, 0 }, // 0x3A
{ 0, 0 }, // 0x3B
{ 0, 0 }, // 0x3C
{ 0, 0 }, // 0x3D
{ 0, 0 }, // 0x3E
{ 0, 0 }, // 0x3F
{ 0, 0 }, // 0x40
{ 0, 0 }, // 0x41
{ 0, 0 }, // 0x42
{ 0, 0 }, // 0x43
{ &opcode_dd_44, 9 }, // LD B, IXH
{ &opcode_dd_45, 9 }, // LD B, IXL
{ &opcode_dd_46, 19 }, // LD B, (IX + d)
{ 0, 0 }, // 0x47
{ 0, 0 }, // 0x48
{ 0, 0 }, // 0x49
{ 0, 0 }, // 0x4A
{ 0, 0 }, // 0x4B
{ &opcode_dd_4c, 9 }, // LD C, IXH
{ &opcode_dd_4d, 9 }, // LD C, IXL
{ &opcode_dd_4e, 19 }, // LD C, (IX + d)
{ 0, 0 }, // 0x4F
{ 0, 0 }, // 0x50
{ 0, 0 }, // 0x51
{ 0, 0 }, // 0x52
{ 0, 0 }, // 0x53
{ &opcode_dd_54, 9 }, // LD D, IXH
{ &opcode_dd_55, 9 }, // LD D, IXL
{ &opcode_dd_56, 19 }, // LD D, (IX + d)
{ 0, 0 }, // 0x57
{ 0, 0 }, // 0x58
{ 0, 0 }, // 0x59
{ 0, 0 }, // 0x5A
{ 0, 0 }, // 0x5B
{ &opcode_dd_5c, 9 }, // LD E, IXH
{ &opcode_dd_5d, 9 }, // LD E, IXL
{ &opcode_dd_5e, 19 }, // LD E, (IX + d)
{ 0, 0 }, // 0x5F
{ &opcode_dd_60, 9 }, // LD IXH, B
{ &opcode_dd_61, 9 }, // LD IXH, C
{ &opcode_dd_62, 9 }, // LD IXH, D
{ &opcode_dd_63, 9 }, // LD IXH, E
{ &opcode_dd_64, 9 }, // LD IXH, IXH
{ &opcode_dd_65, 9 }, // LD IXH, IXL
{ &opcode_dd_66, 9 }, // LD H, (IX + d)
{ &opcode_dd_67, 9 }, // LD IXH, A
{ &opcode_dd_68, 9 }, // LD IXL, B
{ &opcode_dd_69, 9 }, // LD IXL, C
{ &opcode_dd_6a, 9 }, // LD IXL, D
{ &opcode_dd_6b, 9 }, // LD IXL, E
{ &opcode_dd_6c, 9 }, // LD IXL, IXH
{ &opcode_dd_6d, 9 }, // LD IXL, IXL
{ &opcode_dd_6e, 9 }, // LD L, (IX + d)
{ &opcode_dd_6f, 9 }, // LD IXL, A
{ &opcode_dd_70, 19 }, // LD (IX + d), B
{ &opcode_dd_71, 19 }, // LD (IX + d), C
{ &opcode_dd_72, 19 }, // LD (IX + d), D
{ &opcode_dd_73, 19 }, // LD (IX + d), E
{ &opcode_dd_74, 19 }, // LD (IX + d), H
{ &opcode_dd_75, 19 }, // LD (IX + d), L
{ 0,19 }, // 0x76
{ &opcode_dd_77, 19 }, // LD (IX + d), A
{ 0, 0 }, // 0x78
{ 0, 0 }, // 0x79
{ 0, 0 }, // 0x7A
{ 0, 0 }, // 0x7B
{ &opcode_dd_7c, 9 }, // LD A, IXH
{ &opcode_dd_7d, 9 }, // LD A, IXL
{ &opcode_dd_7e, 19 }, // LD A, (IX + d)
{ 0, 0 }, // 0x7F
{ 0, 0 }, // 0x80
{ 0, 0 }, // 0x81
{ 0, 0 }, // 0x82
{ 0, 0 }, // 0x83
{ &opcode_dd_84, 9 }, // ADD A, IXH
{ &opcode_dd_85, 9 }, // ADD A, IXL
{ &opcode_dd_86, 19 }, // ADD A, (IX + d)
{ 0, 0 }, // 0x87
{ 0, 0 }, // 0x88
{ 0, 0 }, // 0x89
{ 0, 0 }, // 0x8A
{ 0, 0 }, // 0x8B
{ &opcode_dd_8c, 9 }, // ADC A, IXH
{ &opcode_dd_8d, 9 }, // ADC A, IXL
{ &opcode_dd_8e, 19 }, // ADC A, (IX + d)
{ 0, 0 }, // 0x8F
{ 0, 0 }, // 0x90
{ 0, 0 }, // 0x91
{ 0, 0 }, // 0x92
{ 0, 0 }, // 0x93
{ &opcode_dd_94, 9 }, // SUB IXH
{ &opcode_dd_95, 9 }, // SUB IXL
{ &opcode_dd_96, 19 }, // SUB (IX + d)
{ 0, 0 }, // 0x97
{ 0, 0 }, // 0x98
{ 0, 0 }, // 0x99
{ 0, 0 }, // 0x9A
{ 0, 0 }, // 0x9B
{ &opcode_dd_9c, 9 }, // SBC A, IXH
{ &opcode_dd_9d, 9 }, // SBC A, IXL
{ &opcode_dd_9e, 19 }, // SBC A, (IX + d)
{ 0, 0 }, // 0x9F
{ 0, 0 }, // 0xA0
{ 0, 0 }, // 0xA1
{ 0, 0 }, // 0xA2
{ 0, 0 }, // 0xA3
{ &opcode_dd_a4, 9 }, // AND IXH
{ &opcode_dd_a5, 9 }, // AND IXL
{ &opcode_dd_a6, 19 }, // AND (IX + d)
{ 0, 0 }, // 0xA7
{ 0, 0 }, // 0xA8
{ 0, 0 }, // 0xA9
{ 0, 0 }, // 0xAA
{ 0, 0 }, // 0xAB
{ &opcode_dd_ac, 9 }, // XOR IXH
{ &opcode_dd_ad, 9 }, // XOR IXL
{ &opcode_dd_ae, 19 }, // XOR (IX + d)
{ 0, 0 }, // 0xAF
{ 0, 0 }, // 0xB0
{ 0, 0 }, // 0xB1
{ 0, 0 }, // 0xB2
{ 0, 0 }, // 0xB3
{ &opcode_dd_b4, 9 }, // OR IXH
{ &opcode_dd_b5, 9 }, // OR IXL
{ &opcode_dd_b6, 19 }, // OR (IX + d)
{ 0, 0 }, // 0xB7
{ 0, 0 }, // 0xB8
{ 0, 0 }, // 0xB9
{ 0, 0 }, // 0xBA
{ 0, 0 }, // 0xBB
{ &opcode_dd_bc, 9 }, // CP IXH
{ &opcode_dd_bd, 9 }, // CP IXL
{ &opcode_dd_be, 19 }, // CP (IX + d)
{ 0, 0 }, // 0xBF
{ 0, 0 }, // 0xC0
{ 0, 0 }, // 0xC1
{ 0, 0 }, // 0xC2
{ 0, 0 }, // 0xC3
{ 0, 0 }, // 0xC4
{ 0, 0 }, // 0xC5
{ 0, 0 }, // 0xC6
{ 0, 0 }, // 0xC7
{ 0, 0 }, // 0xC8
{ 0, 0 }, // 0xC9
{ 0, 0 }, // 0xCA
{ &opcode_dd_cb, 0 }, //
{ 0, 0 }, // 0xCC
{ 0, 0 }, // 0xCD
{ 0, 0 }, // 0xCE
{ 0, 0 }, // 0xCF
{ 0, 0 }, // 0xD0
{ 0, 0 }, // 0xD1
{ 0, 0 }, // 0xD2
{ 0, 0 }, // 0xD3
{ 0, 0 }, // 0xD4
{ 0, 0 }, // 0xD5
{ 0, 0 }, // 0xD6
{ 0, 0 }, // 0xD7
{ 0, 0 }, // 0xD8
{ 0, 0 }, // 0xD9
{ 0, 0 }, // 0xDA
{ 0, 0 }, // 0xDB
{ 0, 0 }, // 0xDC
{ 0, 0 }, // 0xDD
{ 0, 0 }, // 0xDE
{ 0, 0 }, // 0xDF
{ 0, 0 }, // 0xE0
{ &opcode_dd_e1, 14 }, // POP IX
{ 0, 0 }, // 0xE2
{ &opcode_dd_e3, 23 }, // EX (SP), IX
{ 0, 0 }, // 0xE4
{ &opcode_dd_e5, 15 }, // PUSH IX
{ 0, 0 }, // 0xE6
{ 0, 0 }, // 0xE7
{ 0, 0 }, // 0xE8
{ &opcode_dd_e9, 8 }, // JP (IX)
{ 0, 0 }, // 0xEA
{ 0, 0 }, // 0xEB
{ 0, 0 }, // 0xEC
{ 0, 0 }, // 0xED
{ 0, 0 }, // 0xEE
{ 0, 0 }, // 0xEF
{ 0, 0 }, // 0xF0
{ 0, 0 }, // 0xF1
{ 0, 0 }, // 0xF2
{ 0, 0 }, // 0xF3
{ 0, 0 }, // 0xF4
{ 0, 0 }, // 0xF5
{ 0, 0 }, // 0xF6
{ 0, 0 }, // 0xF7
{ 0, 0 }, // 0xF8
{ &opcode_dd_f9, 10 }, // LD SP, IX
{ 0, 0 }, // 0xFA
{ 0, 0 }, // 0xFB
{ 0, 0 }, // 0xFC
{ 0, 0 }, // 0xFD
{ 0, 0 }, // 0xFE
{ 0, 0 } // 0xFF
};
void opcode_dd_09() // ADD IX, BC
{
unsigned rr = BC();
F &= (Zero | Sign | Parity);
if( ((IX & 0xFFF)+(rr & 0xFFF)) > 0xFFF ) F |= Halfcarry;
IX += rr;
if( IX & 0x10000 ) F |= Carry;
}
void opcode_dd_19() // ADD IX, DE
{
unsigned rr = DE();
F &= (Zero | Sign | Parity);
if( ((IX & 0xFFF)+(rr & 0xFFF)) > 0xFFF ) F |= Halfcarry;
IX += rr;
if( IX & 0x10000 ) F |= Carry;
}
void opcode_dd_21() // LD IX, nn
{
IX = fetchWord();
}
void opcode_dd_22() // LD (nn), IX
{
writeWord( fetchWord(), IX );
}
void opcode_dd_23() // INC IX
{
IX++;
}
void opcode_dd_24() // INC IXH
{
IX = (IX & 0xFF) | ((unsigned)incByte( IX >> 8 ) << 8);
}
void opcode_dd_25() // DEC IXH
{
IX = (IX & 0xFF) | ((unsigned)decByte( IX >> 8 ) << 8);
}
void opcode_dd_26() // LD IXH, n
{
IX = (IX & 0xFF) | ((unsigned)fetchByte() << 8);
}
void opcode_dd_29() // ADD IX, IX
{
F &= (Zero | Sign | Parity);
if( IX & 0x800 ) F |= Halfcarry;
IX += IX;
if( IX & 0x10000 ) F |= Carry;
}
void opcode_dd_2a() // LD IX, (nn)
{
IX = readWord( fetchWord() );
}
void opcode_dd_2b() // DEC IX
{
IX--;
}
void opcode_dd_2c() // INC IXL
{
IX = (IX & 0xFF00) | incByte( IX & 0xFF );
}
void opcode_dd_2d() // DEC IXL
{
IX = (IX & 0xFF00) | decByte( IX & 0xFF );
}
void opcode_dd_2e() // LD IXL, n
{
IX = (IX & 0xFF00) | fetchByte();
}
void opcode_dd_34() // INC (IX + d)
{
unsigned addr = addDispl( IX, fetchByte() );
writeByte( addr, incByte( readByte( addr ) ) );
}
void opcode_dd_35() // DEC (IX + d)
{
unsigned addr = addDispl( IX, fetchByte() );
writeByte( addr, decByte( readByte( addr ) ) );
}
void opcode_dd_36() // LD (IX + d), n
{
unsigned addr = addDispl( IX, fetchByte() );
writeByte( addr, fetchByte() );
}
void opcode_dd_39() // ADD IX, SP
{
F &= (Zero | Sign | Parity);
if( ((IX & 0xFFF)+(SP & 0xFFF)) > 0xFFF ) F |= Halfcarry;
IX += SP;
if( IX & 0x10000 ) F |= Carry;
}
void opcode_dd_44() // LD B, IXH
{
B = IX >> 8;
}
void opcode_dd_45() // LD B, IXL
{
B = IX & 0xFF;
}
void opcode_dd_46() // LD B, (IX + d)
{
B = readByte( addDispl(IX,fetchByte()) );
}
void opcode_dd_4c() // LD C, IXH
{
C = IX >> 8;
}
void opcode_dd_4d() // LD C, IXL
{
C = IX & 0xFF;
}
void opcode_dd_4e() // LD C, (IX + d)
{
C = readByte( addDispl(IX,fetchByte()) );
}
void opcode_dd_54() // LD D, IXH
{
D = IX >> 8;
}
void opcode_dd_55() // LD D, IXL
{
D = IX & 0xFF;
}
void opcode_dd_56() // LD D, (IX + d)
{
D = readByte( addDispl(IX,fetchByte()) );
}
void opcode_dd_5c() // LD E, IXH
{
E = IX >> 8;
}
void opcode_dd_5d() // LD E, IXL
{
E = IX & 0xFF;
}
void opcode_dd_5e() // LD E, (IX + d)
{
E = readByte( addDispl(IX,fetchByte()) );
}
void opcode_dd_60() // LD IXH, B
{
IX = (IX & 0xFF) | ((unsigned)B << 8);
}
void opcode_dd_61() // LD IXH, C
{
IX = (IX & 0xFF) | ((unsigned)C << 8);
}
void opcode_dd_62() // LD IXH, D
{
IX = (IX & 0xFF) | ((unsigned)D << 8);
}
void opcode_dd_63() // LD IXH, E
{
IX = (IX & 0xFF) | ((unsigned)E << 8);
}
void opcode_dd_64() // LD IXH, IXH
{
}
void opcode_dd_65() // LD IXH, IXL
{
IX = (IX & 0xFF) | ((IX << 8) & 0xFF00);
}
void opcode_dd_66() // LD H, (IX + d)
{
H = readByte( addDispl(IX,fetchByte()) );
}
void opcode_dd_67() // LD IXH, A
{
IX = (IX & 0xFF) | ((unsigned)A << 8);
}
void opcode_dd_68() // LD IXL, B
{
IX = (IX & 0xFF00) | B;
}
void opcode_dd_69() // LD IXL, C
{
IX = (IX & 0xFF00) | C;