/* * Copyright 2001, 2007, 2015 Alex Makeev * * This file is part of ZXMAK2 (ZX Spectrum virtual machine). * * ZXMAK2 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. * * ZXMAK2 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 ZXMAK2. If not, see . * * Description: Z80 Disassembler * Date: 13.04.2007 * */ using System; namespace ZXMAK2.Engine.Cpu.Tools { public class DasmTool(Func memRead, bool isHex = true) { private readonly Func _memRead = memRead; public bool IsHex { get; set; } = isHex; public string GetMnemonic(int addr, out int length) { if (_memRead == null) { length = 1; return "N/A"; } var curPtr = 0x0000; var opCode = _memRead((ushort)(addr + curPtr)); length = 1; var fxReg = "*prefix*"; var plusMinusOffsetIndex = 0; string mnem; if (opCode == 0xCB) { curPtr++; length++; var data = _memRead((ushort)(addr + curPtr)); mnem = CBhZ80Code[data]; } else if (opCode == 0xED) { curPtr++; length++; var data = _memRead((ushort)(addr + curPtr)); mnem = EDhZ80Code[data]; if (mnem.Length == 0) { mnem = "*NOP"; } } else if ((opCode == 0xDD) || (opCode == 0xFD)) { REPREFIX_DDFD: opCode = _memRead((ushort)(addr + curPtr)); fxReg = opCode == 0xDD ? "IX" : "IY"; curPtr++; plusMinusOffsetIndex = 1; length++; var fxCode = _memRead((ushort)(addr + curPtr)); if (fxCode == 0xCB) { curPtr++; length++; plusMinusOffsetIndex = 0; var data = _memRead((ushort)(addr + curPtr + 1)); mnem = DDFDCBhZ80Code[data]; if (mnem.Length == 0) { length++; // ??? for CBh } } else if (fxCode == 0xED) { curPtr++; length++; var data = _memRead((ushort)(addr + curPtr)); mnem = EDhZ80Code[data]; if (mnem.Length == 0) { mnem = "*NOP"; } if (mnem[0] != '*') { mnem = "*" + mnem; // mark undocumented as "*"... } } else if (fxCode == 0xDD || fxCode == 0xFD) // DD/FD, DD/FD { goto REPREFIX_DDFD; } else { var data = _memRead((ushort)(addr + curPtr)); mnem = DDFDhZ80Code[data]; } if (mnem.Length == 0) { var data = _memRead((ushort)(addr + curPtr)); mnem = "*" + DirectZ80Code[data]; } } else { var data = _memRead((ushort)(addr + curPtr)); mnem = DirectZ80Code[data]; } if (mnem.IndexOf('$') < 0) { return mnem; } do { if (mnem.Contains("$R", StringComparison.CurrentCulture)) // Prefix register { var pos = mnem.IndexOf("$R"); if (mnem.Length <= (pos + 1 + 1)) // ixl/ixh -> xl/xh !!!!! { mnem = mnem.Remove(pos, 2); mnem = mnem.Insert(pos, fxReg); } else if ((mnem[pos + 2] == 'L') || (mnem[pos + 2] == 'H')) { mnem = mnem.Remove(pos, 2); mnem = mnem.Insert(pos, "" + fxReg[1]); } else { mnem = mnem.Remove(pos, 2); mnem = mnem.Insert(pos, fxReg); } } if (mnem.Contains("$PLUS", StringComparison.CurrentCulture)) // PrefixReg+-offset { var data = (sbyte)_memRead((ushort)(addr + (curPtr + plusMinusOffsetIndex))); var txtValue = FormatOffset(data); var pos = mnem.IndexOf("$PLUS"); mnem = mnem.Remove(pos, 5); mnem = mnem.Insert(pos, txtValue); length++; curPtr++; } if (mnem.Contains("$S", StringComparison.CurrentCulture)) // Internal bits value { var data = _memRead((ushort)(addr + curPtr)); var bitadr = (data & 0x38) >> 3; var txtValue = string.Format("{0}", bitadr); var pos = mnem.IndexOf("$S"); mnem = mnem.Remove(pos, 2); mnem = mnem.Insert(pos, txtValue); } if (mnem.Contains("$W", StringComparison.CurrentCulture)) // 2byte value { var data = (ushort)(_memRead((ushort)(addr + curPtr + 1)) + 256 * _memRead((ushort)(addr + curPtr + 2))); var txtValue = FormatWord(data); var pos = mnem.IndexOf("$W"); mnem = mnem.Remove(pos, 2); mnem = mnem.Insert(pos, txtValue); length += 2; } if (mnem.Contains("$N", StringComparison.CurrentCulture)) // 1byte value { var data = _memRead((ushort)(addr + curPtr + 1)); var txtValue = FormatByte(data); var pos = mnem.IndexOf("$N"); mnem = mnem.Remove(pos, 2); mnem = mnem.Insert(pos, txtValue); length++; } if (mnem.Contains("$T", StringComparison.CurrentCulture)) // Internal bits value ($S)*8 { var data = _memRead((ushort)(addr + curPtr)); var rstadr = (byte)(((data & 0x38) >> 3) * 8); var txtValue = FormatByte(rstadr); var pos = mnem.IndexOf("$T"); mnem = mnem.Remove(pos, 2); mnem = mnem.Insert(pos, txtValue); } if (mnem.Contains("$DIS", StringComparison.CurrentCulture)) // 1byte offset value { var data = (sbyte)_memRead((ushort)(addr + curPtr + 1)); var adr = (ushort)((addr + 2 + curPtr) + data); var txtValue = FormatWord(adr); var pos = mnem.IndexOf("$DIS"); mnem = mnem.Remove(pos, 4); mnem = mnem.Insert(pos, txtValue); length++; } } while (mnem.Contains('$', StringComparison.CurrentCulture)); return mnem; } #region Format private string FormatByte(byte val) { return IsHex ? string.Format("#{0:X2}", val) : string.Format("{0}", val); } private string FormatWord(ushort val) { return IsHex ? string.Format("#{0:X4}", val) : string.Format("{0}", val); } private string FormatOffset(sbyte val) { var absVal = val < 0 ? -val : val; var result = IsHex ? string.Format("#{0:X2}", absVal) : string.Format("{0}", absVal); var sign = val < 0 ? "-" : "+"; return sign + result; } #endregion Format #region Table Direct private static readonly string[] DirectZ80Code = [ "NOP", // 0x00 "LD BC,$W", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,$N", "RLCA", "EX AF,AF'", "ADD HL,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,$N", "RRCA", "DJNZ $DIS", // 0x10 "LD DE,$W", "LD (DE),A", "INC DE", "INC D", "DEC D", "LD D,$N", "RLA", "JR $DIS", "ADD HL,DE", "LD A,(DE)", "DEC DE", "INC E", "DEC E", "LD E,$N", "RRA", "JR NZ,$DIS", // 0x20 "LD HL,$W", "LD ($W),HL", "INC HL", "INC H", "DEC H", "LD H,$N", "DAA", "JR Z,$DIS", "ADD HL,HL", "LD HL,($W)", "DEC HL", "INC L", "DEC L", "LD L,$N", "CPL", "JR NC,$DIS", // 0x30 "LD SP,$W", "LD ($W),A", "INC SP", "INC (HL)", "DEC (HL)", "LD (HL),$N", "SCF", "JR C,$DIS", // 0x38 "ADD HL,SP", "LD A,($W)", "DEC SP", "INC A", "DEC A", "LD A,$N", "CCF", // 0x3F "LD B,B", // 0x40 "LD B,C", "LD B,D", "LD B,E", "LD B,H", "LD B,L", "LD B,(HL)", "LD B,A", "LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,H", "LD C,L", "LD C,(HL)", "LD C,A", "LD D,B", // 0x50 "LD D,C", "LD D,D", "LD D,E", "LD D,H", "LD D,L", "LD D,(HL)", "LD D,A", "LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,H", "LD E,L", "LD E,(HL)", "LD E,A", "LD H,B", // 0x60 "LD H,C", "LD H,D", "LD H,E", "LD H,H", "LD H,L", "LD H,(HL)", "LD H,A", "LD L,B", "LD L,C", "LD L,D", "LD L,E", "LD L,H", "LD L,L", "LD L,(HL)", "LD L,A", "LD (HL),B", // 0x70 "LD (HL),C", "LD (HL),D", "LD (HL),E", "LD (HL),H", "LD (HL),L", "HALT", "LD (HL),A", "LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,H", "LD A,L", "LD A,(HL)", "LD A,A", "ADD A,B", // 0x80 "ADD A,C", "ADD A,D", "ADD A,E", "ADD A,H", "ADD A,L", "ADD A,(HL)", "ADD A,A", "ADC A,B", "ADC A,C", "ADC A,D", "ADC A,E", "ADC A,H", "ADC A,L", "ADC A,(HL)", "ADC A,A", "SUB B", // 0x90 "SUB C", "SUB D", "SUB E", "SUB H", "SUB L", "SUB (HL)", "SUB A", "SBC A,B", "SBC A,C", "SBC A,D", "SBC A,E", "SBC A,H", "SBC A,L", "SBC A,(HL)", "SBC A,A", "AND B", // 0xA0 "AND C", "AND D", "AND E", "AND H", "AND L", "AND (HL)", "AND A", "XOR B", "XOR C", "XOR D", "XOR E", "XOR H", "XOR L", "XOR (HL)", "XOR A", "OR B", // 0xB0 "OR C", "OR D", "OR E", "OR H", "OR L", "OR (HL)", "OR A", "CP B", "CP C", "CP D", "CP E", "CP H", "CP L", "CP (HL)", "CP A", // 0xBF "RET NZ", // 0xC0 "POP BC", "JP NZ,$W", "JP $W", "CALL NZ,$W", "PUSH BC", "ADD A,$N", "RST $T", "RET Z", "RET", "JP Z,$W", "*CB", // 0xCB "CALL Z,$W", "CALL $W", "ADC A,$N", "RST $T", "RET NC", // 0xD0 "POP DE", "JP NC,$W", "OUT ($N),A", "CALL NC,$W", "PUSH DE", "SUB $N", "RST $T", "RET C", "EXX", "JP C,$W", "IN A,($N)", "CALL C,$W", "*IX", // 0xDD "SBC A,$N", "RST $T", "RET PO", // 0xE0 "POP HL", "JP PO,$W", "EX (SP),HL", "CALL PO,$W", "PUSH HL", "AND $N", "RST $T", "RET PE", "JP (HL)", "JP PE,$W", "EX DE,HL", "CALL PE,$W", "*ED", // 0xED "XOR $N", "RST $T", "RET P", // 0xF0 "POP AF", "JP P,$W", "DI", "CALL P,$W", "PUSH AF", "OR $N", "RST $T", "RET M", "LD SP,HL", "JP M,$W", "EI", "CALL M,$W", "*IY", // 0xFD "CP $N", "RST $T" ]; #endregion Direct #region Table #CB private static readonly string[] CBhZ80Code = [ "RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (HL)", "RLC A", "RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (HL)", "RRC A", "RL B", "RL C", "RL D", "RL E", "RL H", "RL L", "RL (HL)", "RL A", "RR B", "RR C", "RR D", "RR E", "RR H", "RR L", "RR (HL)", "RR A", "SLA B", "SLA C", "SLA D", "SLA E", "SLA H", "SLA L", "SLA (HL)", "SLA A", "SRA B", "SRA C", "SRA D", "SRA E", "SRA H", "SRA L", "SRA (HL)", "SRA A", "*SLL B", // SLL or SLI (UNDOCUMENTED) "*SLL C", "*SLL D", "*SLL E", "*SLL H", "*SLL L", "*SLL (HL)", "*SLL A", "SRL B", "SRL C", "SRL D", "SRL E", "SRL H", "SRL L", "SRL (HL)", "SRL A", "BIT $S,B", // Bit 0 "BIT $S,C", "BIT $S,D", "BIT $S,E", "BIT $S,H", "BIT $S,L", "BIT $S,(HL)", "BIT $S,A", "BIT $S,B", // Bit 1 "BIT $S,C", "BIT $S,D", "BIT $S,E", "BIT $S,H", "BIT $S,L", "BIT $S,(HL)", "BIT $S,A", "BIT $S,B", // Bit 2 "BIT $S,C", "BIT $S,D", "BIT $S,E", "BIT $S,H", "BIT $S,L", "BIT $S,(HL)", "BIT $S,A", "BIT $S,B", // Bit 3 "BIT $S,C", "BIT $S,D", "BIT $S,E", "BIT $S,H", "BIT $S,L", "BIT $S,(HL)", "BIT $S,A", "BIT $S,B", // Bit 4 "BIT $S,C", "BIT $S,D", "BIT $S,E", "BIT $S,H", "BIT $S,L", "BIT $S,(HL)", "BIT $S,A", "BIT $S,B", // Bit 5 "BIT $S,C", "BIT $S,D", "BIT $S,E", "BIT $S,H", "BIT $S,L", "BIT $S,(HL)", "BIT $S,A", "BIT $S,B", // Bit 6 "BIT $S,C", "BIT $S,D", "BIT $S,E", "BIT $S,H", "BIT $S,L", "BIT $S,(HL)", "BIT $S,A", "BIT $S,B", // Bit 7 "BIT $S,C", "BIT $S,D", "BIT $S,E", "BIT $S,H", "BIT $S,L", "BIT $S,(HL)", "BIT $S,A", "RES $S,B", // Bit 0 "RES $S,C", "RES $S,D", "RES $S,E", "RES $S,H", "RES $S,L", "RES $S,(HL)", "RES $S,A", "RES $S,B", // Bit 1 "RES $S,C", "RES $S,D", "RES $S,E", "RES $S,H", "RES $S,L", "RES $S,(HL)", "RES $S,A", "RES $S,B", // Bit 2 "RES $S,C", "RES $S,D", "RES $S,E", "RES $S,H", "RES $S,L", "RES $S,(HL)", "RES $S,A", "RES $S,B", // Bit 3 "RES $S,C", "RES $S,D", "RES $S,E", "RES $S,H", "RES $S,L", "RES $S,(HL)", "RES $S,A", "RES $S,B", // Bit 4 "RES $S,C", "RES $S,D", "RES $S,E", "RES $S,H", "RES $S,L", "RES $S,(HL)", "RES $S,A", "RES $S,B", // Bit 5 "RES $S,C", "RES $S,D", "RES $S,E", "RES $S,H", "RES $S,L", "RES $S,(HL)", "RES $S,A", "RES $S,B", // Bit 6 "RES $S,C", "RES $S,D", "RES $S,E", "RES $S,H", "RES $S,L", "RES $S,(HL)", "RES $S,A", "RES $S,B", // Bit 7 "RES $S,C", "RES $S,D", "RES $S,E", "RES $S,H", "RES $S,L", "RES $S,(HL)", "RES $S,A", "SET $S,B", // Bit 0 "SET $S,C", "SET $S,D", "SET $S,E", "SET $S,H", "SET $S,L", "SET $S,(HL)", "SET $S,A", "SET $S,B", // Bit 1 "SET $S,C", "SET $S,D", "SET $S,E", "SET $S,H", "SET $S,L", "SET $S,(HL)", "SET $S,A", "SET $S,B", // Bit 2 "SET $S,C", "SET $S,D", "SET $S,E", "SET $S,H", "SET $S,L", "SET $S,(HL)", "SET $S,A", "SET $S,B", // Bit 3 "SET $S,C", "SET $S,D", "SET $S,E", "SET $S,H", "SET $S,L", "SET $S,(HL)", "SET $S,A", "SET $S,B", // Bit 4 "SET $S,C", "SET $S,D", "SET $S,E", "SET $S,H", "SET $S,L", "SET $S,(HL)", "SET $S,A", "SET $S,B", // Bit 5 "SET $S,C", "SET $S,D", "SET $S,E", "SET $S,H", "SET $S,L", "SET $S,(HL)", "SET $S,A", "SET $S,B", // Bit 6 "SET $S,C", "SET $S,D", "SET $S,E", "SET $S,H", "SET $S,L", "SET $S,(HL)", "SET $S,A", "SET $S,B", // Bit 7 "SET $S,C", "SET $S,D", "SET $S,E", "SET $S,H", "SET $S,L", "SET $S,(HL)", "SET $S,A", ]; #endregion Table #CB #region Table #ED private static readonly string[] EDhZ80Code = [ "", // 0x00 "", "", "", "", "", "", "", "", // 0x08 "", "", "", "", "", "", "", "", // 0x10 "", "", "", "", "", "", "", "", // 0x18 "", "", "", "", "", "", "", "", // 0x20 "", "", "", "", "", "", "", "", // 0x28 "", "", "", "", "", "", "", "", // 0x30 "", "", "", "", "", "", "", "", // 0x38 "", "", "", "", "", "", "", "IN B,(C)", // 0x40 "OUT (C),B", // 0x41 "SBC HL,BC", // 0x42 "LD ($W),BC", // 0x43 "NEG", // 0x44 "RETN", // 0x45 "IM 0", // 0x46 "LD I,A", // 0x47 "IN C,(C)", // 0x48 "OUT (C),C", // 0x49 "ADC HL,BC", // 0x4A "LD BC,($W)", // 0x4B "*NEG", // 0x4C undocumented "RETI", // 0x4D "*IM 0", // 0x4E "LD R,A", // 0x4F "IN D,(C)", // 0x50 "OUT (C),D", // 0x51 "SBC HL,DE", // 0x52 "LD ($W),DE", // 0x53 "*NEG", // 0x54 "*RETN", // 0x55 "IM 1", // 0x56 "LD A,I", // 0x57 "IN E,(C)", // 0x58 "OUT (C),E", // 0x59 "ADC HL,DE", // 0x5A "LD DE,($W)", // 0x5B "*NEG", // 0x5C "*RETN", // 0x5D "IM 2", // 0x5E "LD A,R", // 0x5F "IN H,(C)", // 0x60 "OUT (C),H", // 0x61 "SBC HL,HL", // 0x62 "LD ($W),HL", // 0x63 "*NEG", // 0x64 "*RETN", // 0x65 "*IM 0", // 0x66 "RRD", // 0x67 "IN L,(C)", // 0x68 "OUT (C),L", // 0x69 "ADC HL,HL", // 0x6A "LD HL,($W)", // 0x6B "*NEG", // 0x6C "*RETN", // 0x6D "*IM 0", // 0x6E "RLD", // 0x6F "*IN (C)", // 0x70 NON STORED INPUT PORT! (Only flags) "*OUT (C),0", // 0x71 "SBC HL,SP", // 0x72 "LD ($W),SP", // 0x73 "*NEG", // 0x74 "*RETN", // 0x75 "*IM 1", // 0x76 "*NOP", // 0x77 "IN A,(C)", // 0x78 "OUT (C),A", // 0x79 "ADC HL,SP", // 0x7A "LD SP,($W)", // 0x7B "*NEG", // 0x7C "*RETN", // 0x7D "*IM 2", // 0x7E "*NOP", // 0x7F "", // 0x80 "", "", "", "", "", "", "", "", // 0x88 "", "", "", "", "", "", "", "", // 0x90 "", "", "", "", "", "", "", "", // 0x98 "", "", "", "", "", "", "", "LDI", // 0xA0 "CPI", // 0xA1 "INI", // 0xA2 "OUTI", // 0xA3 "", "", "", "", "LDD", // 0xA8 "CPD", // 0xA9 "IND", // 0xAA "OUTD", // 0xAB "", "", "", "", "LDIR", // 0xB0 "CPIR", // 0xB1 "INIR", // 0xB2 "OTIR", // 0xB3 "", "", "", "", "LDDR", // 0xB8 "CPDR", // 0xB9 "INDR", // 0xBA "OTDR", // 0xBB "", "", "", "", "", // 0xC0 "", "", "", "", "", "", "", "", // 0xC8 "", "", "", "", "", "", "", "", // 0xD0 "", "", "", "", "", "", "", "", // 0xD8 "", "", "", "", "", "", "", "", // 0xE0 "", "", "", "", "", "", "", "", // 0xE8 "", "", "", "", "", "", "", "", // 0xF0 "", "", "", "", "", "", "", "", // 0xF8 "", "", "", "", "", "", "" ]; #endregion Table #ED #region Table #DD/#FD private static readonly string[] DDFDhZ80Code = [ "", // 0x00 "", "", "", "", "", "", "", "", // 0x08 "ADD $R,BC", "", "", "", "", "", "", "", // 0x10 "", "", "", "", "", "", "", "", // 0x18 "ADD $R,DE", "", "", "", "", "", "", "", // 0x20 "LD $R,$W", "LD ($W),$R", "INC $R", "*INC $RH", "*DEC $RH", "*LD $RH,$N", "", "", // 0x28 "ADD $R,$R", "LD $R,($W)", "DEC $R", "*INC $RL", "*DEC $RL", "*LD $RL,$N", "", "", // 0x30 "", "", "", "INC ($R$PLUS)", "DEC ($R$PLUS)", "LD ($R$PLUS),$N", "", "", // 0x38 "ADD $R,SP", "", "", "", "", "", "", "", // 0x40 "", "", "", "*LD B,$RH", "*LD B,$RL", "LD B,($R$PLUS)", "", "", // 0x48 "", "", "", "*LD C,$RH", "*LD C,$RL", "LD C,($R$PLUS)", "", "", // 0x50 "", "", "", "*LD D,$RH", "*LD D,$RL", "LD D,($R$PLUS)", "", "", // 0x58 "", "", "", "*LD E,$RH", "*LD E,$RL", "LD E,($R$PLUS)", "", "*LD $RH,B", // 0x60 "*LD $RH,C", "*LD $RH,D", "*LD $RH,E", "*LD $RH,$RH", "*LD $RH,$RL", "LD H,($R$PLUS)", "*LD $RH,A", "*LD $RL,B", // 0x68 "*LD $RL,C", "*LD $RL,D", "*LD $RL,E", "*LD $RL,$RH", "*LD $RL,$RL", "LD L,($R$PLUS)", "*LD $RL,A", "LD ($R$PLUS),B", // 0x70 "LD ($R$PLUS),C", "LD ($R$PLUS),D", "LD ($R$PLUS),E", "LD ($R$PLUS),H", "LD ($R$PLUS),L", "", "LD ($R$PLUS),A", "", // 0x78 "", "", "", "*LD A,$RH", "*LD A,$RL", "LD A,($R$PLUS)", "", "", // 0x80 "", "", "", "*ADD A,$RH", "*ADD A,$RL", "ADD A,($R$PLUS)", "", "", // 0x88 "", "", "", "*ADC A,$RH", "*ADC A,$RL", "ADC A,($R$PLUS)", "", "", // 0x90 "", "", "", "*SUB $RH", "*SUB $RL", "SUB ($R$PLUS)", "", "", // 0x98 "", "", "", "*SBC A,$RH", "*SBC A,$RL", "SBC A,($R$PLUS)", "", "", // 0xA0 "", "", "", "*AND $RH", "*AND $RL", "AND ($R$PLUS)", "", "", // 0xA8 "", "", "", "*XOR $RH", "*XOR $RL", "XOR ($R$PLUS)", "", "", // 0xB0 "", "", "", "*OR $RH", "*OR $RL", "OR ($R$PLUS)", "", "", // 0xB8 "", "", "", "*CP $RH", "*CP $RL", "CP ($R$PLUS)", "", "", // 0xC0 "", "", "", "", "", "", "", "", // 0xC8 "", "", "*DD/FD,CB", "", "", "", "", "", // 0xD0 "", "", "", "", "", "", "", "", // 0xD8 "", "", "", "", "*DD/FD,DD", "", "", "", // 0xE0 "POP $R", "", "EX (SP),$R", "", "PUSH $R", "", "", "", // 0xE8 "JP ($R)", "", "", // EX DE,HL??? "", "*DD/FD,ED", "", "", "", // 0xF0 "", "", "", "", "", "", "", "", // 0xF8 "LD SP,$R", "", "", "", "*DD/FD,FD", "", "" ]; #endregion Table #DD/#FD #region Table #DD/#FD,#CB private static readonly string[] DDFDCBhZ80Code = [ "*RLC B,($R$PLUS)", // 0x00 "*RLC C,($R$PLUS)", "*RLC D,($R$PLUS)", "*RLC E,($R$PLUS)", "*RLC H,($R$PLUS)", "*RLC L,($R$PLUS)", "RLC ($R$PLUS)", "*RLC A,($R$PLUS)", "*RRC B,($R$PLUS)", // 0x08 "*RRC C,($R$PLUS)", "*RRC D,($R$PLUS)", "*RRC E,($R$PLUS)", "*RRC H,($R$PLUS)", "*RRC L,($R$PLUS)", "RRC ($R$PLUS)", "*RRC A,($R$PLUS)", "*RL B,($R$PLUS)", // 0x10 "*RL C,($R$PLUS)", "*RL D,($R$PLUS)", "*RL E,($R$PLUS)", "*RL H,($R$PLUS)", "*RL L,($R$PLUS)", "RL ($R$PLUS)", "*RL A,($R$PLUS)", "*RR B,($R$PLUS)", // 0x18 "*RR C,($R$PLUS)", "*RR D,($R$PLUS)", "*RR E,($R$PLUS)", "*RR H,($R$PLUS)", "*RR L,($R$PLUS)", "RR ($R$PLUS)", "*RR A,($R$PLUS)", "*SLA B,($R$PLUS)", // 0x20 "*SLA C,($R$PLUS)", "*SLA D,($R$PLUS)", "*SLA E,($R$PLUS)", "*SLA H,($R$PLUS)", "*SLA L,($R$PLUS)", "SLA ($R$PLUS)", "*SLA A,($R$PLUS)", "*SRA B,($R$PLUS)", // 0x28 "*SRA C,($R$PLUS)", "*SRA D,($R$PLUS)", "*SRA E,($R$PLUS)", "*SRA H,($R$PLUS)", "*SRA L,($R$PLUS)", "SRA ($R$PLUS)", "*SRA A,($R$PLUS)", "*SLL B,($R$PLUS)", // 0x30 "*SLL C,($R$PLUS)", "*SLL D,($R$PLUS)", "*SLL E,($R$PLUS)", "*SLL H,($R$PLUS)", "*SLL L,($R$PLUS)", "*SLL ($R$PLUS)", // SLI or SLL "*SLL A,($R$PLUS)", "*SRL B,($R$PLUS)", // 0x38 "*SRL C,($R$PLUS)", "*SRL D,($R$PLUS)", "*SRL E,($R$PLUS)", "*SRL H,($R$PLUS)", "*SRL L,($R$PLUS)", "SRL ($R$PLUS)", "*SRL A,($R$PLUS)", "*BIT $S,($R$PLUS)", // 0x40 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "BIT $S,($R$PLUS)", // BIT 0 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", // 0x48 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "BIT $S,($R$PLUS)", // BIT 1 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", // 0x50 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "BIT $S,($R$PLUS)", // BIT 2 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", // 0x58 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "BIT $S,($R$PLUS)", // BIT 3 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", // 0x60 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "BIT $S,($R$PLUS)", // BIT 4 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", // 0x68 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "BIT $S,($R$PLUS)", // BIT 5 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", // 0x70 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "BIT $S,($R$PLUS)", // BIT 6 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", // 0x78 "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "*BIT $S,($R$PLUS)", "BIT $S,($R$PLUS)", // BIT 7 "*BIT $S,($R$PLUS)", "*RES $S,B,($R$PLUS)", // 0x80 "*RES $S,C,($R$PLUS)", "*RES $S,D,($R$PLUS)", "*RES $S,E,($R$PLUS)", "*RES $S,H,($R$PLUS)", "*RES $S,L,($R$PLUS)", "RES $S,($R$PLUS)", // RES 0 "*RES $S,A,($R$PLUS)", "*RES $S,B,($R$PLUS)", // 0x88 "*RES $S,C,($R$PLUS)", "*RES $S,D,($R$PLUS)", "*RES $S,E,($R$PLUS)", "*RES $S,H,($R$PLUS)", "*RES $S,L,($R$PLUS)", "RES $S,($R$PLUS)", // RES 1 "*RES $S,A,($R$PLUS)", "*RES $S,B,($R$PLUS)", // 0x90 "*RES $S,C,($R$PLUS)", "*RES $S,D,($R$PLUS)", "*RES $S,E,($R$PLUS)", "*RES $S,H,($R$PLUS)", "*RES $S,L,($R$PLUS)", "RES $S,($R$PLUS)", // RES 2 "*RES $S,A,($R$PLUS)", "*RES $S,B,($R$PLUS)", // 0x98 "*RES $S,C,($R$PLUS)", "*RES $S,D,($R$PLUS)", "*RES $S,E,($R$PLUS)", "*RES $S,H,($R$PLUS)", "*RES $S,L,($R$PLUS)", "RES $S,($R$PLUS)", // RES 3 "*RES $S,A,($R$PLUS)", "*RES $S,B,($R$PLUS)", // 0xA0 "*RES $S,C,($R$PLUS)", "*RES $S,D,($R$PLUS)", "*RES $S,E,($R$PLUS)", "*RES $S,H,($R$PLUS)", "*RES $S,L,($R$PLUS)", "RES $S,($R$PLUS)", // RES 4 "*RES $S,A,($R$PLUS)", "*RES $S,B,($R$PLUS)", // 0xA8 "*RES $S,C,($R$PLUS)", "*RES $S,D,($R$PLUS)", "*RES $S,E,($R$PLUS)", "*RES $S,H,($R$PLUS)", "*RES $S,L,($R$PLUS)", "RES $S,($R$PLUS)", // RES 5 "*RES $S,A,($R$PLUS)", "*RES $S,B,($R$PLUS)", // 0xB0 "*RES $S,C,($R$PLUS)", "*RES $S,D,($R$PLUS)", "*RES $S,E,($R$PLUS)", "*RES $S,H,($R$PLUS)", "*RES $S,L,($R$PLUS)", "RES $S,($R$PLUS)", // RES 6 "*RES $S,A,($R$PLUS)", "*RES $S,B,($R$PLUS)", // 0xB8 "*RES $S,C,($R$PLUS)", "*RES $S,D,($R$PLUS)", "*RES $S,E,($R$PLUS)", "*RES $S,H,($R$PLUS)", "*RES $S,L,($R$PLUS)", "RES $S,($R$PLUS)", // RES 7 "*RES $S,A,($R$PLUS)", "*SET $S,B,($R$PLUS)", // 0xC0 "*SET $S,C,($R$PLUS)", "*SET $S,D,($R$PLUS)", "*SET $S,E,($R$PLUS)", "*SET $S,H,($R$PLUS)", "*SET $S,L,($R$PLUS)", "SET $S,($R$PLUS)", // SET 0 "*SET $S,A,($R$PLUS)", "*SET $S,B,($R$PLUS)", // 0xC8 "*SET $S,C,($R$PLUS)", "*SET $S,D,($R$PLUS)", "*SET $S,E,($R$PLUS)", "*SET $S,H,($R$PLUS)", "*SET $S,L,($R$PLUS)", "SET $S,($R$PLUS)", // SET 1 "*SET $S,A,($R$PLUS)", "*SET $S,B,($R$PLUS)", // 0xD0 "*SET $S,C,($R$PLUS)", "*SET $S,D,($R$PLUS)", "*SET $S,E,($R$PLUS)", "*SET $S,H,($R$PLUS)", "*SET $S,L,($R$PLUS)", "SET $S,($R$PLUS)", // SET 2 "*SET $S,A,($R$PLUS)", "*SET $S,B,($R$PLUS)", // 0xD8 "*SET $S,C,($R$PLUS)", "*SET $S,D,($R$PLUS)", "*SET $S,E,($R$PLUS)", "*SET $S,H,($R$PLUS)", "*SET $S,L,($R$PLUS)", "SET $S,($R$PLUS)", // SET 3 "*SET $S,A,($R$PLUS)", "*SET $S,B,($R$PLUS)", // 0xE0 "*SET $S,C,($R$PLUS)", "*SET $S,D,($R$PLUS)", "*SET $S,E,($R$PLUS)", "*SET $S,H,($R$PLUS)", "*SET $S,L,($R$PLUS)", "SET $S,($R$PLUS)", // SET 4 "*SET $S,A,($R$PLUS)", "*SET $S,B,($R$PLUS)", // 0xE8 "*SET $S,C,($R$PLUS)", "*SET $S,D,($R$PLUS)", "*SET $S,E,($R$PLUS)", "*SET $S,H,($R$PLUS)", "*SET $S,L,($R$PLUS)", "SET $S,($R$PLUS)", // SET 5 "*SET $S,A,($R$PLUS)", "*SET $S,B,($R$PLUS)", // 0xF0 "*SET $S,C,($R$PLUS)", "*SET $S,D,($R$PLUS)", "*SET $S,E,($R$PLUS)", "*SET $S,H,($R$PLUS)", "*SET $S,L,($R$PLUS)", "SET $S,($R$PLUS)", // SET 6 "*SET $S,A,($R$PLUS)", "*SET $S,B,($R$PLUS)", // 0xF8 "*SET $S,C,($R$PLUS)", "*SET $S,D,($R$PLUS)", "*SET $S,E,($R$PLUS)", "*SET $S,H,($R$PLUS)", "*SET $S,L,($R$PLUS)", "SET $S,($R$PLUS)", // SET 7 "*SET $S,A,($R$PLUS)", ]; #endregion Table #DD/#FD,#CB } }