unit Z80;

interface

uses
  Classes, SysUtils, SyncObjs, MemoryTypes, Base, Z80Instructions,
  Generics.Collections, Generics.Defaults;

type
  TCpuZ80 = class;

  { TCpuThread }

  TCpuThread = class(TThread)
    Cpu: TCpuZ80;
    procedure Execute; override;
  end;

  TRegAF = record
    case Byte of
      0: (F, A: Byte);
      1: (Value: Word);
  end;

  TRegBC = record
    case Byte of
      0: (C, B: Byte);
      1: (Value: Word);
  end;

  TRegDE = record
    case Byte of
      0: (E, D: Byte);
      1: (Value: Word);
  end;

  TRegHL = record
    case Byte of
      0: (L, H: Byte);
      1: (Value: Word);
  end;

  { TCpuZ80 }

  TCpuZ80 = class
  private
    FOnCall: TAddressEvent;
    FOnInput: TReadEvent;
    FOnMessage: TMessageEvent;
    FOnOutput: TWriteEvent;
    FOnRead: TReadEvent;
    FOnReturn: TBaseEvent;
    FOnStep: TBaseEvent;
    FOnWrite: TWriteEvent;
    FRunning: Boolean;
    FThread: TCpuThread;
    Instruction: TInstruction;
    InstructionAddress: Word;
    MessageText: string;
    FEvent: TEvent;
    FPaused: Boolean;
    procedure Error(Message: string);
    function GetCarry: Boolean;
    function GetParityOverflow: Boolean;
    function GetSignNegative: Boolean;
    function GetZero: Boolean;
    procedure SetCarry(AValue: Boolean);
    procedure SetParityOverflow(AValue: Boolean);
    procedure SetPaused(AValue: Boolean);
    procedure SetSignNegative(AValue: Boolean);
    procedure SetZero(AValue: Boolean);
    procedure SetRunning(AValue: Boolean);
    function DoRead(Address: Word): Byte;
    function DoReadWord(Address: Word): Word;
    procedure DoWrite(Address: Word; Data: Byte);
    procedure DoWriteWord(Address: Word; Data: Word);
    function DoInput(Address: Word): Byte;
    procedure DoOutput(Address: Word; Data: Byte);
    procedure DoMessage(Text: string);
    procedure DoMessageSync;
    procedure DoOnCall(Address: Word);
    procedure DoOnReturn;
    procedure DoOnStep;
    function ReadByte: Byte;
    function ReadWord: Word;
    procedure PushWord(Data: Word);
    function PopWord: Word;
    procedure Call(Address: Word);
    procedure CallCond(Address: Word; Condition: Boolean);
    procedure CpByte(Data: Byte);
    procedure Jr(Condition: Boolean);
    procedure Jp(Condition: Boolean);
    procedure RetCond(Condition: Boolean);
    procedure NotImplemented;
    procedure AddByte(var Target: Byte; Second: Byte);
    procedure AddWord(var Target: Word; Second: Word);
    procedure AdcByte(var Target: Byte; Second: Byte);
    procedure AdcWord(var Target: Word; Second: Word);
    procedure SubByte(var Target: Byte; Second: Byte);
    procedure SbcByte(var Target: Byte; Second: Byte);
    procedure SbcWord(var Target: Word; Second: Word);
    procedure XorByte(var Target: Byte; Second: Byte);
    procedure OrByte(var Target: Byte; Second: Byte);
    procedure AndByte(var Target: Byte; Second: Byte);
    procedure IncByte(var Reg: Byte);
    procedure IncWord(var Reg: Word);
    procedure DecByte(var Reg: Byte);
    procedure DecWord(var Reg: Word);
    procedure RlcByte(var Data: Byte);
    procedure RrcByte(var Data: Byte);

    // Instruction methods
    procedure NOP;
    procedure LD_BC_NN;
    procedure LD_BC_Indirect_A;
    procedure INC_BC;
    procedure INC_B;
    procedure DEC_B;
    procedure LD_B_N;
    procedure RLCA;
    procedure EX_AF_AF_Pair;
    procedure ADD_HL_BC;
    procedure LD_A_BC_Indirect;
    procedure DEC_BC;
    procedure INC_C;
    procedure DEC_C;
    procedure LD_C_N;
    procedure RRCA;
    procedure DJNZ_D;
    procedure LD_DE_NN;
    procedure LD_DE_Indirect_A;
    procedure INC_DE;
    procedure INC_D;
    procedure DEC_D;
    procedure LD_D_N;
    procedure RLA;
    procedure JR_D;
    procedure ADD_HL_DE;
    procedure LD_A_DE_Indirect;
    procedure DEC_DE;
    procedure INC_E;
    procedure DEC_E;
    procedure LD_E_N;
    procedure RRA;
    procedure JR_NZ_D;
    procedure LD_HL_NN;
    procedure LD_NN_Indirect_HL;
    procedure INC_HL;
    procedure INC_H;
    procedure DEC_H;
    procedure LD_H_N;
    procedure DAA;
    procedure JR_Z_D;
    procedure ADD_HL_HL;
    procedure LD_HL_NN_Indirect;
    procedure DEC_HL;
    procedure INC_L;
    procedure DEC_L;
    procedure LD_L_N;
    procedure CPL;
    procedure JR_NC_D;
    procedure LD_SP_NN;
    procedure LD_NN_Indirect_A;
    procedure INC_SP;
    procedure INC_HL_Indirect;
    procedure DEC_HL_Indirect;
    procedure LD_HL_Indirect_N;
    procedure SCF;
    procedure JR_C_D;
    procedure ADD_HL_SP;
    procedure LD_A_NN_Indirect;
    procedure DEC_SP;
    procedure INC_A;
    procedure DEC_A;
    procedure LD_A_N;
    procedure CCF;
    procedure LD_B_B;
    procedure LD_B_C;
    procedure LD_B_D;
    procedure LD_B_E;
    procedure LD_B_H;
    procedure LD_B_L;
    procedure LD_B_HL_Indirect;
    procedure LD_B_A;
    procedure LD_C_B;
    procedure LD_C_C;
    procedure LD_C_D;
    procedure LD_C_E;
    procedure LD_C_H;
    procedure LD_C_L;
    procedure LD_C_HL_Indirect;
    procedure LD_C_A;
    procedure LD_D_B;
    procedure LD_D_C;
    procedure LD_D_D;
    procedure LD_D_E;
    procedure LD_D_H;
    procedure LD_D_L;
    procedure LD_D_HL_Indirect;
    procedure LD_D_A;
    procedure LD_E_B;
    procedure LD_E_C;
    procedure LD_E_D;
    procedure LD_E_E;
    procedure LD_E_H;
    procedure LD_E_L;
    procedure LD_E_HL_Indirect;
    procedure LD_E_A;
    procedure LD_H_B;
    procedure LD_H_C;
    procedure LD_H_D;
    procedure LD_H_E;
    procedure LD_H_H;
    procedure LD_H_L;
    procedure LD_H_HL_Indirect;
    procedure LD_H_A;
    procedure LD_L_B;
    procedure LD_L_C;
    procedure LD_L_D;
    procedure LD_L_E;
    procedure LD_L_H;
    procedure LD_L_L;
    procedure LD_L_HL_Indirect;
    procedure LD_L_A;
    procedure LD_HL_Indirect_B;
    procedure LD_HL_Indirect_C;
    procedure LD_HL_Indirect_D;
    procedure LD_HL_Indirect_E;
    procedure LD_HL_Indirect_H;
    procedure LD_HL_Indirect_L;
    procedure HALT;
    procedure LD_HL_Indirect_A;
    procedure LD_A_B;
    procedure LD_A_C;
    procedure LD_A_D;
    procedure LD_A_E;
    procedure LD_A_H;
    procedure LD_A_L;
    procedure LD_A_HL_Indirect;
    procedure LD_A_A;
    procedure ADD_A_B;
    procedure ADD_A_C;
    procedure ADD_A_D;
    procedure ADD_A_E;
    procedure ADD_A_H;
    procedure ADD_A_L;
    procedure ADD_A_HL_Indirect;
    procedure ADD_A_A;
    procedure ADC_A_B;
    procedure ADC_A_C;
    procedure ADC_A_D;
    procedure ADC_A_E;
    procedure ADC_A_H;
    procedure ADC_A_L;
    procedure ADC_A_HL_Indirect;
    procedure ADC_A_A;
    procedure SUB_B;
    procedure SUB_C;
    procedure SUB_D;
    procedure SUB_E;
    procedure SUB_H;
    procedure SUB_L;
    procedure SUB_HL_Indirect;
    procedure SUB_A;
    procedure SBC_A_B;
    procedure SBC_A_C;
    procedure SBC_A_D;
    procedure SBC_A_E;
    procedure SBC_A_H;
    procedure SBC_A_L;
    procedure SBC_A_HL_Indirect;
    procedure SBC_A_A;
    procedure AND_B;
    procedure AND_C;
    procedure AND_D;
    procedure AND_E;
    procedure AND_H;
    procedure AND_L;
    procedure AND_HL_Indirect;
    procedure AND_A;
    procedure XOR_B;
    procedure XOR_C;
    procedure XOR_D;
    procedure XOR_E;
    procedure XOR_H;
    procedure XOR_L;
    procedure XOR_HL_Indirect;
    procedure XOR_A;
    procedure OR_B;
    procedure OR_C;
    procedure OR_D;
    procedure OR_E;
    procedure OR_H;
    procedure OR_L;
    procedure OR_HL_Indirect;
    procedure OR_A;
    procedure CP_B;
    procedure CP_C;
    procedure CP_D;
    procedure CP_E;
    procedure CP_H;
    procedure CP_L;
    procedure CP_HL_Indirect;
    procedure CP_A;
    procedure RET_NZ;
    procedure POP_BC;
    procedure JP_NZ_NN;
    procedure JP_NN;
    procedure CALL_NZ_NN;
    procedure PUSH_BC;
    procedure ADD_A_N;
    procedure RST_00H;
    procedure RET_Z;
    procedure RET;
    procedure JP_Z_NN;
    procedure CALL_Z_NN;
    procedure CALL_NN;
    procedure ADC_A_N;
    procedure RST_08H;
    procedure RET_NC;
    procedure POP_DE;
    procedure JP_NC_NN;
    procedure OUT_N_Indirect_A;
    procedure CALL_NC_NN;
    procedure PUSH_DE;
    procedure SUB_N;
    procedure RST_10H;
    procedure RET_C;
    procedure EXX;
    procedure JP_C_NN;
    procedure IN_A_N_Indirect;
    procedure CALL_C_NN;
    procedure SBC_A_N;
    procedure RST_18H;
    procedure RET_PO;
    procedure POP_HL;
    procedure JP_PO_NN;
    procedure EX_SP_Indirect_HL;
    procedure CALL_PO_NN;
    procedure PUSH_HL;
    procedure AND_N;
    procedure RST_20H;
    procedure RET_PE;
    procedure JP_HL_Indirect;
    procedure JP_PE_NN;
    procedure EX_DE_HL;
    procedure CALL_PE_NN;
    procedure XOR_N;
    procedure RST_28H;
    procedure RET_P;
    procedure POP_AF;
    procedure JP_P_NN;
    procedure DI;
    procedure CALL_P_NN;
    procedure PUSH_AF;
    procedure OR_N;
    procedure RST_30H;
    procedure RET_M;
    procedure LD_SP_HL;
    procedure JP_M_NN;
    procedure EI;
    procedure CALL_M_NN;
    procedure CP_N;
    procedure RST_38H;
    procedure IN_B_C_Indirect;
    procedure OUT_C_Indirect_B;
    procedure SBC_HL_BC;
    procedure LD_NN_Indirect_BC;
    procedure NEG;
    procedure RETN;
    procedure IM_0;
    procedure LD_I_A;
    procedure IN_C_C_Indirect;
    procedure OUT_C_Indirect_C;
    procedure ADC_HL_BC;
    procedure LD_BC_NN_Indirect;
    procedure RETI;
    procedure LD_R_A;
    procedure IN_D_C_Indirect;
    procedure OUT_C_Indirect_D;
    procedure SBC_HL_DE;
    procedure LD_NN_Indirect_DE;
    procedure IM_1;
    procedure LD_A_I;
    procedure IN_E_C_Indirect;
    procedure OUT_C_Indirect_E;
    procedure ADC_HL_DE;
    procedure LD_DE_NN_Indirect;
    procedure IM_2;
    procedure LD_A_R;
    procedure IN_H_C_Indirect;
    procedure OUT_C_Indirect_H;
    procedure SBC_HL_HL;
    procedure RRD;
    procedure IN_L_C_Indirect;
    procedure OUT_C_Indirect_L;
    procedure ADC_HL_HL;
    procedure RLD;
    procedure SBC_HL_SP;
    procedure LD_NN_Indirect_SP;
    procedure IN_A_C_Indirect;
    procedure OUT_C_Indirect_A;
    procedure ADC_HL_SP;
    procedure LD_SP_NN_Indirect;
    procedure LDI;
    procedure CPI;
    procedure INI;
    procedure OUTI;
    procedure LDD;
    procedure CPD;
    procedure IND;
    procedure OUTD;
    procedure LDIR;
    procedure CPIR;
    procedure INIR;
    procedure OTIR;
    procedure LDDR;
    procedure CPDR;
    procedure INDR;
    procedure OTDR;
    procedure RLC_B;
    procedure RLC_C;
    procedure RLC_D;
    procedure RLC_E;
    procedure RLC_H;
    procedure RLC_L;
    procedure RLC_HL_Indirect;
    procedure RLC_A;
    procedure RRC_B;
    procedure RRC_C;
    procedure RRC_D;
    procedure RRC_E;
    procedure RRC_H;
    procedure RRC_L;
    procedure RRC_HL_Indirect;
    procedure RRC_A;
    procedure RL_B;
    procedure RL_C;
    procedure RL_D;
    procedure RL_E;
    procedure RL_H;
    procedure RL_L;
    procedure RL_HL_Indirect;
    procedure RL_A;
    procedure RR_B;
    procedure RR_C;
    procedure RR_D;
    procedure RR_E;
    procedure RR_H;
    procedure RR_L;
    procedure RR_HL_Indirect;
    procedure RR_A;
    procedure SLA_B;
    procedure SLA_C;
    procedure SLA_D;
    procedure SLA_E;
    procedure SLA_H;
    procedure SLA_L;
    procedure SLA_HL_Indirect;
    procedure SLA_A;
    procedure SRA_B;
    procedure SRA_C;
    procedure SRA_D;
    procedure SRA_E;
    procedure SRA_H;
    procedure SRA_L;
    procedure SRA_HL_Indirect;
    procedure SRA_A;
    procedure SRL_B;
    procedure SRL_C;
    procedure SRL_D;
    procedure SRL_E;
    procedure SRL_H;
    procedure SRL_L;
    procedure SRL_HL_Indirect;
    procedure SRL_A;
    procedure BIT_0_B;
    procedure BIT_0_C;
    procedure BIT_0_D;
    procedure BIT_0_E;
    procedure BIT_0_H;
    procedure BIT_0_L;
    procedure BIT_0_HL_Indirect;
    procedure BIT_0_A;
    procedure BIT_1_B;
    procedure BIT_1_C;
    procedure BIT_1_D;
    procedure BIT_1_E;
    procedure BIT_1_H;
    procedure BIT_1_L;
    procedure BIT_1_HL_Indirect;
    procedure BIT_1_A;
    procedure BIT_2_B;
    procedure BIT_2_C;
    procedure BIT_2_D;
    procedure BIT_2_E;
    procedure BIT_2_H;
    procedure BIT_2_L;
    procedure BIT_2_HL_Indirect;
    procedure BIT_2_A;
    procedure BIT_3_B;
    procedure BIT_3_C;
    procedure BIT_3_D;
    procedure BIT_3_E;
    procedure BIT_3_H;
    procedure BIT_3_L;
    procedure BIT_3_HL_Indirect;
    procedure BIT_3_A;
    procedure BIT_4_B;
    procedure BIT_4_C;
    procedure BIT_4_D;
    procedure BIT_4_E;
    procedure BIT_4_H;
    procedure BIT_4_L;
    procedure BIT_4_HL_Indirect;
    procedure BIT_4_A;
    procedure BIT_5_B;
    procedure BIT_5_C;
    procedure BIT_5_D;
    procedure BIT_5_E;
    procedure BIT_5_H;
    procedure BIT_5_L;
    procedure BIT_5_HL_Indirect;
    procedure BIT_5_A;
    procedure BIT_6_B;
    procedure BIT_6_C;
    procedure BIT_6_D;
    procedure BIT_6_E;
    procedure BIT_6_H;
    procedure BIT_6_L;
    procedure BIT_6_HL_Indirect;
    procedure BIT_6_A;
    procedure BIT_7_B;
    procedure BIT_7_C;
    procedure BIT_7_D;
    procedure BIT_7_E;
    procedure BIT_7_H;
    procedure BIT_7_L;
    procedure BIT_7_HL_Indirect;
    procedure BIT_7_A;
    procedure RES_0_B;
    procedure RES_0_C;
    procedure RES_0_D;
    procedure RES_0_E;
    procedure RES_0_H;
    procedure RES_0_L;
    procedure RES_0_HL_Indirect;
    procedure RES_0_A;
    procedure RES_1_B;
    procedure RES_1_C;
    procedure RES_1_D;
    procedure RES_1_E;
    procedure RES_1_H;
    procedure RES_1_L;
    procedure RES_1_HL_Indirect;
    procedure RES_1_A;
    procedure RES_2_B;
    procedure RES_2_C;
    procedure RES_2_D;
    procedure RES_2_E;
    procedure RES_2_H;
    procedure RES_2_L;
    procedure RES_2_HL_Indirect;
    procedure RES_2_A;
    procedure RES_3_B;
    procedure RES_3_C;
    procedure RES_3_D;
    procedure RES_3_E;
    procedure RES_3_H;
    procedure RES_3_L;
    procedure RES_3_HL_Indirect;
    procedure RES_3_A;
    procedure RES_4_B;
    procedure RES_4_C;
    procedure RES_4_D;
    procedure RES_4_E;
    procedure RES_4_H;
    procedure RES_4_L;
    procedure RES_4_HL_Indirect;
    procedure RES_4_A;
    procedure RES_5_B;
    procedure RES_5_C;
    procedure RES_5_D;
    procedure RES_5_E;
    procedure RES_5_H;
    procedure RES_5_L;
    procedure RES_5_HL_Indirect;
    procedure RES_5_A;
    procedure RES_6_B;
    procedure RES_6_C;
    procedure RES_6_D;
    procedure RES_6_E;
    procedure RES_6_H;
    procedure RES_6_L;
    procedure RES_6_HL_Indirect;
    procedure RES_6_A;
    procedure RES_7_B;
    procedure RES_7_C;
    procedure RES_7_D;
    procedure RES_7_E;
    procedure RES_7_H;
    procedure RES_7_L;
    procedure RES_7_HL_Indirect;
    procedure RES_7_A;
    procedure SET_0_B;
    procedure SET_0_C;
    procedure SET_0_D;
    procedure SET_0_E;
    procedure SET_0_H;
    procedure SET_0_L;
    procedure SET_0_HL_Indirect;
    procedure SET_0_A;
    procedure SET_1_B;
    procedure SET_1_C;
    procedure SET_1_D;
    procedure SET_1_E;
    procedure SET_1_H;
    procedure SET_1_L;
    procedure SET_1_HL_Indirect;
    procedure SET_1_A;
    procedure SET_2_B;
    procedure SET_2_C;
    procedure SET_2_D;
    procedure SET_2_E;
    procedure SET_2_H;
    procedure SET_2_L;
    procedure SET_2_HL_Indirect;
    procedure SET_2_A;
    procedure SET_3_B;
    procedure SET_3_C;
    procedure SET_3_D;
    procedure SET_3_E;
    procedure SET_3_H;
    procedure SET_3_L;
    procedure SET_3_HL_Indirect;
    procedure SET_3_A;
    procedure SET_4_B;
    procedure SET_4_C;
    procedure SET_4_D;
    procedure SET_4_E;
    procedure SET_4_H;
    procedure SET_4_L;
    procedure SET_4_HL_Indirect;
    procedure SET_4_A;
    procedure SET_5_B;
    procedure SET_5_C;
    procedure SET_5_D;
    procedure SET_5_E;
    procedure SET_5_H;
    procedure SET_5_L;
    procedure SET_5_HL_Indirect;
    procedure SET_5_A;
    procedure SET_6_B;
    procedure SET_6_C;
    procedure SET_6_D;
    procedure SET_6_E;
    procedure SET_6_H;
    procedure SET_6_L;
    procedure SET_6_HL_Indirect;
    procedure SET_6_A;
    procedure SET_7_B;
    procedure SET_7_C;
    procedure SET_7_D;
    procedure SET_7_E;
    procedure SET_7_H;
    procedure SET_7_L;
    procedure SET_7_HL_Indirect;
    procedure SET_7_A;
    procedure ADD_IX_BC;
    procedure ADD_IX_DE;
    procedure LD_IX_NN;
    procedure LD_NN_Indirect_IX;
    procedure INC_IX;
    procedure ADD_IX_IX;
    procedure LD_IX_NN_Indirect;
    procedure DEC_IX;
    procedure INC_IX_Plus_D_Indirect;
    procedure DEC_IX_Plus_D_Indirect;
    procedure LD_IX_Plus_D_Indirect_N;
    procedure ADD_IX_SP;
    procedure LD_B_IX_Plus_D_Indirect;
    procedure LD_C_IX_Plus_D_Indirect;
    procedure LD_D_IX_Plus_D_Indirect;
    procedure LD_E_IX_Plus_D_Indirect;
    procedure LD_H_IX_Plus_D_Indirect;
    procedure LD_L_IX_Plus_D_Indirect;
    procedure LD_IX_Plus_D_Indirect_B;
    procedure LD_IX_Plus_D_Indirect_C;
    procedure LD_IX_Plus_D_Indirect_D;
    procedure LD_IX_Plus_D_Indirect_E;
    procedure LD_IX_Plus_D_Indirect_H;
    procedure LD_IX_Plus_D_Indirect_L;
    procedure LD_IX_Plus_D_Indirect_A;
    procedure LD_A_IX_Plus_D_Indirect;
    procedure ADD_A_IX_Plus_D_Indirect;
    procedure ADC_A_IX_Plus_D_Indirect;
    procedure SUB_IX_Plus_D_Indirect;
    procedure SBC_A_IX_Plus_D_Indirect;
    procedure AND_IX_Plus_D_Indirect;
    procedure XOR_IX_Plus_D_Indirect;
    procedure OR_IX_Plus_D_Indirect;
    procedure CP_IX_Plus_D_Indirect;
    procedure POP_IX;
    procedure EX_SP_Indirect_IX;
    procedure PUSH_IX;
    procedure JP_IX_Indirect;
    procedure LD_SP_IX;
    procedure RLC_IX_Plus_D_Indirect;
    procedure RRC_IX_Plus_D_Indirect;
    procedure RL_IX_Plus_D_Indirect;
    procedure RR_IX_Plus_D_Indirect;
    procedure SLA_IX_Plus_D_Indirect;
    procedure SRA_IX_Plus_D_Indirect;
    procedure SRL_IX_Plus_D_Indirect;
    procedure BIT_0_IX_Plus_D_Indirect;
    procedure BIT_1_IX_Plus_D_Indirect;
    procedure BIT_2_IX_Plus_D_Indirect;
    procedure BIT_3_IX_Plus_D_Indirect;
    procedure BIT_4_IX_Plus_D_Indirect;
    procedure BIT_5_IX_Plus_D_Indirect;
    procedure BIT_6_IX_Plus_D_Indirect;
    procedure BIT_7_IX_Plus_D_Indirect;
    procedure RES_0_IX_Plus_D_Indirect;
    procedure RES_1_IX_Plus_D_Indirect;
    procedure RES_2_IX_Plus_D_Indirect;
    procedure RES_3_IX_Plus_D_Indirect;
    procedure RES_4_IX_Plus_D_Indirect;
    procedure RES_5_IX_Plus_D_Indirect;
    procedure RES_6_IX_Plus_D_Indirect;
    procedure RES_7_IX_Plus_D_Indirect;
    procedure SET_0_IX_Plus_D_Indirect;
    procedure SET_1_IX_Plus_D_Indirect;
    procedure SET_2_IX_Plus_D_Indirect;
    procedure SET_3_IX_Plus_D_Indirect;
    procedure SET_4_IX_Plus_D_Indirect;
    procedure SET_5_IX_Plus_D_Indirect;
    procedure SET_6_IX_Plus_D_Indirect;
    procedure SET_7_IX_Plus_D_Indirect;
    procedure ADD_IY_BC;
    procedure ADD_IY_DE;
    procedure LD_IY_NN;
    procedure LD_NN_Indirect_IY;
    procedure INC_IY;
    procedure ADD_IY_IY;
    procedure LD_IY_NN_Indirect;
    procedure DEC_IY;
    procedure INC_IY_Plus_D_Indirect;
    procedure DEC_IY_Plus_D_Indirect;
    procedure LD_IY_Plus_D_Indirect_N;
    procedure ADD_IY_SP;
    procedure LD_B_IY_Plus_D_Indirect;
    procedure LD_C_IY_Plus_D_Indirect;
    procedure LD_D_IY_Plus_D_Indirect;
    procedure LD_E_IY_Plus_D_Indirect;
    procedure LD_H_IY_Plus_D_Indirect;
    procedure LD_L_IY_Plus_D_Indirect;
    procedure LD_IY_Plus_D_Indirect_B;
    procedure LD_IY_Plus_D_Indirect_C;
    procedure LD_IY_Plus_D_Indirect_D;
    procedure LD_IY_Plus_D_Indirect_E;
    procedure LD_IY_Plus_D_Indirect_H;
    procedure LD_IY_Plus_D_Indirect_L;
    procedure LD_IY_Plus_D_Indirect_A;
    procedure LD_A_IY_Plus_D_Indirect;
    procedure ADD_A_IY_Plus_D_Indirect;
    procedure ADC_A_IY_Plus_D_Indirect;
    procedure SUB_IY_Plus_D_Indirect;
    procedure SBC_A_IY_Plus_D_Indirect;
    procedure AND_IY_Plus_D_Indirect;
    procedure XOR_IY_Plus_D_Indirect;
    procedure OR_IY_Plus_D_Indirect;
    procedure CP_IY_Plus_D_Indirect;
    procedure POP_IY;
    procedure EX_SP_Indirect_IY;
    procedure PUSH_IY;
    procedure JP_IY_Indirect;
    procedure LD_SP_IY;
    procedure RLC_IY_Plus_D_Indirect;
    procedure RRC_IY_Plus_D_Indirect;
    procedure RL_IY_Plus_D_Indirect;
    procedure RR_IY_Plus_D_Indirect;
    procedure SLA_IY_Plus_D_Indirect;
    procedure SRA_IY_Plus_D_Indirect;
    procedure SRL_IY_Plus_D_Indirect;
    procedure BIT_0_IY_Plus_D_Indirect;
    procedure BIT_1_IY_Plus_D_Indirect;
    procedure BIT_2_IY_Plus_D_Indirect;
    procedure BIT_3_IY_Plus_D_Indirect;
    procedure BIT_4_IY_Plus_D_Indirect;
    procedure BIT_5_IY_Plus_D_Indirect;
    procedure BIT_6_IY_Plus_D_Indirect;
    procedure BIT_7_IY_Plus_D_Indirect;
    procedure RES_0_IY_Plus_D_Indirect;
    procedure RES_1_IY_Plus_D_Indirect;
    procedure RES_2_IY_Plus_D_Indirect;
    procedure RES_3_IY_Plus_D_Indirect;
    procedure RES_4_IY_Plus_D_Indirect;
    procedure RES_5_IY_Plus_D_Indirect;
    procedure RES_6_IY_Plus_D_Indirect;
    procedure RES_7_IY_Plus_D_Indirect;
    procedure SET_0_IY_Plus_D_Indirect;
    procedure SET_1_IY_Plus_D_Indirect;
    procedure SET_2_IY_Plus_D_Indirect;
    procedure SET_3_IY_Plus_D_Indirect;
    procedure SET_4_IY_Plus_D_Indirect;
    procedure SET_5_IY_Plus_D_Indirect;
    procedure SET_6_IY_Plus_D_Indirect;
    procedure SET_7_IY_Plus_D_Indirect;

    procedure InitInstructions;
  public
    PC: Word;
    SP: Word;
    AF: TRegAF;
    BC: TRegBC;
    DE: TRegDE;
    HL: TRegHL;
    AF2: TRegAF;
    BC2: TRegBC;
    DE2: TRegDE;
    HL2: TRegHL;
    IX: Word;
    IY: Word;
    RegI: Byte;
    RegR: Byte;
    Memory: TMemory;
    Ticks: Cardinal;
    Cycles: Cardinal;
    InterruptEnabled: Boolean;
    InterruptMode: Byte;
    Instructions: TInstructionMethods;
    procedure Step;
    procedure Reset;
    constructor Create;
    destructor Destroy; override;
    property Carry: Boolean read GetCarry write SetCarry;
    property Zero: Boolean read GetZero write SetZero;
    property ParityOverflow: Boolean read GetParityOverflow
      write SetParityOverflow;
    property SignNegative: Boolean read GetSignNegative write SetSignNegative;
    property Thread: TCpuThread read FThread;
    property Paused: Boolean read FPaused write SetPaused;
    property Running: Boolean read FRunning write SetRunning;
    property OnRead: TReadEvent read FOnRead write FOnRead;
    property OnWrite: TWriteEvent read FOnWrite write FOnWrite;
    property OnInput: TReadEvent read FOnInput write FOnInput;
    property OnOutput: TWriteEvent read FOnOutput write FOnOutput;
    property OnMessage: TMessageEvent read FOnMessage write FOnMessage;
    property OnCall: TAddressEvent read FOnCall write FOnCall;
    property OnReturn: TBaseEvent read FOnReturn write FOnReturn;
    property OnStep: TBaseEvent read FOnStep write FOnStep;
  end;


