From 28cce355bf33d96a1cb68894fbe449aa4864eed2 Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Thu, 19 Oct 2017 12:08:34 -0400 Subject: [PATCH] Z80: Fix R register operation --- BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs | 4 +- .../CPUs/Z80A/NewDisassembler.cs | 8 +- .../CPUs/Z80A/Tables_Direct.cs | 6 +- BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs | 107 ++++++++---------- 4 files changed, 55 insertions(+), 70 deletions(-) diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs index 4159f31d7a..c70e4aa503 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs @@ -15,6 +15,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A public const ushort IYpre = 3; public const ushort IXCBpre = 4; public const ushort IYCBpre = 5; + public const ushort IXYprefetch = 6; // variables for executing instructions public int instr_pntr = 0; @@ -1194,8 +1195,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IYCB_prefetch = false; PF = opcode; Regs[ALU] = PF; - PREFETCH_(Iyl, Iyh); - + PREFETCH_(Iyl, Iyh); return; } diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/NewDisassembler.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/NewDisassembler.cs index c19459c741..596e0ff66d 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/NewDisassembler.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/NewDisassembler.cs @@ -34,7 +34,6 @@ namespace BizHawk.Emulation.Cores.Components.Z80A char sign = neg ? '-' : '+'; int val = neg ? 256 - B : B; format = format.Replace("d", string.Format("{0}{1:X2}h", sign, val)); - addr++; } return format; @@ -397,6 +396,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A public string Disassemble(ushort addr, Func read, out ushort size) { ushort start_addr = addr; + ushort extra_inc = 0; byte A = read(addr++); string format; switch (A) @@ -409,7 +409,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A A = read(addr++); switch (A) { - case 0xCB: format = mnemonicsDDCB[A]; break; + case 0xCB: format = mnemonicsDDCB[A]; extra_inc = 1; break; case 0xED: format = mnemonicsED[A]; break; default: format = mnemonicsDD[A]; break; } @@ -422,7 +422,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A A = read(addr++); switch (A) { - case 0xCB: format = mnemonicsFDCB[A]; break; + case 0xCB: format = mnemonicsFDCB[A]; extra_inc = 1; break; case 0xED: format = mnemonicsED[A]; break; default: format = mnemonicsFD[A]; break; } @@ -432,6 +432,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A string temp = Result(format, read, ref addr); + addr += extra_inc; + size = (ushort)(addr - start_addr); return temp; } diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs index 8e473d1527..71b39d6018 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs @@ -395,10 +395,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A private void PREFIX_(ushort src) { cur_instr = new ushort[] - {PREFIX, src, + {IDLE, IDLE, IDLE, - OP }; + PREFIX, src}; } private void PREFETCH_(ushort src_l, ushort src_h) @@ -407,7 +407,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A {TR16, Z, W, src_l, src_h, ADDS, Z, W, ALU, ZERO, IDLE, - OP }; + PREFIX, IXYprefetch }; } private void DI_() diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs index 9155aeb178..2f13b0e6c7 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs @@ -75,7 +75,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A public const ushort I_BIT = 60; public const ushort HL_BIT = 61; - + public byte temp_R; public Z80A() { @@ -147,27 +147,20 @@ namespace BizHawk.Emulation.Cores.Components.Z80A break; case OP: // Read the opcode of the next instruction - if (EI_pending > 0 && NO_prefix) + if (EI_pending > 0) { EI_pending--; - if (EI_pending == 0) - { - IFF1 = IFF2 = true; - } + if (EI_pending == 0) { IFF1 = IFF2 = true; } } // Process interrupt requests. - if (nonMaskableInterruptPending && NO_prefix) + if (nonMaskableInterruptPending) { nonMaskableInterruptPending = false; if (TraceCallback != null) { - TraceCallback(new TraceInfo - { - Disassembly = "====NMI====", - RegisterInfo = "" - }); + TraceCallback(new TraceInfo{Disassembly = "====NMI====", RegisterInfo = ""}); } iff2 = iff1; @@ -175,18 +168,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A NMI_(); NMICallback(); } - else if (iff1 && FlagI && NO_prefix) + else if (iff1 && FlagI) { iff1 = iff2 = false; EI_pending = 0; if (TraceCallback != null) { - TraceCallback(new TraceInfo - { - Disassembly = "====IRQ====", - RegisterInfo = "" - }); + TraceCallback(new TraceInfo{Disassembly = "====IRQ====", RegisterInfo = ""}); } switch (interruptMode) @@ -210,12 +199,15 @@ namespace BizHawk.Emulation.Cores.Components.Z80A else { if (OnExecFetch != null) OnExecFetch(RegPC); - if (TraceCallback != null && NO_prefix) TraceCallback(State()); + if (TraceCallback != null) TraceCallback(State()); FetchInstruction(ReadMemory(RegPC++)); } instr_pntr = 0; - Regs[R]++; - Regs[R] &= 0xFF; + + temp_R = (byte)(Regs[R] & 0x7F); + temp_R++; + temp_R &= 0x7F; + Regs[R] = (byte)((Regs[R] & 0x80) | temp_R); break; case OP_R: // determine if we repeat based on what operation we are doing @@ -280,47 +272,35 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { // Interrupts can occur at this point, so process them accordingly // Read the opcode of the next instruction - if (EI_pending > 0 && NO_prefix) + if (EI_pending > 0) { EI_pending--; - if (EI_pending == 0) - { - IFF1 = IFF2 = true; - } + if (EI_pending == 0) { IFF1 = IFF2 = true; } } // Process interrupt requests. - if (nonMaskableInterruptPending && NO_prefix) + if (nonMaskableInterruptPending) { nonMaskableInterruptPending = false; if (TraceCallback != null) { - TraceCallback(new TraceInfo - { - Disassembly = "====NMI====", - RegisterInfo = "" - }); + TraceCallback(new TraceInfo{Disassembly = "====NMI====", RegisterInfo = ""}); } iff2 = iff1; iff1 = false; NMI_(); NMICallback(); - } - else if (iff1 && FlagI && NO_prefix) + else if (iff1 && FlagI) { iff1 = iff2 = false; EI_pending = 0; if (TraceCallback != null) { - TraceCallback(new TraceInfo - { - Disassembly = "====IRQ====", - RegisterInfo = "" - }); + TraceCallback(new TraceInfo{Disassembly = "====IRQ====", RegisterInfo = ""}); } switch (interruptMode) @@ -346,36 +326,32 @@ namespace BizHawk.Emulation.Cores.Components.Z80A if (OnExecFetch != null) OnExecFetch(RegPC); if (TraceCallback != null) TraceCallback(State()); FetchInstruction(ReadMemory(RegPC++)); - Regs[R]++; - Regs[R] &= 0xFF; } + + temp_R = (byte)(Regs[R] & 0x7F); + temp_R++; + temp_R &= 0x7F; + Regs[R] = (byte)((Regs[R] & 0x80) | temp_R); } instr_pntr = 0; break; case HALT: halted = true; - if (EI_pending > 0 && NO_prefix) + if (EI_pending > 0) { EI_pending--; - if (EI_pending == 0) - { - IFF1 = IFF2 = true; - } + if (EI_pending == 0) { IFF1 = IFF2 = true; } } // Process interrupt requests. - if (nonMaskableInterruptPending && NO_prefix) + if (nonMaskableInterruptPending) { nonMaskableInterruptPending = false; if (TraceCallback != null) { - TraceCallback(new TraceInfo - { - Disassembly = "====NMI====", - RegisterInfo = "" - }); + TraceCallback(new TraceInfo{Disassembly = "====NMI====", RegisterInfo = ""}); } iff2 = iff1; @@ -384,18 +360,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A NMICallback(); halted = false; } - else if (iff1 && FlagI && NO_prefix) + else if (iff1 && FlagI) { iff1 = iff2 = false; EI_pending = 0; if (TraceCallback != null) { - TraceCallback(new TraceInfo - { - Disassembly = "====IRQ====", - RegisterInfo = "" - }); + TraceCallback(new TraceInfo{Disassembly = "====IRQ====", RegisterInfo = ""}); } switch (interruptMode) @@ -419,14 +391,16 @@ namespace BizHawk.Emulation.Cores.Components.Z80A } else { - Regs[R]++; - Regs[R] &= 0xFF; cur_instr = new ushort[] {IDLE, IDLE, IDLE, HALT }; } + temp_R = (byte)(Regs[R] & 0x7F); + temp_R++; + temp_R &= 0x7F; + Regs[R] = (byte)((Regs[R] & 0x80) | temp_R); instr_pntr = 0; break; @@ -567,8 +541,17 @@ namespace BizHawk.Emulation.Cores.Components.Z80A if (prefix_src == IYpre) { IY_prefix = true; } if (prefix_src == IXCBpre) { IXCB_prefix = true; IXCB_prefetch = true; } if (prefix_src == IYCBpre) { IYCB_prefix = true; IYCB_prefetch = true; } - Regs[R]++; - Regs[R] &= 0xFF; + + FetchInstruction(ReadMemory(RegPC++)); + instr_pntr = 0; + // only the first prefix in a double prefix increases R, although I don't know how / why + if (prefix_src < 4) + { + temp_R = (byte)(Regs[R] & 0x7F); + temp_R++; + temp_R &= 0x7F; + Regs[R] = (byte)((Regs[R] & 0x80) | temp_R); + } break; case ASGN: ASGN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);