// This file is part of the Noddybox.Emulation C# suite. // // Noddybox.Emulation is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Noddybox.Emulation is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Noddybox.Emulation. If not, see . // // Copyright (c) 2012 Ian Cowburn // using System; using System.Text; namespace Noddybox.Emulation.EightBit.Z80.Disassembler { /// /// Provides an implementation of a Zilog Z80 disassembler. /// public class Z80Disassembler : IDisassembler { #region Private data private IMemory memory; private sbyte cb_off; private readonly string[] z80_dis_reg8 = new string[] {"b","c","d","e","h","l","(hl)","a"}; private readonly string[] z80_dis_reg16 = new string[] {"bc","de","hl","sp"}; private readonly string[] z80_dis_condition = new string[] {"nz","z","nc","c","po","pe","p","m"}; private delegate void disassemble(byte opcode, ref ushort address); private disassemble[] dis_CB_opcode; private disassemble[] dis_DD_opcode; private disassemble[] dis_DD_CB_opcode; private disassemble[] dis_ED_opcode; private disassemble[] dis_FD_opcode; private disassemble[] dis_FD_CB_opcode; private disassemble[] dis_opcode_z80; #endregion #region Private routines to support the original C code. private byte Z80_Dis_FetchByte(ref ushort addr) { byte b = memory.Read(addr++); if (Hex.Length > 0) { Hex.Append(" "); } Hex.AppendFormat("{0:x2}", b); return b; } private ushort Z80_Dis_FetchWord(ref ushort addr) { Register16 r = new Register16(0); r.low = Z80_Dis_FetchByte(ref addr); r.high = Z80_Dis_FetchByte(ref addr); return r.reg; } private string Opcode {get; set;} private string Argument {get; set;} private StringBuilder Hex {get; set;} private void Z80_Dis_Set(string a, string b) { Opcode = a; Argument = b; } private string PopString(string s, int count) { if (s.Length <= count) { return String.Empty; } else { return s.Substring(count); } } private string Z80_Dis_Printf(string fmt, params object[] o) { StringBuilder sb = new StringBuilder(); int arg = 0; while(fmt.Length > 0) { if (fmt[0] == '%') { if (fmt[1] == 'd' || fmt[1] == 's') { sb.Append("{"); sb.AppendFormat("{0}", arg++); sb.Append("}"); fmt = PopString(fmt, 2); } else if (fmt.StartsWith("%.2x")) { sb.Append("{"); sb.AppendFormat("{0}:x2", arg++); sb.Append("}"); fmt = PopString(fmt, 4); } else if (fmt.StartsWith("%.4x")) { sb.Append("{"); sb.AppendFormat("{0}:x4", arg++); sb.Append("}"); fmt = PopString(fmt, 4); } else { sb.Append(fmt[0]); fmt = PopString(fmt, 1); } } else { sb.Append(fmt[0]); fmt = PopString(fmt, 1); } } return String.Format(sb.ToString(), o); } #endregion #region Disassembler functions. This code pretty much pasted as-is from my original C version, with support routines to help. /* ---------------------------------------- CB xx BYTE OPCODES */ private void DIS_RLC_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("rlc", reg); } private void DIS_RRC_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("rrc", reg); } private void DIS_RL_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("rl", reg); } private void DIS_RR_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("rr", reg); } private void DIS_SLA_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("sla", reg); } private void DIS_SRA_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("sra", reg); } private void DIS_SLL_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("sll", reg); } private void DIS_SRL_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("srl", reg); } private void DIS_BIT_R8(byte op, ref ushort pc) { string reg; int bit; reg = z80_dis_reg8[op % 8]; bit = (op - 0x40) / 8; Z80_Dis_Set("bit", Z80_Dis_Printf("%d,%s", bit, reg)); } private void DIS_RES_R8(byte op, ref ushort pc) { string reg; int bit; reg = z80_dis_reg8[op % 8]; bit = (op - 0x80) / 8; Z80_Dis_Set("res", Z80_Dis_Printf("%d,%s", bit, reg)); } private void DIS_SET_R8(byte op, ref ushort pc) { string reg; int bit; reg = z80_dis_reg8[op % 8]; bit = (op - 0xc0) / 8; Z80_Dis_Set("set", Z80_Dis_Printf("%d,%s", bit, reg)); } /* ---------------------------------------- DD OPCODES */ string IX_RelStr(byte op, ref ushort pc) { sbyte r; r=(sbyte)Z80_Dis_FetchByte(ref pc); if (r<0) return String.Format("(ix-{0:x2})",-r); else return String.Format("(ix+{0:x2})", r); } string IX_RelStrCB(byte op, ref ushort pc) { sbyte r; r=(sbyte)cb_off; if (r<0) return String.Format("(ix-{0:x2})",-r); else return String.Format("(ix+{0:x2})", r); } string XR8(int reg, ref ushort pc) { switch (reg) { case 0: return ("b"); case 1: return ("c"); case 2: return ("d"); case 3: return ("e"); case 4: return ("ixh"); case 5: return ("ixl"); case 6: return (IX_RelStr(0, ref pc)); case 7: return ("a"); default: return String.Format("BUG {0}", reg); } } private void DIS_DD_NOP(byte op, ref ushort pc) { dis_opcode_z80[op](op, ref pc); } private void DIS_ADD_IX_BC(byte op, ref ushort pc) { Z80_Dis_Set("add", "ix,bc"); } private void DIS_ADD_IX_DE(byte op, ref ushort pc) { Z80_Dis_Set("add", "ix,de"); } private void DIS_LD_IX_WORD(byte op, ref ushort pc) { Z80_Dis_Set("ld", Z80_Dis_Printf("ix,$%.4x", Z80_Dis_FetchWord(ref pc))); } private void DIS_LD_ADDR_IX(byte op, ref ushort pc) { ushort w; w = Z80_Dis_FetchWord(ref pc); Z80_Dis_Set("ld", Z80_Dis_Printf("($%.4x),ix", w)); } private void DIS_INC_IX(byte op, ref ushort pc) { Z80_Dis_Set("inc", "ix"); } private void DIS_INC_IXH(byte op, ref ushort pc) { Z80_Dis_Set("inc", "ixh"); } private void DIS_DEC_IXH(byte op, ref ushort pc) { Z80_Dis_Set("dec", "ixh"); } private void DIS_LD_IXH_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("ld", Z80_Dis_Printf("ixh,$%.2x", Z80_Dis_FetchByte(ref pc))); } private void DIS_ADD_IX_IX(byte op, ref ushort pc) { Z80_Dis_Set("add", "ix,ix"); } private void DIS_LD_IX_ADDR(byte op, ref ushort pc) { ushort w; w = Z80_Dis_FetchWord(ref pc); Z80_Dis_Set("ld", Z80_Dis_Printf("ix,($%.4x)", w)); } private void DIS_DEC_IX(byte op, ref ushort pc) { Z80_Dis_Set("dec", "ix"); } private void DIS_INC_IXL(byte op, ref ushort pc) { Z80_Dis_Set("inc", "ixl"); } private void DIS_DEC_IXL(byte op, ref ushort pc) { Z80_Dis_Set("dec", "ixl"); } private void DIS_LD_IXL_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("ld", Z80_Dis_Printf("ixl,$%.2x", Z80_Dis_FetchByte(ref pc))); } private void DIS_INC_IIX(byte op, ref ushort pc) { Z80_Dis_Set("inc", Z80_Dis_Printf("%s", IX_RelStr(op, ref pc))); } private void DIS_DEC_IIX(byte op, ref ushort pc) { Z80_Dis_Set("dec", Z80_Dis_Printf("%s", IX_RelStr(op, ref pc))); } private void DIS_LD_IIX_BYTE(byte op, ref ushort pc) { string rel; int b; rel = IX_RelStr(op, ref pc); b = Z80_Dis_FetchByte(ref pc); Z80_Dis_Set("ld", Z80_Dis_Printf("%s,$%.2x", rel, b)); } private void DIS_ADD_IX_SP(byte op, ref ushort pc) { Z80_Dis_Set("add", "ix,sp"); } private void DIS_XLD_R8_R8(byte op, ref ushort pc) { int src_r,dest_r; string src,dest; dest_r=(op-0x40)/8; src_r=op%8; /* IX can't be used as source and destination when reading z80ory */ if (dest_r==6) { dest=XR8(dest_r, ref pc); src=z80_dis_reg8[src_r]; } else if (((dest_r==4)||(dest_r==5))&&(src_r==6)) { dest=z80_dis_reg8[dest_r]; src = XR8(src_r, ref pc); } else { dest = XR8(dest_r, ref pc); src = XR8(src_r, ref pc); } Z80_Dis_Set("ld",Z80_Dis_Printf("%s,%s",dest,src)); } private void DIS_XADD_R8(byte op, ref ushort pc) { Z80_Dis_Set("add", Z80_Dis_Printf("a,%s", XR8((op % 8), ref pc))); } private void DIS_XADC_R8(byte op, ref ushort pc) { Z80_Dis_Set("adc", Z80_Dis_Printf("a,%s", XR8((op % 8), ref pc))); } private void DIS_XSUB_R8(byte op, ref ushort pc) { Z80_Dis_Set("sub", Z80_Dis_Printf("a,%s", XR8((op % 8), ref pc))); } private void DIS_XSBC_R8(byte op, ref ushort pc) { Z80_Dis_Set("sbc", Z80_Dis_Printf("a,%s", XR8((op % 8), ref pc))); } private void DIS_XAND_R8(byte op, ref ushort pc) { Z80_Dis_Set("and", Z80_Dis_Printf("%s", XR8((op % 8), ref pc))); } private void DIS_XXOR_R8(byte op, ref ushort pc) { Z80_Dis_Set("xor", Z80_Dis_Printf("%s", XR8((op % 8), ref pc))); } private void DIS_X_OR_R8(byte op, ref ushort pc) { Z80_Dis_Set("or", Z80_Dis_Printf("%s", XR8((op % 8), ref pc))); } private void DIS_XCP_R8(byte op, ref ushort pc) { Z80_Dis_Set("cp", Z80_Dis_Printf("%s", XR8((op % 8), ref pc))); } private void DIS_POP_IX(byte op, ref ushort pc) { Z80_Dis_Set("pop", "ix"); } private void DIS_EX_ISP_IX(byte op, ref ushort pc) { Z80_Dis_Set("ex", "(sp),ix"); } private void DIS_PUSH_IX(byte op, ref ushort pc) { Z80_Dis_Set("push", "ix"); } private void DIS_JP_IX(byte op, ref ushort pc) { Z80_Dis_Set("jp", "(ix)"); } private void DIS_LD_SP_IX(byte op, ref ushort pc) { Z80_Dis_Set("ld", "sp,ix"); } private void DIS_DD_CB_DECODE(byte op, ref ushort pc) { byte nop; cb_off = (sbyte)Z80_Dis_FetchByte(ref pc); nop = Z80_Dis_FetchByte(ref pc); dis_DD_CB_opcode[nop](nop, ref pc); } private void DIS_DD_DD_DECODE(byte op, ref ushort pc) { byte nop; nop = Z80_Dis_FetchByte(ref pc); dis_DD_opcode[nop](nop, ref pc); } private void DIS_DD_ED_DECODE(byte op, ref ushort pc) { byte nop; nop = Z80_Dis_FetchByte(ref pc); dis_ED_opcode[nop](nop, ref pc); } private void DIS_DD_FD_DECODE(byte op, ref ushort pc) { byte nop; nop = Z80_Dis_FetchByte(ref pc); dis_FD_opcode[nop](nop, ref pc); } /* ---------------------------------------- DD CB OPCODES */ private void DIS_RLC_IX(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("rlc", Z80_Dis_Printf("%s", IX_RelStrCB(op, ref pc))); else { Z80_Dis_Set("rlc", Z80_Dis_Printf("%s[%s]", IX_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } } private void DIS_RRC_IX(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("rrc", Z80_Dis_Printf("%s", IX_RelStrCB(op, ref pc))); else Z80_Dis_Set("rrc", Z80_Dis_Printf("%s[%s]", IX_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_RL_IX(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("rl", Z80_Dis_Printf("%s", IX_RelStrCB(op, ref pc))); else Z80_Dis_Set("rl", Z80_Dis_Printf("%s[%s]", IX_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_RR_IX(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("rr", Z80_Dis_Printf("%s", IX_RelStrCB(op, ref pc))); else Z80_Dis_Set("rr", Z80_Dis_Printf("%s[%s]", IX_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_SLA_IX(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("sla", Z80_Dis_Printf("%s", IX_RelStrCB(op, ref pc))); else Z80_Dis_Set("sla", Z80_Dis_Printf("%s[%s]", IX_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_SRA_IX(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("sra", Z80_Dis_Printf("%s", IX_RelStrCB(op, ref pc))); else Z80_Dis_Set("sra", Z80_Dis_Printf("%s[%s]", IX_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_SRL_IX(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("srl", Z80_Dis_Printf("%s", IX_RelStrCB(op, ref pc))); else Z80_Dis_Set("srl", Z80_Dis_Printf("%s[%s]", IX_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_SLL_IX(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("sll", Z80_Dis_Printf("%s", IX_RelStrCB(op, ref pc))); else Z80_Dis_Set("sll", Z80_Dis_Printf("%s[%s]", IX_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_BIT_IX(byte op, ref ushort pc) { int bit; bit = (op - 0x40) / 8; Z80_Dis_Set("bit", Z80_Dis_Printf("%d,%s", bit, IX_RelStrCB(op, ref pc))); } private void DIS_RES_IX(byte op, ref ushort pc) { int reg; int bit; reg = (op % 8); bit = (op - 0x80) / 8; if (reg == 6) Z80_Dis_Set("res", Z80_Dis_Printf("%d,%s", bit, IX_RelStrCB(op, ref pc))); else Z80_Dis_Set("res", Z80_Dis_Printf("%d,%s[%s]", bit, IX_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_SET_IX(byte op, ref ushort pc) { int reg; int bit; reg = (op % 8); bit = (op - 0xc0) / 8; if (reg == 6) Z80_Dis_Set("set", Z80_Dis_Printf("%d,%s", bit, IX_RelStrCB(op, ref pc))); else Z80_Dis_Set("set", Z80_Dis_Printf("%d,%s[%s]", bit, IX_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } /* ---------------------------------------- ED OPCODES */ string ER8(int reg) { switch (reg) { case 0: return ("b"); case 1: return ("c"); case 2: return ("d"); case 3: return ("e"); case 4: return ("h"); case 5: return ("l"); case 6: return ("0"); case 7: return ("a"); } return "?"; } /* Assumes illegal ED ops are being used for break points */ private void DIS_ED_NOP(byte op, ref ushort pc) { Z80_Dis_Set("brk", Z80_Dis_Printf("$%.2x", op)); } private void DIS_IN_R8_C(byte op, ref ushort pc) { Z80_Dis_Set("in", Z80_Dis_Printf("%s,(c)", ER8((op - 0x40) / 8))); } private void DIS_OUT_C_R8(byte op, ref ushort pc) { Z80_Dis_Set("out", Z80_Dis_Printf("(c),%s", ER8((op - 0x40) / 8))); } private void DIS_SBC_HL_R16(byte op, ref ushort pc) { Z80_Dis_Set("sbc", Z80_Dis_Printf("hl,%s", z80_dis_reg16[(op - 0x40) / 16])); } private void DIS_ED_LD_ADDR_R16(byte op, ref ushort pc) { ushort w; w = Z80_Dis_FetchWord(ref pc); Z80_Dis_Set("ld", Z80_Dis_Printf("($%.4x),%s", w, z80_dis_reg16[(op - 0x40) / 16])); } private void DIS_NEG(byte op, ref ushort pc) { Z80_Dis_Set("neg", null); } private void DIS_RETN(byte op, ref ushort pc) { Z80_Dis_Set("retn", null); } private void DIS_IM_0(byte op, ref ushort pc) { Z80_Dis_Set("im", "0"); } private void DIS_LD_I_A(byte op, ref ushort pc) { Z80_Dis_Set("ld", "i,a"); } private void DIS_ADC_HL_R16(byte op, ref ushort pc) { Z80_Dis_Set("adc", Z80_Dis_Printf("hl,%s", z80_dis_reg16[(op - 0x40) / 16])); } private void DIS_ED_LD_R16_ADDR(byte op, ref ushort pc) { ushort w; w = Z80_Dis_FetchWord(ref pc); Z80_Dis_Set("ld", Z80_Dis_Printf("%s,($%.4x)", z80_dis_reg16[(op - 0x40) / 16], w)); } private void DIS_RETI(byte op, ref ushort pc) { Z80_Dis_Set("reti", null); } private void DIS_LD_R_A(byte op, ref ushort pc) { Z80_Dis_Set("ld", "r,a"); } private void DIS_IM_1(byte op, ref ushort pc) { Z80_Dis_Set("im", "1"); } private void DIS_LD_A_I(byte op, ref ushort pc) { Z80_Dis_Set("ld", "a,i"); } private void DIS_IM_2(byte op, ref ushort pc) { Z80_Dis_Set("im", "2"); } private void DIS_LD_A_R(byte op, ref ushort pc) { Z80_Dis_Set("ld", "a,r"); } private void DIS_RRD(byte op, ref ushort pc) { Z80_Dis_Set("rrd", null); } private void DIS_RLD(byte op, ref ushort pc) { Z80_Dis_Set("rld", null); } private void DIS_LDI(byte op, ref ushort pc) { Z80_Dis_Set("ldi", null); } private void DIS_CPI(byte op, ref ushort pc) { Z80_Dis_Set("cpi", null); } private void DIS_INI(byte op, ref ushort pc) { Z80_Dis_Set("ini", null); } private void DIS_OUTI(byte op, ref ushort pc) { Z80_Dis_Set("outi", null); } private void DIS_LDD(byte op, ref ushort pc) { Z80_Dis_Set("ldd", null); } private void DIS_CPD(byte op, ref ushort pc) { Z80_Dis_Set("cpd", null); } private void DIS_IND(byte op, ref ushort pc) { Z80_Dis_Set("ind", null); } private void DIS_OUTD(byte op, ref ushort pc) { Z80_Dis_Set("outd", null); } private void DIS_LDIR(byte op, ref ushort pc) { Z80_Dis_Set("ldir", null); } private void DIS_CPIR(byte op, ref ushort pc) { Z80_Dis_Set("cpir", null); } private void DIS_INIR(byte op, ref ushort pc) { Z80_Dis_Set("inir", null); } private void DIS_OTIR(byte op, ref ushort pc) { Z80_Dis_Set("otir", null); } private void DIS_LDDR(byte op, ref ushort pc) { Z80_Dis_Set("lddr", null); } private void DIS_CPDR(byte op, ref ushort pc) { Z80_Dis_Set("cpdr", null); } private void DIS_INDR(byte op, ref ushort pc) { Z80_Dis_Set("indr", null); } private void DIS_OTDR(byte op, ref ushort pc) { Z80_Dis_Set("otdr", null); } /* ---------------------------------------- FD OPCODES */ string IY_RelStr(byte op, ref ushort pc) { sbyte r; r=(sbyte)Z80_Dis_FetchByte(ref pc); if (r<0) return String.Format("(iy-${0:x2})",-r); else return String.Format("(iy+${0:x2})", r); } string IY_RelStrCB(byte op, ref ushort pc) { sbyte r; r=(sbyte)cb_off; if (r<0) return String.Format("(iy-${0:x2})",-r); else return String.Format("(iy+${0:x2})", r); } string YR8(int reg, ref ushort pc) { switch (reg) { case 0: return ("b"); case 1: return ("c"); case 2: return ("d"); case 3: return ("e"); case 4: return ("iyh"); case 5: return ("iyl"); case 6: return (IY_RelStr(0, ref pc)); case 7: return ("a"); default: return String.Format("BUG {0}", reg); } } private void DIS_FD_NOP(byte op, ref ushort pc) { dis_opcode_z80[op](op, ref pc); } private void DIS_ADD_IY_BC(byte op, ref ushort pc) { Z80_Dis_Set("add", "iy,bc"); } private void DIS_ADD_IY_DE(byte op, ref ushort pc) { Z80_Dis_Set("add", "iy,de"); } private void DIS_LD_IY_WORD(byte op, ref ushort pc) { Z80_Dis_Set("ld", Z80_Dis_Printf("iy,$%.4x", Z80_Dis_FetchWord(ref pc))); } private void DIS_LD_ADDR_IY(byte op, ref ushort pc) { ushort w; w = Z80_Dis_FetchWord(ref pc); Z80_Dis_Set("ld", Z80_Dis_Printf("($%.4x),iy", w)); } private void DIS_INC_IY(byte op, ref ushort pc) { Z80_Dis_Set("inc", "iy"); } private void DIS_INC_IYH(byte op, ref ushort pc) { Z80_Dis_Set("inc", "iyh"); } private void DIS_DEC_IYH(byte op, ref ushort pc) { Z80_Dis_Set("dec", "iyh"); } private void DIS_LD_IYH_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("ld", Z80_Dis_Printf("iyh,$%.2x", Z80_Dis_FetchByte(ref pc))); } private void DIS_ADD_IY_IY(byte op, ref ushort pc) { Z80_Dis_Set("add", "iy,iy"); } private void DIS_LD_IY_ADDR(byte op, ref ushort pc) { ushort w; w = Z80_Dis_FetchWord(ref pc); Z80_Dis_Set("ld", Z80_Dis_Printf("iy,($%.4x)", w)); } private void DIS_DEC_IY(byte op, ref ushort pc) { Z80_Dis_Set("dec", "iy"); } private void DIS_INC_IYL(byte op, ref ushort pc) { Z80_Dis_Set("inc", "iyl"); } private void DIS_DEC_IYL(byte op, ref ushort pc) { Z80_Dis_Set("dec", "iyl"); } private void DIS_LD_IYL_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("ld", Z80_Dis_Printf("iyl,$%.2x", Z80_Dis_FetchByte(ref pc))); } private void DIS_INC_IIY(byte op, ref ushort pc) { Z80_Dis_Set("inc", Z80_Dis_Printf("%s", IY_RelStr(op, ref pc))); } private void DIS_DEC_IIY(byte op, ref ushort pc) { Z80_Dis_Set("dec", Z80_Dis_Printf("%s", IY_RelStr(op, ref pc))); } private void DIS_LD_IIY_BYTE(byte op, ref ushort pc) { string rel; int b; rel = IY_RelStr(op, ref pc); b = Z80_Dis_FetchByte(ref pc); Z80_Dis_Set("ld", Z80_Dis_Printf("%s,$%.2x", rel, b)); } private void DIS_ADD_IY_SP(byte op, ref ushort pc) { Z80_Dis_Set("add", "iy,sp"); } private void DIS_YLD_R8_R8(byte op, ref ushort pc) { int src_r,dest_r; string src,dest; dest_r=(op-0x40)/8; src_r=op%8; /* IY can't be used as source and destination when reading z80ory */ if (dest_r==6) { dest=YR8(dest_r,ref pc); src=z80_dis_reg8[src_r]; } else if (((dest_r==4)||(dest_r==5))&&(src_r==6)) { dest=z80_dis_reg8[dest_r]; src=YR8(src_r,ref pc); } else { dest=YR8(dest_r,ref pc); src = YR8(src_r, ref pc); } Z80_Dis_Set("ld",Z80_Dis_Printf("%s,%s",dest,src)); } private void DIS_YADD_R8(byte op, ref ushort pc) { Z80_Dis_Set("add", Z80_Dis_Printf("a,%s", YR8((op % 8), ref pc))); } private void DIS_YADC_R8(byte op, ref ushort pc) { Z80_Dis_Set("adc", Z80_Dis_Printf("a,%s", YR8((op % 8), ref pc))); } private void DIS_YSUB_R8(byte op, ref ushort pc) { Z80_Dis_Set("sub", Z80_Dis_Printf("a,%s", YR8((op % 8), ref pc))); } private void DIS_YSBC_R8(byte op, ref ushort pc) { Z80_Dis_Set("sbc", Z80_Dis_Printf("a,%s", YR8((op % 8), ref pc))); } private void DIS_YAND_R8(byte op, ref ushort pc) { Z80_Dis_Set("and", Z80_Dis_Printf("%s", YR8((op % 8), ref pc))); } private void DIS_YYOR_R8(byte op, ref ushort pc) { Z80_Dis_Set("xor", Z80_Dis_Printf("%s", YR8((op % 8), ref pc))); } private void DIS_Y_OR_R8(byte op, ref ushort pc) { Z80_Dis_Set("or", Z80_Dis_Printf("%s", YR8((op % 8), ref pc))); } private void DIS_YCP_R8(byte op, ref ushort pc) { Z80_Dis_Set("cp", Z80_Dis_Printf("%s", YR8((op % 8), ref pc))); } private void DIS_POP_IY(byte op, ref ushort pc) { Z80_Dis_Set("pop", "iy"); } private void DIS_EY_ISP_IY(byte op, ref ushort pc) { Z80_Dis_Set("ex", "(sp),iy"); } private void DIS_PUSH_IY(byte op, ref ushort pc) { Z80_Dis_Set("push", "iy"); } private void DIS_JP_IY(byte op, ref ushort pc) { Z80_Dis_Set("jp", "(iy)"); } private void DIS_LD_SP_IY(byte op, ref ushort pc) { Z80_Dis_Set("ld", "sp,iy"); } private void DIS_FD_CB_DECODE(byte op, ref ushort pc) { byte nop; cb_off = (sbyte)Z80_Dis_FetchByte(ref pc); nop = Z80_Dis_FetchByte(ref pc); dis_FD_CB_opcode[nop](nop, ref pc); } private void DIS_FD_DD_DECODE(byte op, ref ushort pc) { byte nop; nop = Z80_Dis_FetchByte(ref pc); dis_DD_opcode[nop](nop, ref pc); } private void DIS_FD_ED_DECODE(byte op, ref ushort pc) { byte nop; nop = Z80_Dis_FetchByte(ref pc); dis_ED_opcode[nop](nop, ref pc); } private void DIS_FD_FD_DECODE(byte op, ref ushort pc) { byte nop; nop = Z80_Dis_FetchByte(ref pc); dis_FD_opcode[nop](nop, ref pc); } /* ---------------------------------------- FD CB OPCODES */ private void DIS_RLC_IY(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("rlc", Z80_Dis_Printf("%s", IY_RelStrCB(op, ref pc))); else Z80_Dis_Set("rlc", Z80_Dis_Printf("%s[%s]", IY_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_RRC_IY(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("rrc", Z80_Dis_Printf("%s", IY_RelStrCB(op, ref pc))); else Z80_Dis_Set("rrc", Z80_Dis_Printf("%s[%s]", IY_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_RL_IY(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("rl", Z80_Dis_Printf("%s", IY_RelStrCB(op, ref pc))); else Z80_Dis_Set("rl", Z80_Dis_Printf("%s[%s]", IY_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_RR_IY(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("rr", Z80_Dis_Printf("%s", IY_RelStrCB(op, ref pc))); else Z80_Dis_Set("rr", Z80_Dis_Printf("%s[%s]", IY_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_SLA_IY(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("sla", Z80_Dis_Printf("%s", IY_RelStrCB(op, ref pc))); else Z80_Dis_Set("sla", Z80_Dis_Printf("%s[%s]", IY_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_SRA_IY(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("sra", Z80_Dis_Printf("%s", IY_RelStrCB(op, ref pc))); else Z80_Dis_Set("sra", Z80_Dis_Printf("%s[%s]", IY_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_SRL_IY(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("srl", Z80_Dis_Printf("%s", IY_RelStrCB(op, ref pc))); else Z80_Dis_Set("srl", Z80_Dis_Printf("%s[%s]", IY_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_SLL_IY(byte op, ref ushort pc) { int reg; reg = (op % 8); if (reg == 6) Z80_Dis_Set("sll", Z80_Dis_Printf("%s", IY_RelStrCB(op, ref pc))); else Z80_Dis_Set("sll", Z80_Dis_Printf("%s[%s]", IY_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_BIT_IY(byte op, ref ushort pc) { int bit; bit = (op - 0x40) / 8; Z80_Dis_Set("bit", Z80_Dis_Printf("%d,%s", bit, IY_RelStrCB(op, ref pc))); } private void DIS_RES_IY(byte op, ref ushort pc) { int reg; int bit; reg = (op % 8); bit = (op - 0x80) / 8; if (reg == 6) Z80_Dis_Set("res", Z80_Dis_Printf("%d,%s", bit, IY_RelStrCB(op, ref pc))); else Z80_Dis_Set("res", Z80_Dis_Printf("%d,%s[%s]", bit, IY_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } private void DIS_SET_IY(byte op, ref ushort pc) { int reg; int bit; reg = (op % 8); bit = (op - 0xc0) / 8; if (reg == 6) Z80_Dis_Set("set", Z80_Dis_Printf("%d,%s", bit, IY_RelStrCB(op, ref pc))); else Z80_Dis_Set("set", Z80_Dis_Printf("%d,%s[%s]", bit, IY_RelStrCB(op, ref pc), z80_dis_reg8[reg])); } /* ---------------------------------------- SINGLE BYTE OPCODES */ private void DIS_NOP(byte op, ref ushort pc) { Z80_Dis_Set("nop", null); } private void DIS_LD_R16_WORD(byte op, ref ushort pc) { string reg; reg = z80_dis_reg16[(op & 0x30) / 0x10]; Z80_Dis_Set("ld", Z80_Dis_Printf("%s,$%.4x", reg, Z80_Dis_FetchWord(ref pc))); } private void DIS_LD_R16_A(byte op, ref ushort pc) { string reg; reg = z80_dis_reg16[(op & 0x30) / 0x10]; Z80_Dis_Set("ld", Z80_Dis_Printf("(%s),a", reg)); } private void DIS_INC_R16(byte op, ref ushort pc) { string reg; reg = z80_dis_reg16[(op & 0x30) / 0x10]; Z80_Dis_Set("inc", reg); } private void DIS_INC_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[(op & 0x38) / 0x8]; Z80_Dis_Set("inc", reg); } private void DIS_DEC_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[(op & 0x38) / 0x8]; Z80_Dis_Set("dec", reg); } private void DIS_LD_R8_BYTE(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[(op & 0x38) / 0x8]; Z80_Dis_Set("ld", Z80_Dis_Printf("%s,$%.2x", reg, Z80_Dis_FetchByte(ref pc))); } private void DIS_RLCA(byte op, ref ushort pc) { Z80_Dis_Set("rlca", null); } private void DIS_EX_AF_AF(byte op, ref ushort pc) { Z80_Dis_Set("ex", "af,af'"); } private void DIS_ADD_HL_R16(byte op, ref ushort pc) { string reg; reg = z80_dis_reg16[(op & 0x30) / 0x10]; Z80_Dis_Set("add", Z80_Dis_Printf("hl,%s", reg)); } private void DIS_LD_A_R16(byte op, ref ushort pc) { string reg; reg = z80_dis_reg16[(op & 0x30) / 0x10]; Z80_Dis_Set("ld", Z80_Dis_Printf("a,(%s)", reg)); } private void DIS_DEC_R16(byte op, ref ushort pc) { string reg; reg = z80_dis_reg16[(op & 0x30) / 0x10]; Z80_Dis_Set("dec", reg); } private void DIS_RRCA(byte op, ref ushort pc) { Z80_Dis_Set("rrca", null); } private void DIS_DJNZ(byte op, ref ushort pc) { ushort n; n = (ushort)(pc + (sbyte)((memory.Read(pc) + 1))); pc++; Z80_Dis_Set("djnz", Z80_Dis_Printf("$%.4x", n)); } private void DIS_RLA(byte op, ref ushort pc) { Z80_Dis_Set("rla", null); } private void DIS_JR(byte op, ref ushort pc) { ushort n; n = (ushort)(pc + (sbyte)(memory.Read(pc) + 1)); pc++; Z80_Dis_Set("jr", Z80_Dis_Printf("$%.4x", n)); } private void DIS_RRA(byte op, ref ushort pc) { Z80_Dis_Set("rra", null); } private void DIS_JR_CO(byte op, ref ushort pc) { string con; ushort n; con = z80_dis_condition[(op - 0x20) / 8]; n = (ushort)(pc + (sbyte)(memory.Read(pc) + 1)); pc++; Z80_Dis_Set("jr", Z80_Dis_Printf("%s,$%.4x", con, n)); } private void DIS_LD_ADDR_HL(byte op, ref ushort pc) { ushort w; w = Z80_Dis_FetchWord(ref pc); Z80_Dis_Set("ld", Z80_Dis_Printf("($%.4x),hl", w)); } private void DIS_DAA(byte op, ref ushort pc) { Z80_Dis_Set("daa", null); } private void DIS_LD_HL_ADDR(byte op, ref ushort pc) { ushort w; w = Z80_Dis_FetchWord(ref pc); Z80_Dis_Set("ld", Z80_Dis_Printf("hl,($%.4x)", w)); } private void DIS_CPL(byte op, ref ushort pc) { Z80_Dis_Set("cpl", null); } private void DIS_LD_ADDR_A(byte op, ref ushort pc) { ushort w; w = Z80_Dis_FetchWord(ref pc); Z80_Dis_Set("ld", Z80_Dis_Printf("($%.4x),a", w)); } private void DIS_SCF(byte op, ref ushort pc) { Z80_Dis_Set("scf", null); } private void DIS_LD_A_ADDR(byte op, ref ushort pc) { ushort w; w = Z80_Dis_FetchWord(ref pc); Z80_Dis_Set("ld", Z80_Dis_Printf("a,($%.4x)", w)); } private void DIS_CCF(byte op, ref ushort pc) { Z80_Dis_Set("ccf", null); } private void DIS_LD_R8_R8(byte op, ref ushort pc) { string src,dest; dest=z80_dis_reg8[(op-0x40)/8]; src=z80_dis_reg8[op%8]; Z80_Dis_Set("ld",Z80_Dis_Printf("%s,%s",dest,src)); } private void DIS_HALT(byte op, ref ushort pc) { Z80_Dis_Set("halt", null); } private void DIS_ADD_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("add", Z80_Dis_Printf("a,%s", reg)); } private void DIS_ADC_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("adc", Z80_Dis_Printf("a,%s", reg)); } private void DIS_SUB_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("sub", Z80_Dis_Printf("a,%s", reg)); } private void DIS_SBC_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("sbc", Z80_Dis_Printf("a,%s", reg)); } private void DIS_AND_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("and", Z80_Dis_Printf("%s", reg)); } private void DIS_XOR_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("xor", Z80_Dis_Printf("%s", reg)); } private void DIS_OR_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("or", Z80_Dis_Printf("%s", reg)); } private void DIS_CP_R8(byte op, ref ushort pc) { string reg; reg = z80_dis_reg8[op % 8]; Z80_Dis_Set("cp", Z80_Dis_Printf("%s", reg)); } private void DIS_RET_CO(byte op, ref ushort pc) { string con; con = z80_dis_condition[(op - 0xc0) / 8]; Z80_Dis_Set("ret", con); } private void DIS_POP_R16(byte op, ref ushort pc) { string reg; reg = z80_dis_reg16[(op - 0xc0) / 16]; if (reg == "sp") reg = "af"; Z80_Dis_Set("pop", reg); } private void DIS_JP(byte op, ref ushort pc) { ushort w; w = Z80_Dis_FetchWord(ref pc); Z80_Dis_Set("jp", Z80_Dis_Printf("$%.4x", w)); } private void DIS_PUSH_R16(byte op, ref ushort pc) { string reg; reg = z80_dis_reg16[(op - 0xc0) / 16]; if (reg == "sp") reg = "af"; Z80_Dis_Set("push", reg); } private void DIS_ADD_A_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("add", Z80_Dis_Printf("a,$%.2x", Z80_Dis_FetchByte(ref pc))); } private void DIS_RST(byte op, ref ushort pc) { int add; add = (op & 0x3f) - 7; Z80_Dis_Set("rst", Z80_Dis_Printf("%.2xh", add)); } private void DIS_RET(byte op, ref ushort pc) { Z80_Dis_Set("ret", null); } private void DIS_JP_CO(byte op, ref ushort pc) { string con; ushort w; w = Z80_Dis_FetchWord(ref pc); con = z80_dis_condition[(op - 0xc0) / 8]; Z80_Dis_Set("jp", Z80_Dis_Printf("%s,$%.4x", con, w)); } private void DIS_CB_DECODE(byte op, ref ushort pc) { byte nop; nop = Z80_Dis_FetchByte(ref pc); dis_CB_opcode[nop](nop, ref pc); } private void DIS_CALL_CO(byte op, ref ushort pc) { string con; ushort w; w = Z80_Dis_FetchWord(ref pc); con = z80_dis_condition[(op - 0xc0) / 8]; Z80_Dis_Set("call", Z80_Dis_Printf("%s,$%.4x", con, w)); } private void DIS_CALL(byte op, ref ushort pc) { ushort w; w = Z80_Dis_FetchWord(ref pc); Z80_Dis_Set("call", Z80_Dis_Printf("$%.4x", w)); } private void DIS_ADC_A_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("adc", Z80_Dis_Printf("a,$%.2x", Z80_Dis_FetchByte(ref pc))); } private void DIS_OUT_BYTE_A(byte op, ref ushort pc) { Z80_Dis_Set("out", Z80_Dis_Printf("($%.2x),a", Z80_Dis_FetchByte(ref pc))); } private void DIS_SUB_A_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("sub", Z80_Dis_Printf("a,$%.2x", Z80_Dis_FetchByte(ref pc))); } private void DIS_EXX(byte op, ref ushort pc) { Z80_Dis_Set("exx", null); } private void DIS_IN_A_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("in", Z80_Dis_Printf("a,($%.2x)", Z80_Dis_FetchByte(ref pc))); } private void DIS_DD_DECODE(byte op, ref ushort pc) { byte nop; nop = Z80_Dis_FetchByte(ref pc); dis_DD_opcode[nop](nop, ref pc); } private void DIS_SBC_A_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("sbc", Z80_Dis_Printf("a,$%.2x", Z80_Dis_FetchByte(ref pc))); } private void DIS_EX_ISP_HL(byte op, ref ushort pc) { Z80_Dis_Set("ex", "(sp),hl"); } private void DIS_AND_A_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("and", Z80_Dis_Printf("$%.2x", Z80_Dis_FetchByte(ref pc))); } private void DIS_JP_HL(byte op, ref ushort pc) { Z80_Dis_Set("jp", "(hl)"); } private void DIS_EX_DE_HL(byte op, ref ushort pc) { Z80_Dis_Set("ex", "de,hl"); } private void DIS_ED_DECODE(byte op, ref ushort pc) { byte nop; nop = Z80_Dis_FetchByte(ref pc); dis_ED_opcode[nop](nop, ref pc); } private void DIS_XOR_A_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("xor", Z80_Dis_Printf("$%.2x", Z80_Dis_FetchByte(ref pc))); } private void DIS_DI(byte op, ref ushort pc) { Z80_Dis_Set("di", null); } private void DIS_OR_A_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("or", Z80_Dis_Printf("$%.2x", Z80_Dis_FetchByte(ref pc))); } private void DIS_LD_SP_HL(byte op, ref ushort pc) { Z80_Dis_Set("ld", "sp,hl"); } private void DIS_EI(byte op, ref ushort pc) { Z80_Dis_Set("ei", null); } private void DIS_FD_DECODE(byte op, ref ushort pc) { byte nop; nop = Z80_Dis_FetchByte(ref pc); dis_FD_opcode[nop](nop, ref pc); } private void DIS_CP_A_BYTE(byte op, ref ushort pc) { Z80_Dis_Set("cp", Z80_Dis_Printf("$%.2x", Z80_Dis_FetchByte(ref pc))); } #endregion #region Constructors public Z80Disassembler() { // Verify runtime // Register16.Verify(); Hex = new StringBuilder(); // Setup function tables // dis_CB_opcode = new disassemble[0x100] { /* 0x00 - 0x03 */ DIS_RLC_R8, DIS_RLC_R8, DIS_RLC_R8, DIS_RLC_R8, /* 0x04 - 0x07 */ DIS_RLC_R8, DIS_RLC_R8, DIS_RLC_R8, DIS_RLC_R8, /* 0x08 - 0x0b */ DIS_RRC_R8, DIS_RRC_R8, DIS_RRC_R8, DIS_RRC_R8, /* 0x0c - 0x0f */ DIS_RRC_R8, DIS_RRC_R8, DIS_RRC_R8, DIS_RRC_R8, /* 0x10 - 0x13 */ DIS_RL_R8, DIS_RL_R8, DIS_RL_R8, DIS_RL_R8, /* 0x14 - 0x17 */ DIS_RL_R8, DIS_RL_R8, DIS_RL_R8, DIS_RL_R8, /* 0x18 - 0x1b */ DIS_RR_R8, DIS_RR_R8, DIS_RR_R8, DIS_RR_R8, /* 0x1c - 0x1f */ DIS_RR_R8, DIS_RR_R8, DIS_RR_R8, DIS_RR_R8, /* 0x20 - 0x23 */ DIS_SLA_R8, DIS_SLA_R8, DIS_SLA_R8, DIS_SLA_R8, /* 0x24 - 0x27 */ DIS_SLA_R8, DIS_SLA_R8, DIS_SLA_R8, DIS_SLA_R8, /* 0x28 - 0x2b */ DIS_SRA_R8, DIS_SRA_R8, DIS_SRA_R8, DIS_SRA_R8, /* 0x2c - 0x2f */ DIS_SRA_R8, DIS_SRA_R8, DIS_SRA_R8, DIS_SRA_R8, /* 0x30 - 0x33 */ DIS_SLL_R8, DIS_SLL_R8, DIS_SLL_R8, DIS_SLL_R8, /* 0x34 - 0x37 */ DIS_SLL_R8, DIS_SLL_R8, DIS_SLL_R8, DIS_SLL_R8, /* 0x38 - 0x3b */ DIS_SRL_R8, DIS_SRL_R8, DIS_SRL_R8, DIS_SRL_R8, /* 0x3c - 0x3f */ DIS_SRL_R8, DIS_SRL_R8, DIS_SRL_R8, DIS_SRL_R8, /* 0x40 - 0x43 */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x44 - 0x47 */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x48 - 0x4b */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x4c - 0x4f */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x50 - 0x53 */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x54 - 0x57 */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x58 - 0x5b */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x5c - 0x5f */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x60 - 0x63 */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x64 - 0x67 */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x68 - 0x6b */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x6c - 0x6f */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x70 - 0x73 */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x74 - 0x77 */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x78 - 0x7b */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x7c - 0x7f */ DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, DIS_BIT_R8, /* 0x80 - 0x83 */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0x84 - 0x87 */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0x88 - 0x8b */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0x8c - 0x8f */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0x90 - 0x93 */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0x94 - 0x97 */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0x98 - 0x9b */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0x9c - 0x9f */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0xa0 - 0xa3 */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0xa4 - 0xa7 */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0xa8 - 0xab */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0xac - 0xaf */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0xb0 - 0xb3 */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0xb4 - 0xb7 */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0xb8 - 0xbb */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0xbc - 0xbf */ DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, DIS_RES_R8, /* 0xc0 - 0xc3 */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xc4 - 0xc7 */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xc8 - 0xcb */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xcc - 0xcf */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xd0 - 0xd3 */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xd4 - 0xd7 */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xd8 - 0xdb */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xdc - 0xdf */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xe0 - 0xe3 */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xe4 - 0xe7 */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xe8 - 0xeb */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xec - 0xef */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xf0 - 0xf3 */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xf4 - 0xf7 */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xf8 - 0xfb */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, /* 0xfc - 0xff */ DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, DIS_SET_R8, }; /* DIS_DD opcodes */ dis_DD_opcode = new disassemble[0x100] { /* 0x00 - 0x03 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x04 - 0x07 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x08 - 0x0b */ DIS_DD_NOP, DIS_ADD_IX_BC, DIS_DD_NOP, DIS_DD_NOP, /* 0x0c - 0x0f */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x10 - 0x13 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x14 - 0x17 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x18 - 0x1b */ DIS_DD_NOP, DIS_ADD_IX_DE, DIS_DD_NOP, DIS_DD_NOP, /* 0x1c - 0x1f */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x20 - 0x23 */ DIS_DD_NOP, DIS_LD_IX_WORD, DIS_LD_ADDR_IX, DIS_INC_IX, /* 0x24 - 0x27 */ DIS_INC_IXH, DIS_DEC_IXH, DIS_LD_IXH_BYTE, DIS_DD_NOP, /* 0x28 - 0x2b */ DIS_DD_NOP, DIS_ADD_IX_IX, DIS_LD_IX_ADDR, DIS_DEC_IX, /* 0x2c - 0x2f */ DIS_INC_IXL, DIS_DEC_IXL, DIS_LD_IXL_BYTE, DIS_DD_NOP, /* 0x30 - 0x33 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x34 - 0x37 */ DIS_INC_IIX, DIS_DEC_IIX, DIS_LD_IIX_BYTE, DIS_DD_NOP, /* 0x38 - 0x3b */ DIS_DD_NOP, DIS_ADD_IX_SP, DIS_DD_NOP, DIS_DD_NOP, /* 0x3c - 0x3f */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x40 - 0x43 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x44 - 0x47 */ DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_DD_NOP, /* 0x48 - 0x4b */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x4c - 0x4f */ DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_DD_NOP, /* 0x50 - 0x53 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x54 - 0x57 */ DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_DD_NOP, /* 0x58 - 0x5b */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x5c - 0x5f */ DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_DD_NOP, /* 0x60 - 0x63 */ DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, /* 0x64 - 0x67 */ DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, /* 0x68 - 0x6b */ DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, /* 0x6c - 0x6f */ DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, /* 0x70 - 0x73 */ DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, /* 0x74 - 0x77 */ DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_DD_NOP, DIS_XLD_R8_R8, /* 0x78 - 0x7b */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x7c - 0x7f */ DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_XLD_R8_R8, DIS_DD_NOP, /* 0x80 - 0x83 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x84 - 0x87 */ DIS_XADD_R8, DIS_XADD_R8, DIS_XADD_R8, DIS_DD_NOP, /* 0x88 - 0x8b */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x8c - 0x8f */ DIS_XADC_R8, DIS_XADC_R8, DIS_XADC_R8, DIS_DD_NOP, /* 0x90 - 0x93 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x94 - 0x97 */ DIS_XSUB_R8, DIS_XSUB_R8, DIS_XSUB_R8, DIS_DD_NOP, /* 0x98 - 0x9b */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0x9c - 0x9f */ DIS_XSBC_R8, DIS_XSBC_R8, DIS_XSBC_R8, DIS_DD_NOP, /* 0xa0 - 0xa3 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0xa4 - 0xa7 */ DIS_XAND_R8, DIS_XAND_R8, DIS_XAND_R8, DIS_DD_NOP, /* 0xa8 - 0xab */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0xac - 0xaf */ DIS_XXOR_R8, DIS_XXOR_R8, DIS_XXOR_R8, DIS_DD_NOP, /* 0xb0 - 0xb3 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0xb4 - 0xb7 */ DIS_X_OR_R8, DIS_X_OR_R8, DIS_X_OR_R8, DIS_DD_NOP, /* 0xb8 - 0xbb */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0xbc - 0xbf */ DIS_XCP_R8, DIS_XCP_R8, DIS_XCP_R8, DIS_DD_NOP, /* 0xc0 - 0xc3 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0xc4 - 0xc7 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0xc8 - 0xcb */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_CB_DECODE, /* 0xcc - 0xcf */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0xd0 - 0xd3 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0xd4 - 0xd7 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0xd8 - 0xdb */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0xdc - 0xdf */ DIS_DD_NOP, DIS_DD_DD_DECODE, DIS_DD_NOP, DIS_DD_NOP, /* 0xe0 - 0xe3 */ DIS_DD_NOP, DIS_POP_IX, DIS_DD_NOP, DIS_EX_ISP_IX, /* 0xe4 - 0xe7 */ DIS_DD_NOP, DIS_PUSH_IX, DIS_DD_NOP, DIS_DD_NOP, /* 0xe8 - 0xeb */ DIS_DD_NOP, DIS_JP_IX, DIS_DD_NOP, DIS_DD_NOP, /* 0xec - 0xef */ DIS_DD_NOP, DIS_DD_ED_DECODE, DIS_DD_NOP, DIS_DD_NOP, /* 0xf0 - 0xf3 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0xf4 - 0xf7 */ DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, DIS_DD_NOP, /* 0xf8 - 0xfb */ DIS_DD_NOP, DIS_LD_SP_IX, DIS_DD_NOP, DIS_DD_NOP, /* 0xfc - 0xff */ DIS_DD_NOP, DIS_DD_FD_DECODE, DIS_DD_NOP, DIS_DD_NOP, }; /* DIS_DD DIS_CB opcodes */ dis_DD_CB_opcode = new disassemble[0x100] { /* 0x00 - 0x03 */ DIS_RLC_IX, DIS_RLC_IX, DIS_RLC_IX, DIS_RLC_IX, /* 0x04 - 0x07 */ DIS_RLC_IX, DIS_RLC_IX, DIS_RLC_IX, DIS_RLC_IX, /* 0x08 - 0x0b */ DIS_RRC_IX, DIS_RRC_IX, DIS_RRC_IX, DIS_RRC_IX, /* 0x0c - 0x0f */ DIS_RRC_IX, DIS_RRC_IX, DIS_RRC_IX, DIS_RRC_IX, /* 0x10 - 0x13 */ DIS_RL_IX, DIS_RL_IX, DIS_RL_IX, DIS_RL_IX, /* 0x14 - 0x17 */ DIS_RL_IX, DIS_RL_IX, DIS_RL_IX, DIS_RL_IX, /* 0x18 - 0x1b */ DIS_RR_IX, DIS_RR_IX, DIS_RR_IX, DIS_RR_IX, /* 0x1c - 0x1f */ DIS_RR_IX, DIS_RR_IX, DIS_RR_IX, DIS_RR_IX, /* 0x20 - 0x23 */ DIS_SLA_IX, DIS_SLA_IX, DIS_SLA_IX, DIS_SLA_IX, /* 0x24 - 0x27 */ DIS_SLA_IX, DIS_SLA_IX, DIS_SLA_IX, DIS_SLA_IX, /* 0x28 - 0x2b */ DIS_SRA_IX, DIS_SRA_IX, DIS_SRA_IX, DIS_SRA_IX, /* 0x2c - 0x2f */ DIS_SRA_IX, DIS_SRA_IX, DIS_SRA_IX, DIS_SRA_IX, /* 0x30 - 0x33 */ DIS_SLL_IX, DIS_SLL_IX, DIS_SLL_IX, DIS_SLL_IX, /* 0x34 - 0x37 */ DIS_SLL_IX, DIS_SLL_IX, DIS_SLL_IX, DIS_SLL_IX, /* 0x38 - 0x3b */ DIS_SRL_IX, DIS_SRL_IX, DIS_SRL_IX, DIS_SRL_IX, /* 0x3c - 0x3f */ DIS_SRL_IX, DIS_SRL_IX, DIS_SRL_IX, DIS_SRL_IX, /* 0x40 - 0x43 */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x44 - 0x47 */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x48 - 0x4b */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x4c - 0x4f */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x50 - 0x53 */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x54 - 0x57 */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x58 - 0x5b */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x5c - 0x5f */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x60 - 0x63 */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x64 - 0x67 */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x68 - 0x6b */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x6c - 0x6f */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x70 - 0x73 */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x74 - 0x77 */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x78 - 0x7b */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x7c - 0x7f */ DIS_BIT_IX,DIS_BIT_IX, DIS_BIT_IX, DIS_BIT_IX, /* 0x80 - 0x83 */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0x84 - 0x87 */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0x88 - 0x8b */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0x8c - 0x8f */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0x90 - 0x93 */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0x94 - 0x97 */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0x98 - 0x9b */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0x9c - 0x9f */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0xa0 - 0xa3 */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0xa4 - 0xa7 */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0xa8 - 0xab */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0xac - 0xaf */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0xb0 - 0xb3 */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0xb4 - 0xb7 */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0xb8 - 0xbb */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0xbc - 0xbf */ DIS_RES_IX,DIS_RES_IX, DIS_RES_IX, DIS_RES_IX, /* 0xc0 - 0xc3 */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xc4 - 0xc7 */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xc8 - 0xcb */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xcc - 0xcf */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xd0 - 0xd3 */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xd4 - 0xd7 */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xd8 - 0xdb */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xdc - 0xdf */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xe0 - 0xe3 */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xe4 - 0xe7 */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xe8 - 0xeb */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xec - 0xef */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xf0 - 0xf3 */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xf4 - 0xf7 */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xf8 - 0xfb */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, /* 0xfc - 0xff */ DIS_SET_IX,DIS_SET_IX, DIS_SET_IX, DIS_SET_IX, }; /* DIS_ED opcodes */ dis_ED_opcode = new disassemble[0x100] { /* 0x00 - 0x03 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x04 - 0x07 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x08 - 0x0b */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x0c - 0x0f */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x10 - 0x13 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x14 - 0x17 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x18 - 0x1b */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x1c - 0x1f */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x20 - 0x23 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x24 - 0x27 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x28 - 0x2b */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x2c - 0x2f */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x30 - 0x33 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x34 - 0x37 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x38 - 0x3b */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x3c - 0x3f */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x40 - 0x43 */ DIS_IN_R8_C, DIS_OUT_C_R8, DIS_SBC_HL_R16, DIS_ED_LD_ADDR_R16, /* 0x44 - 0x47 */ DIS_NEG, DIS_RETN, DIS_IM_0, DIS_LD_I_A, /* 0x48 - 0x4b */ DIS_IN_R8_C, DIS_OUT_C_R8, DIS_ADC_HL_R16, DIS_ED_LD_R16_ADDR, /* 0x4c - 0x4f */ DIS_NEG, DIS_RETI, DIS_IM_0, DIS_LD_R_A, /* 0x50 - 0x53 */ DIS_IN_R8_C, DIS_OUT_C_R8, DIS_SBC_HL_R16, DIS_ED_LD_ADDR_R16, /* 0x54 - 0x57 */ DIS_NEG, DIS_RETN, DIS_IM_1, DIS_LD_A_I, /* 0x58 - 0x5b */ DIS_IN_R8_C, DIS_OUT_C_R8, DIS_ADC_HL_R16, DIS_ED_LD_R16_ADDR, /* 0x5c - 0x5f */ DIS_NEG, DIS_RETI, DIS_IM_2, DIS_LD_A_R, /* 0x60 - 0x63 */ DIS_IN_R8_C, DIS_OUT_C_R8, DIS_SBC_HL_R16, DIS_ED_LD_ADDR_R16, /* 0x64 - 0x67 */ DIS_NEG, DIS_RETN, DIS_IM_0, DIS_RRD, /* 0x68 - 0x6b */ DIS_IN_R8_C, DIS_OUT_C_R8, DIS_ADC_HL_R16, DIS_ED_LD_R16_ADDR, /* 0x6c - 0x6f */ DIS_NEG, DIS_RETI, DIS_IM_0, DIS_RLD, /* 0x70 - 0x73 */ DIS_IN_R8_C, DIS_OUT_C_R8, DIS_SBC_HL_R16, DIS_ED_LD_ADDR_R16, /* 0x74 - 0x77 */ DIS_NEG, DIS_RETN, DIS_IM_1, DIS_ED_NOP, /* 0x78 - 0x7b */ DIS_IN_R8_C, DIS_OUT_C_R8, DIS_ADC_HL_R16, DIS_ED_LD_R16_ADDR, /* 0x7c - 0x7f */ DIS_NEG, DIS_RETI, DIS_IM_2, DIS_ED_NOP, /* 0x80 - 0x83 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x84 - 0x87 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x88 - 0x8b */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x8c - 0x8f */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x90 - 0x93 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x94 - 0x97 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x98 - 0x9b */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0x9c - 0x9f */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xa0 - 0xa3 */ DIS_LDI, DIS_CPI, DIS_INI, DIS_OUTI, /* 0xa4 - 0xa7 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xa8 - 0xab */ DIS_LDD, DIS_CPD, DIS_IND, DIS_OUTD, /* 0xac - 0xaf */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xb0 - 0xb3 */ DIS_LDIR, DIS_CPIR, DIS_INIR, DIS_OTIR, /* 0xb4 - 0xb7 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xb8 - 0xbb */ DIS_LDDR, DIS_CPDR, DIS_INDR, DIS_OTDR, /* 0xbc - 0xbf */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xc0 - 0xc3 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xc4 - 0xc7 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xc8 - 0xcb */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xcc - 0xcf */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xd0 - 0xd3 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xd4 - 0xd7 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xd8 - 0xdb */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xdc - 0xdf */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xe0 - 0xe3 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xe4 - 0xe7 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xe8 - 0xeb */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xec - 0xef */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xf0 - 0xf3 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xf4 - 0xf7 */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xf8 - 0xfb */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, /* 0xfc - 0xff */ DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, DIS_ED_NOP, }; /* DIS_FD opcodes */ dis_FD_opcode = new disassemble[0x100] { /* 0x00 - 0x03 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x04 - 0x07 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x08 - 0x0b */ DIS_FD_NOP, DIS_ADD_IY_BC, DIS_FD_NOP, DIS_FD_NOP, /* 0x0c - 0x0f */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x10 - 0x13 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x14 - 0x17 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x18 - 0x1b */ DIS_FD_NOP, DIS_ADD_IY_DE, DIS_FD_NOP, DIS_FD_NOP, /* 0x1c - 0x1f */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x20 - 0x23 */ DIS_FD_NOP, DIS_LD_IY_WORD, DIS_LD_ADDR_IY, DIS_INC_IY, /* 0x24 - 0x27 */ DIS_INC_IYH, DIS_DEC_IYH, DIS_LD_IYH_BYTE, DIS_FD_NOP, /* 0x28 - 0x2b */ DIS_FD_NOP, DIS_ADD_IY_IY, DIS_LD_IY_ADDR, DIS_DEC_IY, /* 0x2c - 0x2f */ DIS_INC_IYL, DIS_DEC_IYL, DIS_LD_IYL_BYTE, DIS_FD_NOP, /* 0x30 - 0x33 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x34 - 0x37 */ DIS_INC_IIY, DIS_DEC_IIY, DIS_LD_IIY_BYTE, DIS_FD_NOP, /* 0x38 - 0x3b */ DIS_FD_NOP, DIS_ADD_IY_SP, DIS_FD_NOP, DIS_FD_NOP, /* 0x3c - 0x3f */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x40 - 0x43 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x44 - 0x47 */ DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_FD_NOP, /* 0x48 - 0x4b */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x4c - 0x4f */ DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_FD_NOP, /* 0x50 - 0x53 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x54 - 0x57 */ DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_FD_NOP, /* 0x58 - 0x5b */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x5c - 0x5f */ DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_FD_NOP, /* 0x60 - 0x63 */ DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, /* 0x64 - 0x67 */ DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, /* 0x68 - 0x6b */ DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, /* 0x6c - 0x6f */ DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, /* 0x70 - 0x73 */ DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, /* 0x74 - 0x77 */ DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_FD_NOP, DIS_YLD_R8_R8, /* 0x78 - 0x7b */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x7c - 0x7f */ DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_YLD_R8_R8, DIS_FD_NOP, /* 0x80 - 0x83 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x84 - 0x87 */ DIS_YADD_R8, DIS_YADD_R8, DIS_YADD_R8, DIS_FD_NOP, /* 0x88 - 0x8b */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x8c - 0x8f */ DIS_YADC_R8, DIS_YADC_R8, DIS_YADC_R8, DIS_FD_NOP, /* 0x90 - 0x93 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x94 - 0x97 */ DIS_YSUB_R8, DIS_YSUB_R8, DIS_YSUB_R8, DIS_FD_NOP, /* 0x98 - 0x9b */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0x9c - 0x9f */ DIS_YSBC_R8, DIS_YSBC_R8, DIS_YSBC_R8, DIS_FD_NOP, /* 0xa0 - 0xa3 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0xa4 - 0xa7 */ DIS_YAND_R8, DIS_YAND_R8, DIS_YAND_R8, DIS_FD_NOP, /* 0xa8 - 0xab */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0xac - 0xaf */ DIS_YYOR_R8, DIS_YYOR_R8, DIS_YYOR_R8, DIS_FD_NOP, /* 0xb0 - 0xb3 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0xb4 - 0xb7 */ DIS_Y_OR_R8, DIS_Y_OR_R8, DIS_Y_OR_R8, DIS_FD_NOP, /* 0xb8 - 0xbb */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0xbc - 0xbf */ DIS_YCP_R8, DIS_YCP_R8, DIS_YCP_R8, DIS_FD_NOP, /* 0xc0 - 0xc3 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0xc4 - 0xc7 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0xc8 - 0xcb */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_CB_DECODE, /* 0xcc - 0xcf */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0xd0 - 0xd3 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0xd4 - 0xd7 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0xd8 - 0xdb */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0xdc - 0xdf */ DIS_FD_NOP, DIS_FD_DD_DECODE, DIS_FD_NOP, DIS_FD_NOP, /* 0xe0 - 0xe3 */ DIS_FD_NOP, DIS_POP_IY, DIS_FD_NOP, DIS_EY_ISP_IY, /* 0xe4 - 0xe7 */ DIS_FD_NOP, DIS_PUSH_IY, DIS_FD_NOP, DIS_FD_NOP, /* 0xe8 - 0xeb */ DIS_FD_NOP, DIS_JP_IY, DIS_FD_NOP, DIS_FD_NOP, /* 0xec - 0xef */ DIS_FD_NOP, DIS_FD_ED_DECODE, DIS_FD_NOP, DIS_FD_NOP, /* 0xf0 - 0xf3 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0xf4 - 0xf7 */ DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, DIS_FD_NOP, /* 0xf8 - 0xfb */ DIS_FD_NOP, DIS_LD_SP_IY, DIS_FD_NOP, DIS_FD_NOP, /* 0xfc - 0xff */ DIS_FD_NOP, DIS_FD_FD_DECODE, DIS_FD_NOP, DIS_FD_NOP, }; /* DIS_FD DIS_CB opcodes */ dis_FD_CB_opcode = new disassemble[0x100] { /* 0x00 - 0x03 */ DIS_RLC_IY, DIS_RLC_IY, DIS_RLC_IY, DIS_RLC_IY, /* 0x04 - 0x07 */ DIS_RLC_IY, DIS_RLC_IY, DIS_RLC_IY, DIS_RLC_IY, /* 0x08 - 0x0b */ DIS_RRC_IY, DIS_RRC_IY, DIS_RRC_IY, DIS_RRC_IY, /* 0x0c - 0x0f */ DIS_RRC_IY, DIS_RRC_IY, DIS_RRC_IY, DIS_RRC_IY, /* 0x10 - 0x13 */ DIS_RL_IY, DIS_RL_IY, DIS_RL_IY, DIS_RL_IY, /* 0x14 - 0x17 */ DIS_RL_IY, DIS_RL_IY, DIS_RL_IY, DIS_RL_IY, /* 0x18 - 0x1b */ DIS_RR_IY, DIS_RR_IY, DIS_RR_IY, DIS_RR_IY, /* 0x1c - 0x1f */ DIS_RR_IY, DIS_RR_IY, DIS_RR_IY, DIS_RR_IY, /* 0x20 - 0x23 */ DIS_SLA_IY, DIS_SLA_IY, DIS_SLA_IY, DIS_SLA_IY, /* 0x24 - 0x27 */ DIS_SLA_IY, DIS_SLA_IY, DIS_SLA_IY, DIS_SLA_IY, /* 0x28 - 0x2b */ DIS_SRA_IY, DIS_SRA_IY, DIS_SRA_IY, DIS_SRA_IY, /* 0x2c - 0x2f */ DIS_SRA_IY, DIS_SRA_IY, DIS_SRA_IY, DIS_SRA_IY, /* 0x30 - 0x33 */ DIS_SLL_IY, DIS_SLL_IY, DIS_SLL_IY, DIS_SLL_IY, /* 0x34 - 0x37 */ DIS_SLL_IY, DIS_SLL_IY, DIS_SLL_IY, DIS_SLL_IY, /* 0x38 - 0x3b */ DIS_SRL_IY, DIS_SRL_IY, DIS_SRL_IY, DIS_SRL_IY, /* 0x3c - 0x3f */ DIS_SRL_IY, DIS_SRL_IY, DIS_SRL_IY, DIS_SRL_IY, /* 0x40 - 0x43 */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x44 - 0x47 */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x48 - 0x4b */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x4c - 0x4f */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x50 - 0x53 */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x54 - 0x57 */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x58 - 0x5b */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x5c - 0x5f */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x60 - 0x63 */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x64 - 0x67 */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x68 - 0x6b */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x6c - 0x6f */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x70 - 0x73 */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x74 - 0x77 */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x78 - 0x7b */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x7c - 0x7f */ DIS_BIT_IY,DIS_BIT_IY, DIS_BIT_IY, DIS_BIT_IY, /* 0x80 - 0x83 */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0x84 - 0x87 */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0x88 - 0x8b */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0x8c - 0x8f */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0x90 - 0x93 */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0x94 - 0x97 */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0x98 - 0x9b */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0x9c - 0x9f */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0xa0 - 0xa3 */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0xa4 - 0xa7 */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0xa8 - 0xab */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0xac - 0xaf */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0xb0 - 0xb3 */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0xb4 - 0xb7 */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0xb8 - 0xbb */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0xbc - 0xbf */ DIS_RES_IY,DIS_RES_IY, DIS_RES_IY, DIS_RES_IY, /* 0xc0 - 0xc3 */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xc4 - 0xc7 */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xc8 - 0xcb */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xcc - 0xcf */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xd0 - 0xd3 */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xd4 - 0xd7 */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xd8 - 0xdb */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xdc - 0xdf */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xe0 - 0xe3 */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xe4 - 0xe7 */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xe8 - 0xeb */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xec - 0xef */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xf0 - 0xf3 */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xf4 - 0xf7 */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xf8 - 0xfb */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, /* 0xfc - 0xff */ DIS_SET_IY,DIS_SET_IY, DIS_SET_IY, DIS_SET_IY, }; /* DIS_First/single byte opcodes */ dis_opcode_z80 = new disassemble[0x100] { /* 0x00 - 0x03 */ DIS_NOP, DIS_LD_R16_WORD, DIS_LD_R16_A, DIS_INC_R16, /* 0x04 - 0x07 */ DIS_INC_R8, DIS_DEC_R8, DIS_LD_R8_BYTE, DIS_RLCA, /* 0x08 - 0x0b */ DIS_EX_AF_AF, DIS_ADD_HL_R16, DIS_LD_A_R16, DIS_DEC_R16, /* 0x0c - 0x0f */ DIS_INC_R8, DIS_DEC_R8, DIS_LD_R8_BYTE, DIS_RRCA, /* 0x10 - 0x13 */ DIS_DJNZ, DIS_LD_R16_WORD, DIS_LD_R16_A, DIS_INC_R16, /* 0x14 - 0x17 */ DIS_INC_R8, DIS_DEC_R8, DIS_LD_R8_BYTE, DIS_RLA, /* 0x18 - 0x1b */ DIS_JR, DIS_ADD_HL_R16, DIS_LD_A_R16, DIS_DEC_R16, /* 0x1c - 0x1f */ DIS_INC_R8, DIS_DEC_R8, DIS_LD_R8_BYTE, DIS_RRA, /* 0x20 - 0x23 */ DIS_JR_CO, DIS_LD_R16_WORD, DIS_LD_ADDR_HL, DIS_INC_R16, /* 0x24 - 0x27 */ DIS_INC_R8, DIS_DEC_R8, DIS_LD_R8_BYTE, DIS_DAA, /* 0x28 - 0x2b */ DIS_JR_CO, DIS_ADD_HL_R16, DIS_LD_HL_ADDR, DIS_DEC_R16, /* 0x2c - 0x2f */ DIS_INC_R8, DIS_DEC_R8, DIS_LD_R8_BYTE, DIS_CPL, /* 0x30 - 0x33 */ DIS_JR_CO, DIS_LD_R16_WORD, DIS_LD_ADDR_A, DIS_INC_R16, /* 0x34 - 0x37 */ DIS_INC_R8, DIS_DEC_R8, DIS_LD_R8_BYTE, DIS_SCF, /* 0x38 - 0x3b */ DIS_JR_CO, DIS_ADD_HL_R16, DIS_LD_A_ADDR, DIS_DEC_R16, /* 0x3c - 0x3f */ DIS_INC_R8, DIS_DEC_R8, DIS_LD_R8_BYTE, DIS_CCF, /* 0x40 - 0x43 */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x44 - 0x47 */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x48 - 0x4b */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x4c - 0x4f */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x50 - 0x53 */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x54 - 0x57 */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x58 - 0x5b */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x5c - 0x5f */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x60 - 0x63 */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x64 - 0x67 */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x68 - 0x6b */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x6c - 0x6f */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x70 - 0x73 */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x74 - 0x77 */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_HALT, DIS_LD_R8_R8, /* 0x78 - 0x7b */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x7c - 0x7f */ DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, DIS_LD_R8_R8, /* 0x80 - 0x83 */ DIS_ADD_R8, DIS_ADD_R8, DIS_ADD_R8, DIS_ADD_R8, /* 0x84 - 0x87 */ DIS_ADD_R8, DIS_ADD_R8, DIS_ADD_R8, DIS_ADD_R8, /* 0x88 - 0x8b */ DIS_ADC_R8, DIS_ADC_R8, DIS_ADC_R8, DIS_ADC_R8, /* 0x8c - 0x8f */ DIS_ADC_R8, DIS_ADC_R8, DIS_ADC_R8, DIS_ADC_R8, /* 0x90 - 0x93 */ DIS_SUB_R8, DIS_SUB_R8, DIS_SUB_R8, DIS_SUB_R8, /* 0x94 - 0x97 */ DIS_SUB_R8, DIS_SUB_R8, DIS_SUB_R8, DIS_SUB_R8, /* 0x98 - 0x9b */ DIS_SBC_R8, DIS_SBC_R8, DIS_SBC_R8, DIS_SBC_R8, /* 0x9c - 0x9f */ DIS_SBC_R8, DIS_SBC_R8, DIS_SBC_R8, DIS_SBC_R8, /* 0xa0 - 0xa3 */ DIS_AND_R8, DIS_AND_R8, DIS_AND_R8, DIS_AND_R8, /* 0xa4 - 0xa7 */ DIS_AND_R8, DIS_AND_R8, DIS_AND_R8, DIS_AND_R8, /* 0xa8 - 0xab */ DIS_XOR_R8, DIS_XOR_R8, DIS_XOR_R8, DIS_XOR_R8, /* 0xac - 0xaf */ DIS_XOR_R8, DIS_XOR_R8, DIS_XOR_R8, DIS_XOR_R8, /* 0xb0 - 0xb3 */ DIS_OR_R8, DIS_OR_R8, DIS_OR_R8, DIS_OR_R8, /* 0xb4 - 0xb7 */ DIS_OR_R8, DIS_OR_R8, DIS_OR_R8, DIS_OR_R8, /* 0xb8 - 0xbb */ DIS_CP_R8, DIS_CP_R8, DIS_CP_R8, DIS_CP_R8, /* 0xbc - 0xbf */ DIS_CP_R8, DIS_CP_R8, DIS_CP_R8, DIS_CP_R8, /* 0xc0 - 0xc3 */ DIS_RET_CO, DIS_POP_R16, DIS_JP_CO, DIS_JP, /* 0xc4 - 0xc7 */ DIS_CALL_CO, DIS_PUSH_R16, DIS_ADD_A_BYTE, DIS_RST, /* 0xc8 - 0xcb */ DIS_RET_CO, DIS_RET, DIS_JP_CO, DIS_CB_DECODE, /* 0xcc - 0xcf */ DIS_CALL_CO, DIS_CALL, DIS_ADC_A_BYTE, DIS_RST, /* 0xd0 - 0xd3 */ DIS_RET_CO, DIS_POP_R16, DIS_JP_CO, DIS_OUT_BYTE_A, /* 0xd4 - 0xd7 */ DIS_CALL_CO, DIS_PUSH_R16, DIS_SUB_A_BYTE, DIS_RST, /* 0xd8 - 0xdb */ DIS_RET_CO, DIS_EXX, DIS_JP_CO, DIS_IN_A_BYTE, /* 0xdc - 0xdf */ DIS_CALL_CO, DIS_DD_DECODE, DIS_SBC_A_BYTE, DIS_RST, /* 0xe0 - 0xe3 */ DIS_RET_CO, DIS_POP_R16, DIS_JP_CO, DIS_EX_ISP_HL, /* 0xe4 - 0xe7 */ DIS_CALL_CO, DIS_PUSH_R16, DIS_AND_A_BYTE, DIS_RST, /* 0xe8 - 0xeb */ DIS_RET_CO, DIS_JP_HL, DIS_JP_CO, DIS_EX_DE_HL, /* 0xec - 0xef */ DIS_CALL_CO, DIS_ED_DECODE, DIS_XOR_A_BYTE, DIS_RST, /* 0xf0 - 0xf3 */ DIS_RET_CO, DIS_POP_R16, DIS_JP_CO, DIS_DI, /* 0xf4 - 0xf7 */ DIS_CALL_CO, DIS_PUSH_R16, DIS_OR_A_BYTE, DIS_RST, /* 0xf8 - 0xfb */ DIS_RET_CO, DIS_LD_SP_HL, DIS_JP_CO, DIS_EI, /* 0xfc - 0xff */ DIS_CALL_CO, DIS_FD_DECODE, DIS_CP_A_BYTE, DIS_RST, }; } #endregion #region IDisassembler interface public void Initialise(IMemory memory) { this.memory = memory; } public ushort Disassemble(ushort startAddress, out string address, out string opcode, out string hexdump) { address = String.Format("{0:X4}", startAddress); Hex.Clear(); byte op = Z80_Dis_FetchByte(ref startAddress); dis_opcode_z80[op](op, ref startAddress); opcode = String.Format("{0,-5} {1}", Opcode, Argument); hexdump = Hex.ToString(); return startAddress; } #endregion } }