implementation

{ TCpuThread }

procedure TCpuThread.Execute;
begin
  while not Terminated do begin
    Cpu.FEvent.WaitFor(INFINITE);
    Cpu.Step;
  end;
  Cpu.FRunning := False;
end;

{ TCpuZ80 }

procedure TCpuZ80.Error(Message: string);
begin
  PC := InstructionAddress;
  DoMessage(Message + ' on address ' + IntToHex(Word(PC), 4));
  Halt;
end;

function TCpuZ80.GetCarry: Boolean;
begin
  Result := (AF.F and $1) <> 0;
end;

function TCpuZ80.GetParityOverflow: Boolean;
begin
  Result := (AF.F and $4) <> 0;
end;

function TCpuZ80.GetSignNegative: Boolean;
begin
  Result := (AF.F and $80) <> 0;
end;

function TCpuZ80.GetZero: Boolean;
begin
  Result := (AF.F and $40) <> 0;
end;

procedure TCpuZ80.SetCarry(AValue: Boolean);
begin
  AF.F := (AF.F and $fe) or Byte(AValue);
end;

procedure TCpuZ80.SetParityOverflow(AValue: Boolean);
begin
  AF.F := (AF.F and $fb) or (Byte(AValue) shl 2);
end;

procedure TCpuZ80.SetPaused(AValue: Boolean);
begin
  if not Running then Exit;

  if FPaused = AValue then Exit;
  if FPaused then begin
    FPaused := False;
    FEvent.SetEvent;
  end;
  FPaused := AValue;
  if FPaused then begin
    FPaused := True;
    FEvent.ResetEvent;
  end;
end;

procedure TCpuZ80.SetSignNegative(AValue: Boolean);
begin
  AF.F := (AF.F and $7f) or (Byte(AValue) shl 7);
end;

procedure TCpuZ80.SetZero(AValue: Boolean);
begin
  AF.F := (AF.F and $bf) or (Byte(AValue) shl 6);
end;

procedure TCpuZ80.SetRunning(AValue: Boolean);
begin
  if FRunning and FPaused then Paused := False;

  if FRunning = AValue then Exit;
  if FRunning then begin
    FThread.Terminate;
    if FPaused then Paused := False;
    FThread.WaitFor;
    FreeAndNil(FThread);
  end;
  FRunning := AValue;
  if FRunning then begin
    if Assigned(FThread) then FThread.Free;
    FThread := TCpuThread.Create(True);
    FThread.FreeOnTerminate := False;
    FThread.Cpu := Self;
    FThread.Start;
  end;
end;

function TCpuZ80.DoRead(Address: Word): Byte;
begin
  if Assigned(FOnRead) then Result := FOnRead(Address);
end;

function TCpuZ80.DoReadWord(Address: Word): Word;
begin
  Result := DoRead(Address) or (DoRead(Address + 1) shl 8);
end;

procedure TCpuZ80.DoWrite(Address: Word; Data: Byte);
begin
  if Assigned(FOnRead) then FOnWrite(Address, Data);
end;

procedure TCpuZ80.DoWriteWord(Address: Word; Data: Word);
begin
  DoWrite(Address, Data and $ff);
  DoWrite(Address + 1, Data shr 8);
end;

function TCpuZ80.DoInput(Address: Word): Byte;
begin
  if Assigned(FOnInput) then Result := FOnInput(Address);
