BizHawk/BizHawk.Emulation/CPUs/Z80/Disassembler.cs

526 lines
30 KiB
C#

//http://www.zophar.net/fileuploads/2/10819kouzv/z80undoc.html
//TODO: ex. (IX+00h) could be turned into (IX)
//usage:
//VgMuseum.Z80.Disassembler disasm = new Disassembler();
//ushort pc = RegPC.Word;
//string str = disasm.Disassemble(() => ReadMemory(pc++));
//Console.WriteLine(str);
//please note that however much youre tempted to, timings can't be put in a table here because they depend on how the instruction executes at runtime
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.CPUs.Z80
{
public class Disassembler
{
readonly static sbyte[,] opcodeSizes = new sbyte[7, 256];
public static void GenerateOpcodeSizes()
{
Disassembler disasm = new Disassembler();
for (int i = 0; i < 256; i++)
{
int pc = 0;
byte[] opcode = { (byte)i, 0, 0, 0 };
disasm.Disassemble(() => opcode[pc++]);
opcodeSizes[0,i] = (sbyte)pc;
}
opcodeSizes[0, 0xCB] = -1;
opcodeSizes[0, 0xED] = -2;
opcodeSizes[0, 0xDD] = -3;
opcodeSizes[0, 0xFD] = -4;
for (int i = 0; i < 256; i++)
{
int pc = 0;
byte[] opcode = { 0xCB, (byte)i, 0, 0, 0 };
disasm.Disassemble(() => opcode[pc++]);
opcodeSizes[1, i] = (sbyte)pc;
}
for (int i = 0; i < 256; i++)
{
int pc = 0;
byte[] opcode = { 0xED, (byte)i, 0, 0, 0 };
disasm.Disassemble(() => opcode[pc++]);
opcodeSizes[2, i] = (sbyte)pc;
}
for (int i = 0; i < 256; i++)
{
int pc = 0;
byte[] opcode = { 0xDD, (byte)i, 0, 0, 0 };
disasm.Disassemble(() => opcode[pc++]);
opcodeSizes[3, i] = (sbyte)pc;
}
opcodeSizes[3, 0xCB] = -5;
opcodeSizes[3, 0xED] = -2;
for (int i = 0; i < 256; i++)
{
int pc = 0;
byte[] opcode = { 0xFD, (byte)i, 0, 0, 0 };
disasm.Disassemble(() => opcode[pc++]);
opcodeSizes[4, i] = (sbyte)pc;
}
opcodeSizes[3, 0xCB] = -6;
opcodeSizes[3, 0xED] = -2;
for (int i = 0; i < 256; i++)
{
int pc = 0;
byte[] opcode = { 0xDD, 0xCB, (byte)i, 0, 0, 0 };
disasm.Disassemble(() => opcode[pc++]);
opcodeSizes[5, i] = (sbyte)pc;
}
for (int i = 0; i < 256; i++)
{
int pc = 0;
byte[] opcode = { 0xFD, 0xCB, (byte)i, 0, 0, 0 };
disasm.Disassemble(() => opcode[pc++]);
opcodeSizes[6, i] = (sbyte)pc;
}
}
static string Result(string format, Func<byte> read)
{
//d immediately succeeds the opcode
//n immediate succeeds the opcode and the displacement (if present)
//nn immediately succeeds the opcode and the displacement (if present)
if (format.IndexOf("nn") != -1)
{
byte B = read();
byte C = read();
format = format.Replace("nn", string.Format("{0:X4}h", B + C * 256));
}
if (format.IndexOf("n") != -1)
{
byte B = read();
format = format.Replace("n", string.Format("{0:X2}h", B));
}
if(format.IndexOf("+d") != -1) format = format.Replace("+d","d");
if (format.IndexOf("d") != -1)
{
byte B = read();
bool neg = ((B & 0x80) != 0);
char sign = neg ? '-' : '+';
int val = neg ? 256 - B : B;
format = format.Replace("d", string.Format("{0}{1:X2}h", sign, val));
}
return format;
}
readonly static string[] mnemonics = new string[]
{
"NOP", "LD BC, nn", "LD (BC), A", "INC BC", //0x04
"INC B", "DEC B", "LD B, n", "RLCA", //0x08
"EX AF, AF'", "ADD HL, BC", "LD A, (BC)", "DEC BC", //0x0C
"INC C", "DEC C", "LD C, n", "RRCA", //0x10
"DJNZ d", "LD DE, nn", "LD (DE), A", "INC DE", //0x14
"INC D", "DEC D", "LD D, n", "RLA", //0x18
"JR d", "ADD HL, DE", "LD A, (DE)", "DEC DE", //0x1C
"INC E", "DEC E", "LD E, n", "RRA", //0x20
"JR NZ, d", "LD HL, nn", "LD (nn), HL", "INC HL", //0x24
"INC H", "DEC H", "LD H, n", "DAA", //0x28
"JR Z, d", "ADD HL, HL", "LD HL, (nn)", "DEC HL", //0x2C
"INC L", "DEC L", "LD L, n", "CPL", //0x30
"JR NC, d", "LD SP, nn", "LD (nn), A", "INC SP", //0x34
"INC (HL)", "DEC (HL)", "LD (HL), n", "SCF", //0x38
"JR C, d", "ADD HL, SP", "LD A, (nn)", "DEC SP", //0x3C
"INC A", "DEC A", "LD A, n", "CCF", //0x40
"LD B, B", "LD B, C", "LD B, D", "LD B, E", //0x44
"LD B, H", "LD B, L", "LD B, (HL)", "LD B, A", //0x48
"LD C, B", "LD C, C", "LD C, D", "LD C, E", //0x4C
"LD C, H", "LD C, L", "LD C, (HL)", "LD C, A", //0x50
"LD D, B", "LD D, C", "LD D, D", "LD D, E", //0x54
"LD D, H", "LD D, L", "LD D, (HL)", "LD D, A", //0x58
"LD E, B", "LD E, C", "LD E, D", "LD E, E", //0x5C
"LD E, H", "LD E, L", "LD E, (HL)", "LD E, A", //0x60
"LD H, B", "LD H, C", "LD H, D", "LD H, E", //0x64
"LD H, H", "LD H, L", "LD H, (HL)", "LD H, A", //0x68
"LD L, B", "LD L, B", "LD L, D", "LD L, E", //0x6C
"LD L, H", "LD L, L", "LD L, (HL)", "LD L, A", //0x70
"LD (HL), B", "LD (HL), C", "LD (HL), D", "LD (HL), E", //0x74
"LD (HL), H", "LD (HL), L", "HALT", "LD (HL), A", //0x78
"LD A, B", "LD A, C", "LD A, D", "LD A, E", //0x7C
"LD A, H", "LD A, L", "LD A, (HL)", "LD A, A", //0x80
"ADD A, B", "ADD A, C", "ADD A, D", "ADD A, E", //0x84
"ADD A, H", "ADD A, L", "ADD A, (HL)", "ADD A, A", //0x88
"ADC A, B", "ADC A, C", "ADC A, D", "ADC A, E", //0x8C
"ADC A, H", "ADC A, L", "ADC A, (HL)", "ADC A, A", //0x90
"SUB A, B", "SUB A, C", "SUB A, D", "SUB A, E", //0x94
"SUB A, H", "SUB A, L", "SUB A, (HL)", "SUB A, A", //0x98
"SBC A, B", "SBC A, C", "SBC A, D", "SBC A, E", //0x9C
"SBC A, H", "SBC A, L", "SBC A, (HL)", "SBC A, A", //0xA0
"AND B", "AND C", "AND D", "AND E", //0xA4
"AND H", "AND L", "AND (HL)", "AND A", //0xA8
"XOR B", "XOR C", "XOR D", "XOR E", //0xAC
"XOR H", "XOR L", "XOR (HL)", "XOR A", //0xB0
"OR B", "OR C", "OR D", "OR E", //0xB4
"OR H", "OR L", "OR (HL)", "OR A", //0xB8
"CP B", "CP C", "CP D", "CP E", //0xBC
"CP H", "CP L", "CP (HL)", "CP A", //0xC0
"RET NZ", "POP BC", "JP NZ, nn", "JP nn", //0xC4
"CALL NZ, nn", "PUSH BC", "ADD A, n", "RST $00", //0xC8
"RET Z", "RET", "JP Z, nn", "[CB]", //0xCC
"CALL Z, nn", "CALL nn", "ADC A, n", "RST $08", //0xD0
"RET NC", "POP DE", "JP NC, nn", "OUT n, A", //0xD4
"CALL NC, nn", "PUSH DE", "SUB n", "RST $10", //0xD8
"RET C", "EXX", "JP C, nn", "IN A, n", //0xDC
"CALL C, nn", "[DD]", "SBC A, n", "RST $18", //0xE0
"RET PO", "POP HL", "JP PO, nn", "EX (SP), HL", //0xE4
"CALL C, nn", "PUSH HL", "AND n", "RST $20", //0xE8
"RET PE", "JP HL", "JP PE, nn", "EX DE, HL", //0xEC
"CALL PE, nn", "[ED]", "XOR n", "RST $28", //0xF0
"RET P", "POP AF", "JP P, nn", "DI", //0xF4
"CALL P, nn", "PUSH AF", "OR n", "RST $30", //0xF8
"RET M", "LD SP, HL", "JP M, nn", "EI", //0xFC
"CALL M, nn", "[FD]", "CP n", "RST $38", //0x100
};
readonly static string[] mnemonicsDD = new string[]
{
"NOP", "LD BC, nn", "LD (BC), A", "INC BC", //0x04
"INC B", "DEC B", "LD B, n", "RLCA", //0x08
"EX AF, AF'", "ADD IX, BC", "LD A, (BC)", "DEC BC", //0x0C
"INC C", "DEC C", "LD C, n", "RRCA", //0x10
"DJNZ d", "LD DE, nn", "LD (DE), A", "INC DE", //0x14
"INC D", "DEC D", "LD D, n", "RLA", //0x18
"JR d", "ADD IX, DE", "LD A, (DE)", "DEC DE", //0x1C
"INC E", "DEC E", "LD E, n", "RRA", //0x20
"JR NZ, d", "LD IX, nn", "LD (nn), IX", "INC IX", //0x24
"INC IXH", "DEC IXH", "LD IXH, n", "DAA", //0x28
"JR Z, d", "ADD IX, IX", "LD IX, (nn)", "DEC IX", //0x2C
"INC IXL", "DEC IXL", "LD IXL, n", "CPL", //0x30
"JR NC, d", "LD SP, nn", "LD (nn), A", "INC SP", //0x34
"INC (IX+d)", "DEC (IX+d)", "LD (IX+d), n", "SCF", //0x38
"JR C, d", "ADD IX, SP", "LD A, (nn)", "DEC SP", //0x3C
"INC A", "DEC A", "LD A, n", "CCF", //0x40
"LD B, B", "LD B, C", "LD B, D", "LD B, E", //0x44
"LD B, IXH", "LD B, IXL", "LD B, (IX+d)", "LD B, A", //0x48
"LD C, B", "LD C, C", "LD C, D", "LD C, E", //0x4C
"LD C, IXH", "LD C, IXL", "LD C, (IX+d)", "LD C, A", //0x50
"LD D, B", "LD D, C", "LD D, D", "LD D, E", //0x54
"LD D, IXH", "LD D, IXL", "LD D, (IX+d)", "LD D, A", //0x58
"LD E, B", "LD E, C", "LD E, D", "LD E, E", //0x5C
"LD E, IXH", "LD E, IXL", "LD E, (IX+d)", "LD E, A", //0x60
"LD IXH, B", "LD IXH, C", "LD IXH, D", "LD IXH, E", //0x64
"LD IXH, IXH", "LD IXH, IXL", "LD H, (IX+d)", "LD IXH, A", //0x68
"LD IXL, B", "LD IXL, C", "LD IXL, D", "LD IXL, E", //0x6C
"LD IXL, IXH", "LD IXL, IXL", "LD L, (IX+d)", "LD IXL, A", //0x70
"LD (IX+d), B", "LD (IX+d), C", "LD (IX+d), D", "LD (IX+d), E", //0x74
"LD (IX+d), H", "LD (IX+d), L", "HALT", "LD (IX+d), A", //0x78
"LD A, B", "LD A, C", "LD A, D", "LD A, E", //0x7C
"LD A, IXH", "LD A, IXL", "LD A, (IX+d)", "LD A, A", //0x80
"ADD A, B", "ADD A, C", "ADD A, D", "ADD A, E", //0x84
"ADD A, IXH", "ADD A, IXL", "ADD A, (IX+d)", "ADD A, A", //0x88
"ADC A, B", "ADC A, C", "ADC A, D", "ADC A, E", //0x8C
"ADC A, IXH", "ADC A, IXL", "ADC A, (IX+d)", "ADC A, A", //0x90
"SUB A, B", "SUB A, C", "SUB A, D", "SUB A, E", //0x94
"SUB A, IXH", "SUB A, IXL", "SUB A, (IX+d)", "SUB A, A", //0x98
"SBC A, B", "SBC A, C", "SBC A, D", "SBC A, E", //0x9C
"SBC A, IXH", "SBC A, IXL", "SBC A, (IX+d)", "SBC A, A", //0xA0
"AND B", "AND C", "AND D", "AND E", //0xA4
"AND IXH", "AND IXL", "AND (IX+d)", "AND A", //0xA8
"XOR B", "XOR C", "XOR D", "XOR E", //0xAC
"XOR IXH", "XOR IXL", "XOR (IX+d)", "XOR A", //0xB0
"OR B", "OR C", "OR D", "OR E", //0xB4
"OR IXH", "OR IXL", "OR (IX+d)", "OR A", //0xB8
"CP B", "CP C", "CP D", "CP E", //0xBC
"CP IXH", "CP IXL", "CP (IX+d)", "CP A", //0xC0
"RET NZ", "POP BC", "JP NZ, nn", "JP nn", //0xC4
"CALL NZ, nn", "PUSH BC", "ADD A, n", "RST $00", //0xC8
"RET Z", "RET", "JP Z, nn", "[DD CB]", //0xCC
"CALL Z, nn", "CALL nn", "ADC A, n", "RST $08", //0xD0
"RET NC", "POP DE", "JP NC, nn", "OUT n, A", //0xD4
"CALL NC, nn", "PUSH DE", "SUB n", "RST $10", //0xD8
"RET C", "EXX", "JP C, nn", "IN A, n", //0xDC
"CALL C, nn", "[!DD DD!]", "SBC A, n", "RST $18", //0xE0
"RET PO", "POP IX", "JP PO, nn", "EX (SP), IX", //0xE4
"CALL C, nn", "PUSH IX", "AND n", "RST $20", //0xE8
"RET PE", "JP IX", "JP PE, nn", "EX DE, HL", //0xEC
"CALL PE, nn", "[DD ED]", "XOR n", "RST $28", //0xF0
"RET P", "POP AF", "JP P, nn", "DI", //0xF4
"CALL P, nn", "PUSH AF", "OR n", "RST $30", //0xF8
"RET M", "LD SP, IX", "JP M, nn", "EI", //0xFC
"CALL M, nn", "[!!DD FD!!]", "CP n", "RST $38", //0x100
};
readonly static string[] mnemonicsFD = new string[]
{
"NOP", "LD BC, nn", "LD (BC), A", "INC BC", //0x04
"INC B", "DEC B", "LD B, n", "RLCA", //0x08
"EX AF, AF'", "ADD IY, BC", "LD A, (BC)", "DEC BC", //0x0C
"INC C", "DEC C", "LD C, n", "RRCA", //0x10
"DJNZ d", "LD DE, nn", "LD (DE), A", "INC DE", //0x14
"INC D", "DEC D", "LD D, n", "RLA", //0x18
"JR d", "ADD IY, DE", "LD A, (DE)", "DEC DE", //0x1C
"INC E", "DEC E", "LD E, n", "RRA", //0x20
"JR NZ, d", "LD IY, nn", "LD (nn), IY", "INC IY", //0x24
"INC IYH", "DEC IYH", "LD IYH, n", "DAA", //0x28
"JR Z, d", "ADD IY, IY", "LD IY, (nn)", "DEC IY", //0x2C
"INC IYL", "DEC IYL", "LD IYL, n", "CPL", //0x30
"JR NC, d", "LD SP, nn", "LD (nn), A", "INC SP", //0x34
"INC (IY+d)", "DEC (IY+d)", "LD (IY+d), n", "SCF", //0x38
"JR C, d", "ADD IY, SP", "LD A, (nn)", "DEC SP", //0x3C
"INC A", "DEC A", "LD A, n", "CCF", //0x40
"LD B, B", "LD B, C", "LD B, D", "LD B, E", //0x44
"LD B, IYH", "LD B, IYL", "LD B, (IY+d)", "LD B, A", //0x48
"LD C, B", "LD C, C", "LD C, D", "LD C, E", //0x4C
"LD C, IYH", "LD C, IYL", "LD C, (IY+d)", "LD C, A", //0x50
"LD D, B", "LD D, C", "LD D, D", "LD D, E", //0x54
"LD D, IYH", "LD D, IYL", "LD D, (IY+d)", "LD D, A", //0x58
"LD E, B", "LD E, C", "LD E, D", "LD E, E", //0x5C
"LD E, IYH", "LD E, IYL", "LD E, (IY+d)", "LD E, A", //0x60
"LD IYH, B", "LD IYH, C", "LD IYH, D", "LD IYH, E", //0x64
"LD IYH, IYH", "LD IYH, IYL", "LD H, (IY+d)", "LD IYH, A", //0x68
"LD IYL, B", "LD IYL, C", "LD IYL, D", "LD IYL, E", //0x6C
"LD IYL, IYH", "LD IYL, IYL", "LD L, (IY+d)", "LD IYL, A", //0x70
"LD (IY+d), B", "LD (IY+d), C", "LD (IY+d), D", "LD (IY+d), E", //0x74
"LD (IY+d), H", "LD (IY+d), L", "HALT", "LD (IY+d), A", //0x78
"LD A, B", "LD A, C", "LD A, D", "LD A, E", //0x7C
"LD A, IYH", "LD A, IYL", "LD A, (IY+d)", "LD A, A", //0x80
"ADD A, B", "ADD A, C", "ADD A, D", "ADD A, E", //0x84
"ADD A, IYH", "ADD A, IYL", "ADD A, (IY+d)", "ADD A, A", //0x88
"ADC A, B", "ADC A, C", "ADC A, D", "ADC A, E", //0x8C
"ADC A, IYH", "ADC A, IYL", "ADC A, (IY+d)", "ADC A, A", //0x90
"SUB A, B", "SUB A, C", "SUB A, D", "SUB A, E", //0x94
"SUB A, IYH", "SUB A, IYL", "SUB A, (IY+d)", "SUB A, A", //0x98
"SBC A, B", "SBC A, C", "SBC A, D", "SBC A, E", //0x9C
"SBC A, IYH", "SBC A, IYL", "SBC A, (IY+d)", "SBC A, A", //0xA0
"AND B", "AND C", "AND D", "AND E", //0xA4
"AND IYH", "AND IYL", "AND (IY+d)", "AND A", //0xA8
"XOR B", "XOR C", "XOR D", "XOR E", //0xAC
"XOR IYH", "XOR IYL", "XOR (IY+d)", "XOR A", //0xB0
"OR B", "OR C", "OR D", "OR E", //0xB4
"OR IYH", "OR IYL", "OR (IY+d)", "OR A", //0xB8
"CP B", "CP C", "CP D", "CP E", //0xBC
"CP IYH", "CP IYL", "CP (IY+d)", "CP A", //0xC0
"RET NZ", "POP BC", "JP NZ, nn", "JP nn", //0xC4
"CALL NZ, nn", "PUSH BC", "ADD A, n", "RST $00", //0xC8
"RET Z", "RET", "JP Z, nn", "[DD CB]", //0xCC
"CALL Z, nn", "CALL nn", "ADC A, n", "RST $08", //0xD0
"RET NC", "POP DE", "JP NC, nn", "OUT n, A", //0xD4
"CALL NC, nn", "PUSH DE", "SUB n", "RST $10", //0xD8
"RET C", "EXX", "JP C, nn", "IN A, n", //0xDC
"CALL C, nn", "[!FD DD!]", "SBC A, n", "RST $18", //0xE0
"RET PO", "POP IY", "JP PO, nn", "EX (SP), IY", //0xE4
"CALL C, nn", "PUSH IY", "AND n", "RST $20", //0xE8
"RET PE", "JP IY", "JP PE, nn", "EX DE, HL", //0xEC
"CALL PE, nn", "[FD ED]", "XOR n", "RST $28", //0xF0
"RET P", "POP AF", "JP P, nn", "DI", //0xF4
"CALL P, nn", "PUSH AF", "OR n", "RST $30", //0xF8
"RET M", "LD SP, IY", "JP M, nn", "EI", //0xFC
"CALL M, nn", "[!FD FD!]", "CP n", "RST $38", //0x100
};
readonly static string[] mnemonicsDDCB = new string[]
{
"RLC (IX+d)->B", "RLC (IX+d)->C", "RLC (IX+d)->D", "RLC (IX+d)->E", "RLC (IX+d)->H", "RLC (IX+d)->L", "RLC (IX+d)", "RLC (IX+d)->A",
"RRC (IX+d)->B", "RRC (IX+d)->C", "RRC (IX+d)->D", "RRC (IX+d)->E", "RRC (IX+d)->H", "RRC (IX+d)->L", "RRC (IX+d)", "RRC (IX+d)->A",
"RL (IX+d)->B", "RL (IX+d)->C", "RL (IX+d)->D", "RL (IX+d)->E", "RL (IX+d)->H", "RL (IX+d)->L", "RL (IX+d)", "RL (IX+d)->A",
"RR (IX+d)->B", "RR (IX+d)->C", "RR (IX+d)->D", "RR (IX+d)->E", "RR (IX+d)->H", "RR (IX+d)->L", "RR (IX+d)", "RR (IX+d)->A",
"SLA (IX+d)->B", "SLA (IX+d)->C", "SLA (IX+d)->D", "SLA (IX+d)->E", "SLA (IX+d)->H", "SLA (IX+d)->L", "SLA (IX+d)", "SLA (IX+d)->A",
"SRA (IX+d)->B", "SRA (IX+d)->C", "SRA (IX+d)->D", "SRA (IX+d)->E", "SRA (IX+d)->H", "SRA (IX+d)->L", "SRA (IX+d)", "SRA (IX+d)->A",
"SL1 (IX+d)->B", "SL1 (IX+d)->C", "SL1 (IX+d)->D", "SL1 (IX+d)->E", "SL1 (IX+d)->H", "SL1 (IX+d)->L", "SL1 (IX+d)", "SL1 (IX+d)->A",
"SRL (IX+d)->B", "SRL (IX+d)->C", "SRL (IX+d)->D", "SRL (IX+d)->E", "SRL (IX+d)->H", "SRL (IX+d)->L", "SRL (IX+d)", "SRL (IX+d)->A",
"BIT 0, (IX+d)", "BIT 0, (IX+d)", "BIT 0, (IX+d)", "BIT 0, (IX+d)", "BIT 0, (IX+d)", "BIT 0, (IX+d)", "BIT 0, (IX+d)", "BIT 0, (IX+d)",
"BIT 1, (IX+d)", "BIT 1, (IX+d)", "BIT 1, (IX+d)", "BIT 1, (IX+d)", "BIT 1, (IX+d)", "BIT 1, (IX+d)", "BIT 1, (IX+d)", "BIT 1, (IX+d)",
"BIT 2, (IX+d)", "BIT 2, (IX+d)", "BIT 2, (IX+d)", "BIT 2, (IX+d)", "BIT 2, (IX+d)", "BIT 2, (IX+d)", "BIT 2, (IX+d)", "BIT 2, (IX+d)",
"BIT 3, (IX+d)", "BIT 3, (IX+d)", "BIT 3, (IX+d)", "BIT 3, (IX+d)", "BIT 3, (IX+d)", "BIT 3, (IX+d)", "BIT 3, (IX+d)", "BIT 3, (IX+d)",
"BIT 4, (IX+d)", "BIT 4, (IX+d)", "BIT 4, (IX+d)", "BIT 4, (IX+d)", "BIT 4, (IX+d)", "BIT 4, (IX+d)", "BIT 4, (IX+d)", "BIT 4, (IX+d)",
"BIT 5, (IX+d)", "BIT 5, (IX+d)", "BIT 5, (IX+d)", "BIT 5, (IX+d)", "BIT 5, (IX+d)", "BIT 5, (IX+d)", "BIT 5, (IX+d)", "BIT 5, (IX+d)",
"BIT 6, (IX+d)", "BIT 6, (IX+d)", "BIT 6, (IX+d)", "BIT 6, (IX+d)", "BIT 6, (IX+d)", "BIT 6, (IX+d)", "BIT 6, (IX+d)", "BIT 6, (IX+d)",
"BIT 7, (IX+d)", "BIT 7, (IX+d)", "BIT 7, (IX+d)", "BIT 7, (IX+d)", "BIT 7, (IX+d)", "BIT 7, (IX+d)", "BIT 7, (IX+d)", "BIT 7, (IX+d)",
"RES 0 (IX+d)->B", "RES 0 (IX+d)->C", "RES 0 (IX+d)->D", "RES 0 (IX+d)->E", "RES 0 (IX+d)->H", "RES 0 (IX+d)->L", "RES 0 (IX+d)", "RES 0 (IX+d)->A",
"RES 1 (IX+d)->B", "RES 1 (IX+d)->C", "RES 1 (IX+d)->D", "RES 1 (IX+d)->E", "RES 1 (IX+d)->H", "RES 1 (IX+d)->L", "RES 1 (IX+d)", "RES 1 (IX+d)->A",
"RES 2 (IX+d)->B", "RES 2 (IX+d)->C", "RES 2 (IX+d)->D", "RES 2 (IX+d)->E", "RES 2 (IX+d)->H", "RES 2 (IX+d)->L", "RES 2 (IX+d)", "RES 2 (IX+d)->A",
"RES 3 (IX+d)->B", "RES 3 (IX+d)->C", "RES 3 (IX+d)->D", "RES 3 (IX+d)->E", "RES 3 (IX+d)->H", "RES 3 (IX+d)->L", "RES 3 (IX+d)", "RES 3 (IX+d)->A",
"RES 4 (IX+d)->B", "RES 4 (IX+d)->C", "RES 4 (IX+d)->D", "RES 4 (IX+d)->E", "RES 4 (IX+d)->H", "RES 4 (IX+d)->L", "RES 4 (IX+d)", "RES 4 (IX+d)->A",
"RES 5 (IX+d)->B", "RES 5 (IX+d)->C", "RES 5 (IX+d)->D", "RES 5 (IX+d)->E", "RES 5 (IX+d)->H", "RES 5 (IX+d)->L", "RES 5 (IX+d)", "RES 5 (IX+d)->A",
"RES 6 (IX+d)->B", "RES 6 (IX+d)->C", "RES 6 (IX+d)->D", "RES 6 (IX+d)->E", "RES 6 (IX+d)->H", "RES 6 (IX+d)->L", "RES 6 (IX+d)", "RES 6 (IX+d)->A",
"RES 7 (IX+d)->B", "RES 7 (IX+d)->C", "RES 7 (IX+d)->D", "RES 7 (IX+d)->E", "RES 7 (IX+d)->H", "RES 7 (IX+d)->L", "RES 7 (IX+d)", "RES 7 (IX+d)->A",
"SET 0 (IX+d)->B", "SET 0 (IX+d)->C", "SET 0 (IX+d)->D", "SET 0 (IX+d)->E", "SET 0 (IX+d)->H", "SET 0 (IX+d)->L", "SET 0 (IX+d)", "SET 0 (IX+d)->A",
"SET 1 (IX+d)->B", "SET 1 (IX+d)->C", "SET 1 (IX+d)->D", "SET 1 (IX+d)->E", "SET 1 (IX+d)->H", "SET 1 (IX+d)->L", "SET 1 (IX+d)", "SET 1 (IX+d)->A",
"SET 2 (IX+d)->B", "SET 2 (IX+d)->C", "SET 2 (IX+d)->D", "SET 2 (IX+d)->E", "SET 2 (IX+d)->H", "SET 2 (IX+d)->L", "SET 2 (IX+d)", "SET 2 (IX+d)->A",
"SET 3 (IX+d)->B", "SET 3 (IX+d)->C", "SET 3 (IX+d)->D", "SET 3 (IX+d)->E", "SET 3 (IX+d)->H", "SET 3 (IX+d)->L", "SET 3 (IX+d)", "SET 3 (IX+d)->A",
"SET 4 (IX+d)->B", "SET 4 (IX+d)->C", "SET 4 (IX+d)->D", "SET 4 (IX+d)->E", "SET 4 (IX+d)->H", "SET 4 (IX+d)->L", "SET 4 (IX+d)", "SET 4 (IX+d)->A",
"SET 5 (IX+d)->B", "SET 5 (IX+d)->C", "SET 5 (IX+d)->D", "SET 5 (IX+d)->E", "SET 5 (IX+d)->H", "SET 5 (IX+d)->L", "SET 5 (IX+d)", "SET 5 (IX+d)->A",
"SET 6 (IX+d)->B", "SET 6 (IX+d)->C", "SET 6 (IX+d)->D", "SET 6 (IX+d)->E", "SET 6 (IX+d)->H", "SET 6 (IX+d)->L", "SET 6 (IX+d)", "SET 6 (IX+d)->A",
"SET 7 (IX+d)->B", "SET 7 (IX+d)->C", "SET 7 (IX+d)->D", "SET 7 (IX+d)->E", "SET 7 (IX+d)->H", "SET 7 (IX+d)->L", "SET 7 (IX+d)", "SET 7 (IX+d)->A",
};
readonly static string[] mnemonicsFDCB = new string[]
{
"RLC (IY+d)->B", "RLC (IY+d)->C", "RLC (IY+d)->D", "RLC (IY+d)->E", "RLC (IY+d)->H", "RLC (IY+d)->L", "RLC (IY+d)", "RLC (IY+d)->A",
"RRC (IY+d)->B", "RRC (IY+d)->C", "RRC (IY+d)->D", "RRC (IY+d)->E", "RRC (IY+d)->H", "RRC (IY+d)->L", "RRC (IY+d)", "RRC (IY+d)->A",
"RL (IY+d)->B", "RL (IY+d)->C", "RL (IY+d)->D", "RL (IY+d)->E", "RL (IY+d)->H", "RL (IY+d)->L", "RL (IY+d)", "RL (IY+d)->A",
"RR (IY+d)->B", "RR (IY+d)->C", "RR (IY+d)->D", "RR (IY+d)->E", "RR (IY+d)->H", "RR (IY+d)->L", "RR (IY+d)", "RR (IY+d)->A",
"SLA (IY+d)->B", "SLA (IY+d)->C", "SLA (IY+d)->D", "SLA (IY+d)->E", "SLA (IY+d)->H", "SLA (IY+d)->L", "SLA (IY+d)", "SLA (IY+d)->A",
"SRA (IY+d)->B", "SRA (IY+d)->C", "SRA (IY+d)->D", "SRA (IY+d)->E", "SRA (IY+d)->H", "SRA (IY+d)->L", "SRA (IY+d)", "SRA (IY+d)->A",
"SL1 (IY+d)->B", "SL1 (IY+d)->C", "SL1 (IY+d)->D", "SL1 (IY+d)->E", "SL1 (IY+d)->H", "SL1 (IY+d)->L", "SL1 (IY+d)", "SL1 (IY+d)->A",
"SRL (IY+d)->B", "SRL (IY+d)->C", "SRL (IY+d)->D", "SRL (IY+d)->E", "SRL (IY+d)->H", "SRL (IY+d)->L", "SRL (IY+d)", "SRL (IY+d)->A",
"BIT 0, (IY+d)", "BIT 0, (IY+d)", "BIT 0, (IY+d)", "BIT 0, (IY+d)", "BIT 0, (IY+d)", "BIT 0, (IY+d)", "BIT 0, (IY+d)", "BIT 0, (IY+d)",
"BIT 1, (IY+d)", "BIT 1, (IY+d)", "BIT 1, (IY+d)", "BIT 1, (IY+d)", "BIT 1, (IY+d)", "BIT 1, (IY+d)", "BIT 1, (IY+d)", "BIT 1, (IY+d)",
"BIT 2, (IY+d)", "BIT 2, (IY+d)", "BIT 2, (IY+d)", "BIT 2, (IY+d)", "BIT 2, (IY+d)", "BIT 2, (IY+d)", "BIT 2, (IY+d)", "BIT 2, (IY+d)",
"BIT 3, (IY+d)", "BIT 3, (IY+d)", "BIT 3, (IY+d)", "BIT 3, (IY+d)", "BIT 3, (IY+d)", "BIT 3, (IY+d)", "BIT 3, (IY+d)", "BIT 3, (IY+d)",
"BIT 4, (IY+d)", "BIT 4, (IY+d)", "BIT 4, (IY+d)", "BIT 4, (IY+d)", "BIT 4, (IY+d)", "BIT 4, (IY+d)", "BIT 4, (IY+d)", "BIT 4, (IY+d)",
"BIT 5, (IY+d)", "BIT 5, (IY+d)", "BIT 5, (IY+d)", "BIT 5, (IY+d)", "BIT 5, (IY+d)", "BIT 5, (IY+d)", "BIT 5, (IY+d)", "BIT 5, (IY+d)",
"BIT 6, (IY+d)", "BIT 6, (IY+d)", "BIT 6, (IY+d)", "BIT 6, (IY+d)", "BIT 6, (IY+d)", "BIT 6, (IY+d)", "BIT 6, (IY+d)", "BIT 6, (IY+d)",
"BIT 7, (IY+d)", "BIT 7, (IY+d)", "BIT 7, (IY+d)", "BIT 7, (IY+d)", "BIT 7, (IY+d)", "BIT 7, (IY+d)", "BIT 7, (IY+d)", "BIT 7, (IY+d)",
"RES 0 (IY+d)->B", "RES 0 (IY+d)->C", "RES 0 (IY+d)->D", "RES 0 (IY+d)->E", "RES 0 (IY+d)->H", "RES 0 (IY+d)->L", "RES 0 (IY+d)", "RES 0 (IY+d)->A",
"RES 1 (IY+d)->B", "RES 1 (IY+d)->C", "RES 1 (IY+d)->D", "RES 1 (IY+d)->E", "RES 1 (IY+d)->H", "RES 1 (IY+d)->L", "RES 1 (IY+d)", "RES 1 (IY+d)->A",
"RES 2 (IY+d)->B", "RES 2 (IY+d)->C", "RES 2 (IY+d)->D", "RES 2 (IY+d)->E", "RES 2 (IY+d)->H", "RES 2 (IY+d)->L", "RES 2 (IY+d)", "RES 2 (IY+d)->A",
"RES 3 (IY+d)->B", "RES 3 (IY+d)->C", "RES 3 (IY+d)->D", "RES 3 (IY+d)->E", "RES 3 (IY+d)->H", "RES 3 (IY+d)->L", "RES 3 (IY+d)", "RES 3 (IY+d)->A",
"RES 4 (IY+d)->B", "RES 4 (IY+d)->C", "RES 4 (IY+d)->D", "RES 4 (IY+d)->E", "RES 4 (IY+d)->H", "RES 4 (IY+d)->L", "RES 4 (IY+d)", "RES 4 (IY+d)->A",
"RES 5 (IY+d)->B", "RES 5 (IY+d)->C", "RES 5 (IY+d)->D", "RES 5 (IY+d)->E", "RES 5 (IY+d)->H", "RES 5 (IY+d)->L", "RES 5 (IY+d)", "RES 5 (IY+d)->A",
"RES 6 (IY+d)->B", "RES 6 (IY+d)->C", "RES 6 (IY+d)->D", "RES 6 (IY+d)->E", "RES 6 (IY+d)->H", "RES 6 (IY+d)->L", "RES 6 (IY+d)", "RES 6 (IY+d)->A",
"RES 7 (IY+d)->B", "RES 7 (IY+d)->C", "RES 7 (IY+d)->D", "RES 7 (IY+d)->E", "RES 7 (IY+d)->H", "RES 7 (IY+d)->L", "RES 7 (IY+d)", "RES 7 (IY+d)->A",
"SET 0 (IY+d)->B", "SET 0 (IY+d)->C", "SET 0 (IY+d)->D", "SET 0 (IY+d)->E", "SET 0 (IY+d)->H", "SET 0 (IY+d)->L", "SET 0 (IY+d)", "SET 0 (IY+d)->A",
"SET 1 (IY+d)->B", "SET 1 (IY+d)->C", "SET 1 (IY+d)->D", "SET 1 (IY+d)->E", "SET 1 (IY+d)->H", "SET 1 (IY+d)->L", "SET 1 (IY+d)", "SET 1 (IY+d)->A",
"SET 2 (IY+d)->B", "SET 2 (IY+d)->C", "SET 2 (IY+d)->D", "SET 2 (IY+d)->E", "SET 2 (IY+d)->H", "SET 2 (IY+d)->L", "SET 2 (IY+d)", "SET 2 (IY+d)->A",
"SET 3 (IY+d)->B", "SET 3 (IY+d)->C", "SET 3 (IY+d)->D", "SET 3 (IY+d)->E", "SET 3 (IY+d)->H", "SET 3 (IY+d)->L", "SET 3 (IY+d)", "SET 3 (IY+d)->A",
"SET 4 (IY+d)->B", "SET 4 (IY+d)->C", "SET 4 (IY+d)->D", "SET 4 (IY+d)->E", "SET 4 (IY+d)->H", "SET 4 (IY+d)->L", "SET 4 (IY+d)", "SET 4 (IY+d)->A",
"SET 5 (IY+d)->B", "SET 5 (IY+d)->C", "SET 5 (IY+d)->D", "SET 5 (IY+d)->E", "SET 5 (IY+d)->H", "SET 5 (IY+d)->L", "SET 5 (IY+d)", "SET 5 (IY+d)->A",
"SET 6 (IY+d)->B", "SET 6 (IY+d)->C", "SET 6 (IY+d)->D", "SET 6 (IY+d)->E", "SET 6 (IY+d)->H", "SET 6 (IY+d)->L", "SET 6 (IY+d)", "SET 6 (IY+d)->A",
"SET 7 (IY+d)->B", "SET 7 (IY+d)->C", "SET 7 (IY+d)->D", "SET 7 (IY+d)->E", "SET 7 (IY+d)->H", "SET 7 (IY+d)->L", "SET 7 (IY+d)", "SET 7 (IY+d)->A",
};
readonly static string[] mnemonicsCB = new string[]
{
"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",
"SL1 B", "SL1 C", "SL1 D", "SL1 E", "SL1 H", "SL1 L", "SL1 (HL)", "SL1 A",
"SRL B", "SRL C", "SRL D", "SRL E", "SRL H", "SRL L", "SRL (HL)", "SRL A",
"BIT 0, B", "BIT 0, C", "BIT 0, D", "BIT 0, E", "BIT 0, H", "BIT 0, L", "BIT 0, (HL)", "BIT 0, A",
"BIT 1, B", "BIT 1, C", "BIT 1, D", "BIT 1, E", "BIT 1, H", "BIT 1, L", "BIT 1, (HL)", "BIT 1, A",
"BIT 2, B", "BIT 2, C", "BIT 2, D", "BIT 2, E", "BIT 2, H", "BIT 2, L", "BIT 2, (HL)", "BIT 2, A",
"BIT 3, B", "BIT 3, C", "BIT 3, D", "BIT 3, E", "BIT 3, H", "BIT 3, L", "BIT 3, (HL)", "BIT 3, A",
"BIT 4, B", "BIT 4, C", "BIT 4, D", "BIT 4, E", "BIT 4, H", "BIT 4, L", "BIT 4, (HL)", "BIT 4, A",
"BIT 5, B", "BIT 5, C", "BIT 5, D", "BIT 5, E", "BIT 5, H", "BIT 5, L", "BIT 5, (HL)", "BIT 5, A",
"BIT 6, B", "BIT 6, C", "BIT 6, D", "BIT 6, E", "BIT 6, H", "BIT 6, L", "BIT 6, (HL)", "BIT 6, A",
"BIT 7, B", "BIT 7, C", "BIT 7, D", "BIT 7, E", "BIT 7, H", "BIT 7, L", "BIT 7, (HL)", "BIT 7, A",
"RES 0, B", "RES 0, C", "RES 0, D", "RES 0, E", "RES 0, H", "RES 0, L", "RES 0, (HL)", "RES 0, A",
"RES 1, B", "RES 1, C", "RES 1, D", "RES 1, E", "RES 1, H", "RES 1, L", "RES 1, (HL)", "RES 1, A",
"RES 2, B", "RES 2, C", "RES 2, D", "RES 2, E", "RES 2, H", "RES 2, L", "RES 2, (HL)", "RES 2, A",
"RES 3, B", "RES 3, C", "RES 3, D", "RES 3, E", "RES 3, H", "RES 3, L", "RES 3, (HL)", "RES 3, A",
"RES 4, B", "RES 4, C", "RES 4, D", "RES 4, E", "RES 4, H", "RES 4, L", "RES 4, (HL)", "RES 4, A",
"RES 5, B", "RES 5, C", "RES 5, D", "RES 5, E", "RES 5, H", "RES 5, L", "RES 5, (HL)", "RES 5, A",
"RES 6, B", "RES 6, C", "RES 6, D", "RES 6, E", "RES 6, H", "RES 6, L", "RES 6, (HL)", "RES 6, A",
"RES 7, B", "RES 7, C", "RES 7, D", "RES 7, E", "RES 7, H", "RES 7, L", "RES 7, (HL)", "RES 7, A",
"SET 0, B", "SET 0, C", "SET 0, D", "SET 0, E", "SET 0, H", "SET 0, L", "SET 0, (HL)", "SET 0, A",
"SET 1, B", "SET 1, C", "SET 1, D", "SET 1, E", "SET 1, H", "SET 1, L", "SET 1, (HL)", "SET 1, A",
"SET 2, B", "SET 2, C", "SET 2, D", "SET 2, E", "SET 2, H", "SET 2, L", "SET 2, (HL)", "SET 2, A",
"SET 3, B", "SET 3, C", "SET 3, D", "SET 3, E", "SET 3, H", "SET 3, L", "SET 3, (HL)", "SET 3, A",
"SET 4, B", "SET 4, C", "SET 4, D", "SET 4, E", "SET 4, H", "SET 4, L", "SET 4, (HL)", "SET 4, A",
"SET 5, B", "SET 5, C", "SET 5, D", "SET 5, E", "SET 5, H", "SET 5, L", "SET 5, (HL)", "SET 5, A",
"SET 6, B", "SET 6, C", "SET 6, D", "SET 6, E", "SET 6, H", "SET 6, L", "SET 6, (HL)", "SET 6, A",
"SET 7, B", "SET 7, C", "SET 7, D", "SET 7, E", "SET 7, H", "SET 7, L", "SET 7, (HL)", "SET 7, A",
};
readonly static string[] mnemonicsED = new string[]
{
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP",
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP",
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP",
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP",
"IN B, C", "OUT C, B", "SBC HL, BC", "LD (nn), BC", //0x44
"NEG", "RETN", "IM $0", "LD I, A", //0x48
"IN C, C", "OUT C, C", "ADC HL, BC", "LD BC, (nn)", //0x4C
"NEG", "RETI", "IM $0", "LD R, A", //0x50
"IN D, C", "OUT C, D", "SBC HL, DE", "LD (nn), DE", //0x54
"NEG", "RETN", "IM $1", "LD A, I", //0x58
"IN E, C", "OUT C, E", "ADC HL, DE", "LD DE, (nn)", //0x5C
"NEG", "RETI", "IM $2", "LD A, R", //0x60
"IN H, C", "OUT C, H", "SBC HL, HL", "LD (nn), HL", //0x64
"NEG", "RETN", "IM $0", "RRD", //0x68
"IN L, C", "OUT C, L", "ADC HL, HL", "LD HL, (nn)", //0x6C
"NEG", "RETI", "IM $0", "RLD", //0x70
"IN 0, C", "OUT C, 0", "SBC HL, SP", "LD (nn), SP", //0x74
"NEG", "RETN", "IM $1", "NOP", //0x78
"IN A, C", "OUT C, A", "ADC HL, SP", "LD SP, (nn)", //0x7C
"NEG", "RETI", "IM $2", "NOP", //0x80
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0x90
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0xA0
"LDI", "CPI", "INI", "OUTI", //0xA4
"NOP", "NOP", "NOP", "NOP", //0xA8
"LDD", "CPD", "IND", "OUTD", //0xAC
"NOP", "NOP", "NOP", "NOP", //0xB0
"LDIR", "CPIR", "INIR", "OTIR", //0xB4
"NOP", "NOP", "NOP", "NOP", //0xB8
"LDDR", "CPDR", "INDR", "OTDR", //0xBC
"NOP", "NOP", "NOP", "NOP", //0xC0
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0xD0
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0xE0
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0xF0
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0x100
};
string DisassembleInternal(Func<byte> read)
{
byte A = read();
string format;
switch (A)
{
case 0xCB:
A = read();
format = mnemonicsCB[A];
break;
case 0xDD:
A = read();
switch(A)
{
case 0xCB: format = mnemonicsDDCB[A]; break;
case 0xED: format = mnemonicsED[A]; break;
default: format = mnemonicsDD[A]; break;
}
break;
case 0xED:
A = read();
format = mnemonicsED[A];
break;
case 0xFD:
A = read();
switch (A)
{
case 0xCB: format = mnemonicsFDCB[A]; break;
case 0xED: format = mnemonicsED[A]; break;
default: format = mnemonicsFD[A]; break;
}
break;
default: format = mnemonics[A]; break;
}
return format;
}
public string Disassemble(Func<byte> read)
{
return Result(DisassembleInternal(read),read);
}
}
}