/* * z80.c * * Written by * Andreas Boose * * This file is part of VICE, the Versatile Commodore Emulator. * See README for copyright notice. * * 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 program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA. * */ #include "../StdAfx.h" #include "../CPU.h" #include "../Memory.h" #include "../YamlHelper.h" #undef IN // Defined in windef.h #undef OUT // Defined in windef.h //#include "vice.h" // [AppleWin-TC] #include #include "../CommonVICE/6510core.h" // [AppleWin-TC] //#include "../CommonVICE/alarm.h" // [AppleWin-TC] #include "daa.h" //#include "debug.h" // [AppleWin-TC] #include "../CommonVICE/interrupt.h" //#include "log.h" // [AppleWin-TC] //#include "maincpu.h" // [AppleWin-TC] //#include "monitor.h" // [AppleWin-TC] #include "../CommonVICE/types.h" #include "z80.h" #include "z80mem.h" #include "z80regs.h" /*#define DEBUG_Z80*/ CLOCK maincpu_clk = 0; // [AppleWin-TC] static BYTE reg_a = 0; static BYTE reg_b = 0; static BYTE reg_c = 0; static BYTE reg_d = 0; static BYTE reg_e = 0; static BYTE reg_f = 0; static BYTE reg_h = 0; static BYTE reg_l = 0; static BYTE reg_ixh = 0; static BYTE reg_ixl = 0; static BYTE reg_iyh = 0; static BYTE reg_iyl = 0; static WORD reg_sp = 0; static DWORD z80_reg_pc = 0; static BYTE reg_i = 0; static BYTE reg_r = 0; static BYTE iff1 = 0; static BYTE iff2 = 0; static BYTE im_mode = 0; static BYTE reg_a2 = 0; static BYTE reg_b2 = 0; static BYTE reg_c2 = 0; static BYTE reg_d2 = 0; static BYTE reg_e2 = 0; static BYTE reg_f2 = 0; static BYTE reg_h2 = 0; static BYTE reg_l2 = 0; #if 0 // [AppleWin-TC] Not used static int dma_request = 0; #endif static BYTE *z80_bank_base; static int z80_bank_limit; #if 0 // [AppleWin-TC] Not used void z80_trigger_dma(void) { dma_request = 1; } #endif void z80_reset(void) { z80_reg_pc = 0; z80_regs.reg_pc = 0; iff1 = 0; iff2 = 0; im_mode = 0; } /*inline*/ static BYTE *z80mem_read_base(int addr) // [AppleWin-TC] { BYTE *p = _z80mem_read_base_tab_ptr[addr >> 8]; if (p == 0) return p; return p - (addr & 0xff00); } /*inline*/ static int z80mem_read_limit(int addr) // [AppleWin-TC] { return z80mem_read_limit_tab_ptr[addr >> 8]; } #define JUMP(addr) \ do { \ z80_reg_pc = (addr); \ z80_bank_base = z80mem_read_base(z80_reg_pc); \ z80_bank_limit = z80mem_read_limit(z80_reg_pc); \ z80_old_reg_pc = z80_reg_pc; \ } while (0) #define LOAD(addr) \ (*_z80mem_read_tab_ptr[(addr) >> 8])((WORD)(addr)) #define STORE(addr, value) \ (*_z80mem_write_tab_ptr[(addr) >> 8])((WORD)(addr), (BYTE)(value)) #define IN(addr) \ (io_read_tab[(addr) >> 8])((WORD)(addr)) #define OUT(addr, value) \ (io_write_tab[(addr) >> 8])((WORD)(addr), (BYTE)(value)) #define opcode_t DWORD #define FETCH_OPCODE(o) ((o) = (LOAD(z80_reg_pc) \ | (LOAD(z80_reg_pc + 1) << 8) \ | (LOAD(z80_reg_pc + 2) << 16) \ | (LOAD(z80_reg_pc + 3) << 24))) #define p0 (opcode & 0xff) #define p1 ((opcode >> 8) & 0xff) #define p2 ((opcode >> 16) & 0xff) #define p3 (opcode >> 24) #define p12 ((opcode >> 8) & 0xffff) #define p23 ((opcode >> 16) & 0xffff) #define CLK maincpu_clk #define INC_PC(value) (z80_reg_pc += (value)) /* ------------------------------------------------------------------------- */ #if 0 // [AppleWin-TC] static unsigned int z80_last_opcode_info; #define LAST_OPCODE_INFO z80_last_opcode_info /* Remember the number of the last opcode. By default, the opcode does not delay interrupt and does not change the I flag. */ #define SET_LAST_OPCODE(x) \ OPINFO_SET(LAST_OPCODE_INFO, (x), 0, 0, 0) /* Remember that the last opcode delayed a pending IRQ or NMI by one cycle. */ #define OPCODE_DELAYS_INTERRUPT() \ OPINFO_SET_DELAYS_INTERRUPT(LAST_OPCODE_INFO, 1) /* Remember that the last opcode changed the I flag from 0 to 1, so we have to dispatch an IRQ even if the I flag is 0 when we check it. */ #define OPCODE_DISABLES_IRQ() \ OPINFO_SET_DISABLES_IRQ(LAST_OPCODE_INFO, 1) /* Remember that the last opcode changed the I flag from 1 to 0, so we must not dispatch an IRQ even if the I flag is 1 when we check it. */ #define OPCODE_ENABLES_IRQ() \ OPINFO_SET_ENABLES_IRQ(LAST_OPCODE_INFO, 1) #else // [AppleWin-TC] #define SET_LAST_OPCODE(x) #define OPCODE_DELAYS_INTERRUPT() #define OPCODE_DISABLES_IRQ() #define OPCODE_ENABLES_IRQ() #endif /* ------------------------------------------------------------------------- */ /* Word register manipulation. */ #define BC_WORD() ((reg_b << 8) | reg_c) #define DE_WORD() ((reg_d << 8) | reg_e) #define HL_WORD() ((reg_h << 8) | reg_l) #define IX_WORD() ((reg_ixh << 8) | reg_ixl) #define IY_WORD() ((reg_iyh << 8) | reg_iyl) #define IX_WORD_OFF(offset) (IX_WORD() + (signed char)(offset)) #define IY_WORD_OFF(offset) (IY_WORD() + (signed char)(offset)) #define DEC_BC_WORD() \ do { \ if (!reg_c) \ reg_b--; \ reg_c--; \ } while (0) #define DEC_DE_WORD() \ do { \ if (!reg_e) \ reg_d--; \ reg_e--; \ } while (0) #define DEC_HL_WORD() \ do { \ if (!reg_l) \ reg_h--; \ reg_l--; \ } while (0) #define DEC_IX_WORD() \ do { \ if (!reg_ixl) \ reg_ixh--; \ reg_ixl--; \ } while (0) #define DEC_IY_WORD() \ do { \ if (!reg_iyl) \ reg_iyh--; \ reg_iyl--; \ } while (0) #define INC_BC_WORD() \ do { \ reg_c++; \ if (!reg_c) \ reg_b++; \ } while (0) #define INC_DE_WORD() \ do { \ reg_e++; \ if (!reg_e) \ reg_d++; \ } while (0) #define INC_HL_WORD() \ do { \ reg_l++; \ if (!reg_l) \ reg_h++; \ } while (0) #define INC_IX_WORD() \ do { \ reg_ixl++; \ if (!reg_ixl) \ reg_ixh++; \ } while (0) #define INC_IY_WORD() \ do { \ reg_iyl++; \ if (!reg_iyl) \ reg_iyh++; \ } while (0) /* ------------------------------------------------------------------------- */ /* Flags. */ #define C_FLAG 0x01 #define N_FLAG 0x02 #define P_FLAG 0x04 #define U3_FLAG 0x08 #define H_FLAG 0x10 #define U5_FLAG 0x20 #define Z_FLAG 0x40 #define S_FLAG 0x80 #define LOCAL_SET_CARRY(val) \ do { \ if (val) \ reg_f |= C_FLAG; \ else \ reg_f &= ~C_FLAG; \ } while (0) #define LOCAL_SET_NADDSUB(val) \ do { \ if (val) \ reg_f |= N_FLAG; \ else \ reg_f &= ~N_FLAG; \ } while (0) #define LOCAL_SET_PARITY(val) \ do { \ if (val) \ reg_f |= P_FLAG; \ else \ reg_f &= ~P_FLAG; \ } while (0) #define LOCAL_SET_HALFCARRY(val) \ do { \ if (val) \ reg_f |= H_FLAG; \ else \ reg_f &= ~H_FLAG; \ } while (0) #define LOCAL_SET_ZERO(val) \ do { \ if (val) \ reg_f |= Z_FLAG; \ else \ reg_f &= ~Z_FLAG; \ } while (0) #define LOCAL_SET_SIGN(val) \ do { \ if (val) \ reg_f |= S_FLAG; \ else \ reg_f &= ~S_FLAG; \ } while (0) #define LOCAL_CARRY() (reg_f & C_FLAG) #define LOCAL_NADDSUB() (reg_f & N_FLAG) #define LOCAL_PARITY() (reg_f & P_FLAG) #define LOCAL_HALFCARRY() (reg_f & H_FLAG) #define LOCAL_ZERO() (reg_f & Z_FLAG) #define LOCAL_SIGN() (reg_f & S_FLAG) static const BYTE SZP[256] = { P_FLAG|Z_FLAG, 0, 0, P_FLAG, 0, P_FLAG, P_FLAG, 0, 0, P_FLAG, P_FLAG, 0, P_FLAG, 0, 0, P_FLAG, 0, P_FLAG, P_FLAG, 0, P_FLAG, 0, 0, P_FLAG, P_FLAG, 0, 0, P_FLAG, 0, P_FLAG, P_FLAG, 0, 0, P_FLAG, P_FLAG, 0, P_FLAG, 0, 0, P_FLAG, P_FLAG, 0, 0, P_FLAG, 0, P_FLAG, P_FLAG, 0, P_FLAG, 0, 0, P_FLAG, 0, P_FLAG, P_FLAG, 0, 0, P_FLAG, P_FLAG, 0, P_FLAG, 0, 0, P_FLAG, 0, P_FLAG, P_FLAG, 0, P_FLAG, 0, 0, P_FLAG, P_FLAG, 0, 0, P_FLAG, 0, P_FLAG, P_FLAG, 0, P_FLAG, 0, 0, P_FLAG, 0, P_FLAG, P_FLAG, 0, 0, P_FLAG, P_FLAG, 0, P_FLAG, 0, 0, P_FLAG, P_FLAG, 0, 0, P_FLAG, 0, P_FLAG, P_FLAG, 0, 0, P_FLAG, P_FLAG, 0, P_FLAG, 0, 0, P_FLAG, 0, P_FLAG, P_FLAG, 0, P_FLAG, 0, 0, P_FLAG, P_FLAG, 0, 0, P_FLAG, 0, P_FLAG, P_FLAG, 0, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG|P_FLAG, S_FLAG, S_FLAG, S_FLAG|P_FLAG }; /* ------------------------------------------------------------------------- */ z80_regs_t z80_regs; static void import_registers(void) { reg_a = z80_regs.reg_af >> 8; reg_f = z80_regs.reg_af & 0xff; reg_b = z80_regs.reg_bc >> 8; reg_c = z80_regs.reg_bc & 0xff; reg_d = z80_regs.reg_de >> 8; reg_e = z80_regs.reg_de & 0xff; reg_h = z80_regs.reg_hl >> 8; reg_l = z80_regs.reg_hl & 0xff; reg_ixh = z80_regs.reg_ix >> 8; reg_ixl = z80_regs.reg_ix & 0xff; reg_iyh = z80_regs.reg_iy >> 8; reg_iyl = z80_regs.reg_iy & 0xff; reg_sp = z80_regs.reg_sp; z80_reg_pc = (DWORD)z80_regs.reg_pc; reg_i = z80_regs.reg_i; reg_r = z80_regs.reg_r; reg_a2 = z80_regs.reg_af2 >> 8; reg_f2 = z80_regs.reg_af2 & 0xff; reg_b2 = z80_regs.reg_bc2 >> 8; reg_c2 = z80_regs.reg_bc2 & 0xff; reg_d2 = z80_regs.reg_de2 >> 8; reg_e2 = z80_regs.reg_de2 & 0xff; reg_h2 = z80_regs.reg_hl2 >> 8; reg_l2 = z80_regs.reg_hl2 & 0xff; } static void export_registers(void) { z80_regs.reg_af = (reg_a << 8) | reg_f; z80_regs.reg_bc = (reg_b << 8) | reg_c; z80_regs.reg_de = (reg_d << 8) | reg_e; z80_regs.reg_hl = (reg_h << 8) | reg_l; z80_regs.reg_ix = (reg_ixh << 8) | reg_ixl; z80_regs.reg_iy = (reg_iyh << 8) | reg_iyl; z80_regs.reg_sp = reg_sp; z80_regs.reg_pc = (WORD)z80_reg_pc; z80_regs.reg_i = reg_i; z80_regs.reg_r = reg_r; z80_regs.reg_af2 = (reg_a2 << 8) | reg_f2; z80_regs.reg_bc2 = (reg_b2 << 8) | reg_c2; z80_regs.reg_de2 = (reg_d2 << 8) | reg_e2; z80_regs.reg_hl2 = (reg_h2 << 8) | reg_l2; } /* ------------------------------------------------------------------------- */ // [AppleWin-TC] Z80 IRQs not supported #if 0 /* Interrupt handling. */ #define DO_INTERRUPT(int_kind) \ do { \ BYTE ik = (int_kind); \ \ if (ik & (IK_IRQ | IK_NMI)) { \ if ((ik & IK_NMI) && 0) { \ } else if ((ik & IK_IRQ) && iff1 \ && !OPINFO_DISABLES_IRQ(LAST_OPCODE_INFO)) { \ WORD jumpdst; \ /*TRACE_IRQ();*/ \ if (monitor_mask[e_comp_space] & (MI_STEP)) { \ monitor_check_icount_interrupt(); \ } \ CLK += 4; \ --reg_sp; \ STORE((reg_sp), ((BYTE)(z80_reg_pc >> 8))); \ CLK += 4; \ --reg_sp; \ STORE((reg_sp), ((BYTE)(z80_reg_pc & 0xff))); \ iff1 = 0; \ iff2 = 0; \ if (im_mode == 1) { \ jumpdst = 0x38; \ CLK += 4; \ JUMP(jumpdst); \ CLK += 3; \ } else { \ jumpdst = (LOAD(reg_i << 8) << 8); \ CLK += 4; \ jumpdst |= (LOAD((reg_i << 8) + 1)); \ JUMP(jumpdst); \ CLK += 3; \ } \ } \ } \ if (ik & (IK_TRAP | IK_RESET)) { \ if (ik & IK_TRAP) { \ export_registers(); \ interrupt_do_trap(cpu_int_status, (WORD)z80_reg_pc); \ import_registers(); \ if (cpu_int_status->global_pending_int & IK_RESET) \ ik |= IK_RESET; \ } \ if (ik & IK_RESET) { \ interrupt_ack_reset(cpu_int_status); \ maincpu_reset(); \ } \ } \ if (ik & (IK_MONITOR)) { \ caller_space = e_comp_space; \ if (monitor_force_import(e_comp_space)) \ import_registers(); \ if (monitor_mask[e_comp_space]) \ export_registers(); \ if (monitor_mask[e_comp_space] & (MI_BREAK)) { \ if (monitor_check_breakpoints(e_comp_space, \ (WORD)z80_reg_pc)) { \ monitor_startup(); \ } \ } \ if (monitor_mask[e_comp_space] & (MI_STEP)) { \ monitor_check_icount((WORD)z80_reg_pc); \ } \ if (monitor_mask[e_comp_space] & (MI_WATCH)) { \ monitor_check_watchpoints((WORD)z80_reg_pc); \ } \ } \ } while (0) #endif /* ------------------------------------------------------------------------- */ /* Opcodes. */ #define ADC(loadval, clk_inc1, clk_inc2, pc_inc) \ do { \ BYTE tmp, carry, value; \ \ CLK += clk_inc1; \ value = (BYTE)(loadval); \ carry = LOCAL_CARRY(); \ tmp = reg_a + value + carry; \ reg_f = SZP[tmp]; \ LOCAL_SET_CARRY((WORD)((WORD)reg_a + (WORD)value \ + (WORD)(carry)) & 0x100); \ LOCAL_SET_HALFCARRY((reg_a ^ value ^ tmp) & H_FLAG); \ LOCAL_SET_PARITY((~(reg_a ^ value)) & (reg_a ^ tmp) & 0x80); \ reg_a = tmp; \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define ADCHLREG(reg_valh, reg_vall) \ do { \ DWORD tmp, carry; \ \ carry = LOCAL_CARRY(); \ tmp = (DWORD)((reg_h << 8) + reg_l) \ + (DWORD)((reg_valh << 8) + reg_vall) + carry; \ LOCAL_SET_ZERO(!(tmp & 0xffff)); \ LOCAL_SET_NADDSUB(0); \ LOCAL_SET_SIGN(tmp & 0x8000); \ LOCAL_SET_CARRY(tmp & 0x10000); \ LOCAL_SET_HALFCARRY(((tmp >> 8) ^ reg_valh ^ reg_h) & H_FLAG); \ LOCAL_SET_PARITY((~(reg_h ^ reg_valh)) & \ (reg_valh ^ (tmp >> 8)) & 0x80); \ reg_h = (BYTE)(tmp >> 8); \ reg_l = (BYTE)(tmp & 0xff); \ CLK += 15; \ INC_PC(2); \ } while (0) #define ADCHLSP() \ do { \ DWORD tmp, carry; \ \ carry = LOCAL_CARRY(); \ tmp = (DWORD)((reg_h << 8) + reg_l) + (DWORD)(reg_sp) + carry; \ LOCAL_SET_ZERO(!(tmp & 0xffff)); \ LOCAL_SET_NADDSUB(0); \ LOCAL_SET_SIGN(tmp & 0x8000); \ LOCAL_SET_CARRY(tmp & 0x10000); \ LOCAL_SET_HALFCARRY(((tmp >> 8) ^ (reg_sp >> 8) ^ reg_h) & H_FLAG); \ LOCAL_SET_PARITY((~(reg_h ^ (reg_sp >> 8))) & \ ((reg_sp >> 8) ^ (tmp >> 8)) & 0x80); \ reg_h = (BYTE)(tmp >> 8); \ reg_l = (BYTE)(tmp & 0xff); \ CLK += 15; \ INC_PC(2); \ } while (0) #define ADD(loadval, clk_inc1, clk_inc2, pc_inc) \ do { \ BYTE tmp, value; \ \ CLK += clk_inc1; \ value = (BYTE)(loadval); \ tmp = reg_a + value; \ reg_f = SZP[tmp]; \ LOCAL_SET_CARRY((WORD)((WORD)reg_a + (WORD)value) & 0x100); \ LOCAL_SET_HALFCARRY((reg_a ^ value ^ tmp) & H_FLAG); \ LOCAL_SET_PARITY((~(reg_a ^ value)) & (reg_a ^ tmp) & 0x80); \ reg_a = tmp; \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define ADDXXREG(reg_dsth, reg_dstl, reg_valh, reg_vall, clk_inc, pc_inc) \ do { \ DWORD tmp; \ \ tmp = (DWORD)((reg_dsth << 8) + reg_dstl) \ + (DWORD)((reg_valh << 8) + reg_vall); \ LOCAL_SET_NADDSUB(0); \ LOCAL_SET_CARRY(tmp & 0x10000); \ LOCAL_SET_HALFCARRY(((tmp >> 8) ^ reg_valh ^ reg_dsth) & H_FLAG); \ reg_dsth = (BYTE)(tmp >> 8); \ reg_dstl = (BYTE)(tmp & 0xff); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define ADDXXSP(reg_dsth, reg_dstl, clk_inc, pc_inc) \ do { \ DWORD tmp; \ \ tmp = (DWORD)((reg_dsth << 8) + reg_dstl) + (DWORD)(reg_sp); \ LOCAL_SET_NADDSUB(0); \ LOCAL_SET_CARRY(tmp & 0x10000); \ LOCAL_SET_HALFCARRY(((tmp >> 8) ^ (reg_sp >> 8) ^ reg_dsth) & H_FLAG); \ reg_dsth = (BYTE)(tmp >> 8); \ reg_dstl = (BYTE)(tmp & 0xff); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define AND(value, clk_inc1, clk_inc2, pc_inc) \ do { \ CLK += clk_inc1; \ reg_a &= (value); \ reg_f = SZP[reg_a]; \ LOCAL_SET_HALFCARRY(1); \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define BIT(reg_val, value, clk_inc1, clk_inc2, pc_inc) \ do { \ CLK += clk_inc1; \ LOCAL_SET_NADDSUB(0); \ LOCAL_SET_HALFCARRY(1); \ LOCAL_SET_ZERO(!((reg_val) & (1 << value))); \ /***LOCAL_SET_PARITY(LOCAL_ZERO());***/ \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define BRANCH(cond, value, pc_inc) \ do { \ if (cond) { \ unsigned int dest_addr; \ \ dest_addr = z80_reg_pc + pc_inc + (signed char)(value); \ z80_reg_pc = dest_addr & 0xffff; \ CLK += 7; \ } else { \ CLK += 7; \ INC_PC(pc_inc); \ } \ } while (0) #define CALL(reg_val, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ INC_PC(pc_inc); \ CLK += clk_inc1; \ --reg_sp; \ STORE((reg_sp), ((BYTE)(z80_reg_pc >> 8))); \ CLK += clk_inc2; \ --reg_sp; \ STORE((reg_sp), ((BYTE)(z80_reg_pc & 0xff))); \ JUMP(reg_val); \ CLK += clk_inc3; \ } while (0) #define CALL_COND(reg_value, cond, clk_inc1, clk_inc2, clk_inc3, \ clk_inc4, pc_inc) \ do { \ if (cond) { \ CALL(reg_value, clk_inc1, clk_inc2, clk_inc3, pc_inc); \ } else { \ CLK += clk_inc4; \ INC_PC(3); \ } \ } while (0) #define CCF(clk_inc, pc_inc) \ do { \ LOCAL_SET_HALFCARRY((LOCAL_CARRY())); \ LOCAL_SET_CARRY(!(LOCAL_CARRY())); \ LOCAL_SET_NADDSUB(0); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define CP(loadval, clk_inc1, clk_inc2, pc_inc) \ do { \ BYTE tmp, value; \ \ CLK += clk_inc1; \ value = (BYTE)(loadval); \ tmp = reg_a - value; \ reg_f = N_FLAG | SZP[tmp]; \ LOCAL_SET_CARRY(value > reg_a); \ LOCAL_SET_HALFCARRY((reg_a ^ value ^ tmp) & H_FLAG); \ LOCAL_SET_PARITY((reg_a ^ value) & (reg_a ^ tmp) & 0x80); \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define CPDI(HL_FUNC) \ do { \ BYTE val, tmp; \ \ CLK += 4; \ val = LOAD(HL_WORD()); \ tmp = reg_a - val; \ HL_FUNC; \ DEC_BC_WORD(); \ reg_f = N_FLAG | SZP[tmp] | LOCAL_CARRY(); \ /***LOCAL_SET_CARRY(val > reg_a);***/ \ LOCAL_SET_HALFCARRY((reg_a ^ val ^ tmp) & H_FLAG); \ LOCAL_SET_PARITY(reg_b | reg_c); \ CLK += 1; \ INC_PC(2); \ } while (0) #define CPDIR(HL_FUNC) \ do { \ BYTE val, tmp; \ \ CLK += 4; \ val = LOAD(HL_WORD()); \ tmp = reg_a - val; \ HL_FUNC; \ DEC_BC_WORD(); \ CLK += 17; \ if (!(BC_WORD() && tmp)) { \ reg_f = N_FLAG | SZP[tmp] | LOCAL_CARRY(); \ /***LOCAL_SET_CARRY(val > reg_a);***/ \ LOCAL_SET_HALFCARRY((reg_a ^ val ^ tmp) & H_FLAG); \ LOCAL_SET_PARITY(reg_b | reg_c); \ CLK += 5; \ INC_PC(2); \ } \ } while (0) #define CPL(clk_inc, pc_inc) \ do { \ reg_a ^= 0xff; \ LOCAL_SET_NADDSUB(1); \ LOCAL_SET_HALFCARRY(1); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define DAA(clk_inc, pc_inc) \ do { \ WORD tmp; \ \ tmp = reg_a | (LOCAL_CARRY() ? 0x100 : 0) \ | (LOCAL_HALFCARRY() ? 0x200 : 0) \ | (LOCAL_NADDSUB() ? 0x400 : 0); \ reg_a = daa_reg_a[tmp]; \ reg_f = daa_reg_f[tmp]; \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define DECXXIND(reg_val, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((reg_val)); \ tmp--; \ CLK += clk_inc2; \ STORE((reg_val), tmp); \ reg_f = N_FLAG | SZP[tmp] | LOCAL_CARRY(); \ LOCAL_SET_PARITY((tmp == 0x7f)); \ LOCAL_SET_HALFCARRY(((tmp & 0x0f) == 0x0f)); \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define DECINC(FUNC, clk_inc, pc_inc) \ do { \ CLK += clk_inc; \ FUNC; \ INC_PC(pc_inc); \ } while (0) #define DECREG(reg_val, clk_inc, pc_inc) \ do { \ reg_val--; \ reg_f = N_FLAG | SZP[reg_val] | LOCAL_CARRY(); \ LOCAL_SET_PARITY((reg_val == 0x7f)); \ LOCAL_SET_HALFCARRY(((reg_val & 0x0f) == 0x0f)); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define DJNZ(value, pc_inc) \ do { \ reg_b--; \ /***LOCAL_SET_NADDSUB(1);***/ \ BRANCH(reg_b, value, pc_inc); \ } while (0) #define DI(clk_inc, pc_inc) \ do { \ iff1 = 0; \ iff2 = 0; \ OPCODE_DISABLES_IRQ(); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define EI(clk_inc, pc_inc) \ do { \ iff1 = 1; \ iff2 = 1; \ OPCODE_DISABLES_IRQ(); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define EXAFAF(clk_inc, pc_inc) \ do { \ BYTE tmpl, tmph; \ \ tmph = reg_a; \ tmpl = reg_f; \ reg_a = reg_a2; \ reg_f = reg_f2; \ reg_a2 = tmph; \ reg_f2 = tmpl; \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define EXX(clk_inc, pc_inc) \ do { \ BYTE tmpl, tmph; \ \ tmph = reg_b; \ tmpl = reg_c; \ reg_b = reg_b2; \ reg_c = reg_c2; \ reg_b2 = tmph; \ reg_c2 = tmpl; \ tmph = reg_d; \ tmpl = reg_e; \ reg_d = reg_d2; \ reg_e = reg_e2; \ reg_d2 = tmph; \ reg_e2 = tmpl; \ tmph = reg_h; \ tmpl = reg_l; \ reg_h = reg_h2; \ reg_l = reg_l2; \ reg_h2 = tmph; \ reg_l2 = tmpl; \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define EXDEHL(clk_inc, pc_inc) \ do { \ BYTE tmpl, tmph; \ \ tmph = reg_d; \ tmpl = reg_e; \ reg_d = reg_h; \ reg_e = reg_l; \ reg_h = tmph; \ reg_l = tmpl; \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define EXXXSP(reg_valh, reg_vall, clk_inc1, clk_inc2, clk_inc3, \ clk_inc4, clk_inc5, pc_inc) \ do { \ BYTE tmpl, tmph; \ \ tmph = reg_valh; \ tmpl = reg_vall; \ CLK += clk_inc1; \ reg_valh = LOAD(reg_sp + 1); \ CLK += clk_inc2; \ reg_vall = LOAD(reg_sp); \ CLK += clk_inc3; \ STORE((reg_sp + 1), tmph); \ CLK += clk_inc4; \ STORE(reg_sp, tmpl); \ CLK += clk_inc5; \ INC_PC(pc_inc); \ } while (0) /* FIXME: Continue if INT occurs. */ #define HALT() \ do { \ CLK += 4; \ } while (0) #define IM(value) \ do { \ im_mode = value; \ CLK += 8; \ INC_PC(2); \ } while (0) #define INA(value, clk_inc1, clk_inc2, pc_inc) \ do { \ CLK += clk_inc1; \ /***reg_a = IN(value);***/ \ reg_a = IN((reg_a << 8) | value); \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define INBC(reg_val, clk_inc1, clk_inc2, pc_inc) \ do { \ CLK += clk_inc1; \ reg_val = IN(BC_WORD()); \ reg_f = SZP[reg_val & 0xff] | LOCAL_CARRY(); \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define INBC0(clk_inc1, clk_inc2, pc_inc) \ do { \ BYTE tmp; \ CLK += clk_inc1; \ tmp = IN(BC_WORD()); \ reg_f = SZP[tmp] | LOCAL_CARRY(); \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define INCXXIND(reg_val, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((reg_val)); \ tmp++; \ CLK += clk_inc2; \ STORE((reg_val), tmp); \ reg_f = SZP[tmp] | LOCAL_CARRY(); \ LOCAL_SET_PARITY((tmp == 0x80)); \ LOCAL_SET_HALFCARRY(!(tmp & 0x0f)); \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define INCREG(reg_val, clk_inc, pc_inc) \ do { \ reg_val++; \ reg_f = SZP[reg_val] | LOCAL_CARRY(); \ LOCAL_SET_PARITY((reg_val == 0x80)); \ LOCAL_SET_HALFCARRY(!(reg_val & 0x0f)); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define INDI(HL_FUNC) \ do { \ BYTE tmp; \ \ CLK += 4; \ tmp = IN(BC_WORD()); \ CLK += 4; \ STORE(HL_WORD(), tmp); \ HL_FUNC; \ reg_b--; \ reg_f = N_FLAG; \ LOCAL_SET_ZERO(!reg_b); \ CLK += 4; \ INC_PC(2); \ } while (0) #define INDIR(HL_FUNC) \ do { \ BYTE tmp; \ \ CLK += 4; \ tmp = IN(BC_WORD()); \ CLK += 4; \ STORE(HL_WORD(), tmp); \ HL_FUNC; \ reg_b--; \ if (!reg_b) { \ CLK += 4; \ reg_f = N_FLAG | Z_FLAG; \ INC_PC(2); \ } else { \ reg_f = N_FLAG; \ } \ CLK += 4; \ } while (0) #define JMP(addr, clk_inc) \ do { \ CLK += clk_inc; \ JUMP(addr); \ } while (0) #define JMP_COND(addr, cond, clk_inc1, clk_inc2) \ do { \ if (cond) { \ JMP(addr, clk_inc1); \ } else { \ CLK += clk_inc2; \ INC_PC(3); \ } \ } while (0) #define LDAIR(reg_val) \ do { \ CLK += 6; \ reg_a = reg_val; \ reg_f = SZP[reg_a] | LOCAL_CARRY(); \ LOCAL_SET_PARITY(iff2); \ CLK += 3; \ INC_PC(2); \ } while (0) #define LDDI(DE_FUNC, HL_FUNC) \ do { \ BYTE tmp; \ \ CLK += 4; \ tmp = LOAD(HL_WORD()); \ CLK += 4; \ STORE(DE_WORD(), tmp); \ DEC_BC_WORD(); \ DE_FUNC; \ HL_FUNC; \ LOCAL_SET_NADDSUB(0); \ LOCAL_SET_PARITY(reg_b | reg_c); \ LOCAL_SET_HALFCARRY(0); \ CLK += 12; \ INC_PC(2); \ } while (0) #define LDDIR(DE_FUNC, HL_FUNC) \ do { \ BYTE tmp; \ \ CLK += 4; \ tmp = LOAD(HL_WORD()); \ CLK += 4; \ STORE(DE_WORD(), tmp); \ DEC_BC_WORD(); \ DE_FUNC; \ HL_FUNC; \ CLK += 13; \ if (!(BC_WORD())) { \ LOCAL_SET_NADDSUB(0); \ LOCAL_SET_PARITY(0); \ LOCAL_SET_HALFCARRY(0); \ CLK += 5; \ INC_PC(2); \ } \ } while (0) #define LDIND(val, reg_valh, reg_vall, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ CLK += clk_inc1; \ reg_vall = LOAD((val)); \ CLK += clk_inc2; \ reg_valh = LOAD((val) + 1); \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define LDSP(value, clk_inc1, clk_inc2, pc_inc) \ do { \ CLK += clk_inc1; \ reg_sp = (WORD)(value); \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define LDSPIND(value, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ CLK += clk_inc1; \ reg_sp = LOAD(value); \ CLK += clk_inc2; \ reg_sp |= LOAD(value + 1) << 8; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define LDREG(reg_dest, value, clk_inc1, clk_inc2, pc_inc) \ do { \ BYTE tmp; \ \ CLK += clk_inc1; \ tmp = (BYTE)(value); \ reg_dest = tmp; \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define LDW(value, reg_valh, reg_vall, clk_inc1, clk_inc2, pc_inc) \ do { \ CLK += clk_inc1; \ reg_vall = (BYTE)((value) & 0xff); \ reg_valh = (BYTE)((value) >> 8); \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define NEG() \ do { \ BYTE tmp; \ \ tmp = 0 - reg_a; \ reg_f = N_FLAG | SZP[tmp]; \ LOCAL_SET_HALFCARRY((reg_a ^ tmp) & H_FLAG); \ LOCAL_SET_PARITY(reg_a & tmp & 0x80); \ LOCAL_SET_CARRY(reg_a > 0); \ reg_a = tmp; \ CLK += 8; \ INC_PC(2); \ } while (0) #define NOP(clk_inc, pc_inc) \ do { \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define OR(reg_val, clk_inc1, clk_inc2, pc_inc) \ do { \ CLK += clk_inc1; \ reg_a |= reg_val; \ reg_f = SZP[reg_a]; \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define OUTA(value, clk_inc1, clk_inc2, pc_inc) \ do { \ CLK += clk_inc1; \ /***OUT(value, reg_a);***/ \ OUT((reg_a << 8) | value, reg_a); \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define OUTBC(value, clk_inc1, clk_inc2, pc_inc) \ do { \ CLK += clk_inc1; \ OUT(BC_WORD(), value); \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define OUTDI(HL_FUNC) \ do { \ BYTE tmp; \ \ CLK += 4; \ tmp = LOAD(HL_WORD()); \ CLK += 4; \ OUT(BC_WORD(), tmp); \ HL_FUNC; \ reg_b--; \ reg_f = N_FLAG; \ LOCAL_SET_ZERO(!reg_b); \ CLK += 4; \ INC_PC(2); \ } while (0) #define OTDIR(HL_FUNC) \ do { \ BYTE tmp; \ \ CLK += 4; \ tmp = LOAD(HL_WORD()); \ CLK += 4; \ OUT(BC_WORD(), tmp); \ HL_FUNC; \ reg_b--; \ if (!reg_b) { \ CLK += 4; \ reg_f = N_FLAG | Z_FLAG; \ INC_PC(2); \ } else { \ reg_f = N_FLAG; \ } \ CLK += 4; \ } while (0) #define POP(reg_valh, reg_vall, pc_inc) \ do { \ CLK += 4; \ reg_vall = LOAD(reg_sp); \ ++reg_sp; \ CLK += 4; \ reg_valh = LOAD(reg_sp); \ ++reg_sp; \ CLK += 2; \ INC_PC(pc_inc); \ } while (0) #define PUSH(reg_valh, reg_vall, pc_inc) \ do { \ CLK += 4; \ --reg_sp; \ STORE((reg_sp), (reg_valh)); \ CLK += 4; \ --reg_sp; \ STORE((reg_sp), (reg_vall)); \ CLK += 3; \ INC_PC(pc_inc); \ } while (0) #define RES(reg_val, value) \ do { \ reg_val &= (~(1 << value)); \ CLK += 8; \ INC_PC(2); \ } while (0) #define RESXX(value, addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ tmp &= (~(1 << value)); \ CLK += clk_inc2; \ STORE((addr), tmp); \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define RESXXREG(value, reg_val, addr, clk_inc1, clk_inc2, \ clk_inc3, pc_inc) \ do { \ BYTE tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ tmp &= (~(1 << value)); \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_val = tmp; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define RET(clk_inc1, clk_inc2, clk_inc3) \ do { \ WORD tmp; \ \ CLK += clk_inc1; \ tmp = LOAD(reg_sp); \ CLK += clk_inc2; \ tmp |= LOAD((reg_sp + 1)) << 8; \ reg_sp += 2; \ JUMP(tmp); \ CLK += clk_inc3; \ } while (0) #define RET_COND(cond, clk_inc1, clk_inc2, clk_inc3, clk_inc4, pc_inc) \ do { \ if (cond) { \ RET(clk_inc1, clk_inc2, clk_inc3); \ } else { \ CLK += clk_inc4; \ INC_PC(pc_inc); \ } \ } while (0) #define RETNI() \ do { \ WORD tmp; \ \ CLK += 4; \ tmp = LOAD(reg_sp); \ CLK += 4; \ tmp |= LOAD((reg_sp + 1)) << 8; \ reg_sp += 2; \ iff1 = iff2; \ JUMP(tmp); \ CLK += 2; \ } while (0) #define RL(reg_val) \ do { \ BYTE rot; \ \ rot = (reg_val & 0x80) ? C_FLAG : 0; \ reg_val = (reg_val << 1) | LOCAL_CARRY(); \ reg_f = rot | SZP[reg_val]; \ CLK += 8; \ INC_PC(2); \ } while (0) #define RLA(clk_inc, pc_inc) \ do { \ BYTE rot; \ \ rot = (reg_a & 0x80) ? C_FLAG : 0; \ reg_a = (reg_a << 1) | LOCAL_CARRY(); \ LOCAL_SET_CARRY(rot); \ LOCAL_SET_NADDSUB(0); \ LOCAL_SET_HALFCARRY(0); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define RLC(reg_val) \ do { \ BYTE rot; \ \ rot = (reg_val & 0x80) ? C_FLAG : 0; \ reg_val = (reg_val << 1) | rot; \ reg_f = rot | SZP[reg_val]; \ CLK += 8; \ INC_PC(2); \ } while (0) #define RLCA(clk_inc, pc_inc) \ do { \ BYTE rot; \ \ rot = (reg_a & 0x80) ? C_FLAG : 0; \ reg_a = (reg_a << 1) | rot; \ LOCAL_SET_CARRY(rot); \ LOCAL_SET_NADDSUB(0); \ LOCAL_SET_HALFCARRY(0); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define RLCXX(addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = (tmp & 0x80) ? C_FLAG : 0; \ tmp = (tmp << 1) | rot; \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define RLCXXREG(reg_val, addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = (tmp & 0x80) ? C_FLAG : 0; \ tmp = (tmp << 1) | rot; \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_val = tmp; \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define RLD() \ do { \ BYTE tmp; \ \ tmp = LOAD(HL_WORD()); \ CLK += 8; \ STORE(HL_WORD(), (tmp << 4) | (reg_a & 0x0f)); \ reg_a = (tmp >> 4) | (reg_a & 0xf0); \ reg_f = SZP[reg_a] | LOCAL_CARRY(); \ CLK += 10; \ INC_PC(2); \ } while (0) #define RLXX(addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = (tmp & 0x80) ? C_FLAG : 0; \ tmp = (tmp << 1) | LOCAL_CARRY(); \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define RLXXREG(reg_val, addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = (tmp & 0x80) ? C_FLAG : 0; \ tmp = (tmp << 1) | LOCAL_CARRY(); \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_val = tmp; \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define RR(reg_val) \ do { \ BYTE rot; \ \ rot = reg_val & C_FLAG; \ reg_val = (reg_val >> 1) | (LOCAL_CARRY() ? 0x80 : 0); \ reg_f = rot | SZP[reg_val]; \ CLK += 8; \ INC_PC(2); \ } while (0) #define RRA(clk_inc, pc_inc) \ do { \ BYTE rot; \ \ rot = reg_a & C_FLAG; \ reg_a = (reg_a >> 1) | (LOCAL_CARRY() ? 0x80 : 0); \ LOCAL_SET_CARRY(rot); \ LOCAL_SET_NADDSUB(0); \ LOCAL_SET_HALFCARRY(0); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define RRC(reg_val) \ do { \ BYTE rot; \ \ rot = reg_val & C_FLAG; \ reg_val = (reg_val >> 1) | ((rot) ? 0x80 : 0); \ reg_f = rot | SZP[reg_val]; \ CLK += 8; \ INC_PC(2); \ } while (0) #define RRCA(clk_inc, pc_inc) \ do { \ BYTE rot; \ \ rot = reg_a & C_FLAG; \ reg_a = (reg_a >> 1) | ((rot) ? 0x80 : 0); \ LOCAL_SET_CARRY(rot); \ LOCAL_SET_NADDSUB(0); \ LOCAL_SET_HALFCARRY(0); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define RRCXX(addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = tmp & C_FLAG; \ tmp = (tmp >> 1) | ((rot) ? 0x80 : 0); \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define RRCXXREG(reg_val, addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = tmp & C_FLAG; \ tmp = (tmp >> 1) | ((rot) ? 0x80 : 0); \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_val = tmp; \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define RRD() \ do { \ BYTE tmp; \ \ tmp = LOAD(HL_WORD()); \ CLK += 8; \ STORE(HL_WORD(), (tmp >> 4) | (reg_a << 4)); \ reg_a = (tmp & 0x0f) | (reg_a & 0xf0); \ reg_f = SZP[reg_a] | LOCAL_CARRY(); \ CLK += 10; \ INC_PC(2); \ } while (0) #define RRXX(addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = tmp & C_FLAG; \ tmp = (tmp >> 1) | (LOCAL_CARRY() ? 0x80 : 0); \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define RRXXREG(reg_val, addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = tmp & C_FLAG; \ tmp = (tmp >> 1) | (LOCAL_CARRY() ? 0x80 : 0); \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_val = tmp; \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define SBCHLREG(reg_valh, reg_vall) \ do { \ DWORD tmp; \ BYTE carry; \ \ carry = LOCAL_CARRY(); \ tmp = (DWORD)(HL_WORD()) - (DWORD)((reg_valh << 8) + reg_vall) \ - (DWORD)(carry); \ reg_f = N_FLAG; \ LOCAL_SET_CARRY(tmp & 0x10000); \ LOCAL_SET_HALFCARRY((reg_h ^ reg_valh ^ (tmp >> 8)) & H_FLAG); \ LOCAL_SET_PARITY(((reg_h ^ (tmp >> 8)) & (reg_h ^ reg_valh)) & 0x80); \ LOCAL_SET_ZERO(!(tmp & 0xffff)); \ LOCAL_SET_SIGN(tmp & 0x8000); \ reg_h = (BYTE)(tmp >> 8); \ reg_l = (BYTE)(tmp & 0xff); \ CLK += 15; \ INC_PC(2); \ } while (0) #define SBCHLSP() \ do { \ DWORD tmp; \ BYTE carry; \ \ carry = LOCAL_CARRY(); \ tmp = (DWORD)(HL_WORD()) - (DWORD)reg_sp - (DWORD)(carry); \ reg_f = N_FLAG; \ LOCAL_SET_CARRY(tmp & 0x10000); \ LOCAL_SET_HALFCARRY((reg_h ^ (reg_sp >> 8) ^ (tmp >> 8)) & H_FLAG); \ LOCAL_SET_PARITY(((reg_h ^ (tmp >> 8)) \ & (reg_h ^ (reg_sp >> 8))) & 0x80); \ LOCAL_SET_ZERO(!(tmp & 0xffff)); \ LOCAL_SET_SIGN(tmp & 0x8000); \ reg_h = (BYTE)(tmp >> 8); \ reg_l = (BYTE)(tmp & 0xff); \ CLK += 15; \ INC_PC(2); \ } while (0) #define SBC(loadval, clk_inc1, clk_inc2, pc_inc) \ do { \ BYTE tmp, carry, value; \ \ CLK += clk_inc1; \ value = (BYTE)(loadval); \ carry = LOCAL_CARRY(); \ tmp = reg_a - value - carry; \ reg_f = N_FLAG | SZP[tmp]; \ LOCAL_SET_HALFCARRY((reg_a ^ value ^ tmp) & H_FLAG); \ LOCAL_SET_PARITY((reg_a ^ value) & (reg_a ^ tmp) & 0x80); \ LOCAL_SET_CARRY((WORD)((WORD)value \ + (WORD)(carry)) > reg_a); \ reg_a = tmp; \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define SCF(clk_inc, pc_inc) \ do { \ LOCAL_SET_CARRY(1); \ LOCAL_SET_HALFCARRY(0); \ LOCAL_SET_NADDSUB(0); \ CLK += clk_inc; \ INC_PC(pc_inc); \ } while (0) #define SET(reg_val, value) \ do { \ reg_val |= (1 << value); \ CLK += 8; \ INC_PC(2); \ } while (0) #define SETXX(value, addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ tmp |= (1 << value); \ CLK += clk_inc2; \ STORE((addr), tmp); \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define SETXXREG(value, reg_val, addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ tmp |= (1 << value); \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_val = tmp; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define SLA(reg_val) \ do { \ BYTE rot; \ \ rot = (reg_val & 0x80) ? C_FLAG : 0; \ reg_val <<= 1; \ reg_f = rot | SZP[reg_val]; \ CLK += 8; \ INC_PC(2); \ } while (0) #define SLAXX(addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = (tmp & 0x80) ? C_FLAG : 0; \ tmp <<= 1; \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define SLAXXREG(reg_val, addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = (tmp & 0x80) ? C_FLAG : 0; \ tmp <<= 1; \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_val = tmp; \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define SLL(reg_val) \ do { \ BYTE rot; \ \ rot = (reg_val & 0x80) ? C_FLAG : 0; \ reg_val = (reg_val << 1) | 1; \ reg_f = rot | SZP[reg_val]; \ CLK += 8; \ INC_PC(2); \ } while (0) #define SLLXX(addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = (tmp & 0x80) ? C_FLAG : 0; \ tmp = (tmp << 1) | 1; \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define SLLXXREG(reg_val, addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = (tmp & 0x80) ? C_FLAG : 0; \ tmp = (tmp << 1) | 1; \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_val = tmp; \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define SRA(reg_val) \ do { \ BYTE rot; \ \ rot = reg_val & C_FLAG; \ reg_val = (reg_val >> 1) | (reg_val & 0x80); \ reg_f = rot | SZP[reg_val]; \ CLK += 8; \ INC_PC(2); \ } while (0) #define SRAXX(addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = tmp & C_FLAG; \ tmp = (tmp >> 1) | (tmp & 0x80); \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define SRAXXREG(reg_val, addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = tmp & C_FLAG; \ tmp = (tmp >> 1) | (tmp & 0x80); \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_val = tmp; \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define SRL(reg_val) \ do { \ BYTE rot; \ \ rot = reg_val & C_FLAG; \ reg_val >>= 1; \ reg_f = rot | SZP[reg_val]; \ CLK += 8; \ INC_PC(2); \ } while (0) #define SRLXX(addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = tmp & C_FLAG; \ tmp >>= 1; \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define SRLXXREG(reg_val, addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ BYTE rot, tmp; \ \ CLK += clk_inc1; \ tmp = LOAD((addr)); \ rot = tmp & C_FLAG; \ tmp >>= 1; \ CLK += clk_inc2; \ STORE((addr), tmp); \ reg_val = tmp; \ reg_f = rot | SZP[tmp]; \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define STW(addr, reg_valh, reg_vall, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ CLK += clk_inc1; \ STORE((WORD)(addr), reg_vall); \ CLK += clk_inc2; \ STORE((WORD)(addr + 1), reg_valh); \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define STSPW(addr, clk_inc1, clk_inc2, clk_inc3, pc_inc) \ do { \ CLK += clk_inc1; \ STORE((WORD)(addr), (reg_sp & 0xff)); \ CLK += clk_inc2; \ STORE((WORD)(addr + 1), (reg_sp >> 8)); \ CLK += clk_inc3; \ INC_PC(pc_inc); \ } while (0) #define STREG(addr, reg_val, clk_inc1, clk_inc2, pc_inc) \ do { \ CLK += clk_inc1; \ STORE(addr, reg_val); \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define SUB(loadval, clk_inc1, clk_inc2, pc_inc) \ do { \ BYTE tmp, value; \ \ CLK += clk_inc1; \ value = (BYTE)(loadval); \ tmp = reg_a - value; \ reg_f = N_FLAG | SZP[tmp]; \ LOCAL_SET_HALFCARRY((reg_a ^ value ^ tmp) & H_FLAG); \ LOCAL_SET_PARITY((reg_a ^ value) & (reg_a ^ tmp) & 0x80); \ LOCAL_SET_CARRY(value > reg_a); \ reg_a = tmp; \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) #define XOR(value, clk_inc1, clk_inc2, pc_inc) \ do { \ CLK += clk_inc1; \ reg_a ^= value; \ reg_f = SZP[reg_a]; \ CLK += clk_inc2; \ INC_PC(pc_inc); \ } while (0) /* ------------------------------------------------------------------------- */ /* Extented opcodes. */ static void opcode_cb(BYTE ip1, BYTE ip2, BYTE ip3, WORD ip12, WORD ip23) { switch (ip1) { case 0x00: /* RLC B */ RLC(reg_b); break; case 0x01: /* RLC C */ RLC(reg_c); break; case 0x02: /* RLC D */ RLC(reg_d); break; case 0x03: /* RLC E */ RLC(reg_e); break; case 0x04: /* RLC H */ RLC(reg_h); break; case 0x05: /* RLC L */ RLC(reg_l); break; case 0x06: /* RLC (HL) */ RLCXX(HL_WORD(), 4, 4, 7, 2); break; case 0x07: /* RLC A */ RLC(reg_a); break; case 0x08: /* RRC B */ RRC(reg_b); break; case 0x09: /* RRC C */ RRC(reg_c); break; case 0x0a: /* RRC D */ RRC(reg_d); break; case 0x0b: /* RRC E */ RRC(reg_e); break; case 0x0c: /* RRC H */ RRC(reg_h); break; case 0x0d: /* RRC L */ RRC(reg_l); break; case 0x0e: /* RRC (HL) */ RRCXX(HL_WORD(), 4, 4, 7, 2); break; case 0x0f: /* RRC A */ RRC(reg_a); break; case 0x10: /* RL B */ RL(reg_b); break; case 0x11: /* RL C */ RL(reg_c); break; case 0x12: /* RL D */ RL(reg_d); break; case 0x13: /* RL E */ RL(reg_e); break; case 0x14: /* RL H */ RL(reg_h); break; case 0x15: /* RL L */ RL(reg_l); break; case 0x16: /* RL (HL) */ RLXX(HL_WORD(), 4, 4, 7, 2); break; case 0x17: /* RL A */ RL(reg_a); break; case 0x18: /* RR B */ RR(reg_b); break; case 0x19: /* RR C */ RR(reg_c); break; case 0x1a: /* RR D */ RR(reg_d); break; case 0x1b: /* RR E */ RR(reg_e); break; case 0x1c: /* RR H */ RR(reg_h); break; case 0x1d: /* RR L */ RR(reg_l); break; case 0x1e: /* RR (HL) */ RRXX(HL_WORD(), 4, 4, 7, 2); break; case 0x1f: /* RR A */ RR(reg_a); break; case 0x20: /* SLA B */ SLA(reg_b); break; case 0x21: /* SLA C */ SLA(reg_c); break; case 0x22: /* SLA D */ SLA(reg_d); break; case 0x23: /* SLA E */ SLA(reg_e); break; case 0x24: /* SLA H */ SLA(reg_h); break; case 0x25: /* SLA L */ SLA(reg_l); break; case 0x26: /* SLA (HL) */ SLAXX(HL_WORD(), 4, 4, 7, 2); break; case 0x27: /* SLA A */ SLA(reg_a); break; case 0x28: /* SRA B */ SRA(reg_b); break; case 0x29: /* SRA C */ SRA(reg_c); break; case 0x2a: /* SRA D */ SRA(reg_d); break; case 0x2b: /* SRA E */ SRA(reg_e); break; case 0x2c: /* SRA H */ SRA(reg_h); break; case 0x2d: /* SRA L */ SRA(reg_l); break; case 0x2e: /* SRA (HL) */ SRAXX(HL_WORD(), 4, 4, 7, 2); break; case 0x2f: /* SRA A */ SRA(reg_a); break; case 0x30: /* SLL B */ SLL(reg_b); break; case 0x31: /* SLL C */ SLL(reg_c); break; case 0x32: /* SLL D */ SLL(reg_d); break; case 0x33: /* SLL E */ SLL(reg_e); break; case 0x34: /* SLL H */ SLL(reg_h); break; case 0x35: /* SLL L */ SLL(reg_l); break; case 0x36: /* SLL (HL) */ SLLXX(HL_WORD(), 4, 4, 7, 2); break; case 0x37: /* SLL A */ SLL(reg_a); break; case 0x38: /* SRL B */ SRL(reg_b); break; case 0x39: /* SRL C */ SRL(reg_c); break; case 0x3a: /* SRL D */ SRL(reg_d); break; case 0x3b: /* SRL E */ SRL(reg_e); break; case 0x3c: /* SRL H */ SRL(reg_h); break; case 0x3d: /* SRL L */ SRL(reg_l); break; case 0x3e: /* SRL (HL) */ SRLXX(HL_WORD(), 4, 4, 7, 2); break; case 0x3f: /* SRL A */ SRL(reg_a); break; case 0x40: /* BIT B 0 */ BIT(reg_b, 0, 0, 8, 2); break; case 0x41: /* BIT C 0 */ BIT(reg_c, 0, 0, 8, 2); break; case 0x42: /* BIT D 0 */ BIT(reg_d, 0, 0, 8, 2); break; case 0x43: /* BIT E 0 */ BIT(reg_e, 0, 0, 8, 2); break; case 0x44: /* BIT H 0 */ BIT(reg_h, 0, 0, 8, 2); break; case 0x45: /* BIT L 0 */ BIT(reg_l, 0, 0, 8, 2); break; case 0x46: /* BIT (HL) 0 */ BIT(LOAD(HL_WORD()), 0, 4, 8, 2); break; case 0x47: /* BIT A 0 */ BIT(reg_a, 0, 0, 8, 2); break; case 0x48: /* BIT B 1 */ BIT(reg_b, 1, 0, 8, 2); break; case 0x49: /* BIT C 1 */ BIT(reg_c, 1, 0, 8, 2); break; case 0x4a: /* BIT D 1 */ BIT(reg_d, 1, 0, 8, 2); break; case 0x4b: /* BIT E 1 */ BIT(reg_e, 1, 0, 8, 2); break; case 0x4c: /* BIT H 1 */ BIT(reg_h, 1, 0, 8, 2); break; case 0x4d: /* BIT L 1 */ BIT(reg_l, 1, 0, 8, 2); break; case 0x4e: /* BIT (HL) 1 */ BIT(LOAD(HL_WORD()), 1, 4, 8, 2); break; case 0x4f: /* BIT A 1 */ BIT(reg_a, 1, 0, 8, 2); break; case 0x50: /* BIT B 2 */ BIT(reg_b, 2, 0, 8, 2); break; case 0x51: /* BIT C 2 */ BIT(reg_c, 2, 0, 8, 2); break; case 0x52: /* BIT D 2 */ BIT(reg_d, 2, 0, 8, 2); break; case 0x53: /* BIT E 2 */ BIT(reg_e, 2, 0, 8, 2); break; case 0x54: /* BIT H 2 */ BIT(reg_h, 2, 0, 8, 2); break; case 0x55: /* BIT L 2 */ BIT(reg_l, 2, 0, 8, 2); break; case 0x56: /* BIT (HL) 2 */ BIT(LOAD(HL_WORD()), 2, 4, 8, 2); break; case 0x57: /* BIT A 2 */ BIT(reg_a, 2, 0, 8, 2); break; case 0x58: /* BIT B 3 */ BIT(reg_b, 3, 0, 8, 2); break; case 0x59: /* BIT C 3 */ BIT(reg_c, 3, 0, 8, 2); break; case 0x5a: /* BIT D 3 */ BIT(reg_d, 3, 0, 8, 2); break; case 0x5b: /* BIT E 3 */ BIT(reg_e, 3, 0, 8, 2); break; case 0x5c: /* BIT H 3 */ BIT(reg_h, 3, 0, 8, 2); break; case 0x5d: /* BIT L 3 */ BIT(reg_l, 3, 0, 8, 2); break; case 0x5e: /* BIT (HL) 3 */ BIT(LOAD(HL_WORD()), 3, 4, 8, 2); break; case 0x5f: /* BIT A 3 */ BIT(reg_a, 3, 0, 8, 2); break; case 0x60: /* BIT B 4 */ BIT(reg_b, 4, 0, 8, 2); break; case 0x61: /* BIT C 4 */ BIT(reg_c, 4, 0, 8, 2); break; case 0x62: /* BIT D 4 */ BIT(reg_d, 4, 0, 8, 2); break; case 0x63: /* BIT E 4 */ BIT(reg_e, 4, 0, 8, 2); break; case 0x64: /* BIT H 4 */ BIT(reg_h, 4, 0, 8, 2); break; case 0x65: /* BIT L 4 */ BIT(reg_l, 4, 0, 8, 2); break; case 0x66: /* BIT (HL) 4 */ BIT(LOAD(HL_WORD()), 4, 4, 8, 2); break; case 0x67: /* BIT A 4 */ BIT(reg_a, 4, 0, 8, 2); break; case 0x68: /* BIT B 5 */ BIT(reg_b, 5, 0, 8, 2); break; case 0x69: /* BIT C 5 */ BIT(reg_c, 5, 0, 8, 2); break; case 0x6a: /* BIT D 5 */ BIT(reg_d, 5, 0, 8, 2); break; case 0x6b: /* BIT E 5 */ BIT(reg_e, 5, 0, 8, 2); break; case 0x6c: /* BIT H 5 */ BIT(reg_h, 5, 0, 8, 2); break; case 0x6d: /* BIT L 5 */ BIT(reg_l, 5, 0, 8, 2); break; case 0x6e: /* BIT (HL) 5 */ BIT(LOAD(HL_WORD()), 5, 4, 8, 2); break; case 0x6f: /* BIT A 5 */ BIT(reg_a, 5, 0, 8, 2); break; case 0x70: /* BIT B 6 */ BIT(reg_b, 6, 0, 8, 2); break; case 0x71: /* BIT C 6 */ BIT(reg_c, 6, 0, 8, 2); break; case 0x72: /* BIT D 6 */ BIT(reg_d, 6, 0, 8, 2); break; case 0x73: /* BIT E 6 */ BIT(reg_e, 6, 0, 8, 2); break; case 0x74: /* BIT H 6 */ BIT(reg_h, 6, 0, 8, 2); break; case 0x75: /* BIT L 6 */ BIT(reg_l, 6, 0, 8, 2); break; case 0x76: /* BIT (HL) 6 */ BIT(LOAD(HL_WORD()), 6, 4, 8, 2); break; case 0x77: /* BIT A 6 */ BIT(reg_a, 6, 0, 8, 2); break; case 0x78: /* BIT B 7 */ BIT(reg_b, 7, 0, 8, 2); break; case 0x79: /* BIT C 7 */ BIT(reg_c, 7, 0, 8, 2); break; case 0x7a: /* BIT D 7 */ BIT(reg_d, 7, 0, 8, 2); break; case 0x7b: /* BIT E 7 */ BIT(reg_e, 7, 0, 8, 2); break; case 0x7c: /* BIT H 7 */ BIT(reg_h, 7, 0, 8, 2); break; case 0x7d: /* BIT L 7 */ BIT(reg_l, 7, 0, 8, 2); break; case 0x7e: /* BIT (HL) 7 */ BIT(LOAD(HL_WORD()), 7, 4, 8, 2); break; case 0x7f: /* BIT A 7 */ BIT(reg_a, 7, 0, 8, 2); break; case 0x80: /* RES B 0 */ RES(reg_b, 0); break; case 0x81: /* RES C 0 */ RES(reg_c, 0); break; case 0x82: /* RES D 0 */ RES(reg_d, 0); break; case 0x83: /* RES E 0 */ RES(reg_e, 0); break; case 0x84: /* RES H 0 */ RES(reg_h, 0); break; case 0x85: /* RES L 0 */ RES(reg_l, 0); break; case 0x86: /* RES (HL) 0 */ RESXX(0, HL_WORD(), 4, 4, 7, 2); break; case 0x87: /* RES A 0 */ RES(reg_a, 0); break; case 0x88: /* RES B 1 */ RES(reg_b, 1); break; case 0x89: /* RES C 1 */ RES(reg_c, 1); break; case 0x8a: /* RES D 1 */ RES(reg_d, 1); break; case 0x8b: /* RES E 1 */ RES(reg_e, 1); break; case 0x8c: /* RES H 1 */ RES(reg_h, 1); break; case 0x8d: /* RES L 1 */ RES(reg_l, 1); break; case 0x8e: /* RES (HL) 1 */ RESXX(1, HL_WORD(), 4, 4, 7, 2); break; case 0x8f: /* RES A 1 */ RES(reg_a, 1); break; case 0x90: /* RES B 2 */ RES(reg_b, 2); break; case 0x91: /* RES C 2 */ RES(reg_c, 2); break; case 0x92: /* RES D 2 */ RES(reg_d, 2); break; case 0x93: /* RES E 2 */ RES(reg_e, 2); break; case 0x94: /* RES H 2 */ RES(reg_h, 2); break; case 0x95: /* RES L 2 */ RES(reg_l, 2); break; case 0x96: /* RES (HL) 2 */ RESXX(2, HL_WORD(), 4, 4, 7, 2); break; case 0x97: /* RES A 2 */ RES(reg_a, 2); break; case 0x98: /* RES B 3 */ RES(reg_b, 3); break; case 0x99: /* RES C 3 */ RES(reg_c, 3); break; case 0x9a: /* RES D 3 */ RES(reg_d, 3); break; case 0x9b: /* RES E 3 */ RES(reg_e, 3); break; case 0x9c: /* RES H 3 */ RES(reg_h, 3); break; case 0x9d: /* RES L 3 */ RES(reg_l, 3); break; case 0x9e: /* RES (HL) 3 */ RESXX(3, HL_WORD(), 4, 4, 7, 2); break; case 0x9f: /* RES A 3 */ RES(reg_a, 3); break; case 0xa0: /* RES B 4 */ RES(reg_b, 4); break; case 0xa1: /* RES C 4 */ RES(reg_c, 4); break; case 0xa2: /* RES D 4 */ RES(reg_d, 4); break; case 0xa3: /* RES E 4 */ RES(reg_e, 4); break; case 0xa4: /* RES H 4 */ RES(reg_h, 4); break; case 0xa5: /* RES L 4 */ RES(reg_l, 4); break; case 0xa6: /* RES (HL) 4 */ RESXX(4, HL_WORD(), 4, 4, 7, 2); break; case 0xa7: /* RES A 4 */ RES(reg_a, 4); break; case 0xa8: /* RES B 5 */ RES(reg_b, 5); break; case 0xa9: /* RES C 5 */ RES(reg_c, 5); break; case 0xaa: /* RES D 5 */ RES(reg_d, 5); break; case 0xab: /* RES E 5 */ RES(reg_e, 5); break; case 0xac: /* RES H 5 */ RES(reg_h, 5); break; case 0xad: /* RES L 5 */ RES(reg_l, 5); break; case 0xae: /* RES (HL) 5 */ RESXX(5, HL_WORD(), 4, 4, 7, 2); break; case 0xaf: /* RES A 5 */ RES(reg_a, 5); break; case 0xb0: /* RES B 6 */ RES(reg_b, 6); break; case 0xb1: /* RES C 6 */ RES(reg_c, 6); break; case 0xb2: /* RES D 6 */ RES(reg_d, 6); break; case 0xb3: /* RES E 6 */ RES(reg_e, 6); break; case 0xb4: /* RES H 6 */ RES(reg_h, 6); break; case 0xb5: /* RES L 6 */ RES(reg_l, 6); break; case 0xb6: /* RES (HL) 6 */ RESXX(6, HL_WORD(), 4, 4, 7, 2); break; case 0xb7: /* RES A 6 */ RES(reg_a, 6); break; case 0xb8: /* RES B 7 */ RES(reg_b, 7); break; case 0xb9: /* RES C 7 */ RES(reg_c, 7); break; case 0xba: /* RES D 7 */ RES(reg_d, 7); break; case 0xbb: /* RES E 7 */ RES(reg_e, 7); break; case 0xbc: /* RES H 7 */ RES(reg_h, 7); break; case 0xbd: /* RES L 7 */ RES(reg_l, 7); break; case 0xbe: /* RES (HL) 7 */ RESXX(7, HL_WORD(), 4, 4, 7, 2); break; case 0xbf: /* RES A 7 */ RES(reg_a, 7); break; case 0xc0: /* SET B 0 */ SET(reg_b, 0); break; case 0xc1: /* SET C 0 */ SET(reg_c, 0); break; case 0xc2: /* SET D 0 */ SET(reg_d, 0); break; case 0xc3: /* SET E 0 */ SET(reg_e, 0); break; case 0xc4: /* SET H 0 */ SET(reg_h, 0); break; case 0xc5: /* SET L 0 */ SET(reg_l, 0); break; case 0xc6: /* SET (HL) 0 */ SETXX(0, HL_WORD(), 4, 4, 7, 2); break; case 0xc7: /* SET A 0 */ SET(reg_a, 0); break; case 0xc8: /* SET B 1 */ SET(reg_b, 1); break; case 0xc9: /* SET C 1 */ SET(reg_c, 1); break; case 0xca: /* SET D 1 */ SET(reg_d, 1); break; case 0xcb: /* SET E 1 */ SET(reg_e, 1); break; case 0xcc: /* SET H 1 */ SET(reg_h, 1); break; case 0xcd: /* SET L 1 */ SET(reg_l, 1); break; case 0xce: /* SET (HL) 1 */ SETXX(1, HL_WORD(), 4, 4, 7, 2); break; case 0xcf: /* SET A 1 */ SET(reg_a, 1); break; case 0xd0: /* SET B 2 */ SET(reg_b, 2); break; case 0xd1: /* SET C 2 */ SET(reg_c, 2); break; case 0xd2: /* SET D 2 */ SET(reg_d, 2); break; case 0xd3: /* SET E 2 */ SET(reg_e, 2); break; case 0xd4: /* SET H 2 */ SET(reg_h, 2); break; case 0xd5: /* SET L 2 */ SET(reg_l, 2); break; case 0xd6: /* SET (HL) 2 */ SETXX(2, HL_WORD(), 4, 4, 7, 2); break; case 0xd7: /* SET A 2 */ SET(reg_a, 2); break; case 0xd8: /* SET B 3 */ SET(reg_b, 3); break; case 0xd9: /* SET C 3 */ SET(reg_c, 3); break; case 0xda: /* SET D 3 */ SET(reg_d, 3); break; case 0xdb: /* SET E 3 */ SET(reg_e, 3); break; case 0xdc: /* SET H 3 */ SET(reg_h, 3); break; case 0xdd: /* SET L 3 */ SET(reg_l, 3); break; case 0xde: /* SET (HL) 3 */ SETXX(3, HL_WORD(), 4, 4, 7, 2); break; case 0xdf: /* SET A 3 */ SET(reg_a, 3); break; case 0xe0: /* SET B 4 */ SET(reg_b, 4); break; case 0xe1: /* SET C 4 */ SET(reg_c, 4); break; case 0xe2: /* SET D 4 */ SET(reg_d, 4); break; case 0xe3: /* SET E 4 */ SET(reg_e, 4); break; case 0xe4: /* SET H 4 */ SET(reg_h, 4); break; case 0xe5: /* SET L 4 */ SET(reg_l, 4); break; case 0xe6: /* SET (HL) 4 */ SETXX(4, HL_WORD(), 4, 4, 7, 2); break; case 0xe7: /* SET A 4 */ SET(reg_a, 4); break; case 0xe8: /* SET B 5 */ SET(reg_b, 5); break; case 0xe9: /* SET C 5 */ SET(reg_c, 5); break; case 0xea: /* SET D 5 */ SET(reg_d, 5); break; case 0xeb: /* SET E 5 */ SET(reg_e, 5); break; case 0xec: /* SET H 5 */ SET(reg_h, 5); break; case 0xed: /* SET L 5 */ SET(reg_l, 5); break; case 0xee: /* SET (HL) 5 */ SETXX(5, HL_WORD(), 4, 4, 7, 2); break; case 0xef: /* SET A 5 */ SET(reg_a, 5); break; case 0xf0: /* SET B 6 */ SET(reg_b, 6); break; case 0xf1: /* SET C 6 */ SET(reg_c, 6); break; case 0xf2: /* SET D 6 */ SET(reg_d, 6); break; case 0xf3: /* SET E 6 */ SET(reg_e, 6); break; case 0xf4: /* SET H 6 */ SET(reg_h, 6); break; case 0xf5: /* SET L 6 */ SET(reg_l, 6); break; case 0xf6: /* SET (HL) 6 */ SETXX(6, HL_WORD(), 4, 4, 7, 2); break; case 0xf7: /* SET A 6 */ SET(reg_a, 6); break; case 0xf8: /* SET B 7 */ SET(reg_b, 7); break; case 0xf9: /* SET C 7 */ SET(reg_c, 7); break; case 0xfa: /* SET D 7 */ SET(reg_d, 7); break; case 0xfb: /* SET E 7 */ SET(reg_e, 7); break; case 0xfc: /* SET H 7 */ SET(reg_h, 7); break; case 0xfd: /* SET L 7 */ SET(reg_l, 7); break; case 0xfe: /* SET (HL) 7 */ SETXX(7, HL_WORD(), 4, 4, 7, 2); break; case 0xff: /* SET A 7 */ SET(reg_a, 7); break; default: INC_PC(2); } } static void opcode_dd_cb(BYTE iip2, BYTE iip3, WORD iip23) { switch (iip3) { case 0x00: /* RLC (IX+d),B */ RLCXXREG(reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x01: /* RLC (IX+d),C */ RLCXXREG(reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x02: /* RLC (IX+d),D */ RLCXXREG(reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x03: /* RLC (IX+d),E */ RLCXXREG(reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x04: /* RLC (IX+d),H */ RLCXXREG(reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x05: /* RLC (IX+d),L */ RLCXXREG(reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x06: /* RLC (IX+d) */ RLCXX(IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x07: /* RLC (IX+d),A */ RLCXXREG(reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x08: /* RRC (IX+d),B */ RRCXXREG(reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x09: /* RRC (IX+d),C */ RRCXXREG(reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x0a: /* RRC (IX+d),D */ RRCXXREG(reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x0b: /* RRC (IX+d),E */ RRCXXREG(reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x0c: /* RRC (IX+d),H */ RRCXXREG(reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x0d: /* RRC (IX+d),L */ RRCXXREG(reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x0e: /* RRC (IX+d) */ RRCXX(IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x0f: /* RRC (IX+d),A */ RRCXXREG(reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x10: /* RL (IX+d),B */ RLXXREG(reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x11: /* RL (IX+d),C */ RLXXREG(reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x12: /* RL (IX+d),D */ RLXXREG(reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x13: /* RL (IX+d),E */ RLXXREG(reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x14: /* RL (IX+d),H */ RLXXREG(reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x15: /* RL (IX+d),L */ RLXXREG(reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x16: /* RL (IX+d) */ RLXX(IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x17: /* RL (IX+d),A */ RLXXREG(reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x18: /* RR (IX+d),B */ RRXXREG(reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x19: /* RR (IX+d),C */ RRXXREG(reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x1a: /* RR (IX+d),D */ RRXXREG(reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x1b: /* RR (IX+d),E */ RRXXREG(reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x1c: /* RR (IX+d),H */ RRXXREG(reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x1d: /* RR (IX+d),L */ RRXXREG(reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x1e: /* RR (IX+d) */ RRXX(IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x1f: /* RR (IX+d),A */ RRXXREG(reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x20: /* SLA (IX+d),B */ SLAXXREG(reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x21: /* SLA (IX+d),C */ SLAXXREG(reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x22: /* SLA (IX+d),D */ SLAXXREG(reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x23: /* SLA (IX+d),E */ SLAXXREG(reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x24: /* SLA (IX+d),H */ SLAXXREG(reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x25: /* SLA (IX+d),L */ SLAXXREG(reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x26: /* SLA (IX+d) */ SLAXX(IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x27: /* SLA (IX+d),A */ SLAXXREG(reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x28: /* SRA (IX+d),B */ SRAXXREG(reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x29: /* SRA (IX+d),C */ SRAXXREG(reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x2a: /* SRA (IX+d),D */ SRAXXREG(reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x2b: /* SRA (IX+d),E */ SRAXXREG(reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x2c: /* SRA (IX+d),H */ SRAXXREG(reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x2d: /* SRA (IX+d),L */ SRAXXREG(reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x2e: /* SRA (IX+d) */ SRAXX(IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x2f: /* SRA (IX+d),A */ SRAXXREG(reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x30: /* SLL (IX+d),B */ SLLXXREG(reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x31: /* SLL (IX+d),C */ SLLXXREG(reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x32: /* SLL (IX+d),D */ SLLXXREG(reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x33: /* SLL (IX+d),E */ SLLXXREG(reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x34: /* SLL (IX+d),H */ SLLXXREG(reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x35: /* SLL (IX+d),L */ SLLXXREG(reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x36: /* SLL (IX+d) */ SLLXX(IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x37: /* SLL (IX+d),A */ SLLXXREG(reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x38: /* SRL (IX+d),B */ SRLXXREG(reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x39: /* SRL (IX+d),C */ SRLXXREG(reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x3a: /* SRL (IX+d),D */ SRLXXREG(reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x3b: /* SRL (IX+d),E */ SRLXXREG(reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x3c: /* SRL (IX+d),H */ SRLXXREG(reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x3d: /* SRL (IX+d),L */ SRLXXREG(reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x3e: /* SRL (IX+d) */ SRLXX(IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x3f: /* SRL (IX+d),A */ SRLXXREG(reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x40: /* BIT (IX+d) 0 */ case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: BIT(LOAD(IX_WORD_OFF(iip2)), 0, 8, 12, 4); break; case 0x48: /* BIT (IX+d) 1 */ case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: BIT(LOAD(IX_WORD_OFF(iip2)), 1, 8, 12, 4); break; case 0x50: /* BIT (IX+d) 2 */ case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: BIT(LOAD(IX_WORD_OFF(iip2)), 2, 8, 12, 4); break; case 0x58: /* BIT (IX+d) 3 */ case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: BIT(LOAD(IX_WORD_OFF(iip2)), 3, 8, 12, 4); break; case 0x60: /* BIT (IX+d) 4 */ case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: BIT(LOAD(IX_WORD_OFF(iip2)), 4, 8, 12, 4); break; case 0x68: /* BIT (IX+d) 5 */ case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: BIT(LOAD(IX_WORD_OFF(iip2)), 5, 8, 12, 4); break; case 0x70: /* BIT (IX+d) 6 */ case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: BIT(LOAD(IX_WORD_OFF(iip2)), 6, 8, 12, 4); break; case 0x78: /* BIT (IX+d) 7 */ case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: BIT(LOAD(IX_WORD_OFF(iip2)), 7, 8, 12, 4); break; case 0x80: /* RES (IX+d),B 0 */ RESXXREG(0, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x81: /* RES (IX+d),C 0 */ RESXXREG(0, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x82: /* RES (IX+d),D 0 */ RESXXREG(0, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x83: /* RES (IX+d),E 0 */ RESXXREG(0, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x84: /* RES (IX+d),H 0 */ RESXXREG(0, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x85: /* RES (IX+d),L 0 */ RESXXREG(0, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x86: /* RES (IX+d) 0 */ RESXX(0, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x87: /* RES (IX+d),A 0 */ RESXXREG(0, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x88: /* RES (IX+d),B 1 */ RESXXREG(1, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x89: /* RES (IX+d),C 1 */ RESXXREG(1, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x8a: /* RES (IX+d),D 1 */ RESXXREG(1, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x8b: /* RES (IX+d),E 1 */ RESXXREG(1, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x8c: /* RES (IX+d),H 1 */ RESXXREG(1, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x8d: /* RES (IX+d),L 1 */ RESXXREG(1, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x8e: /* RES (IX+d) 1 */ RESXX(1, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x8f: /* RES (IX+d),A 1 */ RESXXREG(1, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x90: /* RES (IX+d),B 2 */ RESXXREG(2, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x91: /* RES (IX+d),C 2 */ RESXXREG(2, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x92: /* RES (IX+d),D 2 */ RESXXREG(2, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x93: /* RES (IX+d),E 2 */ RESXXREG(2, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x94: /* RES (IX+d),H 2 */ RESXXREG(2, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x95: /* RES (IX+d),L 2 */ RESXXREG(2, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x96: /* RES (IX+d) 2 */ RESXX(2, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x97: /* RES (IX+d),A 2 */ RESXXREG(2, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x98: /* RES (IX+d),B 3 */ RESXXREG(3, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x99: /* RES (IX+d),C 3 */ RESXXREG(3, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x9a: /* RES (IX+d),D 3 */ RESXXREG(3, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x9b: /* RES (IX+d),E 3 */ RESXXREG(3, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x9c: /* RES (IX+d),H 3 */ RESXXREG(3, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x9d: /* RES (IX+d),L 3 */ RESXXREG(3, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x9e: /* RES (IX+d) 3 */ RESXX(3, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x9f: /* RES (IX+d),A 3 */ RESXXREG(3, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa0: /* RES (IX+d),B 4 */ RESXXREG(4, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa1: /* RES (IX+d),C 4 */ RESXXREG(4, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa2: /* RES (IX+d),D 4 */ RESXXREG(4, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa3: /* RES (IX+d),E 4 */ RESXXREG(4, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa4: /* RES (IX+d),H 4 */ RESXXREG(4, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa5: /* RES (IX+d),L 4 */ RESXXREG(4, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa6: /* RES (IX+d) 4 */ RESXX(4, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa7: /* RES (IX+d),A 4 */ RESXXREG(4, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa8: /* RES (IX+d),B 5 */ RESXXREG(5, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa9: /* RES (IX+d),C 5 */ RESXXREG(5, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xaa: /* RES (IX+d),D 5 */ RESXXREG(5, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xab: /* RES (IX+d),E 5 */ RESXXREG(5, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xac: /* RES (IX+d),H 5 */ RESXXREG(5, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xad: /* RES (IX+d),L 5 */ RESXXREG(5, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xae: /* RES (IX+d) 5 */ RESXX(5, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xaf: /* RES (IX+d),A 5 */ RESXXREG(5, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb0: /* RES (IX+d),B 6 */ RESXXREG(6, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb1: /* RES (IX+d),C 6 */ RESXXREG(6, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb2: /* RES (IX+d),D 6 */ RESXXREG(6, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb3: /* RES (IX+d),E 6 */ RESXXREG(6, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb4: /* RES (IX+d),H 6 */ RESXXREG(6, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb5: /* RES (IX+d),L 6 */ RESXXREG(6, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb6: /* RES (IX+d) 6 */ RESXX(6, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb7: /* RES (IX+d),A 6 */ RESXXREG(6, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb8: /* RES (IX+d),B 7 */ RESXXREG(7, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb9: /* RES (IX+d),C 7 */ RESXXREG(7, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xba: /* RES (IX+d),D 7 */ RESXXREG(7, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xbb: /* RES (IX+d),E 7 */ RESXXREG(7, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xbc: /* RES (IX+d),H 7 */ RESXXREG(7, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xbd: /* RES (IX+d),L 7 */ RESXXREG(7, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xbe: /* RES (IX+d) 7 */ RESXX(7, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xbf: /* RES (IX+d),A 7 */ RESXXREG(7, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc0: /* SET (IX+d),B 0 */ SETXXREG(0, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc1: /* SET (IX+d),C 0 */ SETXXREG(0, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc2: /* SET (IX+d),D 0 */ SETXXREG(0, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc3: /* SET (IX+d),E 0 */ SETXXREG(0, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc4: /* SET (IX+d),H 0 */ SETXXREG(0, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc5: /* SET (IX+d),L 0 */ SETXXREG(0, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc6: /* SET (IX+d) 0 */ SETXX(0, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc7: /* SET (IX+d),A 0 */ SETXXREG(0, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc8: /* SET (IX+d),B 1 */ SETXXREG(1, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc9: /* SET (IX+d),C 1 */ SETXXREG(1, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xca: /* SET (IX+d),D 1 */ SETXXREG(1, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xcb: /* SET (IX+d),E 1 */ SETXXREG(1, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xcc: /* SET (IX+d),H 1 */ SETXXREG(1, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xcd: /* SET (IX+d),L 1 */ SETXXREG(1, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xce: /* SET (IX+d) 1 */ SETXX(1, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xcf: /* SET (IX+d),A 1 */ SETXXREG(1, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd0: /* SET (IX+d),B 2 */ SETXXREG(2, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd1: /* SET (IX+d),C 2 */ SETXXREG(2, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd2: /* SET (IX+d),D 2 */ SETXXREG(2, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd3: /* SET (IX+d),E 2 */ SETXXREG(2, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd4: /* SET (IX+d),H 2 */ SETXXREG(2, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd5: /* SET (IX+d),L 2 */ SETXXREG(2, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd6: /* SET (IX+d) 2 */ SETXX(2, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd7: /* SET (IX+d),A 2 */ SETXXREG(2, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd8: /* SET (IX+d),B 3 */ SETXXREG(3, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd9: /* SET (IX+d),C 3 */ SETXXREG(3, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xda: /* SET (IX+d),D 3 */ SETXXREG(3, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xdb: /* SET (IX+d),E 3 */ SETXXREG(3, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xdc: /* SET (IX+d),H 3 */ SETXXREG(3, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xdd: /* SET (IX+d),L 3 */ SETXXREG(3, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xde: /* SET (IX+d) 3 */ SETXX(3, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xdf: /* SET (IX+d),A 3 */ SETXXREG(3, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe0: /* SET (IX+d),B 4 */ SETXXREG(4, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe1: /* SET (IX+d),C 4 */ SETXXREG(4, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe2: /* SET (IX+d),D 4 */ SETXXREG(4, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe3: /* SET (IX+d),E 4 */ SETXXREG(4, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe4: /* SET (IX+d),H 4 */ SETXXREG(4, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe5: /* SET (IX+d),L 4 */ SETXXREG(4, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe6: /* SET (IX+d) 4 */ SETXX(4, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe7: /* SET (IX+d),A 4 */ SETXXREG(4, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe8: /* SET (IX+d),B 5 */ SETXXREG(5, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe9: /* SET (IX+d),C 5 */ SETXXREG(5, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xea: /* SET (IX+d),D 5 */ SETXXREG(5, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xeb: /* SET (IX+d),E 5 */ SETXXREG(5, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xec: /* SET (IX+d),H 5 */ SETXXREG(5, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xed: /* SET (IX+d),L 5 */ SETXXREG(5, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xee: /* SET (IX+d) 5 */ SETXX(5, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xef: /* SET (IX+d),A 5 */ SETXXREG(5, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf0: /* SET (IX+d),B 6 */ SETXXREG(6, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf1: /* SET (IX+d),C 6 */ SETXXREG(6, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf2: /* SET (IX+d),D 6 */ SETXXREG(6, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf3: /* SET (IX+d),E 6 */ SETXXREG(6, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf4: /* SET (IX+d),H 6 */ SETXXREG(6, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf5: /* SET (IX+d),L 6 */ SETXXREG(6, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf6: /* SET (IX+d) 6 */ SETXX(6, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf7: /* SET (IX+d),A 6 */ SETXXREG(6, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf8: /* SET (IX+d),B 7 */ SETXXREG(7, reg_b, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf9: /* SET (IX+d),C 7 */ SETXXREG(7, reg_c, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xfa: /* SET (IX+d),D 7 */ SETXXREG(7, reg_d, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xfb: /* SET (IX+d),E 7 */ SETXXREG(7, reg_e, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xfc: /* SET (IX+d),H 7 */ SETXXREG(7, reg_h, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xfd: /* SET (IX+d),L 7 */ SETXXREG(7, reg_l, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xfe: /* SET (IX+d) 7 */ SETXX(7, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xff: /* SET (IX+d),A 7 */ SETXXREG(7, reg_a, IX_WORD_OFF(iip2), 4, 4, 15, 4); break; default: INC_PC(4); } } static void opcode_dd(BYTE ip1, BYTE ip2, BYTE ip3, WORD ip12, WORD ip23) { switch (ip1) { case 0x00: /* NOP */ NOP(8, 2); break; case 0x01: /* LD BC # */ LDW(ip23, reg_b, reg_c, 10, 0, 4); break; case 0x02: /* LD (BC) A */ STREG(BC_WORD(), reg_a, 8, 3, 2); break; case 0x03: /* INC BC */ DECINC(INC_BC_WORD(), 10, 2); break; case 0x04: /* INC B */ INCREG(reg_b, 7, 2); break; case 0x05: /* DEC B */ DECREG(reg_b, 7, 2); break; case 0x06: /* LD B # */ LDREG(reg_b, ip2, 4, 5, 3); break; case 0x07: /* RLCA */ RLCA(8, 2); break; case 0x08: /* EX AF AF' */ EXAFAF(12, 2); break; case 0x09: /* ADD IX BC */ ADDXXREG(reg_ixh, reg_ixl, reg_b, reg_c, 15, 2); break; case 0x0a: /* LD A (BC) */ LDREG(reg_a, LOAD(BC_WORD()), 8, 3, 2); break; case 0x0b: /* DEC BC */ DECINC(DEC_BC_WORD(), 10, 2); break; case 0x0c: /* INC C */ INCREG(reg_c, 7, 2); break; case 0x0d: /* DEC C */ DECREG(reg_c, 7, 2); break; case 0x0e: /* LD C # */ LDREG(reg_c, ip2, 4, 5, 3); break; case 0x0f: /* RRCA */ RRCA(8, 2); break; case 0x10: /* DJNZ */ DJNZ(ip2, 3); break; case 0x11: /* LD DE # */ LDW(ip23, reg_d, reg_e, 10, 0, 4); break; case 0x12: /* LD (DE) A */ STREG(DE_WORD(), reg_a, 8, 3, 2); break; case 0x13: /* INC DE */ DECINC(INC_DE_WORD(), 10, 2); break; case 0x14: /* INC D */ INCREG(reg_d, 7, 2); break; case 0x15: /* DEC D */ DECREG(reg_d, 7, 2); break; case 0x16: /* LD D # */ LDREG(reg_d, ip2, 4, 5, 3); break; case 0x17: /* RLA */ RLA(8, 2); break; case 0x19: /* ADD IX DE */ ADDXXREG(reg_ixh, reg_ixl, reg_d, reg_e, 15, 2); break; case 0x1a: /* LD A DE */ LDREG(reg_a, LOAD(DE_WORD()), 8, 3, 2); break; case 0x1b: /* DEC DE */ DECINC(DEC_DE_WORD(), 10, 2); break; case 0x1c: /* INC E */ INCREG(reg_e, 7, 2); break; case 0x1d: /* DEC E */ DECREG(reg_e, 7, 2); break; case 0x1e: /* LD E # */ LDREG(reg_e, ip2, 4, 5, 3); break; case 0x1f: /* RRA */ RRA(8, 2); break; case 0x20: /* JR NZ */ BRANCH(!LOCAL_ZERO(), ip2, 3); break; case 0x21: /* LD IX # */ LDW(ip23, reg_ixh, reg_ixl, 10, 4, 4); break; case 0x22: /* LD (WORD) IX */ STW(ip23, reg_ixh, reg_ixl, 4, 9, 7, 4); break; case 0x23: /* INC IX */ DECINC(INC_IX_WORD(), 10, 2); break; case 0x24: /* INC IXH */ INCREG(reg_ixh, 7, 2); break; case 0x25: /* DEC IXH */ DECREG(reg_ixh, 7, 2); break; case 0x26: /* LD IXH # */ LDREG(reg_ixh, ip2, 4, 5, 3); break; case 0x27: /* DAA */ DAA(8, 2); break; case 0x29: /* ADD IX IX */ ADDXXREG(reg_ixh, reg_ixl, reg_ixh, reg_ixl, 15, 2); break; case 0x28: /* JR Z */ BRANCH(LOCAL_ZERO(), ip2, 3); break; case 0x2a: /* LD IX (WORD) */ LDIND(ip23, reg_ixh, reg_ixl, 4, 4, 12, 4); break; case 0x2b: /* DEC IX */ DECINC(DEC_IX_WORD(), 10, 2); break; case 0x2c: /* INC IXL */ INCREG(reg_ixl, 7, 2); break; case 0x2d: /* DEC IXL */ DECREG(reg_ixl, 7, 2); break; case 0x2e: /* LD IXL # */ LDREG(reg_ixl, ip2, 4, 5, 3); break; case 0x2f: /* CPL */ CPL(8, 2); break; case 0x30: /* JR NC */ BRANCH(!LOCAL_CARRY(), ip2, 3); break; case 0x31: /* LD SP # */ LDSP(ip23, 10, 0, 4); break; case 0x32: /* LD (WORD) A */ STREG(ip23, reg_a, 10, 7, 4); break; case 0x33: /* INC SP */ DECINC(reg_sp++, 10, 2); break; case 0x34: /* INC (IX+d) */ INCXXIND(IX_WORD_OFF(ip2), 4, 7, 12, 3); break; case 0x35: /* DEC (IX+d) */ DECXXIND(IX_WORD_OFF(ip2), 4, 7, 12, 3); break; case 0x36: /* LD (IX+d) # */ STREG(IX_WORD_OFF(ip2), ip3, 8, 11, 4); break; case 0x37: /* SCF */ SCF(8, 2); break; case 0x38: /* JR C */ BRANCH(LOCAL_CARRY(), ip2, 3); break; case 0x39: /* ADD IX SP */ ADDXXSP(reg_ixh, reg_ixl, 15, 2); break; case 0x3a: /* LD A (WORD) */ LDREG(reg_a, LOAD(ip23), 10, 7, 4); break; case 0x3b: /* DEC SP */ DECINC(reg_sp--, 10, 2); break; case 0x3c: /* INC A */ INCREG(reg_a, 7, 2); break; case 0x3d: /* DEC A */ DECREG(reg_a, 7, 2); break; case 0x3e: /* LD A # */ LDREG(reg_a, ip2, 4, 5, 3); break; case 0x3f: /* CCF */ CCF(8, 2); break; case 0x40: /* LD B B */ LDREG(reg_b, reg_b, 0, 4, 2); break; case 0x41: /* LD B C */ LDREG(reg_b, reg_c, 0, 4, 2); break; case 0x42: /* LD B D */ LDREG(reg_b, reg_d, 0, 4, 2); break; case 0x43: /* LD B E */ LDREG(reg_b, reg_e, 0, 4, 2); break; case 0x44: /* LD B IXH */ LDREG(reg_b, reg_ixh, 0, 4, 2); break; case 0x45: /* LD B IXL */ LDREG(reg_b, reg_ixl, 0, 4, 2); break; case 0x46: /* LD B (IX+d) */ LDREG(reg_b, LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0x47: /* LD B A */ LDREG(reg_b, reg_a, 0, 4, 2); break; case 0x48: /* LD C B */ LDREG(reg_c, reg_b, 0, 4, 2); break; case 0x49: /* LD C C */ LDREG(reg_c, reg_c, 0, 4, 2); break; case 0x4a: /* LD C D */ LDREG(reg_c, reg_d, 0, 4, 2); break; case 0x4b: /* LD C E */ LDREG(reg_c, reg_e, 0, 4, 2); break; case 0x4c: /* LD C IXH */ LDREG(reg_c, reg_ixh, 0, 4, 2); break; case 0x4d: /* LD C IXL */ LDREG(reg_c, reg_ixl, 0, 4, 2); break; case 0x4e: /* LD C (IX+d) */ LDREG(reg_c, LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0x4f: /* LD C A */ LDREG(reg_c, reg_a, 0, 4, 2); break; case 0x50: /* LD D B */ LDREG(reg_d, reg_b, 0, 4, 2); break; case 0x51: /* LD D C */ LDREG(reg_d, reg_c, 0, 4, 2); break; case 0x52: /* LD D D */ LDREG(reg_d, reg_d, 0, 4, 2); break; case 0x53: /* LD D E */ LDREG(reg_d, reg_e, 0, 4, 2); break; case 0x54: /* LD D IXH */ LDREG(reg_d, reg_ixh, 0, 4, 2); break; case 0x55: /* LD D L */ LDREG(reg_d, reg_ixl, 0, 4, 2); break; case 0x56: /* LD D (IX+d) */ LDREG(reg_d, LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0x57: /* LD D A */ LDREG(reg_d, reg_a, 0, 4, 2); break; case 0x58: /* LD E B */ LDREG(reg_e, reg_b, 0, 4, 2); break; case 0x59: /* LD E C */ LDREG(reg_e, reg_c, 0, 4, 2); break; case 0x5a: /* LD E D */ LDREG(reg_e, reg_d, 0, 4, 2); break; case 0x5b: /* LD E E */ LDREG(reg_e, reg_e, 0, 4, 2); break; case 0x5c: /* LD E IXH */ LDREG(reg_e, reg_ixh, 0, 4, 2); break; case 0x5d: /* LD E IXL */ LDREG(reg_e, reg_ixl, 0, 4, 2); break; case 0x5e: /* LD E (IX+d) */ LDREG(reg_e, LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0x5f: /* LD E A */ LDREG(reg_e, reg_a, 0, 4, 2); break; case 0x60: /* LD IXH B */ LDREG(reg_ixh, reg_b, 0, 4, 2); break; case 0x61: /* LD IXH C */ LDREG(reg_ixh, reg_c, 0, 4, 2); break; case 0x62: /* LD IXH D */ LDREG(reg_ixh, reg_d, 0, 4, 2); break; case 0x63: /* LD IXH E */ LDREG(reg_ixh, reg_e, 0, 4, 2); break; case 0x64: /* LD IXH IXH */ LDREG(reg_ixh, reg_ixh, 0, 4, 2); break; case 0x65: /* LD IXH IXL */ LDREG(reg_ixh, reg_ixl, 0, 4, 2); break; case 0x66: /* LD H (IX+d) */ LDREG(reg_h, LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0x67: /* LD IXH A */ LDREG(reg_ixh, reg_a, 0, 4, 2); break; case 0x68: /* LD IXL B */ LDREG(reg_ixl, reg_b, 0, 4, 2); break; case 0x69: /* LD IXL C */ LDREG(reg_ixl, reg_c, 0, 4, 2); break; case 0x6a: /* LD IXL D */ LDREG(reg_ixl, reg_d, 0, 4, 2); break; case 0x6b: /* LD IXL E */ LDREG(reg_ixl, reg_e, 0, 4, 2); break; case 0x6c: /* LD IXL IXH */ LDREG(reg_ixl, reg_ixh, 0, 4, 2); break; case 0x6d: /* LD IXL IXL */ LDREG(reg_ixl, reg_ixl, 0, 4, 2); break; case 0x6e: /* LD L (IX+d) */ LDREG(reg_l, LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0x6f: /* LD IXL A */ LDREG(reg_ixl, reg_a, 0, 4, 2); break; case 0x70: /* LD (IX+d) B */ STREG(IX_WORD_OFF(ip2), reg_b, 8, 11, 3); break; case 0x71: /* LD (IX+d) C */ STREG(IX_WORD_OFF(ip2), reg_c, 8, 11, 3); break; case 0x72: /* LD (IX+d) D */ STREG(IX_WORD_OFF(ip2), reg_d, 8, 11, 3); break; case 0x73: /* LD (IX+d) E */ STREG(IX_WORD_OFF(ip2), reg_e, 8, 11, 3); break; case 0x74: /* LD (IX+d) H */ STREG(IX_WORD_OFF(ip2), reg_h, 8, 11, 3); break; case 0x75: /* LD (IX+d) L */ STREG(IX_WORD_OFF(ip2), reg_l, 8, 11, 3); break; case 0x76: /* HALT */ HALT(); break; case 0x77: /* LD (IX+d) A */ STREG(IX_WORD_OFF(ip2), reg_a, 8, 11, 3); break; case 0x78: /* LD A B */ LDREG(reg_a, reg_b, 0, 4, 2); break; case 0x79: /* LD A C */ LDREG(reg_a, reg_c, 0, 4, 2); break; case 0x7a: /* LD A D */ LDREG(reg_a, reg_d, 0, 4, 2); break; case 0x7b: /* LD A E */ LDREG(reg_a, reg_e, 0, 4, 2); break; case 0x7c: /* LD A IXH */ LDREG(reg_a, reg_ixh, 0, 4, 2); break; case 0x7d: /* LD A IXL */ LDREG(reg_a, reg_ixl, 0, 4, 2); break; case 0x7e: /* LD A (IX+d) */ LDREG(reg_a, LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0x7f: /* LD A A */ LDREG(reg_a, reg_a, 0, 4, 2); break; case 0x80: /* ADD B */ ADD(reg_b, 0, 4, 2); break; case 0x81: /* ADD C */ ADD(reg_c, 0, 4, 2); break; case 0x82: /* ADD D */ ADD(reg_d, 0, 4, 2); break; case 0x83: /* ADD E */ ADD(reg_e, 0, 4, 2); break; case 0x84: /* ADD IXH */ ADD(reg_ixh, 0, 4, 2); break; case 0x85: /* ADD IXL */ ADD(reg_ixl, 0, 4, 2); break; case 0x86: /* ADD (IX+d) */ ADD(LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0x87: /* ADD A */ ADD(reg_a, 0, 4, 2); break; case 0x88: /* ADC B */ ADC(reg_b, 0, 4, 2); break; case 0x89: /* ADC C */ ADC(reg_c, 0, 4, 2); break; case 0x8a: /* ADC D */ ADC(reg_d, 0, 4, 2); break; case 0x8b: /* ADC E */ ADC(reg_e, 0, 4, 2); break; case 0x8c: /* ADC IXH */ ADC(reg_ixh, 0, 4, 2); break; case 0x8d: /* ADC IXL */ ADC(reg_ixl, 0, 4, 2); break; case 0x8e: /* ADC (IX+d) */ ADC(LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0x8f: /* ADC A */ ADC(reg_a, 0, 4, 2); break; case 0x90: /* SUB B */ SUB(reg_b, 0, 4, 2); break; case 0x91: /* SUB C */ SUB(reg_c, 0, 4, 2); break; case 0x92: /* SUB D */ SUB(reg_d, 0, 4, 2); break; case 0x93: /* SUB E */ SUB(reg_e, 0, 4, 2); break; case 0x94: /* SUB IXH */ SUB(reg_ixh, 0, 4, 2); break; case 0x95: /* SUB IXL */ SUB(reg_ixl, 0, 4, 2); break; case 0x96: /* SUB (IX+d) */ SUB(LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0x97: /* SUB A */ SUB(reg_a, 0, 4, 2); break; case 0x98: /* SBC B */ SBC(reg_b, 0, 4, 2); break; case 0x99: /* SBC C */ SBC(reg_c, 0, 4, 2); break; case 0x9a: /* SBC D */ SBC(reg_d, 0, 4, 2); break; case 0x9b: /* SBC E */ SBC(reg_e, 0, 4, 2); break; case 0x9c: /* SBC IXH */ SBC(reg_ixh, 0, 4, 2); break; case 0x9d: /* SBC IXL */ SBC(reg_ixl, 0, 4, 2); break; case 0x9e: /* SBC (IX+d) */ SBC(LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0x9f: /* SBC A */ SBC(reg_a, 0, 4, 2); break; case 0xa0: /* AND B */ AND(reg_b, 0, 4, 2); break; case 0xa1: /* AND C */ AND(reg_c, 0, 4, 2); break; case 0xa2: /* AND D */ AND(reg_d, 0, 4, 2); break; case 0xa3: /* AND E */ AND(reg_e, 0, 4, 2); break; case 0xa4: /* AND IXH */ AND(reg_ixh, 0, 4, 2); break; case 0xa5: /* AND IXL */ AND(reg_ixl, 0, 4, 2); break; case 0xa6: /* AND (IX+d) */ AND(LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0xa7: /* AND A */ AND(reg_a, 0, 4, 2); break; case 0xa8: /* XOR B */ XOR(reg_b, 0, 4, 2); break; case 0xa9: /* XOR C */ XOR(reg_c, 0, 4, 2); break; case 0xaa: /* XOR D */ XOR(reg_d, 0, 4, 2); break; case 0xab: /* XOR E */ XOR(reg_e, 0, 4, 2); break; case 0xac: /* XOR IXH */ XOR(reg_ixh, 0, 4, 2); break; case 0xad: /* XOR IXL */ XOR(reg_ixl, 0, 4, 2); break; case 0xae: /* XOR (IX+d) */ XOR(LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0xaf: /* XOR A */ XOR(reg_a, 0, 4, 2); break; case 0xb0: /* OR B */ OR(reg_b, 0, 4, 2); break; case 0xb1: /* OR C */ OR(reg_c, 0, 4, 2); break; case 0xb2: /* OR D */ OR(reg_d, 0, 4, 2); break; case 0xb3: /* OR E */ OR(reg_e, 0, 4, 2); break; case 0xb4: /* OR IXH */ OR(reg_ixh, 0, 4, 2); break; case 0xb5: /* OR IXL */ OR(reg_ixl, 0, 4, 2); break; case 0xb6: /* OR (IX+d) */ OR(LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0xb7: /* OR A */ OR(reg_a, 0, 4, 2); break; case 0xb8: /* CP B */ CP(reg_b, 0, 4, 2); break; case 0xb9: /* CP C */ CP(reg_c, 0, 4, 2); break; case 0xba: /* CP D */ CP(reg_d, 0, 4, 2); break; case 0xbb: /* CP E */ CP(reg_e, 0, 4, 2); break; case 0xbc: /* CP IXH */ CP(reg_ixh, 0, 4, 2); break; case 0xbd: /* CP IXL */ CP(reg_ixl, 0, 4, 2); break; case 0xbe: /* CP (IX+d) */ CP(LOAD(IX_WORD_OFF(ip2)), 8, 11, 3); break; case 0xbf: /* CP A */ CP(reg_a, 0, 4, 2); break; case 0xc1: /* POP BC */ POP(reg_b, reg_c, 2); break; case 0xc5: /* PUSH BC */ PUSH(reg_b, reg_c, 2); break; case 0xcb: /* OPCODE DD CB */ opcode_dd_cb((BYTE)ip2, (BYTE)ip3, (WORD)ip23); break; case 0xd1: /* POP DE */ POP(reg_d, reg_e, 2); break; case 0xd3: /* OUT A */ OUTA(ip2, 8, 7, 3); break; case 0xd5: /* PUSH DE */ PUSH(reg_d, reg_e, 2); break; case 0xd9: /* EXX */ EXX(12, 2); break; case 0xdb: /* IN A */ INA(ip2, 8, 7, 3); break; case 0xdd: /* Skip DD */ NOP(4, 1); break; case 0xe1: /* POP IX */ POP(reg_ixh, reg_ixl, 2); break; case 0xe3: /* EX IX (SP) */ EXXXSP(reg_ixh, reg_ixl, 4, 4, 4, 4, 7, 2); break; case 0xe5: /* PUSH IX */ PUSH(reg_ixh, reg_ixl, 2); break; case 0xe9: /* LD PC IX */ JMP((IX_WORD()), 8); break; case 0xeb: EXDEHL(8, 2); break; case 0xed: /* Skip DD */ NOP(4, 1); break; case 0xf1: /* POP AF */ POP(reg_a, reg_f, 2); break; case 0xf3: /* DI */ DI(8, 2); break; case 0xf5: /* PUSH AF */ PUSH(reg_a, reg_f, 2); break; case 0xf9: /* LD SP IX */ LDSP(IX_WORD(), 4, 6, 2); break; case 0xfb: /* EI */ EI(8, 2); break; case 0xfd: /* Skip DD */ NOP(4, 1); break; default: #if 0 && defined(DEBUG_Z80) log_message(LOG_DEFAULT, "%i PC %04x A%02x F%02x B%02x C%02x D%02x E%02x " "H%02x L%02x SP%04x OP DD %02x %02x %02x.", (int)(CLK), (unsigned int)(z80_reg_pc), reg_a, reg_f, reg_b, reg_c, reg_d, reg_e, reg_h, reg_l, reg_sp, ip1, ip2, ip3); #endif INC_PC(2); } } static void opcode_ed(BYTE ip1, BYTE ip2, BYTE ip3, WORD ip12, WORD ip23) { switch (ip1) { case 0x40: /* IN B BC */ INBC(reg_b, 4, 8, 2); break; case 0x41: /* OUT BC B */ OUTBC(reg_b, 4, 8, 2); break; case 0x42: /* SBC HL BC */ SBCHLREG(reg_b, reg_c); break; case 0x43: /* LD (WORD) BC */ STW(ip23, reg_b, reg_c, 4, 13, 3, 4); break; case 0x44: /* NEG */ NEG(); break; case 0x45: /* RETN */ RETNI(); break; case 0x46: /* IM0 */ IM(0); break; case 0x47: /* LD I A */ LDREG(reg_i, reg_a, 6, 3, 2); break; case 0x48: /* IN C BC */ INBC(reg_c, 4, 8, 2); break; case 0x49: /* OUT BC C */ OUTBC(reg_c, 4, 8, 2); break; case 0x4a: /* ADC HL BC */ ADCHLREG(reg_b, reg_c); break; case 0x4b: /* LD BC (WORD) */ LDIND(ip23, reg_b, reg_c, 4, 4, 12, 4); break; case 0x4d: /* RETI */ RETNI(); break; case 0x4f: /* LD R A FIXME: Not emulated. */ NOP(8, 2); break; case 0x50: /* IN D BC */ INBC(reg_d, 4, 8, 2); break; case 0x51: /* OUT BC D */ OUTBC(reg_d, 4, 8, 2); break; case 0x52: /* SBC HL DE */ SBCHLREG(reg_d, reg_e); break; case 0x53: /* LD (WORD) DE */ STW(ip23, reg_d, reg_e, 4, 13, 3, 4); break; case 0x56: /* IM1 */ IM(1); break; case 0x57: /* LD A I */ LDAIR(reg_i); break; case 0x58: /* IN E BC */ INBC(reg_e, 4, 8, 2); break; case 0x59: /* OUT BC E */ OUTBC(reg_e, 4, 8, 2); break; case 0x5a: /* ADC HL DE */ ADCHLREG(reg_d, reg_e); break; case 0x5b: /* LD DE (WORD) */ LDIND(ip23, reg_d, reg_e, 4, 4, 12, 4); break; case 0x5e: /* IM2 */ IM(2); break; case 0x5f: /* LD A R */ LDAIR((BYTE)(CLK & 0xff)); break; case 0x60: /* IN H BC */ INBC(reg_h, 4, 8, 2); break; case 0x61: /* OUT BC H */ OUTBC(reg_h, 4, 8, 2); break; case 0x62: /* SBC HL HL */ SBCHLREG(reg_h, reg_l); break; case 0x63: /* LD (WORD) HL */ STW(ip23, reg_h, reg_l, 4, 13, 3, 4); break; case 0x67: /* RRD */ RRD(); break; case 0x68: /* IN L BC */ INBC(reg_l, 4, 8, 2); break; case 0x69: /* OUT BC L */ OUTBC(reg_l, 4, 8, 2); break; case 0x6a: /* ADC HL HL */ ADCHLREG(reg_h, reg_l); break; case 0x6b: /* LD HL (WORD) */ LDIND(ip23, reg_h, reg_l, 4, 4, 12, 4); break; case 0x6f: /* RLD */ RLD(); break; case 0x70: /* IN F BC */ INBC0(4, 8, 2); break; case 0x71: /* OUT BC #0 */ OUTBC(0, 4, 8, 2); break; case 0x72: /* SBC HL SP */ SBCHLSP(); break; case 0x73: /* LD (WORD) SP */ STSPW(ip23, 4, 13, 3, 4); break; case 0x78: /* IN A BC */ INBC(reg_a, 4, 8, 2); break; case 0x79: /* OUT BC A */ OUTBC(reg_a, 4, 8, 2); break; case 0x7a: /* ADC HL SP */ ADCHLSP(); break; case 0x7b: /* LD SP (WORD) */ LDSPIND(ip23, 4, 4, 12, 4); break; case 0xa0: /* LDI */ LDDI(INC_DE_WORD(), INC_HL_WORD()); break; case 0xa1: /* CPI */ CPDI(INC_HL_WORD()); break; case 0xa2: /* INI */ INDI(INC_HL_WORD()); break; case 0xa3: /* OUTI */ OUTDI(INC_HL_WORD()); break; case 0xa8: /* LDD */ LDDI(DEC_DE_WORD(), DEC_HL_WORD()); break; case 0xa9: /* CPD */ CPDI(DEC_HL_WORD()); break; case 0xaa: /* IND */ INDI(DEC_HL_WORD()); break; case 0xab: /* OUTD */ OUTDI(DEC_HL_WORD()); break; case 0xb0: /* LDIR */ LDDIR(INC_DE_WORD(), INC_HL_WORD()); break; case 0xb1: /* CPIR */ CPDIR(INC_HL_WORD()); break; case 0xb2: /* INIR */ INDIR(INC_HL_WORD()); break; case 0xb3: /* OTIR */ OTDIR(INC_HL_WORD()); break; case 0xb8: /* LDDR */ LDDIR(DEC_DE_WORD(), DEC_HL_WORD()); break; case 0xb9: /* CPDR */ CPDIR(DEC_HL_WORD()); break; case 0xba: /* INDR */ INDIR(DEC_HL_WORD()); break; case 0xbb: /* OTDR */ OTDIR(DEC_HL_WORD()); break; case 0xcb: /* NOP */ NOP(8, 2); break; case 0xdd: /* NOP */ NOP(8, 2); break; case 0xed: /* NOP */ NOP(8, 2); break; case 0xfd: /* NOP */ NOP(8, 2); break; default: #if 0 && defined(DEBUG_Z80) log_message(LOG_DEFAULT, "%i PC %04x A%02x F%02x B%02x C%02x D%02x E%02x " "H%02x L%02x SP%04x OP ED %02x %02x %02x.", (int)(CLK), (unsigned int)(z80_reg_pc), reg_a, reg_f, reg_b, reg_c, reg_d, reg_e, reg_h, reg_l, reg_sp, ip1, ip2, ip3); #endif INC_PC(2); } } static void opcode_fd_cb(BYTE iip2, BYTE iip3, WORD iip23) { switch (iip3) { case 0x00: /* RLC (IY+d),B */ RLCXXREG(reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x01: /* RLC (IY+d),C */ RLCXXREG(reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x02: /* RLC (IY+d),D */ RLCXXREG(reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x03: /* RLC (IY+d),E */ RLCXXREG(reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x04: /* RLC (IY+d),H */ RLCXXREG(reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x05: /* RLC (IY+d),L */ RLCXXREG(reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x06: /* RLC (IY+d) */ RLCXX(IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x07: /* RLC (IY+d),A */ RLCXXREG(reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x08: /* RRC (IY+d),B */ RRCXXREG(reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x09: /* RRC (IY+d),C */ RRCXXREG(reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x0a: /* RRC (IY+d),D */ RRCXXREG(reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x0b: /* RRC (IY+d),E */ RRCXXREG(reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x0c: /* RRC (IY+d),H */ RRCXXREG(reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x0d: /* RRC (IY+d),L */ RRCXXREG(reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x0e: /* RRC (IY+d) */ RRCXX(IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x0f: /* RRC (IY+d),A */ RRCXXREG(reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x10: /* RL (IY+d),B */ RLXXREG(reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x11: /* RL (IY+d),C */ RLXXREG(reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x12: /* RL (IY+d),D */ RLXXREG(reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x13: /* RL (IY+d),E */ RLXXREG(reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x14: /* RL (IY+d),H */ RLXXREG(reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x15: /* RL (IY+d),L */ RLXXREG(reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x16: /* RL (IY+d) */ RLXX(IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x17: /* RL (IY+d),A */ RLXXREG(reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x18: /* RR (IY+d),B */ RRXXREG(reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x19: /* RR (IY+d),C */ RRXXREG(reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x1a: /* RR (IY+d),D */ RRXXREG(reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x1b: /* RR (IY+d),E */ RRXXREG(reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x1c: /* RR (IY+d),H */ RRXXREG(reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x1d: /* RR (IY+d),L */ RRXXREG(reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x1e: /* RR (IY+d) */ RRXX(IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x1f: /* RR (IY+d),A */ RRXXREG(reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x20: /* SLA (IY+d),B */ SLAXXREG(reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x21: /* SLA (IY+d),C */ SLAXXREG(reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x22: /* SLA (IY+d),D */ SLAXXREG(reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x23: /* SLA (IY+d),E */ SLAXXREG(reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x24: /* SLA (IY+d),H */ SLAXXREG(reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x25: /* SLA (IY+d),L */ SLAXXREG(reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x26: /* SLA (IY+d) */ SLAXX(IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x27: /* SLA (IY+d),A */ SLAXXREG(reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x28: /* SRA (IY+d),B */ SRAXXREG(reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x29: /* SRA (IY+d),C */ SRAXXREG(reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x2a: /* SRA (IY+d),D */ SRAXXREG(reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x2b: /* SRA (IY+d),E */ SRAXXREG(reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x2c: /* SRA (IY+d),H */ SRAXXREG(reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x2d: /* SRA (IY+d),L */ SRAXXREG(reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x2e: /* SRA (IY+d) */ SRAXX(IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x2f: /* SRA (IY+d),A */ SRAXXREG(reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x30: /* SLL (IY+d),B */ SLLXXREG(reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x31: /* SLL (IY+d),C */ SLLXXREG(reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x32: /* SLL (IY+d),D */ SLLXXREG(reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x33: /* SLL (IY+d),E */ SLLXXREG(reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x34: /* SLL (IY+d),H */ SLLXXREG(reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x35: /* SLL (IY+d),L */ SLLXXREG(reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x36: /* SLL (IY+d) */ SLLXX(IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x37: /* SLL (IY+d),A */ SLLXXREG(reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x38: /* SRL (IY+d),B */ SRLXXREG(reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x39: /* SRL (IY+d),C */ SRLXXREG(reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x3a: /* SRL (IY+d),D */ SRLXXREG(reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x3b: /* SRL (IY+d),E */ SRLXXREG(reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x3c: /* SRL (IY+d),H */ SRLXXREG(reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x3d: /* SRL (IY+d),L */ SRLXXREG(reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x3e: /* SRL (IY+d) */ SRLXX(IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x3f: /* SRL (IY+d),A */ SRLXXREG(reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x40: /* BIT (IY+d) 0 */ case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: BIT(LOAD(IY_WORD_OFF(iip2)), 0, 8, 12, 4); break; case 0x48: /* BIT (IY+d) 1 */ case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: BIT(LOAD(IY_WORD_OFF(iip2)), 1, 8, 12, 4); break; case 0x50: /* BIT (IY+d) 2 */ case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: BIT(LOAD(IY_WORD_OFF(iip2)), 2, 8, 12, 4); break; case 0x58: /* BIT (IY+d) 3 */ case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: BIT(LOAD(IY_WORD_OFF(iip2)), 3, 8, 12, 4); break; case 0x60: /* BIT (IY+d) 4 */ case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: BIT(LOAD(IY_WORD_OFF(iip2)), 4, 8, 12, 4); break; case 0x68: /* BIT (IY+d) 5 */ case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: BIT(LOAD(IY_WORD_OFF(iip2)), 5, 8, 12, 4); break; case 0x70: /* BIT (IY+d) 6 */ case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: BIT(LOAD(IY_WORD_OFF(iip2)), 6, 8, 12, 4); break; case 0x78: /* BIT (IY+d) 7 */ case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: BIT(LOAD(IY_WORD_OFF(iip2)), 7, 8, 12, 4); break; case 0x80: /* RES (IY+d),B 0 */ RESXXREG(0, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x81: /* RES (IY+d),C 0 */ RESXXREG(0, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x82: /* RES (IY+d),D 0 */ RESXXREG(0, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x83: /* RES (IY+d),E 0 */ RESXXREG(0, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x84: /* RES (IY+d),H 0 */ RESXXREG(0, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x85: /* RES (IY+d),L 0 */ RESXXREG(0, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x86: /* RES (IY+d) 0 */ RESXX(0, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x87: /* RES (IY+d),A 0 */ RESXXREG(0, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x88: /* RES (IY+d),B 1 */ RESXXREG(1, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x89: /* RES (IY+d),C 1 */ RESXXREG(1, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x8a: /* RES (IY+d),D 1 */ RESXXREG(1, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x8b: /* RES (IY+d),E 1 */ RESXXREG(1, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x8c: /* RES (IY+d),H 1 */ RESXXREG(1, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x8d: /* RES (IY+d),L 1 */ RESXXREG(1, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x8e: /* RES (IY+d) 1 */ RESXX(1, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x8f: /* RES (IY+d),A 1 */ RESXXREG(1, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x90: /* RES (IY+d),B 2 */ RESXXREG(2, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x91: /* RES (IY+d),C 2 */ RESXXREG(2, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x92: /* RES (IY+d),D 2 */ RESXXREG(2, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x93: /* RES (IY+d),E 2 */ RESXXREG(2, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x94: /* RES (IY+d),H 2 */ RESXXREG(2, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x95: /* RES (IY+d),L 2 */ RESXXREG(2, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x96: /* RES (IY+d) 2 */ RESXX(2, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x97: /* RES (IY+d),A 2 */ RESXXREG(2, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x98: /* RES (IY+d),B 3 */ RESXXREG(3, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x99: /* RES (IY+d),C 3 */ RESXXREG(3, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x9a: /* RES (IY+d),D 3 */ RESXXREG(3, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x9b: /* RES (IY+d),E 3 */ RESXXREG(3, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x9c: /* RES (IY+d),H 3 */ RESXXREG(3, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x9d: /* RES (IY+d),L 3 */ RESXXREG(3, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x9e: /* RES (IY+d) 3 */ RESXX(3, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0x9f: /* RES (IY+d),A 3 */ RESXXREG(3, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa0: /* RES (IY+d),B 4 */ RESXXREG(4, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa1: /* RES (IY+d),C 4 */ RESXXREG(4, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa2: /* RES (IY+d),D 4 */ RESXXREG(4, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa3: /* RES (IY+d),E 4 */ RESXXREG(4, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa4: /* RES (IY+d),H 4 */ RESXXREG(4, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa5: /* RES (IY+d),L 4 */ RESXXREG(4, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa6: /* RES (IY+d) 4 */ RESXX(4, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa7: /* RES (IY+d),A 4 */ RESXXREG(4, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa8: /* RES (IY+d),B 5 */ RESXXREG(5, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xa9: /* RES (IY+d),C 5 */ RESXXREG(5, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xaa: /* RES (IY+d),D 5 */ RESXXREG(5, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xab: /* RES (IY+d),E 5 */ RESXXREG(5, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xac: /* RES (IY+d),H 5 */ RESXXREG(5, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xad: /* RES (IY+d),L 5 */ RESXXREG(5, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xae: /* RES (IY+d) 5 */ RESXX(5, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xaf: /* RES (IY+d),A 5 */ RESXXREG(5, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb0: /* RES (IY+d),B 6 */ RESXXREG(6, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb1: /* RES (IY+d),C 6 */ RESXXREG(6, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb2: /* RES (IY+d),D 6 */ RESXXREG(6, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb3: /* RES (IY+d),E 6 */ RESXXREG(6, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb4: /* RES (IY+d),H 6 */ RESXXREG(6, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb5: /* RES (IY+d),L 6 */ RESXXREG(6, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb6: /* RES (IY+d) 6 */ RESXX(6, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb7: /* RES (IY+d),A 6 */ RESXXREG(6, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb8: /* RES (IY+d),B 7 */ RESXXREG(7, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xb9: /* RES (IY+d),C 7 */ RESXXREG(7, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xba: /* RES (IY+d),D 7 */ RESXXREG(7, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xbb: /* RES (IY+d),E 7 */ RESXXREG(7, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xbc: /* RES (IY+d),H 7 */ RESXXREG(7, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xbd: /* RES (IY+d),L 7 */ RESXXREG(7, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xbe: /* RES (IY+d) 7 */ RESXX(7, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xbf: /* RES (IY+d),A 7 */ RESXXREG(7, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc0: /* SET (IY+d),B 0 */ SETXXREG(0, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc1: /* SET (IY+d),C 0 */ SETXXREG(0, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc2: /* SET (IY+d),D 0 */ SETXXREG(0, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc3: /* SET (IY+d),E 0 */ SETXXREG(0, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc4: /* SET (IY+d),H 0 */ SETXXREG(0, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc5: /* SET (IY+d),L 0 */ SETXXREG(0, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc6: /* SET (IY+d) 0 */ SETXX(0, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc7: /* SET (IY+d),A 0 */ SETXXREG(0, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc8: /* SET (IY+d),B 1 */ SETXXREG(1, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xc9: /* SET (IY+d),C 1 */ SETXXREG(1, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xca: /* SET (IY+d),D 1 */ SETXXREG(1, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xcb: /* SET (IY+d),E 1 */ SETXXREG(1, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xcc: /* SET (IY+d),H 1 */ SETXXREG(1, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xcd: /* SET (IY+d),L 1 */ SETXXREG(1, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xce: /* SET (IY+d) 1 */ SETXX(1, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xcf: /* SET (IY+d),A 1 */ SETXXREG(1, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd0: /* SET (IY+d),B 2 */ SETXXREG(2, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd1: /* SET (IY+d),C 2 */ SETXXREG(2, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd2: /* SET (IY+d),D 2 */ SETXXREG(2, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd3: /* SET (IY+d),E 2 */ SETXXREG(2, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd4: /* SET (IY+d),H 2 */ SETXXREG(2, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd5: /* SET (IY+d),L 2 */ SETXXREG(2, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd6: /* SET (IY+d) 2 */ SETXX(2, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd7: /* SET (IY+d),A 2 */ SETXXREG(2, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd8: /* SET (IY+d),B 3 */ SETXXREG(3, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xd9: /* SET (IY+d),C 3 */ SETXXREG(3, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xda: /* SET (IY+d),D 3 */ SETXXREG(3, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xdb: /* SET (IY+d),E 3 */ SETXXREG(3, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xdc: /* SET (IY+d),H 3 */ SETXXREG(3, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xdd: /* SET (IY+d),L 3 */ SETXXREG(3, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xde: /* SET (IY+d) 3 */ SETXX(3, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xdf: /* SET (IY+d),A 3 */ SETXXREG(3, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe0: /* SET (IY+d),B 4 */ SETXXREG(4, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe1: /* SET (IY+d),C 4 */ SETXXREG(4, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe2: /* SET (IY+d),D 4 */ SETXXREG(4, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe3: /* SET (IY+d),E 4 */ SETXXREG(4, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe4: /* SET (IY+d),H 4 */ SETXXREG(4, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe5: /* SET (IY+d),L 4 */ SETXXREG(4, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe6: /* SET (IY+d) 4 */ SETXX(4, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe7: /* SET (IY+d),A 4 */ SETXXREG(4, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe8: /* SET (IY+d),B 5 */ SETXXREG(5, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xe9: /* SET (IY+d),C 5 */ SETXXREG(5, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xea: /* SET (IY+d),D 5 */ SETXXREG(5, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xeb: /* SET (IY+d),E 5 */ SETXXREG(5, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xec: /* SET (IY+d),H 5 */ SETXXREG(5, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xed: /* SET (IY+d),L 5 */ SETXXREG(5, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xee: /* SET (IY+d) 5 */ SETXX(5, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xef: /* SET (IY+d),A 5 */ SETXXREG(5, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf0: /* SET (IY+d),B 6 */ SETXXREG(6, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf1: /* SET (IY+d),C 6 */ SETXXREG(6, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf2: /* SET (IY+d),D 6 */ SETXXREG(6, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf3: /* SET (IY+d),E 6 */ SETXXREG(6, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf4: /* SET (IY+d),H 6 */ SETXXREG(6, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf5: /* SET (IY+d),L 6 */ SETXXREG(6, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf6: /* SET (IY+d) 6 */ SETXX(6, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf7: /* SET (IY+d),A 6 */ SETXXREG(6, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf8: /* SET (IY+d),B 7 */ SETXXREG(7, reg_b, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xf9: /* SET (IY+d),C 7 */ SETXXREG(7, reg_c, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xfa: /* SET (IY+d),D 7 */ SETXXREG(7, reg_d, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xfb: /* SET (IY+d),E 7 */ SETXXREG(7, reg_e, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xfc: /* SET (IY+d),H 7 */ SETXXREG(7, reg_h, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xfd: /* SET (IY+d),L 7 */ SETXXREG(7, reg_l, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xfe: /* SET (IY+d) 7 */ SETXX(7, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; case 0xff: /* SET (IY+d),A 7 */ SETXXREG(7, reg_a, IY_WORD_OFF(iip2), 4, 4, 15, 4); break; default: INC_PC(4); } } static void opcode_fd(BYTE ip1, BYTE ip2, BYTE ip3, WORD ip12, WORD ip23) { switch (ip1) { case 0x00: /* NOP */ NOP(8, 2); break; case 0x01: /* LD BC # */ LDW(ip23, reg_b, reg_c, 10, 0, 4); break; case 0x02: /* LD (BC) A */ STREG(BC_WORD(), reg_a, 8, 3, 2); break; case 0x03: /* INC BC */ DECINC(INC_BC_WORD(), 10, 2); break; case 0x04: /* INC B */ INCREG(reg_b, 7, 2); break; case 0x05: /* DEC B */ DECREG(reg_b, 7, 2); break; case 0x06: /* LD B # */ LDREG(reg_b, ip2, 4, 5, 3); break; case 0x07: /* RLCA */ RLCA(8, 2); break; case 0x08: /* EX AF AF' */ EXAFAF(12, 2); break; case 0x09: /* ADD IY BC */ ADDXXREG(reg_iyh, reg_iyl, reg_b, reg_c, 15, 2); break; case 0x0a: /* LD A (BC) */ LDREG(reg_a, LOAD(BC_WORD()), 8, 3, 2); break; case 0x0b: /* DEC BC */ DECINC(DEC_BC_WORD(), 10, 2); break; case 0x0c: /* INC C */ INCREG(reg_c, 7, 2); break; case 0x0d: /* DEC C */ DECREG(reg_c, 7, 2); break; case 0x0e: /* LD C # */ LDREG(reg_c, ip2, 4, 5, 3); break; case 0x0f: /* RRCA */ RRCA(8, 2); break; case 0x10: /* DJNZ */ DJNZ(ip2, 3); break; case 0x11: /* LD DE # */ LDW(ip23, reg_d, reg_e, 10, 0, 4); break; case 0x12: /* LD (DE) A */ STREG(DE_WORD(), reg_a, 8, 3, 2); break; case 0x13: /* INC DE */ DECINC(INC_DE_WORD(), 10, 2); break; case 0x14: /* INC D */ INCREG(reg_d, 7, 2); break; case 0x15: /* DEC D */ DECREG(reg_d, 7, 2); break; case 0x16: /* LD D # */ LDREG(reg_d, ip2, 4, 5, 3); break; case 0x17: /* RLA */ RLA(8, 2); break; case 0x19: /* ADD IY DE */ ADDXXREG(reg_iyh, reg_iyl, reg_d, reg_e, 15, 2); break; case 0x1a: /* LD A (DE) */ LDREG(reg_a, LOAD(DE_WORD()), 8, 3, 2); break; case 0x1b: /* DEC DE */ DECINC(DEC_DE_WORD(), 10, 2); break; case 0x1c: /* INC E */ INCREG(reg_e, 7, 2); break; case 0x1d: /* DEC E */ DECREG(reg_e, 7, 2); break; case 0x1e: /* LD E # */ LDREG(reg_e, ip2, 4, 5, 3); break; case 0x1f: /* RRA */ RRA(8, 2); break; case 0x20: /* JR NZ */ BRANCH(!LOCAL_ZERO(), ip2, 3); break; case 0x21: /* LD IY # */ LDW(ip23, reg_iyh, reg_iyl, 10, 4, 4); break; case 0x22: /* LD (WORD) IY */ STW(ip23, reg_iyh, reg_iyl, 4, 9, 7, 4); break; case 0x23: /* INC IY */ DECINC(INC_IY_WORD(), 10, 2); break; case 0x24: /* INC IYH */ INCREG(reg_iyh, 7, 2); break; case 0x25: /* DEC IYH */ DECREG(reg_iyh, 7, 2); break; case 0x26: /* LD IYH # */ LDREG(reg_iyh, ip2, 4, 5, 3); break; case 0x27: /* DAA */ DAA(8, 2); break; case 0x28: /* JR Z */ BRANCH(LOCAL_ZERO(), ip2, 3); break; case 0x29: /* ADD IY IY */ ADDXXREG(reg_iyh, reg_iyl, reg_iyh, reg_iyl, 15, 2); break; case 0x2a: /* LD IY (WORD) */ LDIND(ip23, reg_iyh, reg_iyl, 4, 4, 12, 4); break; case 0x2b: /* DEC IY */ DECINC(DEC_IY_WORD(), 10, 2); break; case 0x2c: /* INC IYL */ INCREG(reg_iyl, 7, 2); break; case 0x2d: /* DEC IYL */ DECREG(reg_iyl, 7, 2); break; case 0x2e: /* LD IYL # */ LDREG(reg_iyl, ip2, 4, 5, 3); break; case 0x2f: /* CPL */ CPL(8, 2); break; case 0x30: /* JR NC */ BRANCH(!LOCAL_CARRY(), ip2, 3); break; case 0x31: /* LD SP # */ LDSP(ip23, 10, 0, 4); break; case 0x32: /* LD (WORD) A */ STREG(ip23, reg_a, 10, 7, 4); break; case 0x33: /* INC SP */ DECINC(reg_sp++, 10, 2); break; case 0x34: /* INC (IY+d) */ INCXXIND(IY_WORD_OFF(ip2), 4, 7, 12, 3); break; case 0x35: /* DEC (IY+d) */ DECXXIND(IY_WORD_OFF(ip2), 4, 7, 12, 3); break; case 0x36: /* LD (IY+d) # */ STREG(IY_WORD_OFF(ip2), ip3, 8, 11, 4); break; case 0x37: /* SCF */ SCF(8, 2); break; case 0x38: /* JR C */ BRANCH(LOCAL_CARRY(), ip2, 3); break; case 0x39: /* ADD IY SP */ ADDXXSP(reg_iyh, reg_iyl, 15, 2); break; case 0x3a: /* LD A (WORD) */ LDREG(reg_a, LOAD(ip23), 10, 7, 4); break; case 0x3b: /* DEC SP */ DECINC(reg_sp--, 10, 2); break; case 0x3c: /* INC A */ INCREG(reg_a, 7, 2); break; case 0x3d: /* DEC A */ DECREG(reg_a, 7, 2); break; case 0x3e: /* LD A # */ LDREG(reg_a, ip2, 4, 5, 3); break; case 0x3f: /* CCF */ CCF(8, 2); break; case 0x40: /* LD B B */ LDREG(reg_b, reg_b, 0, 4, 2); break; case 0x41: /* LD B C */ LDREG(reg_b, reg_c, 0, 4, 2); break; case 0x42: /* LD B D */ LDREG(reg_b, reg_d, 0, 4, 2); break; case 0x43: /* LD B E */ LDREG(reg_b, reg_e, 0, 4, 2); break; case 0x44: /* LD B IYH */ LDREG(reg_b, reg_iyh, 0, 4, 2); break; case 0x45: /* LD B IYL */ LDREG(reg_b, reg_iyl, 0, 4, 2); break; case 0x46: /* LD B (IY+d) */ LDREG(reg_b, LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0x47: /* LD B A */ LDREG(reg_b, reg_a, 0, 4, 2); break; case 0x48: /* LD C B */ LDREG(reg_c, reg_b, 0, 4, 2); break; case 0x49: /* LD C C */ LDREG(reg_c, reg_c, 0, 4, 2); break; case 0x4a: /* LD C D */ LDREG(reg_c, reg_d, 0, 4, 2); break; case 0x4b: /* LD C E */ LDREG(reg_c, reg_e, 0, 4, 2); break; case 0x4c: /* LD C IYH */ LDREG(reg_c, reg_iyh, 0, 4, 2); break; case 0x4d: /* LD C IYL */ LDREG(reg_c, reg_iyl, 0, 4, 2); break; case 0x4e: /* LD C (IY+d) */ LDREG(reg_c, LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0x4f: /* LD C A */ LDREG(reg_c, reg_a, 0, 4, 2); break; case 0x50: /* LD D B */ LDREG(reg_d, reg_b, 0, 4, 2); break; case 0x51: /* LD D C */ LDREG(reg_d, reg_c, 0, 4, 2); break; case 0x52: /* LD D D */ LDREG(reg_d, reg_d, 0, 4, 2); break; case 0x53: /* LD D E */ LDREG(reg_d, reg_e, 0, 4, 2); break; case 0x54: /* LD D IYH */ LDREG(reg_d, reg_iyh, 0, 4, 2); break; case 0x55: /* LD D IYL */ LDREG(reg_d, reg_iyl, 0, 4, 2); break; case 0x56: /* LD D (IY+d) */ LDREG(reg_d, LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0x57: /* LD D A */ LDREG(reg_d, reg_a, 0, 4, 2); break; case 0x58: /* LD E B */ LDREG(reg_e, reg_b, 0, 4, 2); break; case 0x59: /* LD E C */ LDREG(reg_e, reg_c, 0, 4, 2); break; case 0x5a: /* LD E D */ LDREG(reg_e, reg_d, 0, 4, 2); break; case 0x5b: /* LD E E */ LDREG(reg_e, reg_e, 0, 4, 2); break; case 0x5c: /* LD E IYH */ LDREG(reg_e, reg_iyh, 0, 4, 2); break; case 0x5d: /* LD E IYL */ LDREG(reg_e, reg_iyl, 0, 4, 2); break; case 0x5e: /* LD E (IY+d) */ LDREG(reg_e, LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0x5f: /* LD E A */ LDREG(reg_e, reg_a, 0, 4, 2); break; case 0x60: /* LD IYH B */ LDREG(reg_iyh, reg_b, 0, 4, 2); break; case 0x61: /* LD IYH C */ LDREG(reg_iyh, reg_c, 0, 4, 2); break; case 0x62: /* LD IYH D */ LDREG(reg_iyh, reg_d, 0, 4, 2); break; case 0x63: /* LD IYH E */ LDREG(reg_iyh, reg_e, 0, 4, 2); break; case 0x64: /* LD IYH IYH */ LDREG(reg_iyh, reg_iyh, 0, 4, 2); break; case 0x65: /* LD IYH IYL */ LDREG(reg_iyh, reg_iyl, 0, 4, 2); break; case 0x66: /* LD H (IY+d) */ LDREG(reg_h, LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0x67: /* LD IYH A */ LDREG(reg_iyh, reg_a, 0, 4, 2); break; case 0x68: /* LD IYL B */ LDREG(reg_iyl, reg_b, 0, 4, 2); break; case 0x69: /* LD IYL C */ LDREG(reg_iyl, reg_c, 0, 4, 2); break; case 0x6a: /* LD IYL D */ LDREG(reg_iyl, reg_d, 0, 4, 2); break; case 0x6b: /* LD IYL E */ LDREG(reg_iyl, reg_e, 0, 4, 2); break; case 0x6c: /* LD IYL IYH */ LDREG(reg_iyl, reg_iyh, 0, 4, 2); break; case 0x6d: /* LD IYL IYL */ LDREG(reg_iyl, reg_iyl, 0, 4, 2); break; case 0x6e: /* LD L (IY+d) */ LDREG(reg_l, LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0x6f: /* LD IYL A */ LDREG(reg_iyl, reg_a, 0, 4, 2); break; case 0x70: /* LD (IY+d) B */ STREG(IY_WORD_OFF(ip2), reg_b, 8, 11, 3); break; case 0x71: /* LD (IY+d) C */ STREG(IY_WORD_OFF(ip2), reg_c, 8, 11, 3); break; case 0x72: /* LD (IY+d) D */ STREG(IY_WORD_OFF(ip2), reg_d, 8, 11, 3); break; case 0x73: /* LD (IY+d) E */ STREG(IY_WORD_OFF(ip2), reg_e, 8, 11, 3); break; case 0x74: /* LD (IY+d) H */ STREG(IY_WORD_OFF(ip2), reg_h, 8, 11, 3); break; case 0x75: /* LD (IY+d) L */ STREG(IY_WORD_OFF(ip2), reg_l, 8, 11, 3); break; case 0x76: /* HALT */ HALT(); break; case 0x77: /* LD (IY+d) A */ STREG(IY_WORD_OFF(ip2), reg_a, 8, 11, 3); break; case 0x78: /* LD A B */ LDREG(reg_a, reg_b, 0, 4, 2); break; case 0x79: /* LD A C */ LDREG(reg_a, reg_c, 0, 4, 2); break; case 0x7a: /* LD A D */ LDREG(reg_a, reg_d, 0, 4, 2); break; case 0x7b: /* LD A E */ LDREG(reg_a, reg_e, 0, 4, 2); break; case 0x7c: /* LD A IYH */ LDREG(reg_a, reg_iyh, 0, 4, 2); break; case 0x7d: /* LD A IYL */ LDREG(reg_a, reg_iyl, 0, 4, 2); break; case 0x7e: /* LD A (IY+d) */ LDREG(reg_a, LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0x7f: /* LD A A */ LDREG(reg_a, reg_a, 0, 4, 2); break; case 0x80: /* ADD B */ ADD(reg_b, 0, 4, 2); break; case 0x81: /* ADD C */ ADD(reg_c, 0, 4, 2); break; case 0x82: /* ADD D */ ADD(reg_d, 0, 4, 2); break; case 0x83: /* ADD E */ ADD(reg_e, 0, 4, 2); break; case 0x84: /* ADD IYH */ ADD(reg_iyh, 0, 4, 2); break; case 0x85: /* ADD IYL */ ADD(reg_iyl, 0, 4, 2); break; case 0x86: /* ADD (IY+d) */ ADD(LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0x87: /* ADD A */ ADD(reg_a, 0, 4, 2); break; case 0x88: /* ADC B */ ADC(reg_b, 0, 4, 2); break; case 0x89: /* ADC C */ ADC(reg_c, 0, 4, 2); break; case 0x8a: /* ADC D */ ADC(reg_d, 0, 4, 2); break; case 0x8b: /* ADC E */ ADC(reg_e, 0, 4, 2); break; case 0x8c: /* ADC IYH */ ADC(reg_iyh, 0, 4, 2); break; case 0x8d: /* ADC IYL */ ADC(reg_iyl, 0, 4, 2); break; case 0x8e: /* ADC (IY+d) */ ADC(LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0x8f: /* ADC A */ ADC(reg_a, 0, 4, 2); break; case 0x90: /* SUB B */ SUB(reg_b, 0, 4, 2); break; case 0x91: /* SUB C */ SUB(reg_c, 0, 4, 2); break; case 0x92: /* SUB D */ SUB(reg_d, 0, 4, 2); break; case 0x93: /* SUB E */ SUB(reg_e, 0, 4, 2); break; case 0x94: /* SUB IYH */ SUB(reg_iyh, 0, 4, 2); break; case 0x95: /* SUB IYL */ SUB(reg_iyl, 0, 4, 2); break; case 0x96: /* SUB (IY+d) */ SUB(LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0x97: /* SUB A */ SUB(reg_a, 0, 4, 2); break; case 0x98: /* SBC B */ SBC(reg_b, 0, 4, 2); break; case 0x99: /* SBC C */ SBC(reg_c, 0, 4, 2); break; case 0x9a: /* SBC D */ SBC(reg_d, 0, 4, 2); break; case 0x9b: /* SBC E */ SBC(reg_e, 0, 4, 2); break; case 0x9c: /* SBC IYH */ SBC(reg_iyh, 0, 4, 2); break; case 0x9d: /* SBC IYL */ SBC(reg_iyl, 0, 4, 2); break; case 0x9e: /* SBC (IY+d) */ SBC(LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0x9f: /* SBC A */ SBC(reg_a, 0, 4, 2); break; case 0xa0: /* AND B */ AND(reg_b, 0, 4, 2); break; case 0xa1: /* AND C */ AND(reg_c, 0, 4, 2); break; case 0xa2: /* AND D */ AND(reg_d, 0, 4, 2); break; case 0xa3: /* AND E */ AND(reg_e, 0, 4, 2); break; case 0xa4: /* AND IYH */ AND(reg_iyh, 0, 4, 2); break; case 0xa5: /* AND IYL */ AND(reg_iyl, 0, 4, 2); break; case 0xa6: /* AND (IY+d) */ AND(LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0xa7: /* AND A */ AND(reg_a, 0, 4, 2); break; case 0xa8: /* XOR B */ XOR(reg_b, 0, 4, 2); break; case 0xa9: /* XOR C */ XOR(reg_c, 0, 4, 2); break; case 0xaa: /* XOR D */ XOR(reg_d, 0, 4, 2); break; case 0xab: /* XOR E */ XOR(reg_e, 0, 4, 2); break; case 0xac: /* XOR IYH */ XOR(reg_iyh, 0, 4, 2); break; case 0xad: /* XOR IYL */ XOR(reg_iyl, 0, 4, 2); break; case 0xae: /* XOR (IY+d) */ XOR(LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0xaf: /* XOR A */ XOR(reg_a, 0, 4, 2); break; case 0xb0: /* OR B */ OR(reg_b, 0, 4, 2); break; case 0xb1: /* OR C */ OR(reg_c, 0, 4, 2); break; case 0xb2: /* OR D */ OR(reg_d, 0, 4, 2); break; case 0xb3: /* OR E */ OR(reg_e, 0, 4, 2); break; case 0xb4: /* OR IYH */ OR(reg_iyh, 0, 4, 2); break; case 0xb5: /* OR IYL */ OR(reg_iyl, 0, 4, 2); break; case 0xb6: /* OR (IY+d) */ OR(LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0xb7: /* OR A */ OR(reg_a, 0, 4, 2); break; case 0xb8: /* CP B */ CP(reg_b, 0, 4, 2); break; case 0xb9: /* CP C */ CP(reg_c, 0, 4, 2); break; case 0xba: /* CP D */ CP(reg_d, 0, 4, 2); break; case 0xbb: /* CP E */ CP(reg_e, 0, 4, 2); break; case 0xbc: /* CP IYH */ CP(reg_iyh, 0, 4, 2); break; case 0xbd: /* CP IYL */ CP(reg_iyl, 0, 4, 2); break; case 0xbe: /* CP (IY+d) */ CP(LOAD(IY_WORD_OFF(ip2)), 8, 11, 3); break; case 0xbf: /* CP A */ CP(reg_a, 0, 4, 2); break; case 0xc1: /* POP BC */ POP(reg_b, reg_c, 2); break; case 0xc5: /* PUSH BC */ PUSH(reg_b, reg_c, 2); break; case 0xcb: /* OPCODE FD CB */ opcode_fd_cb((BYTE)ip2, (BYTE)ip3, (WORD)ip23); break; case 0xd1: /* POP DE */ POP(reg_d, reg_e, 2); break; case 0xd3: /* OUT A */ OUTA(ip2, 8, 7, 3); break; case 0xd5: /* PUSH DE */ PUSH(reg_d, reg_e, 2); break; case 0xd9: /* EXX */ EXX(12, 2); break; case 0xdb: /* IN A */ INA(ip2, 8, 7, 3); break; case 0xdd: /* Skip FD */ NOP(4, 1); break; case 0xe1: /* POP IY */ POP(reg_iyh, reg_iyl, 2); break; case 0xe3: /* EX IY (SP) */ EXXXSP(reg_iyh, reg_iyl, 4, 4, 4, 4, 7, 2); break; case 0xe5: /* PUSH IY */ PUSH(reg_iyh, reg_iyl, 2); break; case 0xe9: /* LD PC IY */ JMP((IY_WORD()), 8); break; case 0xeb: EXDEHL(8, 2); break; case 0xed: /* Skip FD */ NOP(4, 1); break; case 0xf1: /* POP AF */ POP(reg_a, reg_f, 2); break; case 0xf3: /* DI */ DI(8, 2); break; case 0xf5: /* PUSH AF */ PUSH(reg_a, reg_f, 2); break; case 0xf9: /* LD SP IY */ LDSP(IY_WORD(), 4, 6, 2); break; case 0xfb: /* EI */ EI(8, 2); break; case 0xfd: /* Skip FD */ NOP(4, 1); break; default: #if 0 && defined(DEBUG_Z80) log_message(LOG_DEFAULT, "%i PC %04x A%02x F%02x B%02x C%02x D%02x E%02x " "H%02x L%02x SP%04x OP FD %02x %02x %02x.", (int)(CLK), (unsigned int)z80_reg_pc, reg_a, reg_f, reg_b, reg_c, reg_d, reg_e, reg_h, reg_l, reg_sp, ip1, ip2, ip3); #endif INC_PC(2); } } /* ------------------------------------------------------------------------- */ /* Z80 mainloop. */ // The effective Z-80 clock rate is 2.041MHz // See: http://www.apple2info.net/hardware/softcard/SC-SWHW_a2in.pdf static const double uZ80ClockMultiplier = 2; inline static ULONG ConvertZ80TStatesTo6502Cycles(UINT uTStates) { return (uTStates < 0) ? 0 : (ULONG) ((double)uTStates / uZ80ClockMultiplier); } //void z80_mainloop(interrupt_cpu_status_t *cpu_int_status, // alarm_context_t *cpu_alarm_context) DWORD z80_mainloop(ULONG uTotalCycles, ULONG uExecutedCycles) { opcode_t opcode; import_registers(); //z80mem_set_bank_pointer(&z80_bank_base, &z80_bank_limit); // [AppleWin-TC] Not used //dma_request = 0; // [AppleWin-TC] Not used uTotalCycles = (ULONG) ((double)uTotalCycles * uZ80ClockMultiplier); uExecutedCycles = (ULONG) ((double)uExecutedCycles * uZ80ClockMultiplier); maincpu_clk = uExecutedCycles; // Must be signed int, as cycles can go -ve do { // [AppleWin-TC] Z80 IRQs not supported //while (CLK >= alarm_context_next_pending_clk(cpu_alarm_context)) // alarm_context_dispatch(cpu_alarm_context, CLK); //{ // enum cpu_int pending_interrupt; // pending_interrupt = cpu_int_status->global_pending_int; // if (pending_interrupt != IK_NONE) { // DO_INTERRUPT(pending_interrupt); // while (CLK >= alarm_context_next_pending_clk(cpu_alarm_context)) // alarm_context_dispatch(cpu_alarm_context, CLK); // } //} FETCH_OPCODE(opcode); #if 0 && defined(DEBUG_Z80) if (debug.maincpu_traceflg) log_message(LOG_DEFAULT, ".%04x %i %-25s A%02x F%02x B%02x C%02x D%02x E%02x " "H%02x L%02x S%04x", (unsigned int)z80_reg_pc, /*CLK*/ 0, mon_disassemble_to_string(e_comp_space, z80_reg_pc, p0, p1, p2, p3, 1, "z80"), reg_a, reg_f, reg_b, reg_c, reg_d, reg_e, reg_h, reg_l, reg_sp); #endif SET_LAST_OPCODE(p0); switch (p0) { case 0x00: /* NOP */ NOP(4, 1); break; case 0x01: /* LD BC # */ LDW(p12, reg_b, reg_c, 10, 0, 3); break; case 0x02: /* LD (BC) A */ STREG(BC_WORD(), reg_a, 4, 3, 1); break; case 0x03: /* INC BC */ DECINC(INC_BC_WORD(), 6, 1); break; case 0x04: /* INC B */ INCREG(reg_b, 4, 1); break; case 0x05: /* DEC B */ DECREG(reg_b, 4, 1); break; case 0x06: /* LD B # */ LDREG(reg_b, p1, 4, 3, 2); break; case 0x07: /* RLCA */ RLCA(4, 1); break; case 0x08: /* EX AF AF' */ EXAFAF(8, 1); break; case 0x09: /* ADD HL BC */ ADDXXREG(reg_h, reg_l, reg_b, reg_c, 11, 1); break; case 0x0a: /* LD A (BC) */ LDREG(reg_a, LOAD(BC_WORD()), 4, 3, 1); break; case 0x0b: /* DEC BC */ DECINC(DEC_BC_WORD(), 6, 1); break; case 0x0c: /* INC C */ INCREG(reg_c, 4, 1); break; case 0x0d: /* DEC C */ DECREG(reg_c, 4, 1); break; case 0x0e: /* LD C # */ LDREG(reg_c, p1, 4, 3, 2); break; case 0x0f: /* RRCA */ RRCA(4, 1); break; case 0x10: /* DJNZ */ DJNZ(p1, 2); break; case 0x11: /* LD DE # */ LDW(p12, reg_d, reg_e, 10, 0, 3); break; case 0x12: /* LD (DE) A */ STREG(DE_WORD(), reg_a, 4, 3, 1); break; case 0x13: /* INC DE */ DECINC(INC_DE_WORD(), 6, 1); break; case 0x14: /* INC D */ INCREG(reg_d, 4, 1); break; case 0x15: /* DEC D */ DECREG(reg_d, 4, 1); break; case 0x16: /* LD D # */ LDREG(reg_d, p1, 4, 3, 2); break; case 0x17: /* RLA */ RLA(4, 1); break; case 0x18: /* JR */ BRANCH(1, p1, 2); break; case 0x19: /* ADD HL DE */ ADDXXREG(reg_h, reg_l, reg_d, reg_e, 11, 1); break; case 0x1a: /* LD A (DE) */ LDREG(reg_a, LOAD(DE_WORD()), 4, 3, 1); break; case 0x1b: /* DEC DE */ DECINC(DEC_DE_WORD(), 6, 1); break; case 0x1c: /* INC E */ INCREG(reg_e, 4, 1); break; case 0x1d: /* DEC E */ DECREG(reg_e, 4, 1); break; case 0x1e: /* LD E # */ LDREG(reg_e, p1, 4, 3, 2); break; case 0x1f: /* RRA */ RRA(4, 1); break; case 0x20: /* JR NZ */ BRANCH(!LOCAL_ZERO(), p1, 2); break; case 0x21: /* LD HL # */ LDW(p12, reg_h, reg_l, 10, 0, 3); break; case 0x22: /* LD (WORD) HL */ STW(p12, reg_h, reg_l, 4, 9, 3, 3); break; case 0x23: /* INC HL */ DECINC(INC_HL_WORD(), 6, 1); break; case 0x24: /* INC H */ INCREG(reg_h, 4, 1); break; case 0x25: /* DEC H */ DECREG(reg_h, 4, 1); break; case 0x26: /* LD H # */ LDREG(reg_h, p1, 4, 3, 2); break; case 0x27: /* DAA */ DAA(4, 1); break; case 0x28: /* JR Z */ BRANCH(LOCAL_ZERO(), p1, 2); break; case 0x29: /* ADD HL HL */ ADDXXREG(reg_h, reg_l, reg_h, reg_l, 11, 1); break; case 0x2a: /* LD HL (WORD) */ LDIND(p12, reg_h, reg_l, 4, 4, 8, 3); break; case 0x2b: /* DEC HL */ DECINC(DEC_HL_WORD(), 6, 1); break; case 0x2c: /* INC L */ INCREG(reg_l, 4, 1); break; case 0x2d: /* DEC L */ DECREG(reg_l, 4, 1); break; case 0x2e: /* LD L # */ LDREG(reg_l, p1, 4, 3, 2); break; case 0x2f: /* CPL */ CPL(4, 1); break; case 0x30: /* JR NC */ BRANCH(!LOCAL_CARRY(), p1, 2); break; case 0x31: /* LD SP # */ LDSP(p12, 10, 0, 3); break; case 0x32: /* LD (WORD) A */ STREG(p12, reg_a, 10, 3, 3); break; case 0x33: /* INC SP */ DECINC(reg_sp++, 6, 1); break; case 0x34: /* INC (HL) */ INCXXIND(HL_WORD(), 4, 4, 3, 1); break; case 0x35: /* DEC (HL) */ DECXXIND(HL_WORD(), 4, 4, 3, 1); break; case 0x36: /* LD (HL) # */ STREG(HL_WORD(), p1, 8, 2, 2); break; case 0x37: /* SCF */ SCF(4, 1); break; case 0x38: /* JR C */ BRANCH(LOCAL_CARRY(), p1, 2); break; case 0x39: /* ADD HL SP */ ADDXXSP(reg_h, reg_l, 11, 1); break; case 0x3a: /* LD A (WORD) */ LDREG(reg_a, LOAD(p12), 10, 3, 3); break; case 0x3b: /* DEC SP */ DECINC(reg_sp--, 6, 1); break; case 0x3c: /* INC A */ INCREG(reg_a, 4, 1); break; case 0x3d: /* DEC A */ DECREG(reg_a, 4, 1); break; case 0x3e: /* LD A # */ LDREG(reg_a, p1, 4, 3, 2); break; case 0x3f: /* CCF */ CCF(4, 1); break; case 0x40: /* LD B B */ LDREG(reg_b, reg_b, 0, 4, 1); break; case 0x41: /* LD B C */ LDREG(reg_b, reg_c, 0, 4, 1); break; case 0x42: /* LD B D */ LDREG(reg_b, reg_d, 0, 4, 1); break; case 0x43: /* LD B E */ LDREG(reg_b, reg_e, 0, 4, 1); break; case 0x44: /* LD B H */ LDREG(reg_b, reg_h, 0, 4, 1); break; case 0x45: /* LD B L */ LDREG(reg_b, reg_l, 0, 4, 1); break; case 0x46: /* LD B (HL) */ LDREG(reg_b, LOAD(HL_WORD()), 4, 3, 1); break; case 0x47: /* LD B A */ LDREG(reg_b, reg_a, 0, 4, 1); break; case 0x48: /* LD C B */ LDREG(reg_c, reg_b, 0, 4, 1); break; case 0x49: /* LD C C */ LDREG(reg_c, reg_c, 0, 4, 1); break; case 0x4a: /* LD C D */ LDREG(reg_c, reg_d, 0, 4, 1); break; case 0x4b: /* LD C E */ LDREG(reg_c, reg_e, 0, 4, 1); break; case 0x4c: /* LD C H */ LDREG(reg_c, reg_h, 0, 4, 1); break; case 0x4d: /* LD C L */ LDREG(reg_c, reg_l, 0, 4, 1); break; case 0x4e: /* LD C (HL) */ LDREG(reg_c, LOAD(HL_WORD()), 4, 3, 1); break; case 0x4f: /* LD C A */ LDREG(reg_c, reg_a, 0, 4, 1); break; case 0x50: /* LD D B */ LDREG(reg_d, reg_b, 0, 4, 1); break; case 0x51: /* LD D C */ LDREG(reg_d, reg_c, 0, 4, 1); break; case 0x52: /* LD D D */ LDREG(reg_d, reg_d, 0, 4, 1); break; case 0x53: /* LD D E */ LDREG(reg_d, reg_e, 0, 4, 1); break; case 0x54: /* LD D H */ LDREG(reg_d, reg_h, 0, 4, 1); break; case 0x55: /* LD D L */ LDREG(reg_d, reg_l, 0, 4, 1); break; case 0x56: /* LD D (HL) */ LDREG(reg_d, LOAD(HL_WORD()), 4, 3, 1); break; case 0x57: /* LD D A */ LDREG(reg_d, reg_a, 0, 4, 1); break; case 0x58: /* LD E B */ LDREG(reg_e, reg_b, 0, 4, 1); break; case 0x59: /* LD E C */ LDREG(reg_e, reg_c, 0, 4, 1); break; case 0x5a: /* LD E D */ LDREG(reg_e, reg_d, 0, 4, 1); break; case 0x5b: /* LD E E */ LDREG(reg_e, reg_e, 0, 4, 1); break; case 0x5c: /* LD E H */ LDREG(reg_e, reg_h, 0, 4, 1); break; case 0x5d: /* LD E L */ LDREG(reg_e, reg_l, 0, 4, 1); break; case 0x5e: /* LD E (HL) */ LDREG(reg_e, LOAD(HL_WORD()), 4, 3, 1); break; case 0x5f: /* LD E A */ LDREG(reg_e, reg_a, 0, 4, 1); break; case 0x60: /* LD H B */ LDREG(reg_h, reg_b, 0, 4, 1); break; case 0x61: /* LD H C */ LDREG(reg_h, reg_c, 0, 4, 1); break; case 0x62: /* LD H D */ LDREG(reg_h, reg_d, 0, 4, 1); break; case 0x63: /* LD H E */ LDREG(reg_h, reg_e, 0, 4, 1); break; case 0x64: /* LD H H */ LDREG(reg_h, reg_h, 0, 4, 1); break; case 0x65: /* LD H L */ LDREG(reg_h, reg_l, 0, 4, 1); break; case 0x66: /* LD H (HL) */ LDREG(reg_h, LOAD(HL_WORD()), 4, 3, 1); break; case 0x67: /* LD H A */ LDREG(reg_h, reg_a, 0, 4, 1); break; case 0x68: /* LD L B */ LDREG(reg_l, reg_b, 0, 4, 1); break; case 0x69: /* LD L C */ LDREG(reg_l, reg_c, 0, 4, 1); break; case 0x6a: /* LD L D */ LDREG(reg_l, reg_d, 0, 4, 1); break; case 0x6b: /* LD L E */ LDREG(reg_l, reg_e, 0, 4, 1); break; case 0x6c: /* LD L H */ LDREG(reg_l, reg_h, 0, 4, 1); break; case 0x6d: /* LD L L */ LDREG(reg_l, reg_l, 0, 4, 1); break; case 0x6e: /* LD L (HL) */ LDREG(reg_l, LOAD(HL_WORD()), 4, 3, 1); break; case 0x6f: /* LD L A */ LDREG(reg_l, reg_a, 0, 4, 1); break; case 0x70: /* LD (HL) B */ STREG(HL_WORD(), reg_b, 4, 3, 1); break; case 0x71: /* LD (HL) C */ STREG(HL_WORD(), reg_c, 4, 3, 1); break; case 0x72: /* LD (HL) D */ STREG(HL_WORD(), reg_d, 4, 3, 1); break; case 0x73: /* LD (HL) E */ STREG(HL_WORD(), reg_e, 4, 3, 1); break; case 0x74: /* LD (HL) H */ STREG(HL_WORD(), reg_h, 4, 3, 1); break; case 0x75: /* LD (HL) L */ STREG(HL_WORD(), reg_l, 4, 3, 1); break; case 0x76: /* HALT */ HALT(); break; case 0x77: /* LD (HL) A */ STREG(HL_WORD(), reg_a, 4, 3, 1); break; case 0x78: /* LD A B */ LDREG(reg_a, reg_b, 0, 4, 1); break; case 0x79: /* LD A C */ LDREG(reg_a, reg_c, 0, 4, 1); break; case 0x7a: /* LD A D */ LDREG(reg_a, reg_d, 0, 4, 1); break; case 0x7b: /* LD A E */ LDREG(reg_a, reg_e, 0, 4, 1); break; case 0x7c: /* LD A H */ LDREG(reg_a, reg_h, 0, 4, 1); break; case 0x7d: /* LD A L */ LDREG(reg_a, reg_l, 0, 4, 1); break; case 0x7e: /* LD A (HL) */ LDREG(reg_a, LOAD(HL_WORD()), 4, 3, 1); break; case 0x7f: /* LD A A */ LDREG(reg_a, reg_a, 0, 4, 1); break; case 0x80: /* ADD B */ ADD(reg_b, 0, 4, 1); break; case 0x81: /* ADD C */ ADD(reg_c, 0, 4, 1); break; case 0x82: /* ADD D */ ADD(reg_d, 0, 4, 1); break; case 0x83: /* ADD E */ ADD(reg_e, 0, 4, 1); break; case 0x84: /* ADD H */ ADD(reg_h, 0, 4, 1); break; case 0x85: /* ADD L */ ADD(reg_l, 0, 4, 1); break; case 0x86: /* ADD (HL) */ ADD(LOAD(HL_WORD()), 4, 3, 1); break; case 0x87: /* ADD A */ ADD(reg_a, 0, 4, 1); break; case 0x88: /* ADC B */ ADC(reg_b, 0, 4, 1); break; case 0x89: /* ADC C */ ADC(reg_c, 0, 4, 1); break; case 0x8a: /* ADC D */ ADC(reg_d, 0, 4, 1); break; case 0x8b: /* ADC E */ ADC(reg_e, 0, 4, 1); break; case 0x8c: /* ADC H */ ADC(reg_h, 0, 4, 1); break; case 0x8d: /* ADC L */ ADC(reg_l, 0, 4, 1); break; case 0x8e: /* ADC (HL) */ ADC(LOAD(HL_WORD()), 4, 3, 1); break; case 0x8f: /* ADC A */ ADC(reg_a, 0, 4, 1); break; case 0x90: /* SUB B */ SUB(reg_b, 0, 4, 1); break; case 0x91: /* SUB C */ SUB(reg_c, 0, 4, 1); break; case 0x92: /* SUB D */ SUB(reg_d, 0, 4, 1); break; case 0x93: /* SUB E */ SUB(reg_e, 0, 4, 1); break; case 0x94: /* SUB H */ SUB(reg_h, 0, 4, 1); break; case 0x95: /* SUB L */ SUB(reg_l, 0, 4, 1); break; case 0x96: /* SUB (HL) */ SUB(LOAD(HL_WORD()), 4, 3, 1); break; case 0x97: /* SUB A */ SUB(reg_a, 0, 4, 1); break; case 0x98: /* SBC B */ SBC(reg_b, 0, 4, 1); break; case 0x99: /* SBC C */ SBC(reg_c, 0, 4, 1); break; case 0x9a: /* SBC D */ SBC(reg_d, 0, 4, 1); break; case 0x9b: /* SBC E */ SBC(reg_e, 0, 4, 1); break; case 0x9c: /* SBC H */ SBC(reg_h, 0, 4, 1); break; case 0x9d: /* SBC L */ SBC(reg_l, 0, 4, 1); break; case 0x9e: /* SBC (HL) */ SBC(LOAD(HL_WORD()), 4, 3, 1); break; case 0x9f: /* SBC A */ SBC(reg_a, 0, 4, 1); break; case 0xa0: /* AND B */ AND(reg_b, 0, 4, 1); break; case 0xa1: /* AND C */ AND(reg_c, 0, 4, 1); break; case 0xa2: /* AND D */ AND(reg_d, 0, 4, 1); break; case 0xa3: /* AND E */ AND(reg_e, 0, 4, 1); break; case 0xa4: /* AND H */ AND(reg_h, 0, 4, 1); break; case 0xa5: /* AND L */ AND(reg_l, 0, 4, 1); break; case 0xa6: /* AND (HL) */ AND(LOAD(HL_WORD()), 4, 3, 1); break; case 0xa7: /* AND A */ AND(reg_a, 0, 4, 1); break; case 0xa8: /* XOR B */ XOR(reg_b, 0, 4, 1); break; case 0xa9: /* XOR C */ XOR(reg_c, 0, 4, 1); break; case 0xaa: /* XOR D */ XOR(reg_d, 0, 4, 1); break; case 0xab: /* XOR E */ XOR(reg_e, 0, 4, 1); break; case 0xac: /* XOR H */ XOR(reg_h, 0, 4, 1); break; case 0xad: /* XOR L */ XOR(reg_l, 0, 4, 1); break; case 0xae: /* XOR (HL) */ XOR(LOAD(HL_WORD()), 4, 3, 1); break; case 0xaf: /* XOR A */ XOR(reg_a, 0, 4, 1); break; case 0xb0: /* OR B */ OR(reg_b, 0, 4, 1); break; case 0xb1: /* OR C */ OR(reg_c, 0, 4, 1); break; case 0xb2: /* OR D */ OR(reg_d, 0, 4, 1); break; case 0xb3: /* OR E */ OR(reg_e, 0, 4, 1); break; case 0xb4: /* OR H */ OR(reg_h, 0, 4, 1); break; case 0xb5: /* OR L */ OR(reg_l, 0, 4, 1); break; case 0xb6: /* OR (HL) */ OR(LOAD(HL_WORD()), 4, 3, 1); break; case 0xb7: /* OR A */ OR(reg_a, 0, 4, 1); break; case 0xb8: /* CP B */ CP(reg_b, 0, 4, 1); break; case 0xb9: /* CP C */ CP(reg_c, 0, 4, 1); break; case 0xba: /* CP D */ CP(reg_d, 0, 4, 1); break; case 0xbb: /* CP E */ CP(reg_e, 0, 4, 1); break; case 0xbc: /* CP H */ CP(reg_h, 0, 4, 1); break; case 0xbd: /* CP L */ CP(reg_l, 0, 4, 1); break; case 0xbe: /* CP (HL) */ CP(LOAD(HL_WORD()), 4, 3, 1); break; case 0xbf: /* CP A */ CP(reg_a, 0, 4, 1); break; case 0xc0: /* RET NZ */ RET_COND(!LOCAL_ZERO(), 4, 4, 2, 5, 1); break; case 0xc1: /* POP BC */ POP(reg_b, reg_c, 1); break; case 0xc2: /* JP NZ */ JMP_COND(p12, !LOCAL_ZERO(), 10, 10); break; case 0xc3: /* JP */ JMP(p12, 10); break; case 0xc4: /* CALL NZ */ CALL_COND(p12, !LOCAL_ZERO(), 3, 3, 4, 10, 3); break; case 0xc5: /* PUSH BC */ PUSH(reg_b, reg_c, 1); break; case 0xc6: /* ADD # */ ADD(p1, 4, 3, 2); break; case 0xc7: /* RST 00 */ CALL(0x00, 3, 3, 5, 1); break; case 0xc8: /* RET Z */ RET_COND(LOCAL_ZERO(), 4, 4, 2, 5, 1); break; case 0xc9: /* RET */ RET(4, 4, 2); break; case 0xca: /* JP Z */ JMP_COND(p12, LOCAL_ZERO(), 10, 10); break; case 0xcb: /* OPCODE CB */ opcode_cb((BYTE)p1, (BYTE)p2, (BYTE)p3, (WORD)p12, (WORD)p23); break; case 0xcc: /* CALL Z */ CALL_COND(p12, LOCAL_ZERO(), 3, 3, 4, 10, 3); break; case 0xcd: /* CALL */ CALL(p12, 3, 3, 11, 3); break; case 0xce: /* ADC # */ ADC(p1, 4, 3, 2); break; case 0xcf: /* RST 08 */ CALL(0x08, 3, 3, 5, 1); break; case 0xd0: /* RET NC */ RET_COND(!LOCAL_CARRY(), 4, 4, 2, 5, 1); break; case 0xd1: /* POP DE */ POP(reg_d, reg_e, 1); break; case 0xd2: /* JP NC */ JMP_COND(p12, !LOCAL_CARRY(), 10, 10); break; case 0xd3: /* OUT A */ OUTA(p1, 4, 7, 2); break; case 0xd4: /* CALL NC */ CALL_COND(p12, !LOCAL_CARRY(), 3, 3, 4, 10, 3); break; case 0xd5: /* PUSH DE */ PUSH(reg_d, reg_e, 1); break; case 0xd6: /* SUB # */ SUB(p1, 4, 3, 2); break; case 0xd7: /* RST 10 */ CALL(0x10, 3, 3, 5, 1); break; case 0xd8: /* RET C */ RET_COND(LOCAL_CARRY(), 4, 4, 2, 5, 1); break; case 0xd9: /* EXX */ EXX(8, 1); break; case 0xda: /* JP C */ JMP_COND(p12, LOCAL_CARRY(), 10, 10); break; case 0xdb: /* IN A */ INA(p1, 4, 7, 2); break; case 0xdc: /* CALL C */ CALL_COND(p12, LOCAL_CARRY(), 3, 3, 4, 10, 3); break; case 0xdd: /* OPCODE DD */ opcode_dd((BYTE)p1, (BYTE)p2, (BYTE)p3, (WORD)p12, (WORD)p23); break; case 0xde: /* SBC # */ SBC(p1, 4, 3, 2); break; case 0xdf: /* RST 18 */ CALL(0x18, 3, 3, 5, 1); break; case 0xe0: /* RET PO */ RET_COND(!LOCAL_PARITY(), 4, 4, 2, 5, 1); break; case 0xe1: /* POP HL */ POP(reg_h, reg_l, 1); break; case 0xe2: /* JP PO */ JMP_COND(p12, !LOCAL_PARITY(), 10, 10); break; case 0xe3: /* EX HL (SP) */ EXXXSP(reg_h, reg_l, 4, 4, 4, 4, 3, 1); break; case 0xe4: /* CALL PO */ CALL_COND(p12, !LOCAL_PARITY(), 3, 3, 4, 10, 3); break; case 0xe5: /* PUSH HL */ PUSH(reg_h, reg_l, 1); break; case 0xe6: /* AND # */ AND(p1, 4, 3, 2); break; case 0xe7: /* RST 20 */ CALL(0x20, 3, 3, 5, 1); break; case 0xe8: /* RET PE */ RET_COND(LOCAL_PARITY(), 4, 4, 2, 5, 1); break; case 0xe9: /* LD PC HL */ JMP((HL_WORD()), 4); break; case 0xea: /* JP PE */ JMP_COND(p12, LOCAL_PARITY(), 10, 10); break; case 0xeb: /* EX DE HL */ EXDEHL(4, 1); break; case 0xec: /* CALL PE */ CALL_COND(p12, LOCAL_PARITY(), 3, 3, 4, 10, 3); break; case 0xed: /* OPCODE ED */ opcode_ed((BYTE)p1, (BYTE)p2, (BYTE)p3, (WORD)p12, (WORD)p23); break; case 0xee: /* XOR # */ XOR(p1, 4, 3, 2); break; case 0xef: /* RST 28 */ CALL(0x28, 3, 3, 5, 1); break; case 0xf0: /* RET P */ RET_COND(!LOCAL_SIGN(), 4, 4, 2, 5, 1); break; case 0xf1: /* POP AF */ POP(reg_a, reg_f, 1); break; case 0xf2: /* JP P */ JMP_COND(p12, !LOCAL_SIGN(), 10, 10); break; case 0xf3: /* DI */ DI(4, 1); break; case 0xf4: /* CALL P */ CALL_COND(p12, !LOCAL_SIGN(), 3, 3, 4, 10, 3); break; case 0xf5: /* PUSH AF */ PUSH(reg_a, reg_f, 1); break; case 0xf6: /* OR # */ OR(p1, 4, 3, 2); break; case 0xf7: /* RST 30 */ CALL(0x30, 3, 3, 5, 1); break; case 0xf8: /* RET M */ RET_COND(LOCAL_SIGN(), 4, 4, 2, 5, 1); break; case 0xf9: /* LD SP HL */ LDSP(HL_WORD(), 4, 2, 1); break; case 0xfa: /* JP M */ JMP_COND(p12, LOCAL_SIGN(), 10, 10); break; case 0xfb: /* EI */ EI(4, 1); break; case 0xfc: /* CALL M */ CALL_COND(p12, LOCAL_SIGN(), 3, 3, 4, 10, 3); break; case 0xfd: /* OPCODE FD */ opcode_fd((BYTE)p1, (BYTE)p2, (BYTE)p3, (WORD)p12, (WORD)p23); break; case 0xfe: /* CP # */ CP(p1, 4, 3, 2); break; case 0xff: /* RST 38 */ CALL(0x38, 3, 3, 5, 1); break; } //cpu_int_status->num_dma_per_opcode = 0; // [AppleWin-TC] Not used if (GetActiveCpu() != CPU_Z80) // [AppleWin-TC] break; //} while (!dma_request); } while (maincpu_clk < uTotalCycles); // [AppleWin-TC] export_registers(); return ConvertZ80TStatesTo6502Cycles(maincpu_clk - uExecutedCycles); } /****************************************************************************/ /* Read a byte from given memory location */ /****************************************************************************/ BYTE z80_RDMEM(WORD Addr) { WORD addr; switch (Addr / 0x1000) { case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: case 0x8: case 0x9: case 0xA: addr = (WORD)Addr + 0x1000; return CpuRead( addr, ConvertZ80TStatesTo6502Cycles(maincpu_clk) ); break; case 0xB: case 0xC: case 0xD: addr = (WORD)Addr + 0x2000; return CpuRead( addr, ConvertZ80TStatesTo6502Cycles(maincpu_clk) ); break; case 0xE: addr = (WORD)Addr - 0x2000; if ((addr & 0xF000) == 0xC000) { return IORead[(addr>>4) & 0xFF]( regs.pc, addr, 0, 0, ConvertZ80TStatesTo6502Cycles(maincpu_clk) ); } else { return *(mem+addr); } break; case 0xF: addr = (WORD)Addr - 0xF000; return CpuRead( addr, ConvertZ80TStatesTo6502Cycles(maincpu_clk) ); break; } return 255; } /****************************************************************************/ /* Write a byte to given memory location */ /****************************************************************************/ void z80_WRMEM(WORD Addr, BYTE Value) { unsigned int laddr; WORD addr; laddr = Addr & 0x0FFF; switch (Addr & 0xF000) { case 0x0000: addr = laddr+0x1000; break; case 0x1000: addr = laddr+0x2000; break; case 0x2000: addr = laddr+0x3000; break; case 0x3000: addr = laddr+0x4000; break; case 0x4000: addr = laddr+0x5000; break; case 0x5000: addr = laddr+0x6000; break; case 0x6000: addr = laddr+0x7000; break; case 0x7000: addr = laddr+0x8000; break; case 0x8000: addr = laddr+0x9000; break; case 0x9000: addr = laddr+0xA000; break; case 0xA000: addr = laddr+0xB000; break; case 0xB000: addr = laddr+0xD000; break; case 0xC000: addr = laddr+0xE000; break; case 0xD000: addr = laddr+0xF000; break; case 0xE000: addr = laddr+0xC000; break; case 0xF000: addr = laddr+0x0000; break; } CpuWrite( addr, Value, ConvertZ80TStatesTo6502Cycles(maincpu_clk) ); } //=========================================================================== #define SS_YAML_VALUE_CARD_Z80 "Z80" #define SS_YAML_KEY_REGA "A" #define SS_YAML_KEY_REGB "B" #define SS_YAML_KEY_REGC "C" #define SS_YAML_KEY_REGD "D" #define SS_YAML_KEY_REGE "E" #define SS_YAML_KEY_REGF "F" #define SS_YAML_KEY_REGH "H" #define SS_YAML_KEY_REGL "L" #define SS_YAML_KEY_REGIX "IX" #define SS_YAML_KEY_REGIY "IY" #define SS_YAML_KEY_REGSP "SP" #define SS_YAML_KEY_REGPC "PC" #define SS_YAML_KEY_REGI "I" #define SS_YAML_KEY_REGR "R" #define SS_YAML_KEY_IFF1 "IFF1" #define SS_YAML_KEY_IFF2 "IFF2" #define SS_YAML_KEY_IM_MODE "IM Mode" #define SS_YAML_KEY_REGA2 "A'" #define SS_YAML_KEY_REGB2 "B'" #define SS_YAML_KEY_REGC2 "C'" #define SS_YAML_KEY_REGD2 "D'" #define SS_YAML_KEY_REGE2 "E'" #define SS_YAML_KEY_REGF2 "F'" #define SS_YAML_KEY_REGH2 "H'" #define SS_YAML_KEY_REGL2 "L'" #define SS_YAML_KEY_ACTIVE "Active" const std::string& Z80_GetSnapshotCardName(void) { static const std::string name(SS_YAML_VALUE_CARD_Z80); return name; } void Z80_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot) { YamlSaveHelper::Slot slot(yamlSaveHelper, Z80_GetSnapshotCardName(), uSlot, 1); // fixme: object should know its slot YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); // SoftCard SW & HW details: http://apple2info.net/images/f/f0/SC-SWHW.pdf // . SoftCard uses the Apple II's DMA circuit to pause the 6502 (no CLK to 6502) // . But: "In Apple II DMA, the 6502 CPU will die after approximately 15 clocks because it depends on the clock to refresh its internal registers." // ref: Apple Tech Note: https://archive.org/stream/IIe_2523004_RDY_Line/IIe_2523004_RDY_Line_djvu.txt // NB. Not for 65C02 which is a static processor. // . SoftCard controls the 6502's RDY line to periodically allow only 1 memory fetch by 6502 (ie. the opcode fetch) // // So save ActiveCPU to SS_CARD_Z80 (so RDY is like IRQ & NMI signals, ie. saved struct of the producer's card) // // NB. Save-state only occurs when message pump runs: // . ie. at end of 1ms emulation burst // Either 6502 or Z80 could be active. // yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ACTIVE, GetActiveCpu() == CPU_Z80 ? 1 : 0); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGA, reg_a); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGB, reg_b); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGC, reg_c); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGD, reg_d); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGE, reg_e); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGF, reg_f); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGH, reg_h); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGL, reg_l); yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGIX, ((USHORT)reg_ixh<<8)|(USHORT)reg_ixl); yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGIY, ((USHORT)reg_iyh<<8)|(USHORT)reg_iyl); yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGSP, reg_sp); yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGPC, (USHORT)z80_reg_pc); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGI, reg_i); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGR, reg_r); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IFF1, iff1); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IFF2, iff2); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IM_MODE, im_mode); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGA2, reg_a2); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGB2, reg_b2); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGC2, reg_c2); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGD2, reg_d2); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGE2, reg_e2); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGF2, reg_f2); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGH2, reg_h2); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGL2, reg_l2); } bool Z80_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uSlot, UINT version) { if (uSlot != 4 && uSlot != 5) // fixme Card::ThrowErrorInvalidSlot(CT_Z80, uSlot); if (version != 1) Card::ThrowErrorInvalidVersion(CT_Z80, version); reg_a = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGA); reg_b = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGB); reg_c = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGC); reg_d = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGD); reg_e = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGE); reg_f = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGF); reg_h = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGH); reg_l = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGL); USHORT IX = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGIX); reg_ixh = IX >> 8; reg_ixl = IX & 0xFF; USHORT IY = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGIY); reg_iyh = IY >> 8; reg_iyl = IY & 0xFF; reg_sp = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGSP); z80_reg_pc = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGPC); reg_i = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGI); reg_r = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGR); iff1 = yamlLoadHelper.LoadUint(SS_YAML_KEY_IFF1); iff2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_IFF2); im_mode = yamlLoadHelper.LoadUint(SS_YAML_KEY_IM_MODE); reg_a2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGA2); reg_b2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGB2); reg_c2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGC2); reg_d2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGD2); reg_e2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGE2); reg_f2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGF2); reg_h2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGH2); reg_l2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGL2); export_registers(); if ( yamlLoadHelper.LoadUint(SS_YAML_KEY_ACTIVE) ) SetActiveCpu(CPU_Z80); // Support MS SoftCard in multiple slots (only one Z80 can be active at any one time) return true; }