end;

procedure TCpuZ80.DoOutput(Address: Word; Data: Byte);
begin
  if Assigned(FOnOutput) then FOnOutput(Address, Data);
end;

procedure TCpuZ80.DoMessage(Text: string);
begin
  MessageText := Text;
  DoMessageSync;
  MessageText := '';
end;

procedure TCpuZ80.DoMessageSync;
begin
  if Assigned(FOnMessage) then FOnMessage(MessageText);
end;

procedure TCpuZ80.DoOnCall(Address: Word);
begin
  if Assigned(FOnCall) then FOnCall(Address);
end;

procedure TCpuZ80.DoOnReturn;
begin
  if Assigned(FOnReturn) then FOnReturn;
end;

procedure TCpuZ80.DoOnStep;
begin
  if Assigned(FOnStep) then FOnStep;
end;

function TCpuZ80.ReadByte: Byte;
begin
  Result := DoRead(PC);
  PC := (PC + SizeOf(Byte)) mod $10000;
end;

function TCpuZ80.ReadWord: Word;
begin
  Result := DoRead(PC) or (DoRead(PC + 1) shl 8);
  PC := (PC + SizeOf(Word)) mod $10000;
end;

procedure TCpuZ80.PushWord(Data: Word);
begin
  SP := (SP + $10000 - SizeOf(Word)) mod $10000;
  DoWrite(SP, Data and $ff);
  DoWrite(SP + 1, Data shr 8);
end;

function TCpuZ80.PopWord: Word;
begin
  Result := DoRead(SP) or (DoRead(SP + 1) shl 8);
  SP := (SP + SizeOf(Word)) mod $10000;
end;

procedure TCpuZ80.Call(Address: Word);
begin
  DoOnCall(Address);
  PushWord(PC);
  PC := Address;
end;

procedure TCpuZ80.CallCond(Address: Word; Condition: Boolean);
begin
  DoOnCall(Address);
  if Condition then begin
    PushWord(PC);
    PC := Address;
  end;
end;

procedure TCpuZ80.CpByte(Data: Byte);
var
  Temp: Byte;
begin
  Temp := AF.A;
  SubByte(Temp, Data);
end;

procedure TCpuZ80.Jr(Condition: Boolean);
var
  Temp: ShortInt;
begin
  Temp := ShortInt(ReadByte);
  if Condition then
    PC := PC + Temp;
end;

procedure TCpuZ80.Jp(Condition: Boolean);
var
  Temp: Word;
begin
  Temp := ReadWord;
  if Condition then PC := Temp;
end;

procedure TCpuZ80.RetCond(Condition: Boolean);
begin
  if Condition then begin
    PC := PopWord;
    DoOnReturn;
  end;
end;

procedure TCpuZ80.NotImplemented;
begin
  Error('Not implemented instruction ' + IntToHex(Word(Instruction), 4));
end;

procedure TCpuZ80.AddByte(var Target: Byte; Second: Byte);
var
  Temp: Word;
begin
  Temp := Target + Second;
  ParityOverflow := ((Target and $80) = (Second and $80)) and
    ((Target and $80) <> (Temp and $80));
  Carry := (Temp and $100) <> 0;
  Zero := Byte(Temp) = 0;
  SignNegative := (Temp and $80) <> 0;
  Target := Byte(Temp);
end;

procedure TCpuZ80.AddWord(var Target: Word; Second: Word);
var
  Temp: Cardinal;
begin
  Temp := Target + Second;
  Carry := Temp > $ffff;
  Target := Word(Temp + Second);
end;

procedure TCpuZ80.AdcByte(var Target: Byte; Second: Byte);
var
  Temp: Word;
begin
  Temp := Target + Second + Byte(Carry);
  ParityOverflow := ((Target and $80) = (Second and $80)) and
    ((Target and $80) <> (Temp and $80));
  Carry := (Temp and $100) <> 0;
  Zero := Byte(Temp) = 0;
  SignNegative := (Temp and $80) <> 0;
  Target := Byte(Temp);
end;

procedure TCpuZ80.AdcWord(var Target: Word; Second: Word);
var
  Temp: Cardinal;
begin
  Temp := Target + Second + Byte(Carry);
  Carry := Temp > $ffff;
  Target := Word(Temp + Second);
end;

procedure TCpuZ80.SubByte(var Target: Byte; Second: Byte);
var
  Temp: SmallInt;
begin
  Temp := ShortInt(Target) - ShortInt(Second);
  ParityOverflow := ((Target and $80) <> (Second and $80)) and
    ((Target and $80) <> (Temp and $80));
  Carry := (Temp and $100) <> 0;
  Zero := Byte(Temp) = 0;
  SignNegative := (Temp and $80) <> 0;
  Target := Byte(Temp);
end;

procedure TCpuZ80.SbcByte(var Target: Byte; Second: Byte);
var
  Temp: SmallInt;
begin
  Temp := ShortInt(Target) - ShortInt(Second) - Byte(Carry);
  ParityOverflow := ((Target and $80) <> (Second and $80)) and
    ((Target and $80) <> (Temp and $80));
  Carry := (Temp and $100) <> 0;
  Zero := Byte(Temp) = 0;
  SignNegative := (Temp and $80) <> 0;
  Target := Byte(Temp);
end;

procedure TCpuZ80.SbcWord(var Target: Word; Second: Word);
var
  Temp: Integer;
begin
  Temp := SmallInt(Target) - SmallInt(Second);
  ParityOverflow := ((Target and $8000) <> (Second and $8000)) and
    ((Target and $8000) <> (Temp and $8000));
  Carry := (Temp and $10000) <> 0;
  Zero := Word(Temp) = 0;
  SignNegative := (Temp and $8000) <> 0;
  Target := Word(Temp);
end;

procedure TCpuZ80.XorByte(var Target: Byte; Second: Byte);
begin
  Target := Target xor Second;
  Carry := False;
  Zero := Target = 0;
  ParityOverflow := not Odd(Target);
  SignNegative := (Target and $80) <> 0;
end;

procedure TCpuZ80.OrByte(var Target: Byte; Second: Byte);
begin
  Target := Target or Second;
  Carry := False;
  Zero := Target = 0;
  ParityOverflow := not Odd(Target);
  SignNegative := (Target and $80) <> 0;
end;

procedure TCpuZ80.AndByte(var Target: Byte; Second: Byte);
begin
  Target := Target and Second;
  Carry := False;
  Zero := Target = 0;
  ParityOverflow := not Odd(Target);
  SignNegative := (Target and $80) <> 0;
end;

procedure TCpuZ80.IncByte(var Reg: Byte);
begin
  ParityOverflow := Reg = $7f;

  if Reg = High(Reg) then Reg := 0
    else Inc(Reg);

  Zero := Reg = 0;
  SignNegative := (Reg and $80) <> 0;
end;

procedure TCpuZ80.IncWord(var Reg: Word);
begin
  if Reg = High(Reg) then Reg := 0
    else Inc(Reg);
end;

procedure TCpuZ80.DecByte(var Reg: Byte);
begin
  ParityOverflow := Reg = $80;

  if Reg = 0 then Reg := High(Reg)
    else Dec(Reg);

  Zero := Reg = 0;
  SignNegative := (Reg and $80) <> 0;
end;

procedure TCpuZ80.DecWord(var Reg: Word);
begin
  if Reg = 0 then Reg := High(Reg)
    else Dec(Reg);
end;

procedure TCpuZ80.RlcByte(var Data: Byte);
begin
  Carry := (Data and $80) <> 0;
  Data := ((Data shl 1) and $ff) or Byte(Carry);
end;

procedure TCpuZ80.RrcByte(var Data: Byte);
begin
  Carry := (Data and 1) > 0;
  Data := (Data shr 1) or ($80 * Byte(Carry));
end;

