diff --git a/BizHawk.Emulation/CPUs/Z80/Disassembler.cs b/BizHawk.Emulation/CPUs/Z80/Disassembler.cs index 0bf400f81f..deaab17c1e 100644 --- a/BizHawk.Emulation/CPUs/Z80/Disassembler.cs +++ b/BizHawk.Emulation/CPUs/Z80/Disassembler.cs @@ -1,295 +1,525 @@ -namespace BizHawk.Emulation.CPUs.Z80 +//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 partial class Z80A - { - #region Mnemonics - private static readonly string[] Opcodes = new[] - { - "NOP","LD BC,#h","LD (BC),A","INC BC","INC B","DEC B","LD B,*h","RLCA", - "EX AF,AF'","ADD HL,BC","LD A,(BC)","DEC BC","INC C","DEC C","LD C,*h","RRCA", - "DJNZ @h","LD DE,#h","LD (DE),A","INC DE","INC D","DEC D","LD D,*h","RLA", - "JR @h","ADD HL,DE","LD A,(DE)","DEC DE","INC E","DEC E","LD E,*h","RRA", - "JR NZ,@h","LD HL,#h","LD (#h),HL","INC HL","INC H","DEC H","LD H,*h","DAA", - "JR Z,@h","ADD HL,HL","LD HL,(#h)","DEC HL","INC L","DEC L","LD L,*h","CPL", - "JR NC,@h","LD SP,#h","LD (#h),A","INC SP","INC (HL)","DEC (HL)","LD (HL),*h","SCF", - "JR C,@h","ADD HL,SP","LD A,(#h)","DEC SP","INC A","DEC A","LD A,*h","CCF", - "LD B,B","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","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","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","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 B","ADD C","ADD D","ADD E","ADD H","ADD L","ADD (HL)","ADD A", - "ADC B","ADC C","ADC D","ADC E","ADC H","ADC L","ADC (HL)","ADC A", - "SUB B","SUB C","SUB D","SUB E","SUB H","SUB L","SUB (HL)","SUB A", - "SBC B","SBC C","SBC D","SBC E","SBC H","SBC L","SBC (HL)","SBC A", - "AND B","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","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", - "RET NZ","POP BC","JP NZ,#h","JP #h","CALL NZ,#h","PUSH BC","ADD *h","RST 00h", - "RET Z","RET","JP Z,#h","PFX_CB","CALL Z,#h","CALL #h","ADC *h","RST 08h", - "RET NC","POP DE","JP NC,#h","OUTA (*h)","CALL NC,#h","PUSH DE","SUB *h","RST 10h", - "RET C","EXX","JP C,#h","INA (*h)","CALL C,#h","PFX_DD","SBC *h","RST 18h", - "RET PO","POP HL","JP PO,#h","EX HL,(SP)","CALL PO,#h","PUSH HL","AND *h","RST 20h", - "RET PE","LD PC,HL","JP PE,#h","EX DE,HL","CALL PE,#h","PFX_ED","XOR *h","RST 28h", - "RET P","POP AF","JP P,#h","DI","CALL P,#h","PUSH AF","OR *h","RST 30h", - "RET M","LD SP,HL","JP M,#h","EI","CALL M,#h","PFX_FD","CP *h","RST 38h" - }; + public class Disassembler + { + readonly static sbyte[,] opcodeSizes = new sbyte[7, 256]; - private static readonly string[] CBPrefixOpcodes = new[] - { - "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 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 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" - }; + public static void GenerateOpcodeSizes() + { + Disassembler disasm = new Disassembler(); - private static readonly string[] EDPrefixOpcodes = new[] - { - "DB EDh,00h","DB EDh,01h","DB EDh,02h","DB EDh,03h", - "DB EDh,04h","DB EDh,05h","DB EDh,06h","DB EDh,07h", - "DB EDh,08h","DB EDh,09h","DB EDh,0Ah","DB EDh,0Bh", - "DB EDh,0Ch","DB EDh,0Dh","DB EDh,0Eh","DB EDh,0Fh", - "DB EDh,10h","DB EDh,11h","DB EDh,12h","DB EDh,13h", - "DB EDh,14h","DB EDh,15h","DB EDh,16h","DB EDh,17h", - "DB EDh,18h","DB EDh,19h","DB EDh,1Ah","DB EDh,1Bh", - "DB EDh,1Ch","DB EDh,1Dh","DB EDh,1Eh","DB EDh,1Fh", - "DB EDh,20h","DB EDh,21h","DB EDh,22h","DB EDh,23h", - "DB EDh,24h","DB EDh,25h","DB EDh,26h","DB EDh,27h", - "DB EDh,28h","DB EDh,29h","DB EDh,2Ah","DB EDh,2Bh", - "DB EDh,2Ch","DB EDh,2Dh","DB EDh,2Eh","DB EDh,2Fh", - "DB EDh,30h","DB EDh,31h","DB EDh,32h","DB EDh,33h", - "DB EDh,34h","DB EDh,35h","DB EDh,36h","DB EDh,37h", - "DB EDh,38h","DB EDh,39h","DB EDh,3Ah","DB EDh,3Bh", - "DB EDh,3Ch","DB EDh,3Dh","DB EDh,3Eh","DB EDh,3Fh", - "IN B,(C)","OUT (C),B","SBC HL,BC","LD (#h),BC", - "NEG","RETN","IM 0","LD I,A", - "IN C,(C)","OUT (C),C","ADC HL,BC","LD BC,(#h)", - "DB EDh,4Ch","RETI","DB EDh,4Eh","LD R,A", - "IN D,(C)","OUT (C),D","SBC HL,DE","LD (#h),DE", - "DB EDh,54h","DB EDh,55h","IM 1","LD A,I", - "IN E,(C)","OUT (C),E","ADC HL,DE","LD DE,(#h)", - "DB EDh,5Ch","DB EDh,5Dh","IM 2","LD A,R", - "IN H,(C)","OUT (C),H","SBC HL,HL","LD (#h),HL", - "DB EDh,64h","DB EDh,65h","DB EDh,66h","RRD", - "IN L,(C)","OUT (C),L","ADC HL,HL","LD HL,(#h)", - "DB EDh,6Ch","DB EDh,6Dh","DB EDh,6Eh","RLD", - "IN F,(C)","DB EDh,71h","SBC HL,SP","LD (#h),SP", - "DB EDh,74h","DB EDh,75h","DB EDh,76h","DB EDh,77h", - "IN A,(C)","OUT (C),A","ADC HL,SP","LD SP,(#h)", - "DB EDh,7Ch","DB EDh,7Dh","DB EDh,7Eh","DB EDh,7Fh", - "DB EDh,80h","DB EDh,81h","DB EDh,82h","DB EDh,83h", - "DB EDh,84h","DB EDh,85h","DB EDh,86h","DB EDh,87h", - "DB EDh,88h","DB EDh,89h","DB EDh,8Ah","DB EDh,8Bh", - "DB EDh,8Ch","DB EDh,8Dh","DB EDh,8Eh","DB EDh,8Fh", - "DB EDh,90h","DB EDh,91h","DB EDh,92h","DB EDh,93h", - "DB EDh,94h","DB EDh,95h","DB EDh,96h","DB EDh,97h", - "DB EDh,98h","DB EDh,99h","DB EDh,9Ah","DB EDh,9Bh", - "DB EDh,9Ch","DB EDh,9Dh","DB EDh,9Eh","DB EDh,9Fh", - "LDI","CPI","INI","OUTI", - "DB EDh,A4h","DB EDh,A5h","DB EDh,A6h","DB EDh,A7h", - "LDD","CPD","IND","OUTD", - "DB EDh,ACh","DB EDh,ADh","DB EDh,AEh","DB EDh,AFh", - "LDIR","CPIR","INIR","OTIR", - "DB EDh,B4h","DB EDh,B5h","DB EDh,B6h","DB EDh,B7h", - "LDDR","CPDR","INDR","OTDR", - "DB EDh,BCh","DB EDh,BDh","DB EDh,BEh","DB EDh,BFh", - "DB EDh,C0h","DB EDh,C1h","DB EDh,C2h","DB EDh,C3h", - "DB EDh,C4h","DB EDh,C5h","DB EDh,C6h","DB EDh,C7h", - "DB EDh,C8h","DB EDh,C9h","DB EDh,CAh","DB EDh,CBh", - "DB EDh,CCh","DB EDh,CDh","DB EDh,CEh","DB EDh,CFh", - "DB EDh,D0h","DB EDh,D1h","DB EDh,D2h","DB EDh,D3h", - "DB EDh,D4h","DB EDh,D5h","DB EDh,D6h","DB EDh,D7h", - "DB EDh,D8h","DB EDh,D9h","DB EDh,DAh","DB EDh,DBh", - "DB EDh,DCh","DB EDh,DDh","DB EDh,DEh","DB EDh,DFh", - "DB EDh,E0h","DB EDh,E1h","DB EDh,E2h","DB EDh,E3h", - "DB EDh,E4h","DB EDh,E5h","DB EDh,E6h","DB EDh,E7h", - "DB EDh,E8h","DB EDh,E9h","DB EDh,EAh","DB EDh,EBh", - "DB EDh,ECh","DB EDh,EDh","DB EDh,EEh","DB EDh,EFh", - "DB EDh,F0h","DB EDh,F1h","DB EDh,F2h","DB EDh,F3h", - "DB EDh,F4h","DB EDh,F5h","DB EDh,F6h","DB EDh,F7h", - "DB EDh,F8h","DB EDh,F9h","DB EDh,FAh","DB EDh,FBh", - "DB EDh,FCh","DB EDh,FDh","DB EDh,FEh","DB EDh,FFh" - }; + 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; + } - private static readonly string[] DDPrefixOpcodes = new[] - { - "NOP","LD BC,#h","LD (BC),A","INC BC","INC B","DEC B","LD B,*h","RLCA", - "EX AF,AF'","ADD I%,BC","LD A,(BC)","DEC BC","INC C","DEC C","LD C,*h","RRCA", - "DJNZ @h","LD DE,#h","LD (DE),A","INC DE","INC D","DEC D","LD D,*h","RLA", - "JR @h","ADD I%,DE","LD A,(DE)","DEC DE","INC E","DEC E","LD E,*h","RRA", - "JR NZ,@h","LD I%,#h","LD (#h),I%","INC I%","INC I%h","DEC I%h","LD I%h,*h","DAA", - "JR Z,@h","ADD I%,I%","LD I%,(#h)","DEC I%","INC I%l","DEC I%l","LD I%l,*h","CPL", - "JR NC,@h","LD SP,#h","LD (#h),A","INC SP","INC (I%+^h)","DEC (I%+^h)","LD (I%+^h),*h","SCF", - "JR C,@h","ADD I%,SP","LD A,(#h)","DEC SP","INC A","DEC A","LD A,*h","CCF", - "LD B,B","LD B,C","LD B,D","LD B,E","LD B,I%h","LD B,I%l","LD B,(I%+^h)","LD B,A", - "LD C,B","LD C,C","LD C,D","LD C,E","LD C,I%h","LD C,I%l","LD C,(I%+^h)","LD C,A", - "LD D,B","LD D,C","LD D,D","LD D,E","LD D,I%h","LD D,I%l","LD D,(I%+^h)","LD D,A", - "LD E,B","LD E,C","LD E,D","LD E,E","LD E,I%h","LD E,I%l","LD E,(I%+^h)","LD E,A", - "LD I%h,B","LD I%h,C","LD I%h,D","LD I%h,E","LD I%h,I%h","LD I%h,I%l","LD H,(I%+^h)","LD I%h,A", - "LD I%l,B","LD I%l,C","LD I%l,D","LD I%l,E","LD I%l,I%h","LD I%l,I%l","LD L,(I%+^h)","LD I%l,A", - "LD (I%+^h),B","LD (I%+^h),C","LD (I%+^h),D","LD (I%+^h),E","LD (I%+^h),H","LD (I%+^h),L","HALT","LD (I%+^h),A", - "LD A,B","LD A,C","LD A,D","LD A,E","LD A,I%h","LD A,I%l","LD A,(I%+^h)","LD A,A", - "ADD B","ADD C","ADD D","ADD E","ADD I%h","ADD I%l","ADD (I%+^h)","ADD A", - "ADC B","ADC C","ADC D","ADC E","ADC I%h","ADC I%l","ADC (I%+^h)","ADC,A", - "SUB B","SUB C","SUB D","SUB E","SUB I%h","SUB I%l","SUB (I%+^h)","SUB A", - "SBC B","SBC C","SBC D","SBC E","SBC I%h","SBC I%l","SBC (I%+^h)","SBC A", - "AND B","AND C","AND D","AND E","AND I%h","AND I%l","AND (I%+^h)","AND A", - "XOR B","XOR C","XOR D","XOR E","XOR I%h","XOR I%l","XOR (I%+^h)","XOR A", - "OR B","OR C","OR D","OR E","OR I%h","OR I%l","OR (I%+^h)","OR A", - "CP B","CP C","CP D","CP E","CP I%h","CP I%l","CP (I%+^h)","CP A", - "RET NZ","POP BC","JP NZ,#h","JP #h","CALL NZ,#h","PUSH BC","ADD *h","RST 00h", - "RET Z","RET","JP Z,#h","PFX_CB","CALL Z,#h","CALL #h","ADC *h","RST 08h", - "RET NC","POP DE","JP NC,#h","OUTA (*h)","CALL NC,#h","PUSH DE","SUB *h","RST 10h", - "RET C","EXX","JP C,#h","INA (*h)","CALL C,#h","PFX_DD","SBC *h","RST 18h", - "RET PO","POP I%","JP PO,#h","EX I%,(SP)","CALL PO,#h","PUSH I%","AND *h","RST 20h", - "RET PE","LD PC,I%","JP PE,#h","EX DE,I%","CALL PE,#h","PFX_ED","XOR *h","RST 28h", - "RET P","POP AF","JP P,#h","DI","CALL P,#h","PUSH AF","OR *h","RST 30h", - "RET M","LD SP,I%","JP M,#h","EI","CALL M,#h","PFX_FD","CP *h","RST 38h" - }; + opcodeSizes[0, 0xCB] = -1; + opcodeSizes[0, 0xED] = -2; + opcodeSizes[0, 0xDD] = -3; + opcodeSizes[0, 0xFD] = -4; - private static readonly string[] DDCBPrefixOpcodes = new[] - { - "RLC B","RLC C","RLC D","RLC E","RLC H","RLC L","RLC (I%@h)","RLC A", - "RRC B","RRC C","RRC D","RRC E","RRC H","RRC L","RRC (I%@h)","RRC A", - "RL B","RL C","RL D","RL E","RL H","RL L","RL (I%@h)","RL A", - "RR B","RR C","RR D","RR E","RR H","RR L","RR (I%@h)","RR A", - "SLA B","SLA C","SLA D","SLA E","SLA H","SLA L","SLA (I%@h)","SLA A", - "SRA B","SRA C","SRA D","SRA E","SRA H","SRA L","SRA (I%@h)","SRA A", - "SLL B","SLL C","SLL D","SLL E","SLL H","SLL L","SLL (I%@h)","SLL A", - "SRL B","SRL C","SRL D","SRL E","SRL H","SRL L","SRL (I%@h)","SRL A", - "BIT 0,B","BIT 0,C","BIT 0,D","BIT 0,E","BIT 0,H","BIT 0,L","BIT 0,(I%@h)","BIT 0,A", - "BIT 1,B","BIT 1,C","BIT 1,D","BIT 1,E","BIT 1,H","BIT 1,L","BIT 1,(I%@h)","BIT 1,A", - "BIT 2,B","BIT 2,C","BIT 2,D","BIT 2,E","BIT 2,H","BIT 2,L","BIT 2,(I%@h)","BIT 2,A", - "BIT 3,B","BIT 3,C","BIT 3,D","BIT 3,E","BIT 3,H","BIT 3,L","BIT 3,(I%@h)","BIT 3,A", - "BIT 4,B","BIT 4,C","BIT 4,D","BIT 4,E","BIT 4,H","BIT 4,L","BIT 4,(I%@h)","BIT 4,A", - "BIT 5,B","BIT 5,C","BIT 5,D","BIT 5,E","BIT 5,H","BIT 5,L","BIT 5,(I%@h)","BIT 5,A", - "BIT 6,B","BIT 6,C","BIT 6,D","BIT 6,E","BIT 6,H","BIT 6,L","BIT 6,(I%@h)","BIT 6,A", - "BIT 7,B","BIT 7,C","BIT 7,D","BIT 7,E","BIT 7,H","BIT 7,L","BIT 7,(I%@h)","BIT 7,A", - "RES 0,B","RES 0,C","RES 0,D","RES 0,E","RES 0,H","RES 0,L","RES 0,(I%@h)","RES 0,A", - "RES 1,B","RES 1,C","RES 1,D","RES 1,E","RES 1,H","RES 1,L","RES 1,(I%@h)","RES 1,A", - "RES 2,B","RES 2,C","RES 2,D","RES 2,E","RES 2,H","RES 2,L","RES 2,(I%@h)","RES 2,A", - "RES 3,B","RES 3,C","RES 3,D","RES 3,E","RES 3,H","RES 3,L","RES 3,(I%@h)","RES 3,A", - "RES 4,B","RES 4,C","RES 4,D","RES 4,E","RES 4,H","RES 4,L","RES 4,(I%@h)","RES 4,A", - "RES 5,B","RES 5,C","RES 5,D","RES 5,E","RES 5,H","RES 5,L","RES 5,(I%@h)","RES 5,A", - "RES 6,B","RES 6,C","RES 6,D","RES 6,E","RES 6,H","RES 6,L","RES 6,(I%@h)","RES 6,A", - "RES 7,B","RES 7,C","RES 7,D","RES 7,E","RES 7,H","RES 7,L","RES 7,(I%@h)","RES 7,A", - "SET 0,B","SET 0,C","SET 0,D","SET 0,E","SET 0,H","SET 0,L","SET 0,(I%@h)","SET 0,A", - "SET 1,B","SET 1,C","SET 1,D","SET 1,E","SET 1,H","SET 1,L","SET 1,(I%@h)","SET 1,A", - "SET 2,B","SET 2,C","SET 2,D","SET 2,E","SET 2,H","SET 2,L","SET 2,(I%@h)","SET 2,A", - "SET 3,B","SET 3,C","SET 3,D","SET 3,E","SET 3,H","SET 3,L","SET 3,(I%@h)","SET 3,A", - "SET 4,B","SET 4,C","SET 4,D","SET 4,E","SET 4,H","SET 4,L","SET 4,(I%@h)","SET 4,A", - "SET 5,B","SET 5,C","SET 5,D","SET 5,E","SET 5,H","SET 5,L","SET 5,(I%@h)","SET 5,A", - "SET 6,B","SET 6,C","SET 6,D","SET 6,E","SET 6,H","SET 6,L","SET 6,(I%@h)","SET 6,A", - "SET 7,B","SET 7,C","SET 7,D","SET 7,E","SET 7,H","SET 7,L","SET 7,(I%@h)","SET 7,A" - }; - #endregion - - public string Disassemble(ushort pc, out int bytesToAdvance) - { - byte op = ReadMemory(pc++); - string disassembly; - switch (op) - { - case 0xCB: - op = ReadMemory(pc++); - disassembly = CBPrefixOpcodes[op]; - bytesToAdvance = 2; - break; - case 0xED: - op = ReadMemory(pc++); - disassembly = EDPrefixOpcodes[op]; - bytesToAdvance = 2; - break; - case 0xDD: - op = ReadMemory(pc++); - if (op == 0xCB) - { - op = ReadMemory(pc++); - disassembly = DDCBPrefixOpcodes[op]; - bytesToAdvance = 3; - } else { - disassembly = DDPrefixOpcodes[op]; - bytesToAdvance = 2; - } - break; - default: - disassembly = Opcodes[op]; - bytesToAdvance = 1; - break; - } + 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; + } - if (disassembly.IndexOf('*') != -1) - { - disassembly = disassembly.Replace("*", string.Format("{0:X2}", ReadMemory(pc++))); - bytesToAdvance++; - } - if (disassembly.IndexOf('#') != -1) - { - byte L = ReadMemory(pc++); - byte H = ReadMemory(pc++); - disassembly = disassembly.Replace("#", string.Format("{0:X4}", H << 8 | L)); - bytesToAdvance += 2; - } - if (disassembly.IndexOf('@') != -1) - { - sbyte b = (sbyte) ReadMemory(pc++); - char sign = b < 0 ? '-' : '+'; - disassembly = disassembly.Replace("@", string.Format("{0}{1:X2}", sign, b)); - bytesToAdvance++; - } + 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; + } - return disassembly; - } + 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; + } - public string State() - { - int notused; - string a = string.Format("{0:X4} {1}", RegPC.Word, Disassemble(RegPC.Word, out notused)).PadRight(41); - string b = string.Format("AF: {0:X4} BC: {1:X4} DE: {2:X4} HL: {3:X4} IX: {4:X4} IY: {5:X4} SP: {6:X4} ", - RegAF.Word, RegBC.Word, RegDE.Word, RegHL.Word, RegIX.Word, RegIY.Word, RegSP.Word); - string val = a + b; - if (RegFlagC) val += "C"; - if (RegFlagN) val += "N"; - if (RegFlagP) val += "P"; - if (RegFlag3) val += "3"; - if (RegFlagH) val += "H"; - if (RegFlag5) val += "5"; - if (RegFlagZ) val += "Z"; - if (RegFlagS) val += "S"; + opcodeSizes[3, 0xCB] = -5; + opcodeSizes[3, 0xED] = -2; - return val; - } - } + 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 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 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 read) + { + return Result(DisassembleInternal(read),read); + } + } } diff --git a/BizHawk.Emulation/Consoles/Calculator/TI83.cs b/BizHawk.Emulation/Consoles/Calculator/TI83.cs index 3879a3015c..d6cc34a9a2 100644 --- a/BizHawk.Emulation/Consoles/Calculator/TI83.cs +++ b/BizHawk.Emulation/Consoles/Calculator/TI83.cs @@ -331,13 +331,8 @@ namespace BizHawk.Emulation.Consoles.Calculator } public IVideoProvider VideoProvider { get { return new MyVideoProvider(this); } } - class MySoundProvider : ISoundProvider - { - public void GetSamples(short[] samples) - { - } - } - public ISoundProvider SoundProvider { get { return new MySoundProvider(); } } + + public ISoundProvider SoundProvider { get { return new NullEmulator(); } } public static readonly ControllerDefinition TI83Controller = new ControllerDefinition diff --git a/BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs b/BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs index 4c3df08a8c..980f343791 100644 --- a/BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs +++ b/BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs @@ -6,6 +6,12 @@ namespace BizHawk.Emulation.Consoles.Gameboy { public partial class Gameboy : IEmulator { + public interface IDebuggerAPI + { + void DoEvents(); + } + public IDebuggerAPI DebuggerAPI; + public enum ECartType { ROM_ONLY = 0x00, @@ -207,7 +213,7 @@ namespace BizHawk.Emulation.Consoles.Gameboy sanity++; if (sanity == 100000) { - //System.Windows.Forms.Application.DoEvents(); + if(DebuggerAPI != null) DebuggerAPI.DoEvents(); if (DebugBreak) break; sanity = 0; } @@ -267,6 +273,8 @@ namespace BizHawk.Emulation.Consoles.Gameboy Mapper = new MemoryMapper(this); CartFlags.GBC = Rom[0x0143] == 0x80; CartFlags.SGB = Rom[0x0146] == 0x03; + + HardReset(); } public bool BootFromBios = true; @@ -626,17 +634,17 @@ namespace BizHawk.Emulation.Consoles.Gameboy public void FrameAdvance(bool render) { - Cpu.ExecuteCycles(4096); + //Cpu.ExecuteCycles(4096); } public IVideoProvider VideoProvider { - get { throw new NotImplementedException(); } + get { return new NullEmulator(); } } public ISoundProvider SoundProvider { - get { throw new NotImplementedException(); } + get { return new NullEmulator(); } } public int Frame @@ -653,11 +661,11 @@ namespace BizHawk.Emulation.Consoles.Gameboy { get { - throw new NotImplementedException(); + return false; } set { - throw new NotImplementedException(); + } } @@ -673,7 +681,7 @@ namespace BizHawk.Emulation.Consoles.Gameboy public void SaveStateBinary(System.IO.BinaryWriter writer) { - throw new NotImplementedException(); + } public void LoadStateBinary(System.IO.BinaryReader reader) @@ -683,7 +691,7 @@ namespace BizHawk.Emulation.Consoles.Gameboy public byte[] SaveStateBinary() { - throw new NotImplementedException(); + return new byte[0]; } public void RenderOBJLine(int line, byte[] output, bool limit) diff --git a/BizHawk.MultiClient/BizHawk.MultiClient.csproj b/BizHawk.MultiClient/BizHawk.MultiClient.csproj index fb2f33d06a..a3940eb8aa 100644 --- a/BizHawk.MultiClient/BizHawk.MultiClient.csproj +++ b/BizHawk.MultiClient/BizHawk.MultiClient.csproj @@ -3,7 +3,7 @@ Debug AnyCPU - 9.0.21022 + 9.0.30729 2.0 {DD448B37-BA3F-4544-9754-5406E8094723} Exe @@ -58,6 +58,12 @@ + + Form + + + Debugger.cs + @@ -79,6 +85,9 @@ + + Debugger.cs + MainForm.cs Designer diff --git a/BizHawk.Emulation/Consoles/Gameboy/Debugger.Designer.cs b/BizHawk.MultiClient/Gameboy/Debugger.Designer.cs similarity index 97% rename from BizHawk.Emulation/Consoles/Gameboy/Debugger.Designer.cs rename to BizHawk.MultiClient/Gameboy/Debugger.Designer.cs index ff35bfdd13..59d46f5f15 100644 --- a/BizHawk.Emulation/Consoles/Gameboy/Debugger.Designer.cs +++ b/BizHawk.MultiClient/Gameboy/Debugger.Designer.cs @@ -1,6 +1,6 @@ using BizHawk.Core; -namespace VgMuseum.Gameboy +namespace BizHawk.Emulation.Consoles.Gameboy { partial class Debugger { diff --git a/BizHawk.Emulation/Consoles/Gameboy/Debugger.cs b/BizHawk.MultiClient/Gameboy/Debugger.cs similarity index 92% rename from BizHawk.Emulation/Consoles/Gameboy/Debugger.cs rename to BizHawk.MultiClient/Gameboy/Debugger.cs index 3a42d1b37c..68db64fd04 100644 --- a/BizHawk.Emulation/Consoles/Gameboy/Debugger.cs +++ b/BizHawk.MultiClient/Gameboy/Debugger.cs @@ -10,18 +10,24 @@ using System.Text; using System.Windows.Forms; using BizHawk.Core; -namespace VgMuseum.Gameboy +namespace BizHawk.Emulation.Consoles.Gameboy { - public partial class Debugger : Form + public partial class Debugger : Form, Gameboy.IDebuggerAPI { readonly Gameboy gb; public Debugger(Gameboy gb) { this.gb = gb; + gb.DebuggerAPI = this; InitializeComponent(); Refresh(); } + void Gameboy.IDebuggerAPI.DoEvents() + { + System.Windows.Forms.Application.DoEvents(); + } + private void viewDisassembly_Paint(object sender, PaintEventArgs e) { e.Graphics.Clear(SystemColors.Control); @@ -30,7 +36,7 @@ namespace VgMuseum.Gameboy for (int i = 0; i < 16; i++) { ushort size; - string str = VgMuseum.Z80GB.Disassembler.DAsm(addr, gb.Cpu.ReadMemory, out size); + string str = BizHawk.Emulation.CPUs.Z80GB.Disassembler.DAsm(addr, gb.Cpu.ReadMemory, out size); addr += size; sb.AppendLine(str); } diff --git a/BizHawk.Emulation/Consoles/Gameboy/Debugger.resx b/BizHawk.MultiClient/Gameboy/Debugger.resx similarity index 100% rename from BizHawk.Emulation/Consoles/Gameboy/Debugger.resx rename to BizHawk.MultiClient/Gameboy/Debugger.resx diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index d910a8139e..ba091f82f8 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -8,6 +8,7 @@ using BizHawk.Core; using BizHawk.Emulation.Consoles.Sega; using BizHawk.Emulation.Consoles.TurboGrafx; using BizHawk.Emulation.Consoles.Calculator; +using BizHawk.Emulation.Consoles.Gameboy; namespace BizHawk.MultiClient { @@ -215,6 +216,7 @@ namespace BizHawk.MultiClient case "SGX": return "SuperGrafx"; case "GEN": return "Genesis"; case "TI83": return "TI-83"; + case "GB": return "Game Boy"; } return ""; } @@ -256,6 +258,9 @@ namespace BizHawk.MultiClient Global.Emulator = new TI83(); Global.Emulator.Controller = Global.TI83Controls; break; + case "GB": + Global.Emulator = new Gameboy(); + break; } Global.Emulator.LoadGame(game); @@ -264,7 +269,12 @@ namespace BizHawk.MultiClient Global.Config.RecentRoms.Add(file.FullName); if (File.Exists(game.SaveRamPath)) LoadSaveRam(); - return true; + + if (game.System == "GB") + { + new BizHawk.Emulation.Consoles.Gameboy.Debugger(Global.Emulator as Gameboy).Show(); + } + return true; } private void LoadSaveRam()