procedure TCpuZ80.InitInstructions;
begin
  Instructions[in_NOP] := NOP;
  Instructions[in_LD_BC_NN] := LD_BC_NN;
  Instructions[in_LD_BC_Indirect_A] := LD_BC_Indirect_A;
  Instructions[in_INC_BC] := INC_BC;
  Instructions[in_INC_B] := INC_B;
  Instructions[in_DEC_B] := DEC_B;
  Instructions[in_LD_B_N] := LD_B_N;
  Instructions[in_RLCA] := RLCA;
  Instructions[in_EX_AF_AF_Pair] := EX_AF_AF_Pair;
  Instructions[in_ADD_HL_BC] := ADD_HL_BC;
  Instructions[in_LD_A_BC_Indirect] := LD_A_BC_Indirect;
  Instructions[in_DEC_BC] := DEC_BC;
  Instructions[in_INC_C] := INC_C;
  Instructions[in_DEC_C] := DEC_C;
  Instructions[in_LD_C_N] := LD_C_N;
  Instructions[in_RRCA] := RRCA;
  Instructions[in_DJNZ_D] := DJNZ_D;
  Instructions[in_LD_DE_NN] := LD_DE_NN;
  Instructions[in_LD_DE_Indirect_A] := LD_DE_Indirect_A;
  Instructions[in_INC_DE] := INC_DE;
  Instructions[in_INC_D] := INC_D;
  Instructions[in_DEC_D] := DEC_D;
  Instructions[in_LD_D_N] := LD_D_N;
  Instructions[in_RLA] := RLA;
  Instructions[in_JR_D] := JR_D;
  Instructions[in_ADD_HL_DE] := ADD_HL_DE;
  Instructions[in_LD_A_DE_Indirect] := LD_A_DE_Indirect;
  Instructions[in_DEC_DE] := DEC_DE;
  Instructions[in_INC_E] := INC_E;
  Instructions[in_DEC_E] := DEC_E;
  Instructions[in_LD_E_N] := LD_E_N;
  Instructions[in_RRA] := RRA;
  Instructions[in_JR_NZ_D] := JR_NZ_D;
  Instructions[in_LD_HL_NN] := LD_HL_NN;
  Instructions[in_LD_NN_Indirect_HL] := LD_NN_Indirect_HL;
  Instructions[in_INC_HL] := INC_HL;
  Instructions[in_INC_H] := INC_H;
  Instructions[in_DEC_H] := DEC_H;
  Instructions[in_LD_H_N] := LD_H_N;
  Instructions[in_DAA] := DAA;
  Instructions[in_JR_Z_D] := JR_Z_D;
  Instructions[in_ADD_HL_HL] := ADD_HL_HL;
  Instructions[in_LD_HL_NN_Indirect] := LD_HL_NN_Indirect;
  Instructions[in_DEC_HL] := DEC_HL;
  Instructions[in_INC_L] := INC_L;
  Instructions[in_DEC_L] := DEC_L;
  Instructions[in_LD_L_N] := LD_L_N;
  Instructions[in_CPL] := CPL;
  Instructions[in_JR_NC_D] := JR_NC_D;
  Instructions[in_LD_SP_NN] := LD_SP_NN;
  Instructions[in_LD_NN_Indirect_A] := LD_NN_Indirect_A;
  Instructions[in_INC_SP] := INC_SP;
  Instructions[in_INC_HL_Indirect] := INC_HL_Indirect;
  Instructions[in_DEC_HL_Indirect] := DEC_HL_Indirect;
  Instructions[in_LD_HL_Indirect_N] := LD_HL_Indirect_N;
  Instructions[in_SCF] := SCF;
  Instructions[in_JR_C_D] := JR_C_D;
  Instructions[in_ADD_HL_SP] := ADD_HL_SP;
  Instructions[in_LD_A_NN_Indirect] := LD_A_NN_Indirect;
  Instructions[in_DEC_SP] := DEC_SP;
  Instructions[in_INC_A] := INC_A;
  Instructions[in_DEC_A] := DEC_A;
  Instructions[in_LD_A_N] := LD_A_N;
  Instructions[in_CCF] := CCF;
  Instructions[in_LD_B_B] := LD_B_B;
  Instructions[in_LD_B_C] := LD_B_C;
  Instructions[in_LD_B_D] := LD_B_D;
  Instructions[in_LD_B_E] := LD_B_E;
  Instructions[in_LD_B_H] := LD_B_H;
  Instructions[in_LD_B_L] := LD_B_L;
  Instructions[in_LD_B_HL_Indirect] := LD_B_HL_Indirect;
  Instructions[in_LD_B_A] := LD_B_A;
  Instructions[in_LD_C_B] := LD_C_B;
  Instructions[in_LD_C_C] := LD_C_C;
  Instructions[in_LD_C_D] := LD_C_D;
  Instructions[in_LD_C_E] := LD_C_E;
  Instructions[in_LD_C_H] := LD_C_H;
  Instructions[in_LD_C_L] := LD_C_L;
  Instructions[in_LD_C_HL_Indirect] := LD_C_HL_Indirect;
  Instructions[in_LD_C_A] := LD_C_A;
  Instructions[in_LD_D_B] := LD_D_B;
  Instructions[in_LD_D_C] := LD_D_C;
  Instructions[in_LD_D_D] := LD_D_D;
  Instructions[in_LD_D_E] := LD_D_E;
  Instructions[in_LD_D_H] := LD_D_H;
  Instructions[in_LD_D_L] := LD_D_L;
  Instructions[in_LD_D_HL_Indirect] := LD_D_HL_Indirect;
  Instructions[in_LD_D_A] := LD_D_A;
  Instructions[in_LD_E_B] := LD_E_B;
  Instructions[in_LD_E_C] := LD_E_C;
  Instructions[in_LD_E_D] := LD_E_D;
  Instructions[in_LD_E_E] := LD_E_E;
  Instructions[in_LD_E_H] := LD_E_H;
  Instructions[in_LD_E_L] := LD_E_L;
  Instructions[in_LD_E_HL_Indirect] := LD_E_HL_Indirect;
  Instructions[in_LD_E_A] := LD_E_A;
  Instructions[in_LD_H_B] := LD_H_B;
  Instructions[in_LD_H_C] := LD_H_C;
  Instructions[in_LD_H_D] := LD_H_D;
  Instructions[in_LD_H_E] := LD_H_E;
  Instructions[in_LD_H_H] := LD_H_H;
  Instructions[in_LD_H_L] := LD_H_L;
  Instructions[in_LD_H_HL_Indirect] := LD_H_HL_Indirect;
  Instructions[in_LD_H_A] := LD_H_A;
  Instructions[in_LD_L_B] := LD_L_B;
  Instructions[in_LD_L_C] := LD_L_C;
  Instructions[in_LD_L_D] := LD_L_D;
  Instructions[in_LD_L_E] := LD_L_E;
  Instructions[in_LD_L_H] := LD_L_H;
  Instructions[in_LD_L_L] := LD_L_L;
  Instructions[in_LD_L_HL_Indirect] := LD_L_HL_Indirect;
  Instructions[in_LD_L_A] := LD_L_A;
  Instructions[in_LD_HL_Indirect_B] := LD_HL_Indirect_B;
  Instructions[in_LD_HL_Indirect_C] := LD_HL_Indirect_C;
  Instructions[in_LD_HL_Indirect_D] := LD_HL_Indirect_D;
  Instructions[in_LD_HL_Indirect_E] := LD_HL_Indirect_E;
  Instructions[in_LD_HL_Indirect_H] := LD_HL_Indirect_H;
  Instructions[in_LD_HL_Indirect_L] := LD_HL_Indirect_L;
  Instructions[in_HALT] := HALT;
  Instructions[in_LD_HL_Indirect_A] := LD_HL_Indirect_A;
  Instructions[in_LD_A_B] := LD_A_B;
  Instructions[in_LD_A_C] := LD_A_C;
  Instructions[in_LD_A_D] := LD_A_D;
  Instructions[in_LD_A_E] := LD_A_E;
  Instructions[in_LD_A_H] := LD_A_H;
  Instructions[in_LD_A_L] := LD_A_L;
  Instructions[in_LD_A_HL_Indirect] := LD_A_HL_Indirect;
  Instructions[in_LD_A_A] := LD_A_A;
  Instructions[in_ADD_A_B] := ADD_A_B;
  Instructions[in_ADD_A_C] := ADD_A_C;
  Instructions[in_ADD_A_D] := ADD_A_D;
  Instructions[in_ADD_A_E] := ADD_A_E;
  Instructions[in_ADD_A_H] := ADD_A_H;
  Instructions[in_ADD_A_L] := ADD_A_L;
  Instructions[in_ADD_A_HL_Indirect] := ADD_A_HL_Indirect;
  Instructions[in_ADD_A_A] := ADD_A_A;
  Instructions[in_ADC_A_B] := ADC_A_B;
  Instructions[in_ADC_A_C] := ADC_A_C;
  Instructions[in_ADC_A_D] := ADC_A_D;
  Instructions[in_ADC_A_E] := ADC_A_E;
  Instructions[in_ADC_A_H] := ADC_A_H;
  Instructions[in_ADC_A_L] := ADC_A_L;
  Instructions[in_ADC_A_HL_Indirect] := ADC_A_HL_Indirect;
  Instructions[in_ADC_A_A] := ADC_A_A;
  Instructions[in_SUB_B] := SUB_B;
  Instructions[in_SUB_C] := SUB_C;
  Instructions[in_SUB_D] := SUB_D;
  Instructions[in_SUB_E] := SUB_E;
  Instructions[in_SUB_H] := SUB_H;
  Instructions[in_SUB_L] := SUB_L;
  Instructions[in_SUB_HL_Indirect] := SUB_HL_Indirect;
  Instructions[in_SUB_A] := SUB_A;
  Instructions[in_SBC_A_B] := SBC_A_B;
  Instructions[in_SBC_A_C] := SBC_A_C;
  Instructions[in_SBC_A_D] := SBC_A_D;
  Instructions[in_SBC_A_E] := SBC_A_E;
  Instructions[in_SBC_A_H] := SBC_A_H;
  Instructions[in_SBC_A_L] := SBC_A_L;
  Instructions[in_SBC_A_HL_Indirect] := SBC_A_HL_Indirect;
  Instructions[in_SBC_A_A] := SBC_A_A;
  Instructions[in_AND_B] := AND_B;
  Instructions[in_AND_C] := AND_C;
  Instructions[in_AND_D] := AND_D;
  Instructions[in_AND_E] := AND_E;
  Instructions[in_AND_H] := AND_H;
  Instructions[in_AND_L] := AND_L;
  Instructions[in_AND_HL_Indirect] := AND_HL_Indirect;
  Instructions[in_AND_A] := AND_A;
  Instructions[in_XOR_B] := XOR_B;
  Instructions[in_XOR_C] := XOR_C;
  Instructions[in_XOR_D] := XOR_D;
  Instructions[in_XOR_E] := XOR_E;
  Instructions[in_XOR_H] := XOR_H;
  Instructions[in_XOR_L] := XOR_L;
  Instructions[in_XOR_HL_Indirect] := XOR_HL_Indirect;
  Instructions[in_XOR_A] := XOR_A;
  Instructions[in_OR_B] := OR_B;
  Instructions[in_OR_C] := OR_C;
  Instructions[in_OR_D] := OR_D;
  Instructions[in_OR_E] := OR_E;
  Instructions[in_OR_H] := OR_H;
  Instructions[in_OR_L] := OR_L;
  Instructions[in_OR_HL_Indirect] := OR_HL_Indirect;
  Instructions[in_OR_A] := OR_A;
  Instructions[in_CP_B] := CP_B;
  Instructions[in_CP_C] := CP_C;
  Instructions[in_CP_D] := CP_D;
  Instructions[in_CP_E] := CP_E;
  Instructions[in_CP_H] := CP_H;
  Instructions[in_CP_L] := CP_L;
  Instructions[in_CP_HL_Indirect] := CP_HL_Indirect;
  Instructions[in_CP_A] := CP_A;
  Instructions[in_RET_NZ] := RET_NZ;
  Instructions[in_POP_BC] := POP_BC;
  Instructions[in_JP_NZ_NN] := JP_NZ_NN;
  Instructions[in_JP_NN] := JP_NN;
  Instructions[in_CALL_NZ_NN] := CALL_NZ_NN;
  Instructions[in_PUSH_BC] := PUSH_BC;
  Instructions[in_ADD_A_N] := ADD_A_N;
  Instructions[in_RST_00H] := RST_00H;
  Instructions[in_RET_Z] := RET_Z;
  Instructions[in_RET] := RET;
  Instructions[in_JP_Z_NN] := JP_Z_NN;
  Instructions[in_CALL_Z_NN] := CALL_Z_NN;
  Instructions[in_CALL_NN] := CALL_NN;
  Instructions[in_ADC_A_N] := ADC_A_N;
  Instructions[in_RST_08H] := RST_08H;
  Instructions[in_RET_NC] := RET_NC;
  Instructions[in_POP_DE] := POP_DE;
  Instructions[in_JP_NC_NN] := JP_NC_NN;
  Instructions[in_OUT_N_Indirect_A] := OUT_N_Indirect_A;
  Instructions[in_CALL_NC_NN] := CALL_NC_NN;
  Instructions[in_PUSH_DE] := PUSH_DE;
  Instructions[in_SUB_N] := SUB_N;
  Instructions[in_RST_10H] := RST_10H;
  Instructions[in_RET_C] := RET_C;
  Instructions[in_EXX] := EXX;
  Instructions[in_JP_C_NN] := JP_C_NN;
  Instructions[in_IN_A_N_Indirect] := IN_A_N_Indirect;
  Instructions[in_CALL_C_NN] := CALL_C_NN;
  Instructions[in_SBC_A_N] := SBC_A_N;
  Instructions[in_RST_18H] := RST_18H;
  Instructions[in_RET_PO] := RET_PO;
  Instructions[in_POP_HL] := POP_HL;
  Instructions[in_JP_PO_NN] := JP_PO_NN;
  Instructions[in_EX_SP_Indirect_HL] := EX_SP_Indirect_HL;
  Instructions[in_CALL_PO_NN] := CALL_PO_NN;
  Instructions[in_PUSH_HL] := PUSH_HL;
  Instructions[in_AND_N] := AND_N;
  Instructions[in_RST_20H] := RST_20H;
  Instructions[in_RET_PE] := RET_PE;
  Instructions[in_JP_HL_Indirect] := JP_HL_Indirect;
  Instructions[in_JP_PE_NN] := JP_PE_NN;
  Instructions[in_EX_DE_HL] := EX_DE_HL;
  Instructions[in_CALL_PE_NN] := CALL_PE_NN;
  Instructions[in_XOR_N] := XOR_N;
  Instructions[in_RST_28H] := RST_28H;
  Instructions[in_RET_P] := RET_P;
  Instructions[in_POP_AF] := POP_AF;
  Instructions[in_JP_P_NN] := JP_P_NN;
  Instructions[in_DI] := DI;
  Instructions[in_CALL_P_NN] := CALL_P_NN;
  Instructions[in_PUSH_AF] := PUSH_AF;
  Instructions[in_OR_N] := OR_N;
  Instructions[in_RST_30H] := RST_30H;
  Instructions[in_RET_M] := RET_M;
  Instructions[in_LD_SP_HL] := LD_SP_HL;
  Instructions[in_JP_M_NN] := JP_M_NN;
  Instructions[in_EI] := EI;
  Instructions[in_CALL_M_NN] := CALL_M_NN;
  Instructions[in_CP_N] := CP_N;
  Instructions[in_RST_38H] := RST_38H;
  Instructions[in_IN_B_C_Indirect] := IN_B_C_Indirect;
  Instructions[in_OUT_C_Indirect_B] := OUT_C_Indirect_B;
  Instructions[in_SBC_HL_BC] := SBC_HL_BC;
  Instructions[in_LD_NN_Indirect_BC] := LD_NN_Indirect_BC;
  Instructions[in_NEG] := NEG;
  Instructions[in_RETN] := RETN;
  Instructions[in_IM_0] := IM_0;
  Instructions[in_LD_I_A] := LD_I_A;
  Instructions[in_IN_C_C_Indirect] := IN_C_C_Indirect;
  Instructions[in_OUT_C_Indirect_C] := OUT_C_Indirect_C;
  Instructions[in_ADC_HL_BC] := ADC_HL_BC;
  Instructions[in_LD_BC_NN_Indirect] := LD_BC_NN_Indirect;
  Instructions[in_RETI] := RETI;
  Instructions[in_LD_R_A] := LD_R_A;
  Instructions[in_IN_D_C_Indirect] := IN_D_C_Indirect;
  Instructions[in_OUT_C_Indirect_D] := OUT_C_Indirect_D;
  Instructions[in_SBC_HL_DE] := SBC_HL_DE;
  Instructions[in_LD_NN_Indirect_DE] := LD_NN_Indirect_DE;
  Instructions[in_IM_1] := IM_1;
  Instructions[in_LD_A_I] := LD_A_I;
  Instructions[in_IN_E_C_Indirect] := IN_E_C_Indirect;
  Instructions[in_OUT_C_Indirect_E] := OUT_C_Indirect_E;
  Instructions[in_ADC_HL_DE] := ADC_HL_DE;
  Instructions[in_LD_DE_NN_Indirect] := LD_DE_NN_Indirect;
  Instructions[in_IM_2] := IM_2;
  Instructions[in_LD_A_R] := LD_A_R;
  Instructions[in_IN_H_C_Indirect] := IN_H_C_Indirect;
  Instructions[in_OUT_C_Indirect_H] := OUT_C_Indirect_H;
  Instructions[in_SBC_HL_HL] := SBC_HL_HL;
  Instructions[in_RRD] := RRD;
  Instructions[in_IN_L_C_Indirect] := IN_L_C_Indirect;
  Instructions[in_OUT_C_Indirect_L] := OUT_C_Indirect_L;
  Instructions[in_ADC_HL_HL] := ADC_HL_HL;
  Instructions[in_RLD] := RLD;
  Instructions[in_SBC_HL_SP] := SBC_HL_SP;
  Instructions[in_LD_NN_Indirect_SP] := LD_NN_Indirect_SP;
  Instructions[in_IN_A_C_Indirect] := IN_A_C_Indirect;
  Instructions[in_OUT_C_Indirect_A] := OUT_C_Indirect_A;
  Instructions[in_ADC_HL_SP] := ADC_HL_SP;
  Instructions[in_LD_SP_NN_Indirect] := LD_SP_NN_Indirect;
  Instructions[in_LDI] := LDI;
  Instructions[in_CPI] := CPI;
  Instructions[in_INI] := INI;
  Instructions[in_OUTI] := OUTI;
  Instructions[in_LDD] := LDD;
  Instructions[in_CPD] := CPD;
  Instructions[in_IND] := IND;
  Instructions[in_OUTD] := OUTD;
  Instructions[in_LDIR] := LDIR;
  Instructions[in_CPIR] := CPIR;
  Instructions[in_INIR] := INIR;
  Instructions[in_OTIR] := OTIR;
  Instructions[in_LDDR] := LDDR;
  Instructions[in_CPDR] := CPDR;
  Instructions[in_INDR] := INDR;
  Instructions[in_OTDR] := OTDR;
  Instructions[in_RLC_B] := RLC_B;
  Instructions[in_RLC_C] := RLC_C;
  Instructions[in_RLC_D] := RLC_D;
  Instructions[in_RLC_E] := RLC_E;
  Instructions[in_RLC_H] := RLC_H;
  Instructions[in_RLC_L] := RLC_L;
  Instructions[in_RLC_HL_Indirect] := RLC_HL_Indirect;
  Instructions[in_RLC_A] := RLC_A;
  Instructions[in_RRC_B] := RRC_B;
  Instructions[in_RRC_C] := RRC_C;
  Instructions[in_RRC_D] := RRC_D;
  Instructions[in_RRC_E] := RRC_E;
  Instructions[in_RRC_H] := RRC_H;
  Instructions[in_RRC_L] := RRC_L;
  Instructions[in_RRC_HL_Indirect] := RRC_HL_Indirect;
  Instructions[in_RRC_A] := RRC_A;
  Instructions[in_RL_B] := RL_B;
  Instructions[in_RL_C] := RL_C;
  Instructions[in_RL_D] := RL_D;
  Instructions[in_RL_E] := RL_E;
  Instructions[in_RL_H] := RL_H;
  Instructions[in_RL_L] := RL_L;
  Instructions[in_RL_HL_Indirect] := RL_HL_Indirect;
  Instructions[in_RL_A] := RL_A;
  Instructions[in_RR_B] := RR_B;
  Instructions[in_RR_C] := RR_C;
  Instructions[in_RR_D] := RR_D;
  Instructions[in_RR_E] := RR_E;
  Instructions[in_RR_H] := RR_H;
  Instructions[in_RR_L] := RR_L;
  Instructions[in_RR_HL_Indirect] := RR_HL_Indirect;
  Instructions[in_RR_A] := RR_A;
  Instructions[in_SLA_B] := SLA_B;
  Instructions[in_SLA_C] := SLA_C;
  Instructions[in_SLA_D] := SLA_D;
  Instructions[in_SLA_E] := SLA_E;
  Instructions[in_SLA_H] := SLA_H;
  Instructions[in_SLA_L] := SLA_L;
  Instructions[in_SLA_HL_Indirect] := SLA_HL_Indirect;
  Instructions[in_SLA_A] := SLA_A;
  Instructions[in_SRA_B] := SRA_B;
  Instructions[in_SRA_C] := SRA_C;
  Instructions[in_SRA_D] := SRA_D;
  Instructions[in_SRA_E] := SRA_E;
  Instructions[in_SRA_H] := SRA_H;
  Instructions[in_SRA_L] := SRA_L;
  Instructions[in_SRA_HL_Indirect] := SRA_HL_Indirect;
  Instructions[in_SRA_A] := SRA_A;
  Instructions[in_SRL_B] := SRL_B;
  Instructions[in_SRL_C] := SRL_C;
  Instructions[in_SRL_D] := SRL_D;
  Instructions[in_SRL_E] := SRL_E;
  Instructions[in_SRL_H] := SRL_H;
  Instructions[in_SRL_L] := SRL_L;
  Instructions[in_SRL_HL_Indirect] := SRL_HL_Indirect;
  Instructions[in_SRL_A] := SRL_A;
  Instructions[in_BIT_0_B] := BIT_0_B;
  Instructions[in_BIT_0_C] := BIT_0_C;
  Instructions[in_BIT_0_D] := BIT_0_D;
  Instructions[in_BIT_0_E] := BIT_0_E;
  Instructions[in_BIT_0_H] := BIT_0_H;
  Instructions[in_BIT_0_L] := BIT_0_L;
  Instructions[in_BIT_0_HL_Indirect] := BIT_0_HL_Indirect;
  Instructions[in_BIT_0_A] := BIT_0_A;
  Instructions[in_BIT_1_B] := BIT_1_B;
  Instructions[in_BIT_1_C] := BIT_1_C;
  Instructions[in_BIT_1_D] := BIT_1_D;
  Instructions[in_BIT_1_E] := BIT_1_E;
  Instructions[in_BIT_1_H] := BIT_1_H;
  Instructions[in_BIT_1_L] := BIT_1_L;
  Instructions[in_BIT_1_HL_Indirect] := BIT_1_HL_Indirect;
  Instructions[in_BIT_1_A] := BIT_1_A;
  Instructions[in_BIT_2_B] := BIT_2_B;
  Instructions[in_BIT_2_C] := BIT_2_C;
  Instructions[in_BIT_2_D] := BIT_2_D;
  Instructions[in_BIT_2_E] := BIT_2_E;
  Instructions[in_BIT_2_H] := BIT_2_H;
  Instructions[in_BIT_2_L] := BIT_2_L;
  Instructions[in_BIT_2_HL_Indirect] := BIT_2_HL_Indirect;
  Instructions[in_BIT_2_A] := BIT_2_A;
  Instructions[in_BIT_3_B] := BIT_3_B;
  Instructions[in_BIT_3_C] := BIT_3_C;
  Instructions[in_BIT_3_D] := BIT_3_D;
  Instructions[in_BIT_3_E] := BIT_3_E;
  Instructions[in_BIT_3_H] := BIT_3_H;
  Instructions[in_BIT_3_L] := BIT_3_L;
  Instructions[in_BIT_3_HL_Indirect] := BIT_3_HL_Indirect;
  Instructions[in_BIT_3_A] := BIT_3_A;
  Instructions[in_BIT_4_B] := BIT_4_B;
  Instructions[in_BIT_4_C] := BIT_4_C;
  Instructions[in_BIT_4_D] := BIT_4_D;
  Instructions[in_BIT_4_E] := BIT_4_E;
  Instructions[in_BIT_4_H] := BIT_4_H;
  Instructions[in_BIT_4_L] := BIT_4_L;
  Instructions[in_BIT_4_HL_Indirect] := BIT_4_HL_Indirect;
  Instructions[in_BIT_4_A] := BIT_4_A;
  Instructions[in_BIT_5_B] := BIT_5_B;
  Instructions[in_BIT_5_C] := BIT_5_C;
  Instructions[in_BIT_5_D] := BIT_5_D;
  Instructions[in_BIT_5_E] := BIT_5_E;
  Instructions[in_BIT_5_H] := BIT_5_H;
  Instructions[in_BIT_5_L] := BIT_5_L;
  Instructions[in_BIT_5_HL_Indirect] := BIT_5_HL_Indirect;
  Instructions[in_BIT_5_A] := BIT_5_A;
  Instructions[in_BIT_6_B] := BIT_6_B;
  Instructions[in_BIT_6_C] := BIT_6_C;
  Instructions[in_BIT_6_D] := BIT_6_D;
  Instructions[in_BIT_6_E] := BIT_6_E;
  Instructions[in_BIT_6_H] := BIT_6_H;
  Instructions[in_BIT_6_L] := BIT_6_L;
  Instructions[in_BIT_6_HL_Indirect] := BIT_6_HL_Indirect;
  Instructions[in_BIT_6_A] := BIT_6_A;
  Instructions[in_BIT_7_B] := BIT_7_B;
  Instructions[in_BIT_7_C] := BIT_7_C;
  Instructions[in_BIT_7_D] := BIT_7_D;
  Instructions[in_BIT_7_E] := BIT_7_E;
  Instructions[in_BIT_7_H] := BIT_7_H;
  Instructions[in_BIT_7_L] := BIT_7_L;
  Instructions[in_BIT_7_HL_Indirect] := BIT_7_HL_Indirect;
  Instructions[in_BIT_7_A] := BIT_7_A;
  Instructions[in_RES_0_B] := RES_0_B;
  Instructions[in_RES_0_C] := RES_0_C;
  Instructions[in_RES_0_D] := RES_0_D;
  Instructions[in_RES_0_E] := RES_0_E;
  Instructions[in_RES_0_H] := RES_0_H;
  Instructions[in_RES_0_L] := RES_0_L;
  Instructions[in_RES_0_HL_Indirect] := RES_0_HL_Indirect;
  Instructions[in_RES_0_A] := RES_0_A;
  Instructions[in_RES_1_B] := RES_1_B;
  Instructions[in_RES_1_C] := RES_1_C;
  Instructions[in_RES_1_D] := RES_1_D;
  Instructions[in_RES_1_E] := RES_1_E;
  Instructions[in_RES_1_H] := RES_1_H;
  Instructions[in_RES_1_L] := RES_1_L;
  Instructions[in_RES_1_HL_Indirect] := RES_1_HL_Indirect;
  Instructions[in_RES_1_A] := RES_1_A;
  Instructions[in_RES_2_B] := RES_2_B;
  Instructions[in_RES_2_C] := RES_2_C;
  Instructions[in_RES_2_D] := RES_2_D;
  Instructions[in_RES_2_E] := RES_2_E;
  Instructions[in_RES_2_H] := RES_2_H;
  Instructions[in_RES_2_L] := RES_2_L;
  Instructions[in_RES_2_HL_Indirect] := RES_2_HL_Indirect;
  Instructions[in_RES_2_A] := RES_2_A;
  Instructions[in_RES_3_B] := RES_3_B;
  Instructions[in_RES_3_C] := RES_3_C;
  Instructions[in_RES_3_D] := RES_3_D;
  Instructions[in_RES_3_E] := RES_3_E;
  Instructions[in_RES_3_H] := RES_3_H;
  Instructions[in_RES_3_L] := RES_3_L;
  Instructions[in_RES_3_HL_Indirect] := RES_3_HL_Indirect;
  Instructions[in_RES_3_A] := RES_3_A;
  Instructions[in_RES_4_B] := RES_4_B;
  Instructions[in_RES_4_C] := RES_4_C;
  Instructions[in_RES_4_D] := RES_4_D;
  Instructions[in_RES_4_E] := RES_4_E;
  Instructions[in_RES_4_H] := RES_4_H;
  Instructions[in_RES_4_L] := RES_4_L;
  Instructions[in_RES_4_HL_Indirect] := RES_4_HL_Indirect;
  Instructions[in_RES_4_A] := RES_4_A;
  Instructions[in_RES_5_B] := RES_5_B;
  Instructions[in_RES_5_C] := RES_5_C;
  Instructions[in_RES_5_D] := RES_5_D;
  Instructions[in_RES_5_E] := RES_5_E;
  Instructions[in_RES_5_H] := RES_5_H;
  Instructions[in_RES_5_L] := RES_5_L;
  Instructions[in_RES_5_HL_Indirect] := RES_5_HL_Indirect;
  Instructions[in_RES_5_A] := RES_5_A;
  Instructions[in_RES_6_B] := RES_6_B;
  Instructions[in_RES_6_C] := RES_6_C;
  Instructions[in_RES_6_D] := RES_6_D;
  Instructions[in_RES_6_E] := RES_6_E;
  Instructions[in_RES_6_H] := RES_6_H;
  Instructions[in_RES_6_L] := RES_6_L;
  Instructions[in_RES_6_HL_Indirect] := RES_6_HL_Indirect;
  Instructions[in_RES_6_A] := RES_6_A;
  Instructions[in_RES_7_B] := RES_7_B;
  Instructions[in_RES_7_C] := RES_7_C;
  Instructions[in_RES_7_D] := RES_7_D;
  Instructions[in_RES_7_E] := RES_7_E;
  Instructions[in_RES_7_H] := RES_7_H;
  Instructions[in_RES_7_L] := RES_7_L;
  Instructions[in_RES_7_HL_Indirect] := RES_7_HL_Indirect;
  Instructions[in_RES_7_A] := RES_7_A;
  Instructions[in_SET_0_B] := SET_0_B;
  Instructions[in_SET_0_C] := SET_0_C;
  Instructions[in_SET_0_D] := SET_0_D;
  Instructions[in_SET_0_E] := SET_0_E;
  Instructions[in_SET_0_H] := SET_0_H;
  Instructions[in_SET_0_L] := SET_0_L;
  Instructions[in_SET_0_HL_Indirect] := SET_0_HL_Indirect;
  Instructions[in_SET_0_A] := SET_0_A;
  Instructions[in_SET_1_B] := SET_1_B;
  Instructions[in_SET_1_C] := SET_1_C;
  Instructions[in_SET_1_D] := SET_1_D;
  Instructions[in_SET_1_E] := SET_1_E;
  Instructions[in_SET_1_H] := SET_1_H;
  Instructions[in_SET_1_L] := SET_1_L;
  Instructions[in_SET_1_HL_Indirect] := SET_1_HL_Indirect;
  Instructions[in_SET_1_A] := SET_1_A;
  Instructions[in_SET_2_B] := SET_2_B;
  Instructions[in_SET_2_C] := SET_2_C;
  Instructions[in_SET_2_D] := SET_2_D;
  Instructions[in_SET_2_E] := SET_2_E;
  Instructions[in_SET_2_H] := SET_2_H;
  Instructions[in_SET_2_L] := SET_2_L;
  Instructions[in_SET_2_HL_Indirect] := SET_2_HL_Indirect;
  Instructions[in_SET_2_A] := SET_2_A;
  Instructions[in_SET_3_B] := SET_3_B;
  Instructions[in_SET_3_C] := SET_3_C;
  Instructions[in_SET_3_D] := SET_3_D;
  Instructions[in_SET_3_E] := SET_3_E;
  Instructions[in_SET_3_H] := SET_3_H;
  Instructions[in_SET_3_L] := SET_3_L;
  Instructions[in_SET_3_HL_Indirect] := SET_3_HL_Indirect;
  Instructions[in_SET_3_A] := SET_3_A;
  Instructions[in_SET_4_B] := SET_4_B;
  Instructions[in_SET_4_C] := SET_4_C;
  Instructions[in_SET_4_D] := SET_4_D;
  Instructions[in_SET_4_E] := SET_4_E;
  Instructions[in_SET_4_H] := SET_4_H;
  Instructions[in_SET_4_L] := SET_4_L;
  Instructions[in_SET_4_HL_Indirect] := SET_4_HL_Indirect;
  Instructions[in_SET_4_A] := SET_4_A;
  Instructions[in_SET_5_B] := SET_5_B;
  Instructions[in_SET_5_C] := SET_5_C;
  Instructions[in_SET_5_D] := SET_5_D;
  Instructions[in_SET_5_E] := SET_5_E;
  Instructions[in_SET_5_H] := SET_5_H;
  Instructions[in_SET_5_L] := SET_5_L;
  Instructions[in_SET_5_HL_Indirect] := SET_5_HL_Indirect;
  Instructions[in_SET_5_A] := SET_5_A;
  Instructions[in_SET_6_B] := SET_6_B;
  Instructions[in_SET_6_C] := SET_6_C;
  Instructions[in_SET_6_D] := SET_6_D;
  Instructions[in_SET_6_E] := SET_6_E;
  Instructions[in_SET_6_H] := SET_6_H;
  Instructions[in_SET_6_L] := SET_6_L;
  Instructions[in_SET_6_HL_Indirect] := SET_6_HL_Indirect;
  Instructions[in_SET_6_A] := SET_6_A;
  Instructions[in_SET_7_B] := SET_7_B;
  Instructions[in_SET_7_C] := SET_7_C;
  Instructions[in_SET_7_D] := SET_7_D;
  Instructions[in_SET_7_E] := SET_7_E;
  Instructions[in_SET_7_H] := SET_7_H;
  Instructions[in_SET_7_L] := SET_7_L;
  Instructions[in_SET_7_HL_Indirect] := SET_7_HL_Indirect;
  Instructions[in_SET_7_A] := SET_7_A;
  Instructions[in_ADD_IX_BC] := ADD_IX_BC;
  Instructions[in_ADD_IX_DE] := ADD_IX_DE;
  Instructions[in_LD_IX_NN] := LD_IX_NN;
  Instructions[in_LD_NN_Indirect_IX] := LD_NN_Indirect_IX;
  Instructions[in_INC_IX] := INC_IX;
  Instructions[in_ADD_IX_IX] := ADD_IX_IX;
  Instructions[in_LD_IX_NN_Indirect] := LD_IX_NN_Indirect;
  Instructions[in_DEC_IX] := DEC_IX;
  Instructions[in_INC_IX_Plus_D_Indirect] := INC_IX_Plus_D_Indirect;
  Instructions[in_DEC_IX_Plus_D_Indirect] := DEC_IX_Plus_D_Indirect;
  Instructions[in_LD_IX_Plus_D_Indirect_N] := LD_IX_Plus_D_Indirect_N;
  Instructions[in_ADD_IX_SP] := ADD_IX_SP;
  Instructions[in_LD_B_IX_Plus_D_Indirect] := LD_B_IX_Plus_D_Indirect;
  Instructions[in_LD_C_IX_Plus_D_Indirect] := LD_C_IX_Plus_D_Indirect;
  Instructions[in_LD_D_IX_Plus_D_Indirect] := LD_D_IX_Plus_D_Indirect;
  Instructions[in_LD_E_IX_Plus_D_Indirect] := LD_E_IX_Plus_D_Indirect;
  Instructions[in_LD_H_IX_Plus_D_Indirect] := LD_H_IX_Plus_D_Indirect;
  Instructions[in_LD_L_IX_Plus_D_Indirect] := LD_L_IX_Plus_D_Indirect;
  Instructions[in_LD_IX_Plus_D_Indirect_B] := LD_IX_Plus_D_Indirect_B;
  Instructions[in_LD_IX_Plus_D_Indirect_C] := LD_IX_Plus_D_Indirect_C;
  Instructions[in_LD_IX_Plus_D_Indirect_D] := LD_IX_Plus_D_Indirect_D;
  Instructions[in_LD_IX_Plus_D_Indirect_E] := LD_IX_Plus_D_Indirect_E;
  Instructions[in_LD_IX_Plus_D_Indirect_H] := LD_IX_Plus_D_Indirect_H;
  Instructions[in_LD_IX_Plus_D_Indirect_L] := LD_IX_Plus_D_Indirect_L;
  Instructions[in_LD_IX_Plus_D_Indirect_A] := LD_IX_Plus_D_Indirect_A;
  Instructions[in_LD_A_IX_Plus_D_Indirect] := LD_A_IX_Plus_D_Indirect;
  Instructions[in_ADD_A_IX_Plus_D_Indirect] := ADD_A_IX_Plus_D_Indirect;
  Instructions[in_ADC_A_IX_Plus_D_Indirect] := ADC_A_IX_Plus_D_Indirect;
  Instructions[in_SUB_IX_Plus_D_Indirect] := SUB_IX_Plus_D_Indirect;
  Instructions[in_SBC_A_IX_Plus_D_Indirect] := SBC_A_IX_Plus_D_Indirect;
  Instructions[in_AND_IX_Plus_D_Indirect] := AND_IX_Plus_D_Indirect;
  Instructions[in_XOR_IX_Plus_D_Indirect] := XOR_IX_Plus_D_Indirect;
  Instructions[in_OR_IX_Plus_D_Indirect] := OR_IX_Plus_D_Indirect;
  Instructions[in_CP_IX_Plus_D_Indirect] := CP_IX_Plus_D_Indirect;
  Instructions[in_POP_IX] := POP_IX;
  Instructions[in_EX_SP_Indirect_IX] := EX_SP_Indirect_IX;
  Instructions[in_PUSH_IX] := PUSH_IX;
  Instructions[in_JP_IX_Indirect] := JP_IX_Indirect;
  Instructions[in_LD_SP_IX] := LD_SP_IX;
  Instructions[in_RLC_IX_Plus_D_Indirect] := RLC_IX_Plus_D_Indirect;
  Instructions[in_RRC_IX_Plus_D_Indirect] := RRC_IX_Plus_D_Indirect;
  Instructions[in_RL_IX_Plus_D_Indirect] := RL_IX_Plus_D_Indirect;
  Instructions[in_RR_IX_Plus_D_Indirect] := RR_IX_Plus_D_Indirect;
  Instructions[in_SLA_IX_Plus_D_Indirect] := SLA_IX_Plus_D_Indirect;
  Instructions[in_SRA_IX_Plus_D_Indirect] := SRA_IX_Plus_D_Indirect;
  Instructions[in_SRL_IX_Plus_D_Indirect] := SRL_IX_Plus_D_Indirect;
  Instructions[in_BIT_0_IX_Plus_D_Indirect] := BIT_0_IX_Plus_D_Indirect;
  Instructions[in_BIT_1_IX_Plus_D_Indirect] := BIT_1_IX_Plus_D_Indirect;
  Instructions[in_BIT_2_IX_Plus_D_Indirect] := BIT_2_IX_Plus_D_Indirect;
  Instructions[in_BIT_3_IX_Plus_D_Indirect] := BIT_3_IX_Plus_D_Indirect;
  Instructions[in_BIT_4_IX_Plus_D_Indirect] := BIT_4_IX_Plus_D_Indirect;
  Instructions[in_BIT_5_IX_Plus_D_Indirect] := BIT_5_IX_Plus_D_Indirect;
  Instructions[in_BIT_6_IX_Plus_D_Indirect] := BIT_6_IX_Plus_D_Indirect;
  Instructions[in_BIT_7_IX_Plus_D_Indirect] := BIT_7_IX_Plus_D_Indirect;
  Instructions[in_RES_0_IX_Plus_D_Indirect] := RES_0_IX_Plus_D_Indirect;
  Instructions[in_RES_1_IX_Plus_D_Indirect] := RES_1_IX_Plus_D_Indirect;
  Instructions[in_RES_2_IX_Plus_D_Indirect] := RES_2_IX_Plus_D_Indirect;
  Instructions[in_RES_3_IX_Plus_D_Indirect] := RES_3_IX_Plus_D_Indirect;
  Instructions[in_RES_4_IX_Plus_D_Indirect] := RES_4_IX_Plus_D_Indirect;
  Instructions[in_RES_5_IX_Plus_D_Indirect] := RES_5_IX_Plus_D_Indirect;
  Instructions[in_RES_6_IX_Plus_D_Indirect] := RES_6_IX_Plus_D_Indirect;
  Instructions[in_RES_7_IX_Plus_D_Indirect] := RES_7_IX_Plus_D_Indirect;
  Instructions[in_SET_0_IX_Plus_D_Indirect] := SET_0_IX_Plus_D_Indirect;
  Instructions[in_SET_1_IX_Plus_D_Indirect] := SET_1_IX_Plus_D_Indirect;
  Instructions[in_SET_2_IX_Plus_D_Indirect] := SET_2_IX_Plus_D_Indirect;
  Instructions[in_SET_3_IX_Plus_D_Indirect] := SET_3_IX_Plus_D_Indirect;
  Instructions[in_SET_4_IX_Plus_D_Indirect] := SET_4_IX_Plus_D_Indirect;
  Instructions[in_SET_5_IX_Plus_D_Indirect] := SET_5_IX_Plus_D_Indirect;
  Instructions[in_SET_6_IX_Plus_D_Indirect] := SET_6_IX_Plus_D_Indirect;
  Instructions[in_SET_7_IX_Plus_D_Indirect] := SET_7_IX_Plus_D_Indirect;
  Instructions[in_ADD_IY_BC] := ADD_IY_BC;
  Instructions[in_ADD_IY_DE] := ADD_IY_DE;
  Instructions[in_LD_IY_NN] := LD_IY_NN;
  Instructions[in_LD_NN_Indirect_IY] := LD_NN_Indirect_IY;
  Instructions[in_INC_IY] := INC_IY;
  Instructions[in_ADD_IY_IY] := ADD_IY_IY;
  Instructions[in_LD_IY_NN_Indirect] := LD_IY_NN_Indirect;
  Instructions[in_DEC_IY] := DEC_IY;
  Instructions[in_INC_IY_Plus_D_Indirect] := INC_IY_Plus_D_Indirect;
  Instructions[in_DEC_IY_Plus_D_Indirect] := DEC_IY_Plus_D_Indirect;
  Instructions[in_LD_IY_Plus_D_Indirect_N] := LD_IY_Plus_D_Indirect_N;
  Instructions[in_ADD_IY_SP] := ADD_IY_SP;
  Instructions[in_LD_B_IY_Plus_D_Indirect] := LD_B_IY_Plus_D_Indirect;
  Instructions[in_LD_C_IY_Plus_D_Indirect] := LD_C_IY_Plus_D_Indirect;
  Instructions[in_LD_D_IY_Plus_D_Indirect] := LD_D_IY_Plus_D_Indirect;
  Instructions[in_LD_E_IY_Plus_D_Indirect] := LD_E_IY_Plus_D_Indirect;
  Instructions[in_LD_H_IY_Plus_D_Indirect] := LD_H_IY_Plus_D_Indirect;
  Instructions[in_LD_L_IY_Plus_D_Indirect] := LD_L_IY_Plus_D_Indirect;
  Instructions[in_LD_IY_Plus_D_Indirect_B] := LD_IY_Plus_D_Indirect_B;
  Instructions[in_LD_IY_Plus_D_Indirect_C] := LD_IY_Plus_D_Indirect_C;
  Instructions[in_LD_IY_Plus_D_Indirect_D] := LD_IY_Plus_D_Indirect_D;
  Instructions[in_LD_IY_Plus_D_Indirect_E] := LD_IY_Plus_D_Indirect_E;
  Instructions[in_LD_IY_Plus_D_Indirect_H] := LD_IY_Plus_D_Indirect_H;
  Instructions[in_LD_IY_Plus_D_Indirect_L] := LD_IY_Plus_D_Indirect_L;
  Instructions[in_LD_IY_Plus_D_Indirect_A] := LD_IY_Plus_D_Indirect_A;
  Instructions[in_LD_A_IY_Plus_D_Indirect] := LD_A_IY_Plus_D_Indirect;
  Instructions[in_ADD_A_IY_Plus_D_Indirect] := ADD_A_IY_Plus_D_Indirect;
  Instructions[in_ADC_A_IY_Plus_D_Indirect] := ADC_A_IY_Plus_D_Indirect;
  Instructions[in_SUB_IY_Plus_D_Indirect] := SUB_IY_Plus_D_Indirect;
  Instructions[in_SBC_A_IY_Plus_D_Indirect] := SBC_A_IY_Plus_D_Indirect;
  Instructions[in_AND_IY_Plus_D_Indirect] := AND_IY_Plus_D_Indirect;
  Instructions[in_XOR_IY_Plus_D_Indirect] := XOR_IY_Plus_D_Indirect;
  Instructions[in_OR_IY_Plus_D_Indirect] := OR_IY_Plus_D_Indirect;
  Instructions[in_CP_IY_Plus_D_Indirect] := CP_IY_Plus_D_Indirect;
  Instructions[in_POP_IY] := POP_IY;
  Instructions[in_EX_SP_Indirect_IY] := EX_SP_Indirect_IY;
  Instructions[in_PUSH_IY] := PUSH_IY;
  Instructions[in_JP_IY_Indirect] := JP_IY_Indirect;
  Instructions[in_LD_SP_IY] := LD_SP_IY;
  Instructions[in_RLC_IY_Plus_D_Indirect] := RLC_IY_Plus_D_Indirect;
  Instructions[in_RRC_IY_Plus_D_Indirect] := RRC_IY_Plus_D_Indirect;
  Instructions[in_RL_IY_Plus_D_Indirect] := RL_IY_Plus_D_Indirect;
  Instructions[in_RR_IY_Plus_D_Indirect] := RR_IY_Plus_D_Indirect;
  Instructions[in_SLA_IY_Plus_D_Indirect] := SLA_IY_Plus_D_Indirect;
  Instructions[in_SRA_IY_Plus_D_Indirect] := SRA_IY_Plus_D_Indirect;
  Instructions[in_SRL_IY_Plus_D_Indirect] := SRL_IY_Plus_D_Indirect;
  Instructions[in_BIT_0_IY_Plus_D_Indirect] := BIT_0_IY_Plus_D_Indirect;
  Instructions[in_BIT_1_IY_Plus_D_Indirect] := BIT_1_IY_Plus_D_Indirect;
  Instructions[in_BIT_2_IY_Plus_D_Indirect] := BIT_2_IY_Plus_D_Indirect;
  Instructions[in_BIT_3_IY_Plus_D_Indirect] := BIT_3_IY_Plus_D_Indirect;
  Instructions[in_BIT_4_IY_Plus_D_Indirect] := BIT_4_IY_Plus_D_Indirect;
  Instructions[in_BIT_5_IY_Plus_D_Indirect] := BIT_5_IY_Plus_D_Indirect;
  Instructions[in_BIT_6_IY_Plus_D_Indirect] := BIT_6_IY_Plus_D_Indirect;
  Instructions[in_BIT_7_IY_Plus_D_Indirect] := BIT_7_IY_Plus_D_Indirect;
  Instructions[in_RES_0_IY_Plus_D_Indirect] := RES_0_IY_Plus_D_Indirect;
  Instructions[in_RES_1_IY_Plus_D_Indirect] := RES_1_IY_Plus_D_Indirect;
  Instructions[in_RES_2_IY_Plus_D_Indirect] := RES_2_IY_Plus_D_Indirect;
  Instructions[in_RES_3_IY_Plus_D_Indirect] := RES_3_IY_Plus_D_Indirect;
  Instructions[in_RES_4_IY_Plus_D_Indirect] := RES_4_IY_Plus_D_Indirect;
  Instructions[in_RES_5_IY_Plus_D_Indirect] := RES_5_IY_Plus_D_Indirect;
  Instructions[in_RES_6_IY_Plus_D_Indirect] := RES_6_IY_Plus_D_Indirect;
  Instructions[in_RES_7_IY_Plus_D_Indirect] := RES_7_IY_Plus_D_Indirect;
  Instructions[in_SET_0_IY_Plus_D_Indirect] := SET_0_IY_Plus_D_Indirect;
  Instructions[in_SET_1_IY_Plus_D_Indirect] := SET_1_IY_Plus_D_Indirect;
  Instructions[in_SET_2_IY_Plus_D_Indirect] := SET_2_IY_Plus_D_Indirect;
  Instructions[in_SET_3_IY_Plus_D_Indirect] := SET_3_IY_Plus_D_Indirect;
  Instructions[in_SET_4_IY_Plus_D_Indirect] := SET_4_IY_Plus_D_Indirect;
  Instructions[in_SET_5_IY_Plus_D_Indirect] := SET_5_IY_Plus_D_Indirect;
  Instructions[in_SET_6_IY_Plus_D_Indirect] := SET_6_IY_Plus_D_Indirect;
  Instructions[in_SET_7_IY_Plus_D_Indirect] := SET_7_IY_Plus_D_Indirect;
end;

procedure TCpuZ80.NOP;
begin
  // No operation
end;

procedure TCpuZ80.LD_BC_NN;
begin
  BC.Value := ReadWord;
end;

procedure TCpuZ80.LD_BC_Indirect_A;
begin
  DoWrite(BC.Value, AF.A);
end;

procedure TCpuZ80.INC_BC;
begin
  IncWord(BC.Value);
end;

procedure TCpuZ80.INC_B;
begin
  IncByte(BC.B);
end;

procedure TCpuZ80.DEC_B;
begin
  DecByte(BC.B);
end;

procedure TCpuZ80.LD_B_N;
begin
  BC.B := ReadByte;
end;

procedure TCpuZ80.RLCA;
begin
  RlcByte(AF.A);
end;

procedure TCpuZ80.EX_AF_AF_Pair;
var
  Temp: Word;
begin
  Temp := AF.Value;
  AF2.Value := AF.Value;
  AF.Value := Temp;
end;

procedure TCpuZ80.ADD_HL_BC;
begin
  AddWord(HL.Value, BC.Value);
end;

procedure TCpuZ80.LD_A_BC_Indirect;
begin
  AF.A := DoRead(BC.Value);
end;

procedure TCpuZ80.DEC_BC;
begin
  DecWord(BC.Value);
end;

procedure TCpuZ80.INC_C;
begin
  IncByte(BC.C);
end;

procedure TCpuZ80.DEC_C;
begin
  DecByte(BC.C);
end;

procedure TCpuZ80.LD_C_N;
begin
  BC.C := ReadByte;
end;

procedure TCpuZ80.RRCA;
begin
  RrcByte(AF.A);
end;

procedure TCpuZ80.DJNZ_D;
var
  Temp: ShortInt;
begin
  if BC.B = 0 then BC.B := $ff
    else Dec(BC.B);
  Temp := ShortInt(ReadByte);
  if BC.B <> 0 then
    PC := PC + Temp;
end;

procedure TCpuZ80.LD_DE_NN;
begin
  DE.Value := ReadWord;
end;

procedure TCpuZ80.LD_DE_Indirect_A;
begin
  DoWrite(DE.Value, AF.A);
end;

procedure TCpuZ80.INC_DE;
begin
  IncWord(DE.Value);
end;

procedure TCpuZ80.INC_D;
begin
  IncByte(DE.D);
end;

procedure TCpuZ80.DEC_D;
begin
  DecByte(DE.D);
end;

procedure TCpuZ80.LD_D_N;
begin
  DE.D := ReadByte;
end;

procedure TCpuZ80.RLA;
var
  NewCarry: Boolean;
begin
  NewCarry := (AF.A and $80) > 0;
  AF.A := (AF.A shl 1) or Byte(Carry);
  Carry := NewCarry;
end;

procedure TCpuZ80.JR_D;
begin
  Jr(True);
end;

procedure TCpuZ80.ADD_HL_DE;
begin
  AddWord(HL.Value, DE.Value);
end;

procedure TCpuZ80.LD_A_DE_Indirect;
begin
  AF.A := DoRead(DE.Value);
end;

procedure TCpuZ80.DEC_DE;
begin
  DecWord(DE.Value);
end;

procedure TCpuZ80.INC_E;
begin
  IncByte(DE.E);
end;

procedure TCpuZ80.DEC_E;
begin
  DecByte(DE.E);
end;

procedure TCpuZ80.LD_E_N;
begin
  DE.E := ReadByte;
end;

procedure TCpuZ80.RRA;
var
  NewCarry: Boolean;
begin
  NewCarry := (AF.A and 1) > 0;
  AF.A := (AF.A shr 1) or ($80 * Byte(Carry));
  Carry := NewCarry;
end;

procedure TCpuZ80.JR_NZ_D;
begin
  Jr(not Zero)
end;

procedure TCpuZ80.LD_HL_NN;
begin
  HL.Value := ReadWord;
end;

procedure TCpuZ80.LD_NN_Indirect_HL;
begin
  DoWriteWord(ReadWord, HL.Value);
end;

procedure TCpuZ80.INC_HL;
begin
  IncWord(HL.Value);
end;

procedure TCpuZ80.INC_H;
begin
  IncByte(HL.H);
end;

procedure TCpuZ80.DEC_H;
begin
  DecByte(HL.H);
end;

procedure TCpuZ80.LD_H_N;
begin
  HL.H := ReadByte;
end;

procedure TCpuZ80.DAA;
begin
  NotImplemented;
end;

procedure TCpuZ80.JR_Z_D;
begin
  Jr(Zero);
end;

procedure TCpuZ80.ADD_HL_HL;
begin
  AddWord(Hl.Value, HL.Value);
end;

procedure TCpuZ80.LD_HL_NN_Indirect;
begin
  HL.Value := DoReadWord(ReadWord);
end;

procedure TCpuZ80.DEC_HL;
begin
  DecWord(HL.Value);
end;

procedure TCpuZ80.INC_L;
begin
  IncByte(HL.L);
end;

procedure TCpuZ80.DEC_L;
begin
  DecByte(HL.L);
end;

procedure TCpuZ80.LD_L_N;
begin
  HL.L := ReadByte;
end;

procedure TCpuZ80.CPL;
begin
  AF.A := AF.A xor $ff;
end;

procedure TCpuZ80.JR_NC_D;
begin
  Jr(not Carry);
end;

procedure TCpuZ80.LD_SP_NN;
begin
  SP := ReadWord;
end;

procedure TCpuZ80.LD_NN_Indirect_A;
begin
  DoWrite(ReadWord, AF.A);
end;

procedure TCpuZ80.INC_SP;
begin
  IncWord(SP);
end;

procedure TCpuZ80.INC_HL_Indirect;
var
  Temp: Byte;
begin
  Temp := DoRead(HL.Value);
  IncByte(Temp);
  DoWrite(HL.Value, Temp);
end;

procedure TCpuZ80.DEC_HL_Indirect;
var
  Temp: Byte;
begin
  Temp := DoRead(HL.Value);
  DecByte(Temp);
  DoWrite(HL.Value, Temp);
end;

procedure TCpuZ80.LD_HL_Indirect_N;
begin
  DoWrite(HL.Value, ReadByte);
end;

procedure TCpuZ80.SCF;
begin
  Carry := True;
end;

procedure TCpuZ80.JR_C_D;
begin
  Jr(Carry);
end;

procedure TCpuZ80.ADD_HL_SP;
begin
  AddWord(HL.Value, SP);
end;

procedure TCpuZ80.LD_A_NN_Indirect;
begin
  AF.A := DoRead(ReadWord);
end;

procedure TCpuZ80.DEC_SP;
begin
  DecWord(SP);
end;

procedure TCpuZ80.INC_A;
begin
  IncByte(AF.A);
end;

procedure TCpuZ80.DEC_A;
begin
  DecByte(AF.A);
end;

procedure TCpuZ80.LD_A_N;
begin
  AF.A := ReadByte;
end;

procedure TCpuZ80.CCF;
begin
  Carry := not Carry;
end;

procedure TCpuZ80.LD_B_B;
begin
  BC.B := BC.B;
end;

procedure TCpuZ80.LD_B_C;
begin
  BC.B := BC.C;
end;

procedure TCpuZ80.LD_B_D;
begin
  BC.B := DE.D;
end;

procedure TCpuZ80.LD_B_E;
begin
  BC.B := DE.E;
end;

procedure TCpuZ80.LD_B_H;
begin
  BC.B := HL.H;
end;

procedure TCpuZ80.LD_B_L;
begin
  BC.B := HL.L;
end;

procedure TCpuZ80.LD_B_HL_Indirect;
begin
  BC.B := DoRead(HL.Value);
end;

procedure TCpuZ80.LD_B_A;
begin
  BC.B := AF.A;
end;

procedure TCpuZ80.LD_C_B;
begin
  BC.C := BC.B;
end;

procedure TCpuZ80.LD_C_C;
begin
  BC.C := BC.C;
end;

procedure TCpuZ80.LD_C_D;
begin
  BC.C := DE.D;
end;

procedure TCpuZ80.LD_C_E;
begin
  BC.C := DE.E;
end;

procedure TCpuZ80.LD_C_H;
begin
  BC.C := HL.H;
end;

procedure TCpuZ80.LD_C_L;
begin
  BC.C := HL.L;
end;

procedure TCpuZ80.LD_C_HL_Indirect;
begin
  BC.C := DoRead(HL.Value);
end;

procedure TCpuZ80.LD_C_A;
begin
  BC.C := AF.A;
end;

procedure TCpuZ80.LD_D_B;
begin
  DE.D := BC.B;
end;

procedure TCpuZ80.LD_D_C;
begin
  DE.D := BC.C;
end;

procedure TCpuZ80.LD_D_D;
begin
  DE.D := DE.D;
end;

procedure TCpuZ80.LD_D_E;
begin
  DE.D := DE.E;
end;

procedure TCpuZ80.LD_D_H;
begin
  DE.D := HL.H;
end;

procedure TCpuZ80.LD_D_L;
begin
  DE.D := HL.L;
end;

procedure TCpuZ80.LD_D_HL_Indirect;
begin
  DE.D := DoRead(HL.Value);
end;

procedure TCpuZ80.LD_D_A;
begin
  DE.D := AF.A;
end;

procedure TCpuZ80.LD_E_B;
begin
  DE.E := BC.B;
end;

procedure TCpuZ80.LD_E_C;
begin
  DE.E := BC.C;
end;

procedure TCpuZ80.LD_E_D;
begin
  DE.E := DE.D;
end;

procedure TCpuZ80.LD_E_E;
begin
  DE.E := DE.E;
end;

procedure TCpuZ80.LD_E_H;
begin
  DE.E := HL.H;
end;

procedure TCpuZ80.LD_E_L;
begin
  DE.E := HL.L;
end;

procedure TCpuZ80.LD_E_HL_Indirect;
begin
  DE.E := DoRead(HL.Value);
end;

procedure TCpuZ80.LD_E_A;
begin
  DE.E := AF.A;
end;

procedure TCpuZ80.LD_H_B;
begin
  HL.H := BC.B;
end;

procedure TCpuZ80.LD_H_C;
begin
  HL.H := BC.C;
end;

procedure TCpuZ80.LD_H_D;
begin
  HL.H := DE.D;
end;

procedure TCpuZ80.LD_H_E;
begin
  HL.H := DE.E;
end;

procedure TCpuZ80.LD_H_H;
begin
  HL.H := HL.H;
end;

procedure TCpuZ80.LD_H_L;
begin
  HL.H := HL.L;
end;

procedure TCpuZ80.LD_H_HL_Indirect;
begin
  HL.H := DoRead(HL.Value);
end;

procedure TCpuZ80.LD_H_A;
begin
  HL.H := AF.A;
end;

procedure TCpuZ80.LD_L_B;
begin
  HL.L := BC.B;
end;

procedure TCpuZ80.LD_L_C;
begin
  HL.L := BC.C;
end;

procedure TCpuZ80.LD_L_D;
begin
  HL.L := DE.D;
end;

procedure TCpuZ80.LD_L_E;
begin
  HL.L := DE.E;
end;

procedure TCpuZ80.LD_L_H;
begin
  HL.L := HL.H;
end;

procedure TCpuZ80.LD_L_L;
begin
  HL.L := HL.L;
end;

procedure TCpuZ80.LD_L_HL_Indirect;
begin
  HL.L := DoRead(HL.Value);
end;

procedure TCpuZ80.LD_L_A;
begin
  HL.L := AF.A;
end;

procedure TCpuZ80.LD_HL_Indirect_B;
begin
  DoWrite(HL.Value, BC.B);
end;

procedure TCpuZ80.LD_HL_Indirect_C;
begin
  DoWrite(HL.Value, BC.C);
end;

procedure TCpuZ80.LD_HL_Indirect_D;
begin
  DoWrite(HL.Value, DE.D);
end;

procedure TCpuZ80.LD_HL_Indirect_E;
begin
  DoWrite(HL.Value, DE.E);
end;

procedure TCpuZ80.LD_HL_Indirect_H;
begin
  DoWrite(HL.Value, HL.H);
end;

procedure TCpuZ80.LD_HL_Indirect_L;
begin
  DoWrite(HL.Value, HL.L);
end;

procedure TCpuZ80.HALT;
begin
  FThread.Terminate;
end;

procedure TCpuZ80.LD_HL_Indirect_A;
begin
  DoWrite(HL.Value, AF.A);
end;

procedure TCpuZ80.LD_A_B;
begin
  AF.A := BC.B;
end;

procedure TCpuZ80.LD_A_C;
begin
  AF.A := BC.C;
end;

procedure TCpuZ80.LD_A_D;
begin
  AF.A := DE.D;
end;

procedure TCpuZ80.LD_A_E;
begin
  AF.A := DE.E;
end;

procedure TCpuZ80.LD_A_H;
begin
  AF.A := HL.H;
end;

procedure TCpuZ80.LD_A_L;
begin
  AF.A := HL.L;
end;

procedure TCpuZ80.LD_A_HL_Indirect;
begin
  AF.A := DoRead(HL.Value);
end;

procedure TCpuZ80.LD_A_A;
begin
  AF.A := AF.A;
end;

procedure TCpuZ80.ADD_A_B;
begin
  AddByte(AF.A, BC.B);
end;

procedure TCpuZ80.ADD_A_C;
begin
  AddByte(AF.A, BC.C);
end;

procedure TCpuZ80.ADD_A_D;
begin
  AddByte(AF.A, DE.D);
end;

procedure TCpuZ80.ADD_A_E;
begin
  AddByte(AF.A, DE.E);
end;

procedure TCpuZ80.ADD_A_H;
begin
  AddByte(AF.A, HL.H);
end;

procedure TCpuZ80.ADD_A_L;
begin
  AddByte(AF.A, HL.L);
end;

procedure TCpuZ80.ADD_A_HL_Indirect;
begin
  AddByte(AF.A, DoRead(HL.Value));
end;

procedure TCpuZ80.ADD_A_A;
begin
  AddByte(AF.A, AF.A);
end;

procedure TCpuZ80.ADC_A_B;
begin
  AdcByte(AF.A, BC.B);
end;

procedure TCpuZ80.ADC_A_C;
begin
  AdcByte(AF.A, BC.C);
end;

procedure TCpuZ80.ADC_A_D;
begin
  AdcByte(AF.A, DE.D);
end;

procedure TCpuZ80.ADC_A_E;
begin
  AdcByte(AF.A, DE.E);
end;

procedure TCpuZ80.ADC_A_H;
begin
  AdcByte(AF.A, HL.H);
end;

procedure TCpuZ80.ADC_A_L;
begin
  AdcByte(AF.A, HL.L);
end;

procedure TCpuZ80.ADC_A_HL_Indirect;
begin
  AdcByte(AF.A, DoRead(HL.Value));
end;

procedure TCpuZ80.ADC_A_A;
begin
  AdcByte(AF.A, AF.A);
end;

procedure TCpuZ80.SUB_B;
begin
  SubByte(AF.A, BC.B);
end;

procedure TCpuZ80.SUB_C;
begin
  SubByte(AF.A, BC.C);
end;

procedure TCpuZ80.SUB_D;
begin
  SubByte(AF.A, DE.D);
end;

procedure TCpuZ80.SUB_E;
begin
  SubByte(AF.A, DE.E);
end;

procedure TCpuZ80.SUB_H;
begin
  SubByte(AF.A, HL.H);
end;

procedure TCpuZ80.SUB_L;
begin
  SubByte(AF.A, HL.L);
end;

procedure TCpuZ80.SUB_HL_Indirect;
begin
  SubByte(AF.A, DoRead(HL.Value));
end;

procedure TCpuZ80.SUB_A;
begin
  SubByte(AF.A, AF.A);
end;

procedure TCpuZ80.SBC_A_B;
begin
  SbcByte(AF.A, BC.B);
end;

procedure TCpuZ80.SBC_A_C;
begin
  SbcByte(AF.A, BC.C);
end;

procedure TCpuZ80.SBC_A_D;
begin
  SbcByte(AF.A, DE.D);
end;

procedure TCpuZ80.SBC_A_E;
begin
  SbcByte(AF.A, DE.E);
end;

procedure TCpuZ80.SBC_A_H;
begin
  SbcByte(AF.A, HL.H);
end;

procedure TCpuZ80.SBC_A_L;
begin
  SbcByte(AF.A, HL.L);
end;

procedure TCpuZ80.SBC_A_HL_Indirect;
begin
  SbcByte(AF.A, DoRead(HL.Value));
end;

procedure TCpuZ80.SBC_A_A;
begin
  SbcByte(AF.A, AF.A);
end;

procedure TCpuZ80.AND_B;
begin
  AndByte(AF.A, BC.B);
end;

procedure TCpuZ80.AND_C;
begin
  AndByte(AF.A, BC.C);
end;

procedure TCpuZ80.AND_D;
begin
  AndByte(AF.A, DE.D);
end;

procedure TCpuZ80.AND_E;
begin
  AndByte(AF.A, DE.E);
end;

procedure TCpuZ80.AND_H;
begin
  AndByte(AF.A, HL.H);
end;

procedure TCpuZ80.AND_L;
begin
  AndByte(AF.A, HL.L);
end;

procedure TCpuZ80.AND_HL_Indirect;
begin
  AndByte(AF.A, DoRead(HL.Value));
end;

procedure TCpuZ80.AND_A;
begin
  AndByte(AF.A, AF.A);
end;

procedure TCpuZ80.XOR_B;
begin
  XorByte(AF.A, BC.B);
end;

procedure TCpuZ80.XOR_C;
begin
  XorByte(AF.A, BC.C);
end;

procedure TCpuZ80.XOR_D;
begin
  XorByte(AF.A, DE.D);
end;

procedure TCpuZ80.XOR_E;
begin
  XorByte(AF.A, DE.E);
end;

procedure TCpuZ80.XOR_H;
begin
  XorByte(AF.A, HL.H);
end;

procedure TCpuZ80.XOR_L;
begin
  XorByte(AF.A, HL.L);
end;

procedure TCpuZ80.XOR_HL_Indirect;
begin
  XorByte(AF.A, DoRead(HL.Value));
end;

procedure TCpuZ80.XOR_A;
begin
  XorByte(AF.A, AF.A);
end;

procedure TCpuZ80.OR_B;
begin
  OrByte(AF.A, BC.B);
end;

procedure TCpuZ80.OR_C;
begin
  OrByte(AF.A, BC.C);
end;

procedure TCpuZ80.OR_D;
begin
  OrByte(AF.A, DE.D);
end;

procedure TCpuZ80.OR_E;
begin
  OrByte(AF.A, DE.E);
end;

procedure TCpuZ80.OR_H;
begin
  OrByte(AF.A, HL.H);
end;

procedure TCpuZ80.OR_L;
begin
  OrByte(AF.A, HL.L);
end;

procedure TCpuZ80.OR_HL_Indirect;
begin
  OrByte(AF.A, DoRead(HL.Value));
end;

procedure TCpuZ80.OR_A;
begin
  OrByte(AF.A, AF.A);
end;

procedure TCpuZ80.CP_B;
begin
  CpByte(BC.B);
end;

procedure TCpuZ80.CP_C;
begin
  CpByte(BC.C);
end;

procedure TCpuZ80.CP_D;
begin
  CpByte(DE.D);
end;

procedure TCpuZ80.CP_E;
begin
  CpByte(DE.E);
end;

procedure TCpuZ80.CP_H;
begin
  CpByte(HL.H);
end;

procedure TCpuZ80.CP_L;
begin
  CpByte(HL.L);
end;

procedure TCpuZ80.CP_HL_Indirect;
begin
  CpByte(DoRead(HL.Value));
end;

procedure TCpuZ80.CP_A;
begin
  CpByte(AF.A);
end;

procedure TCpuZ80.RET_NZ;
begin
  RetCond(not Zero);
end;

procedure TCpuZ80.POP_BC;
begin
  BC.Value := PopWord;
end;

procedure TCpuZ80.JP_NZ_NN;
begin
  Jp(not Zero);
end;

procedure TCpuZ80.JP_NN;
begin
  PC := ReadWord;
end;

procedure TCpuZ80.CALL_NZ_NN;
begin
  CallCond(ReadWord, not Zero);
end;

procedure TCpuZ80.PUSH_BC;
begin
  PushWord(BC.Value)
end;

procedure TCpuZ80.ADD_A_N;
begin
  AddByte(AF.A, ReadByte);
end;

procedure TCpuZ80.RST_00H;
begin
  Call($00);
end;

procedure TCpuZ80.RET_Z;
begin
  RetCond(Zero);
end;

procedure TCpuZ80.RET;
begin
  RetCond(True);
end;

procedure TCpuZ80.JP_Z_NN;
begin
  Jp(Zero);
end;

procedure TCpuZ80.CALL_Z_NN;
begin
  CallCond(ReadWord, Zero);
end;

procedure TCpuZ80.CALL_NN;
begin
  Call(ReadWord);
end;

procedure TCpuZ80.ADC_A_N;
begin
  AdcByte(AF.A, ReadByte);
end;

procedure TCpuZ80.RST_08H;
begin
  Call($08);
end;

procedure TCpuZ80.RET_NC;
begin
  RetCond(not Carry);
end;

procedure TCpuZ80.POP_DE;
begin
  DE.Value := PopWord;
end;

procedure TCpuZ80.JP_NC_NN;
begin
  Jp(not Carry);
end;

procedure TCpuZ80.OUT_N_Indirect_A;
begin
  DoOutput(ReadByte, AF.A);
end;

procedure TCpuZ80.CALL_NC_NN;
begin
  CallCond(ReadWord, not Carry);
end;

procedure TCpuZ80.PUSH_DE;
begin
  PushWord(DE.Value);
end;

procedure TCpuZ80.SUB_N;
begin
  SubByte(AF.A, ReadByte);
end;

procedure TCpuZ80.RST_10H;
begin
  Call($10);
end;

procedure TCpuZ80.RET_C;
begin
  RetCond(Carry);
end;

procedure TCpuZ80.EXX;
var
  Temp: Word;
begin
  Temp := BC.Value;
  BC.Value := BC2.Value;
  BC2.Value := Temp;
  Temp := DE.Value;
  DE2.Value := DE2.Value;
  DE2.Value := Temp;
  Temp := HL.Value;
  HL.Value := HL2.Value;
  HL2.Value := Temp;
end;

procedure TCpuZ80.JP_C_NN;
begin
  Jp(Carry);
end;

procedure TCpuZ80.IN_A_N_Indirect;
begin
  AF.A := DoInput((AF.A shl 8) or ReadByte);
end;

procedure TCpuZ80.CALL_C_NN;
begin
  CallCond(ReadWord, Carry);
end;

procedure TCpuZ80.SBC_A_N;
begin
  SbcByte(AF.A, ReadByte);
end;

procedure TCpuZ80.RST_18H;
begin
  Call($18);
end;

procedure TCpuZ80.RET_PO;
begin
  RetCond(not ParityOverflow);
end;

procedure TCpuZ80.POP_HL;
begin
  HL.Value := PopWord;
end;

procedure TCpuZ80.JP_PO_NN;
begin
  Jp(not ParityOverflow);
end;

procedure TCpuZ80.EX_SP_Indirect_HL;
var
  Temp: Word;
begin
  Temp := HL.Value;
  HL.Value := DoReadWord(SP);
  DoWriteWord(SP, Temp);
end;

procedure TCpuZ80.CALL_PO_NN;
begin
  CallCond(ReadWord, not ParityOverflow);
end;

procedure TCpuZ80.PUSH_HL;
begin
  PushWord(HL.Value);
end;

procedure TCpuZ80.AND_N;
begin
  AndByte(AF.A, ReadByte);
end;

procedure TCpuZ80.RST_20H;
begin
  Call($20);
end;

procedure TCpuZ80.RET_PE;
begin
  RetCond(ParityOverflow);
end;

procedure TCpuZ80.JP_HL_Indirect;
begin
  PC := DoRead(HL.Value);
end;

procedure TCpuZ80.JP_PE_NN;
begin
  Jp(ParityOverflow);
end;

procedure TCpuZ80.EX_DE_HL;
var
  TempWord: Word;
begin
  TempWord := DE.Value;
  DE.Value := HL.Value;
  HL.Value := TempWord;
end;

procedure TCpuZ80.CALL_PE_NN;
begin
  CallCond(ReadWord, ParityOverflow);
end;

procedure TCpuZ80.XOR_N;
begin
  XorByte(AF.A, ReadByte);
end;

procedure TCpuZ80.RST_28H;
begin
  Call($28);
end;

procedure TCpuZ80.RET_P;
begin
  RetCond(not SignNegative);
end;

procedure TCpuZ80.POP_AF;
begin
  AF.Value := PopWord;
end;

procedure TCpuZ80.JP_P_NN;
begin
  Jp(not SignNegative);
end;

procedure TCpuZ80.DI;
begin
  InterruptEnabled := False;
end;

procedure TCpuZ80.CALL_P_NN;
begin
  CallCond(ReadWord, not SignNegative);
end;

procedure TCpuZ80.PUSH_AF;
begin
  PushWord(AF.Value);
end;

procedure TCpuZ80.OR_N;
begin
  OrByte(AF.A, ReadByte);
end;

procedure TCpuZ80.RST_30H;
begin
  Call($30);
end;

procedure TCpuZ80.RET_M;
begin
  RetCond(SignNegative);
end;

procedure TCpuZ80.LD_SP_HL;
begin
  SP := HL.Value;
end;

procedure TCpuZ80.JP_M_NN;
begin
  Jp(SignNegative);
end;

procedure TCpuZ80.EI;
begin
  InterruptEnabled := True;
end;

procedure TCpuZ80.CALL_M_NN;
begin
  CallCond(ReadWord, SignNegative);
end;

procedure TCpuZ80.CP_N;
begin
  CpByte(ReadByte);
end;

procedure TCpuZ80.RST_38H;
begin
  Call($38);
end;

procedure TCpuZ80.IN_B_C_Indirect;
begin
  BC.B := DoInput(BC.Value);
end;

procedure TCpuZ80.OUT_C_Indirect_B;
begin
  BC.C := DoInput(BC.Value);
end;

procedure TCpuZ80.SBC_HL_BC;
begin
  SbcWord(HL.Value, BC.Value);
end;

procedure TCpuZ80.LD_NN_Indirect_BC;
begin
  DoWrite(ReadWord, BC.Value);
end;

procedure TCpuZ80.NEG;
begin
  ParityOverflow := AF.A = $80;
  Carry := AF.A <> $0;
  AF.A := AF.A xor $ff;
  IncByte(AF.A);
  SignNegative := (AF.A and $80) <> 1;
  Zero := AF.A = 0;
end;

procedure TCpuZ80.RETN;
begin
  InterruptEnabled := False;
  PC := PopWord;
end;

procedure TCpuZ80.IM_0;
begin
  InterruptMode := 0;
end;

procedure TCpuZ80.LD_I_A;
begin
  RegI := AF.A;
end;

procedure TCpuZ80.IN_C_C_Indirect;
begin
  BC.C := DoInput(BC.Value);
end;

procedure TCpuZ80.OUT_C_Indirect_C;
begin
  DoOutput(BC.Value, BC.C);
end;

procedure TCpuZ80.ADC_HL_BC;
begin
  AdcWord(HL.Value, BC.Value);
end;

procedure TCpuZ80.LD_BC_NN_Indirect;
begin
  BC.Value := DoReadWord(ReadWord);
end;

procedure TCpuZ80.RETI;
begin
  InterruptEnabled := False;
  PC := PopWord;
end;

procedure TCpuZ80.LD_R_A;
begin
  RegR := AF.A;
end;

procedure TCpuZ80.IN_D_C_Indirect;
begin
  DE.D := DoInput(BC.Value);
end;

procedure TCpuZ80.OUT_C_Indirect_D;
begin
  DoOutput(BC.Value, DE.D);
end;

procedure TCpuZ80.SBC_HL_DE;
begin
  SbcWord(HL.Value, DE.Value);
end;

procedure TCpuZ80.LD_NN_Indirect_DE;
begin
  DoWriteWord(ReadWord, DE.Value);
end;

procedure TCpuZ80.IM_1;
begin
  InterruptMode := 1;
end;

procedure TCpuZ80.LD_A_I;
begin
  AF.A := RegI;
end;

procedure TCpuZ80.IN_E_C_Indirect;
begin
  DE.E := DoInput(BC.Value);
end;

procedure TCpuZ80.OUT_C_Indirect_E;
begin
  DoOutput(BC.Value, DE.E);
end;

procedure TCpuZ80.ADC_HL_DE;
begin
  AdcWord(HL.Value, DE.Value);
end;

procedure TCpuZ80.LD_DE_NN_Indirect;
begin
  DE.Value := DoReadWord(ReadWord);
end;

procedure TCpuZ80.IM_2;
begin
  InterruptMode := 2;
end;

procedure TCpuZ80.LD_A_R;
begin
  AF.A := RegR;
end;

procedure TCpuZ80.IN_H_C_Indirect;
begin
  HL.H := DoInput(BC.Value);
end;

procedure TCpuZ80.OUT_C_Indirect_H;
begin
  DoOutput(BC.Value, HL.H);
end;

procedure TCpuZ80.SBC_HL_HL;
begin
  SbcWord(HL.Value, HL.Value);
end;

procedure TCpuZ80.RRD;
begin
  NotImplemented;
end;

procedure TCpuZ80.IN_L_C_Indirect;
begin
  HL.L := DoInput(BC.Value);
end;

procedure TCpuZ80.OUT_C_Indirect_L;
begin
  DoOutput(BC.Value, HL.L);
end;

procedure TCpuZ80.ADC_HL_HL;
begin
  AdcWord(HL.Value, HL.Value);
end;

procedure TCpuZ80.RLD;
begin
  NotImplemented;
end;

procedure TCpuZ80.SBC_HL_SP;
begin
  SbcWord(HL.Value, SP);
end;

procedure TCpuZ80.LD_NN_Indirect_SP;
begin
  DoWriteWord(ReadWord, SP);
end;

procedure TCpuZ80.IN_A_C_Indirect;
begin
  AF.A := DoInput(BC.Value);
end;

procedure TCpuZ80.OUT_C_Indirect_A;
begin
  DoOutput(BC.Value, AF.A);
end;

procedure TCpuZ80.ADC_HL_SP;
begin
  AdcWord(Hl.Value, SP);
end;

procedure TCpuZ80.LD_SP_NN_Indirect;
begin
  SP := DoReadWord(ReadWord);
end;

procedure TCpuZ80.LDI;
begin
  DoWrite(DE.Value, DoRead(HL.Value));
  IncWord(HL.Value);
  IncWord(DE.Value);
  DecWord(BC.Value);
end;

procedure TCpuZ80.CPI;
begin
  CpByte(DoRead(HL.Value));
  IncWord(HL.Value);
  DecWord(BC.Value);
end;

procedure TCpuZ80.INI;
begin
  DoWrite(HL.Value, DoInput(BC.Value));
  DecByte(BC.B);
  IncWord(HL.Value);
end;

procedure TCpuZ80.OUTI;
begin
  DoOutput(BC.Value, DoRead(HL.Value));
  DecByte(BC.B);
  IncWord(HL.Value);
end;

procedure TCpuZ80.LDD;
begin
  DoWrite(DE.Value, DoRead(HL.Value));
  DecWord(HL.Value);
  DecWord(DE.Value);
  DecWord(BC.Value);
end;

procedure TCpuZ80.CPD;
begin
  CpByte(DoRead(HL.Value));
  DecWord(HL.Value);
  DecWord(BC.Value);
end;

procedure TCpuZ80.IND;
begin
  DoWrite(HL.Value, DoInput(BC.Value));
  DecByte(BC.B);
  DecWord(HL.Value);
end;

procedure TCpuZ80.OUTD;
begin
  DoOutput(BC.Value, DoRead(HL.Value));
  DecByte(BC.B);
  DecWord(HL.Value);
end;

procedure TCpuZ80.LDIR;
begin
  repeat
    LDI;
  until BC.Value = 0;
end;

procedure TCpuZ80.CPIR;
begin
  repeat
    CPI;
  until (BC.Value = 0) or Zero;
end;

procedure TCpuZ80.INIR;
begin
  repeat
    INI;
  until (BC.B = 0);
end;

procedure TCpuZ80.OTIR;
begin
  repeat
    OUTI;
  until BC.B = 0;
end;

procedure TCpuZ80.LDDR;
begin
  repeat
    LDD;
  until BC.Value = 0;
end;

procedure TCpuZ80.CPDR;
begin
  repeat
    CPD;
  until (BC.Value = 0) or Zero;
end;

procedure TCpuZ80.INDR;
begin
  repeat
    IND;
  until (BC.B = 0);
end;

procedure TCpuZ80.OTDR;
begin
  repeat
    OUTD;
  until BC.B = 0;
end;

procedure TCpuZ80.RLC_B;
begin
  RlcByte(BC.B);
end;

procedure TCpuZ80.RLC_C;
begin
  RlcByte(BC.C);
end;

procedure TCpuZ80.RLC_D;
begin
  RlcByte(DE.D);
end;

procedure TCpuZ80.RLC_E;
begin
  RlcByte(DE.E);
end;

procedure TCpuZ80.RLC_H;
begin
  RlcByte(HL.H);
end;

procedure TCpuZ80.RLC_L;
begin
  RlcByte(HL.L);
end;

procedure TCpuZ80.RLC_HL_Indirect;
var
  Temp: Byte;
begin
  Temp := DoRead(HL.Value);
  RlcByte(Temp);
  DoWrite(HL.Value, Temp);
end;

procedure TCpuZ80.RLC_A;
begin
  RlcByte(AF.A);
end;

procedure TCpuZ80.RRC_B;
begin
  RrcByte(BC.B);
end;

procedure TCpuZ80.RRC_C;
begin
  RrcByte(BC.C);
end;

procedure TCpuZ80.RRC_D;
begin
  RrcByte(DE.D);
end;

procedure TCpuZ80.RRC_E;
begin
  RrcByte(DE.E);
end;

procedure TCpuZ80.RRC_H;
begin
  RrcByte(HL.H);
end;

procedure TCpuZ80.RRC_L;
begin
  RrcByte(HL.L);
end;

procedure TCpuZ80.RRC_HL_Indirect;
var
  Temp: Byte;
begin
  Temp := DoRead(HL.Value);
  RrcByte(Temp);
  DoWrite(HL.Value, Temp);
end;

procedure TCpuZ80.RRC_A;
begin
  RrcByte(AF.A);
end;

procedure TCpuZ80.RL_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.RL_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.RL_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.RL_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.RL_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.RL_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.RL_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RL_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.RR_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.RR_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.RR_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.RR_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.RR_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.RR_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.RR_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RR_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.SLA_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.SLA_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.SLA_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.SLA_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.SLA_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.SLA_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.SLA_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SLA_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRA_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRA_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRA_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRA_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRA_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRA_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRA_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRA_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRL_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRL_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRL_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRL_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRL_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRL_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRL_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRL_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_0_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_0_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_0_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_0_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_0_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_0_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_0_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_0_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_1_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_1_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_1_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_1_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_1_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_1_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_1_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_1_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_2_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_2_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_2_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_2_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_2_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_2_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_2_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_2_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_3_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_3_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_3_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_3_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_3_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_3_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_3_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_3_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_4_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_4_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_4_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_4_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_4_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_4_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_4_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_4_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_5_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_5_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_5_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_5_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_5_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_5_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_5_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_5_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_6_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_6_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_6_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_6_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_6_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_6_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_6_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_6_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_7_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_7_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_7_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_7_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_7_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_7_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_7_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_7_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_0_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_0_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_0_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_0_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_0_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_0_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_0_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_0_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_1_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_1_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_1_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_1_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_1_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_1_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_1_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_1_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_2_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_2_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_2_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_2_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_2_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_2_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_2_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_2_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_3_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_3_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_3_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_3_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_3_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_3_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_3_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_3_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_4_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_4_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_4_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_4_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_4_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_4_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_4_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_4_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_5_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_5_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_5_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_5_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_5_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_5_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_5_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_5_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_6_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_6_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_6_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_6_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_6_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_6_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_6_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_6_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_7_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_7_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_7_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_7_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_7_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_7_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_7_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_7_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_0_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_0_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_0_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_0_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_0_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_0_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_0_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_0_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_1_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_1_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_1_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_1_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_1_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_1_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_1_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_1_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_2_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_2_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_2_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_2_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_2_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_2_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_2_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_2_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_3_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_3_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_3_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_3_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_3_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_3_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_3_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_3_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_4_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_4_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_4_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_4_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_4_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_4_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_4_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_4_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_5_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_5_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_5_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_5_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_5_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_5_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_5_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_5_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_6_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_6_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_6_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_6_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_6_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_6_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_6_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_6_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_7_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_7_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_7_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_7_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_7_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_7_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_7_HL_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_7_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.ADD_IX_BC;
begin
  NotImplemented;
end;

procedure TCpuZ80.ADD_IX_DE;
begin
  AddWord(IX, DE.Value);
end;

procedure TCpuZ80.LD_IX_NN;
begin
  IX := ReadWord;
end;

procedure TCpuZ80.LD_NN_Indirect_IX;
begin
  NotImplemented;
end;

procedure TCpuZ80.INC_IX;
begin
  IncWord(IX);
end;

procedure TCpuZ80.ADD_IX_IX;
begin
  AddWord(IX, IX);
end;

procedure TCpuZ80.LD_IX_NN_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.DEC_IX;
begin
  NotImplemented;
end;

procedure TCpuZ80.INC_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.DEC_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IX_Plus_D_Indirect_N;
begin
  NotImplemented;
end;

procedure TCpuZ80.ADD_IX_SP;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_B_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_C_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_D_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_E_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_H_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_L_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IX_Plus_D_Indirect_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IX_Plus_D_Indirect_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IX_Plus_D_Indirect_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IX_Plus_D_Indirect_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IX_Plus_D_Indirect_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IX_Plus_D_Indirect_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IX_Plus_D_Indirect_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_A_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.ADD_A_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.ADC_A_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SUB_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SBC_A_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.AND_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.XOR_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.OR_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.CP_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.POP_IX;
begin
  NotImplemented;
end;

procedure TCpuZ80.EX_SP_Indirect_IX;
begin
  NotImplemented;
end;

procedure TCpuZ80.PUSH_IX;
begin
  NotImplemented;
end;

procedure TCpuZ80.JP_IX_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_SP_IX;
begin
  NotImplemented;
end;

procedure TCpuZ80.RLC_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RRC_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RL_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RR_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SLA_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRA_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRL_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_0_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_1_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_2_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_3_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_4_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_5_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_6_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_7_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_0_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_1_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_2_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_3_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_4_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_5_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_6_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_7_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_0_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_1_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_2_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_3_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_4_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_5_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_6_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_7_IX_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.ADD_IY_BC;
begin
  NotImplemented;
end;

procedure TCpuZ80.ADD_IY_DE;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IY_NN;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_NN_Indirect_IY;
begin
  NotImplemented;
end;

procedure TCpuZ80.INC_IY;
begin
  NotImplemented;
end;

procedure TCpuZ80.ADD_IY_IY;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IY_NN_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.DEC_IY;
begin
  NotImplemented;
end;

procedure TCpuZ80.INC_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.DEC_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IY_Plus_D_Indirect_N;
begin
  NotImplemented;
end;

procedure TCpuZ80.ADD_IY_SP;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_B_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_C_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_D_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_E_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_H_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_L_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IY_Plus_D_Indirect_B;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IY_Plus_D_Indirect_C;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IY_Plus_D_Indirect_D;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IY_Plus_D_Indirect_E;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IY_Plus_D_Indirect_H;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IY_Plus_D_Indirect_L;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_IY_Plus_D_Indirect_A;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_A_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.ADD_A_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.ADC_A_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SUB_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SBC_A_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.AND_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.XOR_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.OR_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.CP_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.POP_IY;
begin
  NotImplemented;
end;

procedure TCpuZ80.EX_SP_Indirect_IY;
begin
  NotImplemented;
end;

procedure TCpuZ80.PUSH_IY;
begin
  NotImplemented;
end;

procedure TCpuZ80.JP_IY_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.LD_SP_IY;
begin
  NotImplemented;
end;

procedure TCpuZ80.RLC_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RRC_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RL_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RR_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SLA_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRA_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SRL_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_0_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_1_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_2_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_3_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_4_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_5_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_6_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.BIT_7_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_0_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_1_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_2_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_3_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_4_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_5_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_6_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.RES_7_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_0_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_1_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_2_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_3_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_4_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_5_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_6_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.SET_7_IY_Plus_D_Indirect;
begin
  NotImplemented;
end;

procedure TCpuZ80.Step;
var
  Opcode: Byte;
  Proc: TBaseEvent;
begin
  InstructionAddress := PC;
  Opcode := ReadByte;
  if Opcode = $CB then begin
    Opcode := ReadByte;
    Instruction := TInstruction($100 or ReadByte);
  end
  else if Opcode = $DD then begin
    Opcode := ReadByte;
    if Opcode = $CB then begin
      Opcode := ReadByte;
      Instruction := TInstruction($500 or Opcode);
    end else Instruction := TInstruction($200 or Opcode);
  end
  else if Opcode = $ED then begin
    Opcode := ReadByte;
    Instruction := TInstruction($300 or Opcode);
  end
  else if Opcode = $FD then begin
    Opcode := ReadByte;
    if Opcode = $CB then begin
      Opcode := ReadByte;
      Instruction := TInstruction($600 or Opcode);
    end else Instruction := TInstruction($400 or Opcode);
  end
  else Instruction := TInstruction(Opcode);

  Proc := Instructions[Instruction];
  if Assigned(Proc) then Proc
  else begin
    Error('Unsupported instruction ' + IntToHex(Word(Instruction), 4));
  end;
  Ticks := Cardinal(Ticks + 1);
  DoOnStep;
end;

procedure TCpuZ80.Reset;
begin
  PC := 0;
  SP := 0;
  IX := 0;
  IY := 0;
  AF.Value := 0;
  BC.Value := 0;
  DE.Value := 0;
  HL.Value := 0;
  InterruptEnabled := True;
  InterruptMode := 0;
  Ticks := 0;
end;

constructor TCpuZ80.Create;
begin
  FRunning := False;
  FPaused := False;
  FEvent := TEvent.Create(nil, True, True, '');
  InitInstructions;
  Reset;
end;

destructor TCpuZ80.Destroy;
begin
  Running := False;
  FreeAndNil(FEvent);
  inherited;
end;

end.

