diff --git a/Assets/gamedb/gamedb_nes.txt b/Assets/gamedb/gamedb_nes.txt index 5ccc1128a5..b837ef1be5 100644 --- a/Assets/gamedb/gamedb_nes.txt +++ b/Assets/gamedb/gamedb_nes.txt @@ -346,6 +346,7 @@ sha1:D89EE629F8F60613999EAD84A3C7B2F6B38C399F fme7ramtest_128k NES board=MAPPE sha1:78C4441E42C8F423EBF6558AA00AB6D0DBCC2B4B 34_test_1 NES board=AVE-NINA-01;PRG=64;CHR=64;WRAM=8;VRAM=0;PAD_V=1;PAD_H=0 sha1:F2D5CB78D78831CB6A2A17CD418A753F3C99C7F4 34_test_2 NES board=NES-BNROM;PRG=256;CHR=0;WRAM=8;VRAM=8;PAD_V=1;PAD_H=0 sha1:77C5C2473AF13003B7BD8273A5E23BE4964107A3 M34_P128K_H NES board=AVE-NINA-07;PRG=128;CHR=0;WRAM=0;VRAM=8;PAD_V=1;PAD_H=0 +sha1:B6721E1C1EC2E2F215180ED7BB31EDA80BCDE869 2nd2006_next_level NES board=MAPPER000;PRG=16;CHR=8;PAD_V=1;PAD_H=0 ;other sha1:4180276C50DF9958DEDD6C6D19C9E7AEBB75A89F o Galaxian (Japan) NES board=NAMCOT-3301;PRG=16;CHR=8;WRAM=8;VRAM=0;PAD_V=1;PAD_H=0 diff --git a/BizHawk.Client.Common/lua/EmuLuaLibrary.GameInfo.cs b/BizHawk.Client.Common/lua/EmuLuaLibrary.GameInfo.cs index c098594f37..61d2d4afb0 100644 --- a/BizHawk.Client.Common/lua/EmuLuaLibrary.GameInfo.cs +++ b/BizHawk.Client.Common/lua/EmuLuaLibrary.GameInfo.cs @@ -19,7 +19,7 @@ namespace BizHawk.Client.Common public override string Name => "gameinfo"; [LuaMethodExample("local stgamget = gameinfo.getromname( );")] - [LuaMethod("getromname", "returns the path of the currently loaded rom, if a rom is loaded")] + [LuaMethod("getromname", "returns the name of the currently loaded rom, if a rom is loaded")] public string GetRomName() { if (Global.Game != null) diff --git a/BizHawk.Client.EmuHawk/config/N64/N64VideoPluginconfig.cs b/BizHawk.Client.EmuHawk/config/N64/N64VideoPluginconfig.cs index ebb0d105d9..0bcbccdbfd 100644 --- a/BizHawk.Client.EmuHawk/config/N64/N64VideoPluginconfig.cs +++ b/BizHawk.Client.EmuHawk/config/N64/N64VideoPluginconfig.cs @@ -30,6 +30,7 @@ namespace BizHawk.Client.EmuHawk "1600 x 1200", "1920 x 1440", "2048 x 1536", + "2880 x 2160", "Custom" }; diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/A78Schema.cs b/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/A78Schema.cs index 61de5d9c5c..eeaf72f352 100644 --- a/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/A78Schema.cs +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/A78Schema.cs @@ -155,7 +155,7 @@ namespace BizHawk.Client.EmuHawk }, new PadSchema.ButtonSchema { - Name = "P" + controller + " Trigger", + Name = "P" + controller + " Button", DisplayName = "1", Location = new Point(120, 24), Type = PadSchema.PadInputType.Boolean diff --git a/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs b/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs index 12c13662aa..063b41ee5c 100644 --- a/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs +++ b/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs @@ -396,11 +396,22 @@ namespace BizHawk.Emulation.Common.Components.LR35902 } else { - cur_instr = new ushort[] - {HALT_CHK, - IDLE, - IDLE, + if (is_GBC) + { + cur_instr = new ushort[] + {IDLE, + IDLE, + HALT_CHK, HALT, 0 }; + } + else + { + cur_instr = new ushort[] + {HALT_CHK, + IDLE, + IDLE, + HALT, 0 }; + } } } diff --git a/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Disassembler.cs b/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Disassembler.cs index 25d28f85c3..c6eed76817 100644 --- a/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Disassembler.cs +++ b/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Disassembler.cs @@ -185,6 +185,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 case 0xAE: bytesToAdvance = 3; return string.Format("LDX ${0:X4}", peeker_word(++pc, peeker)); case 0xB0: bytesToAdvance = 2; return string.Format("BCS ${0:X4}", pc + 2 + (sbyte)peeker(++pc)); case 0xB1: bytesToAdvance = 2; return string.Format("LDA (${0:X2}),Y *", peeker(++pc)); + case 0xB3: bytesToAdvance = 2; return string.Format("LAX (${0:X2}),Y *", peeker(++pc)); case 0xB4: bytesToAdvance = 2; return string.Format("LDY ${0:X2},X", peeker(++pc)); case 0xB5: bytesToAdvance = 2; return string.Format("LDA ${0:X2},X", peeker(++pc)); case 0xB6: bytesToAdvance = 2; return string.Format("LDX ${0:X2},Y", peeker(++pc)); @@ -203,6 +204,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 case 0xC8: bytesToAdvance = 1; return "INY"; case 0xC9: bytesToAdvance = 2; return string.Format("CMP #${0:X2}", peeker(++pc)); case 0xCA: bytesToAdvance = 1; return "DEX"; + case 0xCB: bytesToAdvance = 2; return string.Format("AXS ${0:X2}", peeker(++pc)); case 0xCC: bytesToAdvance = 3; return string.Format("CPY ${0:X4}", peeker_word(++pc, peeker)); case 0xCD: bytesToAdvance = 3; return string.Format("CMP ${0:X4}", peeker_word(++pc, peeker)); case 0xCE: bytesToAdvance = 3; return string.Format("DEC ${0:X4}", peeker_word(++pc, peeker)); diff --git a/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs b/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs index 9724899735..5d9282cae4 100644 --- a/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs @@ -600,6 +600,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 return; } } + Fetch1_Real(); } @@ -2971,8 +2972,6 @@ namespace BizHawk.Emulation.Cores.Components.M6502 TotalExecutedCycles++; if (!rdy_freeze) { - - interrupt_pending |= Interrupted; } rdy_freeze = false; diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs index b8b65bdf39..d9a9c4336c 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs @@ -24,10 +24,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A public int bus_pntr = 0; public int mem_pntr = 0; public int irq_pntr = 0; - public ushort[] cur_instr; - public ushort[] BUSRQ; - public ushort[] MEMRQ; - public ushort[] IRQS; + public ushort[] cur_instr = new ushort[38]; // fixed size - do not change at runtime + public ushort[] BUSRQ = new ushort[19]; // fixed size - do not change at runtime + public ushort[] MEMRQ = new ushort[19]; // fixed size - do not change at runtime + public int IRQS; public byte opcode; public bool NO_prefix, CB_prefix, IX_prefix, EXTD_prefix, IY_prefix, IXCB_prefix, IYCB_prefix; public bool halted; diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Interrupts.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Interrupts.cs index 5eec6cf45f..869dcdac8a 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Interrupts.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Interrupts.cs @@ -36,8 +36,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A private void NMI_() { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, IDLE, IDLE, @@ -47,11 +47,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WR_DEC, SPl, SPh, PCh, TR16, PCl, PCh, NMI_V, ZERO, WAIT, - WR, SPl, SPh, ALU }; + WR, SPl, SPh, ALU); - BUSRQ = new ushort[] { 0, 0, 0, 0, 0, SPh, 0, 0, SPh, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0, SPh, 0, 0, SPh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, 0, 0, 0, 0, SPh, 0, 0, SPh, 0, 0); + PopulateMEMRQ(0, 0, 0, 0, 0, SPh, 0, 0, SPh, 0, 0); + IRQS = 11; } // Mode 0 interrupts only take effect if a CALL or RST is on the data bus @@ -61,25 +61,25 @@ namespace BizHawk.Emulation.Cores.Components.Z80A //NOTE: TODO: When a CALL is present on the data bus, adjust WZ accordingly private void INTERRUPT_0(ushort src) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, IORQ, WAIT, IDLE, WAIT, - RD_INC, ALU, PCl, PCh }; + RD_INC, ALU, PCl, PCh); - BUSRQ = new ushort[] { 0, 0, 0, 0, PCh, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, 0, 0, PCh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, 0, 0, 0, PCh, 0, 0); + PopulateMEMRQ(0, 0, 0, 0, PCh, 0, 0); + IRQS = 7; } // Just jump to $0038 private void INTERRUPT_1() { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, IORQ, WAIT, @@ -91,25 +91,25 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WR_DEC, SPl, SPh, PCh, TR16, PCl, PCh, IRQ_V, ZERO, WAIT, - WR, SPl, SPh, ALU }; + WR, SPl, SPh, ALU); - BUSRQ = new ushort[] { 0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0); + PopulateMEMRQ(0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0); + IRQS = 13; } // Interrupt mode 2 uses the I vector combined with a byte on the data bus private void INTERRUPT_2() { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, IORQ, WAIT, FTCH_DB, IDLE, DEC16, SPl, SPh, - TR16, Z, W, DB, I, + TR16, Z, W, DB, I, WAIT, WR_DEC, SPl, SPh, PCh, IDLE, @@ -120,11 +120,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A RD_INC, PCl, Z, W, IDLE, WAIT, - RD, PCh, Z, W }; + RD, PCh, Z, W); - BUSRQ = new ushort[] { 0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0 ,0 }; - MEMRQ = new ushort[] { 0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0, 0); + PopulateMEMRQ(0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0, 0); + IRQS = 19; } private void ResetInterrupts() diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs index 6af37ce302..d8ea27b445 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs @@ -9,111 +9,111 @@ namespace BizHawk.Emulation.Cores.Components.Z80A private void NOP_() { - cur_instr = new ushort[] - {IDLE }; + PopulateCURINSTR + (IDLE); - BUSRQ = new ushort[] { 0 }; - MEMRQ = new ushort[] { 0 }; - IRQS = new ushort[] { 1 }; + PopulateBUSRQ(0); + PopulateMEMRQ(0); + IRQS = 1; } // NOTE: In a real Z80, this operation just flips a switch to choose between 2 registers // but it's simpler to emulate just by exchanging the register with it's shadow private void EXCH_() { - cur_instr = new ushort[] - {EXCH }; + PopulateCURINSTR + (EXCH); - BUSRQ = new ushort[] { 0 }; - MEMRQ = new ushort[] { 0 }; - IRQS = new ushort[] { 1 }; + PopulateBUSRQ(0); + PopulateMEMRQ(0); + IRQS = 1; } private void EXX_() { - cur_instr = new ushort[] - {EXX }; + PopulateCURINSTR + (EXX); - BUSRQ = new ushort[] { 0 }; - MEMRQ = new ushort[] { 0 }; - IRQS = new ushort[] { 1 }; + PopulateBUSRQ(0); + PopulateMEMRQ(0); + IRQS = 1; } // this exchanges 2 16 bit registers private void EXCH_16_(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {EXCH_16, dest_l, dest_h, src_l, src_h }; + PopulateCURINSTR + (EXCH_16, dest_l, dest_h, src_l, src_h); - BUSRQ = new ushort[] { 0 }; - MEMRQ = new ushort[] { 0 }; - IRQS = new ushort[] { 1 }; + PopulateBUSRQ(0); + PopulateMEMRQ(0); + IRQS = 1; } private void INC_16(ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {INC16, src_l, src_h, + PopulateCURINSTR + (INC16, src_l, src_h, IDLE, - IDLE }; + IDLE); - BUSRQ = new ushort[] { 0, I, I }; - MEMRQ = new ushort[] { 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 1 }; + PopulateBUSRQ(0, I, I); + PopulateMEMRQ(0, 0, 0); + IRQS = 3; } private void DEC_16(ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {DEC16, src_l, src_h, + PopulateCURINSTR + (DEC16, src_l, src_h, IDLE, - IDLE }; + IDLE); - BUSRQ = new ushort[] { 0, I, I }; - MEMRQ = new ushort[] { 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 1 }; + PopulateBUSRQ(0, I, I); + PopulateMEMRQ(0, 0, 0); + IRQS = 3; } // this is done in two steps technically, but the flags don't work out using existing funcitons // so let's use a different function since it's an internal operation anyway private void ADD_16(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, TR16, Z, W, dest_l, dest_h, IDLE, INC16, Z, W, IDLE, ADD16, dest_l, dest_h, src_l, src_h, IDLE, - IDLE}; + IDLE); - BUSRQ = new ushort[] { 0, I, I, I, I, I, I, I }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1}; + PopulateBUSRQ(0, I, I, I, I, I, I, I); + PopulateMEMRQ(0, 0, 0, 0, 0, 0, 0, 0); + IRQS = 8; } private void REG_OP(ushort operation, ushort dest, ushort src) { - cur_instr = new ushort[] - {operation, dest, src }; + PopulateCURINSTR + (operation, dest, src); - BUSRQ = new ushort[] { 0 }; - MEMRQ = new ushort[] { 0 }; - IRQS = new ushort[] { 1 }; + PopulateBUSRQ(0); + PopulateMEMRQ(0); + IRQS = 1; } // Operations using the I and R registers take one T-cycle longer private void REG_OP_IR(ushort operation, ushort dest, ushort src) { - cur_instr = new ushort[] - {IDLE, - SET_FL_IR, dest, src }; + PopulateCURINSTR + (IDLE, + SET_FL_IR, dest, src); - BUSRQ = new ushort[] { 0, I }; - MEMRQ = new ushort[] { 0, 0 }; - IRQS = new ushort[] { 0, 1 }; + PopulateBUSRQ(0, I); + PopulateMEMRQ(0, 0); + IRQS = 2; } // note: do not use DEC here since no flags are affected by this operation @@ -121,8 +121,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { if ((Regs[B] - 1) != 0) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, ASGN, B, (ushort)((Regs[B] - 1) & 0xFF), WAIT, @@ -131,43 +131,43 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IDLE, ASGN, W, 0, ADDS, PCl, PCh, Z, W, - TR16, Z, W, PCl, PCh }; + TR16, Z, W, PCl, PCh); - BUSRQ = new ushort[] { 0, I, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh }; - MEMRQ = new ushort[] { 0, 0, PCh, 0, 0, 0, 0, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, I, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh); + PopulateMEMRQ(0, 0, PCh, 0, 0, 0, 0, 0, 0, 0); + IRQS = 10; } else { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, ASGN, B, (ushort)((Regs[B] - 1) & 0xFF), WAIT, - RD_INC, ALU, PCl, PCh }; + RD_INC, ALU, PCl, PCh); - BUSRQ = new ushort[] { 0, I, PCh, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, PCh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, I, PCh, 0, 0); + PopulateMEMRQ(0, 0, PCh, 0, 0); + IRQS = 5; } } private void HALT_() { - cur_instr = new ushort[] - { HALT }; + PopulateCURINSTR + (HALT); - BUSRQ = new ushort[] { 0 }; - MEMRQ = new ushort[] { 0 }; - IRQS = new ushort[] { 1 }; + PopulateBUSRQ(0); + PopulateMEMRQ(0); + IRQS = 1; } private void JR_COND(bool cond) { if (cond) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, PCl, PCh, @@ -175,23 +175,23 @@ namespace BizHawk.Emulation.Cores.Components.Z80A ASGN, W, 0, IDLE, ADDS, PCl, PCh, Z, W, - TR16, Z, W, PCl, PCh }; + TR16, Z, W, PCl, PCh); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, 0, 0, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh); + PopulateMEMRQ(0, PCh, 0, 0, 0, 0, 0, 0, 0); + IRQS = 9; } else { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, - RD_INC, ALU, PCl, PCh }; + RD_INC, ALU, PCl, PCh); - BUSRQ = new ushort[] { 0, PCh, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0); + IRQS = 4; } } @@ -199,82 +199,82 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { if (cond) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, PCl, PCh, IDLE, WAIT, - RD_INC_TR_PC, Z, W, PCl, PCh}; + RD_INC_TR_PC, Z, W, PCl, PCh); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0, PCh, 0, 0); + IRQS = 7; } else { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, PCl, PCh, IDLE, WAIT, - RD_INC, W, PCl, PCh }; + RD_INC, W, PCl, PCh); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0, PCh, 0, 0); + IRQS = 7; } } private void RET_() { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, SPl, SPh, IDLE, WAIT, - RD_INC_TR_PC, Z, W, SPl, SPh }; + RD_INC_TR_PC, Z, W, SPl, SPh); - BUSRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; - MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, SPh, 0, 0, SPh, 0, 0); + PopulateMEMRQ(0, SPh, 0, 0, SPh, 0, 0); + IRQS = 7; } private void RETI_() { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, SPl, SPh, IDLE, WAIT, - RD_INC_TR_PC, Z, W, SPl, SPh }; + RD_INC_TR_PC, Z, W, SPl, SPh); - BUSRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; - MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, SPh, 0, 0, SPh, 0, 0); + PopulateMEMRQ(0, SPh, 0, 0, SPh, 0, 0); + IRQS = 7; } private void RETN_() { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, SPl, SPh, EI_RETN, WAIT, - RD_INC_TR_PC, Z, W, SPl, SPh }; + RD_INC_TR_PC, Z, W, SPl, SPh); - BUSRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; - MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, SPh, 0, 0, SPh, 0, 0); + PopulateMEMRQ(0, SPh, 0, 0, SPh, 0, 0); + IRQS = 7; } @@ -282,29 +282,29 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { if (cond) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, IDLE, WAIT, - RD_INC, Z, SPl, SPh, - IDLE, + RD_INC, Z, SPl, SPh, + IDLE, WAIT, - RD_INC_TR_PC, Z, W, SPl, SPh}; + RD_INC_TR_PC, Z, W, SPl, SPh); - BUSRQ = new ushort[] { 0, I, SPh, 0, 0, SPh, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, SPh, 0, 0, SPh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, I, SPh, 0, 0, SPh, 0, 0); + PopulateMEMRQ(0, 0, SPh, 0, 0, SPh, 0, 0); + IRQS = 8; } else { - cur_instr = new ushort[] - {IDLE, - IDLE }; + PopulateCURINSTR + (IDLE, + IDLE); - BUSRQ = new ushort[] { 0, I }; - MEMRQ = new ushort[] { 0, 0 }; - IRQS = new ushort[] { 0, 1 }; + PopulateBUSRQ(0, I); + PopulateMEMRQ(0, 0); + IRQS = 2; } } @@ -312,8 +312,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { if (cond) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, PCl, PCh, @@ -326,113 +326,113 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WR_DEC, SPl, SPh, PCh, IDLE, WAIT, - WR_TR_PC, SPl, SPh, PCl }; + WR_TR_PC, SPl, SPh, PCl); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, PCh, SPh, 0, 0, SPh, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, 0, SPh, 0, 0, SPh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, 0, 0, PCh, SPh, 0, 0, SPh, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0, PCh, 0, 0, 0, SPh, 0, 0, SPh, 0, 0); + IRQS = 14; } else { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, PCl, PCh, IDLE, WAIT, - RD_INC, W, PCl, PCh}; + RD_INC, W, PCl, PCh); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0, PCh, 0, 0); + IRQS = 7; } } private void INT_OP(ushort operation, ushort src) { - cur_instr = new ushort[] - {operation, src }; + PopulateCURINSTR + (operation, src); - BUSRQ = new ushort[] { 0 }; - MEMRQ = new ushort[] { 0 }; - IRQS = new ushort[] { 1 }; + PopulateBUSRQ(0); + PopulateMEMRQ(0); + IRQS = 1; } private void BIT_OP(ushort operation, ushort bit, ushort src) { - cur_instr = new ushort[] - {operation, bit, src }; + PopulateCURINSTR + (operation, bit, src); - BUSRQ = new ushort[] { 0 }; - MEMRQ = new ushort[] { 0 }; - IRQS = new ushort[] { 1 }; + PopulateBUSRQ(0); + PopulateMEMRQ(0); + IRQS = 1; } private void PUSH_(ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, DEC16, SPl, SPh, IDLE, WAIT, WR_DEC, SPl, SPh, src_h, IDLE, WAIT, - WR, SPl, SPh, src_l }; + WR, SPl, SPh, src_l); - BUSRQ = new ushort[] { 0, I, SPh, 0, 0, SPh, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, SPh, 0, 0, SPh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, I, SPh, 0, 0, SPh, 0, 0); + PopulateMEMRQ(0, 0, SPh, 0, 0, SPh, 0, 0); + IRQS = 8; } private void POP_(ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, src_l, SPl, SPh, IDLE, WAIT, - RD_INC, src_h, SPl, SPh }; + RD_INC, src_h, SPl, SPh); - BUSRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; - MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; - IRQS = new ushort[] {0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, SPh, 0, 0, SPh, 0, 0); + PopulateMEMRQ(0, SPh, 0, 0, SPh, 0, 0); + IRQS = 7; } private void RST_(ushort n) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, DEC16, SPl, SPh, IDLE, WAIT, WR_DEC, SPl, SPh, PCh, RST, n, WAIT, - WR_TR_PC, SPl, SPh, PCl }; + WR_TR_PC, SPl, SPh, PCl); - BUSRQ = new ushort[] { 0, I, SPh, 0, 0, SPh, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, SPh, 0, 0, SPh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, I, SPh, 0, 0, SPh, 0, 0); + PopulateMEMRQ(0, 0, SPh, 0, 0, SPh, 0, 0); + IRQS = 8; } private void PREFIX_(ushort src) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, - PREFIX }; + PREFIX); PRE_SRC = src; - BUSRQ = new ushort[] { 0, PCh, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0 }; // prefix does not get interrupted + PopulateBUSRQ(0, PCh, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0); + IRQS = -1; // prefix does not get interrupted } private void PREFETCH_(ushort src) @@ -448,160 +448,160 @@ namespace BizHawk.Emulation.Cores.Components.Z80A Regs[Z] = Regs[Iyl]; } - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, ALU, PCl, PCh, ADDS, Z, W, ALU, ZERO, WAIT, IDLE, - PREFIX}; + PREFIX); PRE_SRC = src; //Console.WriteLine(TotalExecutedCycles); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, PCh }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0 }; // prefetch does not get interrupted + PopulateBUSRQ(0, PCh, 0, 0, PCh, 0, 0, PCh); + PopulateMEMRQ(0, PCh, 0, 0, PCh, 0, 0, 0); + IRQS = -1; // prefetch does not get interrupted } private void DI_() { - cur_instr = new ushort[] - {DI }; + PopulateCURINSTR + (DI); - BUSRQ = new ushort[] { 0 }; - MEMRQ = new ushort[] { 0 }; - IRQS = new ushort[] { 1 }; + PopulateBUSRQ(0); + PopulateMEMRQ(0); + IRQS = 1; } private void EI_() { - cur_instr = new ushort[] - {EI }; + PopulateCURINSTR + (EI); - BUSRQ = new ushort[] { 0 }; - MEMRQ = new ushort[] { 0 }; - IRQS = new ushort[] { 1 }; + PopulateBUSRQ(0); + PopulateMEMRQ(0); + IRQS = 1; } private void JP_16(ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {TR16, PCl, PCh, src_l, src_h }; + PopulateCURINSTR + (TR16, PCl, PCh, src_l, src_h); - BUSRQ = new ushort[] { 0 }; - MEMRQ = new ushort[] { 0 }; - IRQS = new ushort[] { 1 }; + PopulateBUSRQ(0); + PopulateMEMRQ(0); + IRQS = 1; } private void LD_SP_16(ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, - TR16, SPl, SPh, src_l, src_h }; + TR16, SPl, SPh, src_l, src_h); - BUSRQ = new ushort[] { 0, I, I }; - MEMRQ = new ushort[] { 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 1 }; + PopulateBUSRQ(0, I, I); + PopulateMEMRQ(0, 0, 0); + IRQS = 3; } private void OUT_() { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, TR, W, A, WAIT, RD_INC, Z, PCl, PCh, - TR, ALU, A, - WAIT, + TR, ALU, A, WAIT, - OUT_INC, Z, ALU, A }; + WAIT, + OUT_INC, Z, ALU, A); - BUSRQ = new ushort[] { 0, PCh, 0, 0, WIO1, WIO2, WIO3, WIO4 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, WIO1, WIO2, WIO3, WIO4 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1}; + PopulateBUSRQ(0, PCh, 0, 0, WIO1, WIO2, WIO3, WIO4); + PopulateMEMRQ(0, PCh, 0, 0, WIO1, WIO2, WIO3, WIO4); + IRQS = 8; } private void OUT_REG_(ushort dest, ushort src) { - cur_instr = new ushort[] - {IDLE, - TR16, Z, W, C, B, - IDLE, + PopulateCURINSTR + (IDLE, + TR16, Z, W, C, B, IDLE, - OUT_INC, Z, W, src }; + IDLE, + OUT_INC, Z, W, src); - BUSRQ = new ushort[] { 0, BIO1, BIO2, BIO3, BIO4 }; - MEMRQ = new ushort[] { 0, BIO1, BIO2, BIO3, BIO4 }; - IRQS = new ushort[] { 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, BIO1, BIO2, BIO3, BIO4); + PopulateMEMRQ(0, BIO1, BIO2, BIO3, BIO4); + IRQS = 5; } private void IN_() { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, TR, W, A, WAIT, RD_INC, Z, PCl, PCh, IDLE, WAIT, WAIT, - IN_A_N_INC, A, Z, W }; + IN_A_N_INC, A, Z, W); - BUSRQ = new ushort[] { 0, PCh, 0, 0, WIO1, WIO2, WIO3, WIO4 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, WIO1, WIO2, WIO3, WIO4 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, WIO1, WIO2, WIO3, WIO4); + PopulateMEMRQ(0, PCh, 0, 0, WIO1, WIO2, WIO3, WIO4); + IRQS = 8; } private void IN_REG_(ushort dest, ushort src) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, TR16, Z, W, C, B, WAIT, WAIT, - IN_INC, dest, Z, W }; + IN_INC, dest, Z, W); - BUSRQ = new ushort[] { 0, BIO1, BIO2, BIO3, BIO4 }; - MEMRQ = new ushort[] { 0, BIO1, BIO2, BIO3, BIO4 }; - IRQS = new ushort[] { 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, BIO1, BIO2, BIO3, BIO4); + PopulateMEMRQ(0, BIO1, BIO2, BIO3, BIO4); + IRQS = 5; } private void REG_OP_16_(ushort op, ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, IDLE, TR16, Z, W, dest_l, dest_h, INC16, Z, W, IDLE, IDLE, - op, dest_l, dest_h, src_l, src_h }; + op, dest_l, dest_h, src_l, src_h); - BUSRQ = new ushort[] { 0, I, I, I, I, I, I, I }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, I, I, I, I, I, I, I); + PopulateMEMRQ(0, 0, 0, 0, 0, 0, 0, 0); + IRQS = 8; } private void INT_MODE_(ushort src) { - cur_instr = new ushort[] - {INT_MODE, src }; + PopulateCURINSTR + (INT_MODE, src); - BUSRQ = new ushort[] { 0 }; - MEMRQ = new ushort[] { 0 }; - IRQS = new ushort[] { 1 }; + PopulateBUSRQ(0); + PopulateMEMRQ(0); + IRQS = 1; } private void RRD_() { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, TR16, Z, W, L, H, WAIT, RD, ALU, Z, W, @@ -611,17 +611,17 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IDLE, IDLE, WAIT, - WR_INC, Z, W, ALU }; + WR_INC, Z, W, ALU); - BUSRQ = new ushort[] { 0, H, 0, 0, H, H, H, H, W, 0, 0 }; - MEMRQ = new ushort[] { 0, H, 0, 0, 0, 0, 0, 0, W, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, H, 0, 0, H, H, H, H, W, 0, 0); + PopulateMEMRQ(0, H, 0, 0, 0, 0, 0, 0, W, 0, 0); + IRQS = 11; } private void RLD_() { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, TR16, Z, W, L, H, WAIT, RD, ALU, Z, W, @@ -631,11 +631,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IDLE, IDLE, WAIT, - WR_INC, Z, W, ALU }; + WR_INC, Z, W, ALU); - BUSRQ = new ushort[] { 0, H, 0, 0, H, H, H, H, W, 0, 0 }; - MEMRQ = new ushort[] { 0, H, 0, 0, 0, 0, 0, 0, W, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, H, 0, 0, H, H, H, H, W, 0, 0); + PopulateMEMRQ(0, H, 0, 0, 0, 0, 0, 0, W, 0, 0); + IRQS = 11; } } } diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Indirect.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Indirect.cs index 65e0b607f5..4549fa54d1 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Indirect.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Indirect.cs @@ -4,36 +4,36 @@ { private void INT_OP_IND(ushort operation, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD, ALU, src_l, src_h, IDLE, operation, ALU, WAIT, - WR, src_l, src_h, ALU }; + WR, src_l, src_h, ALU); - BUSRQ = new ushort[] { 0, src_h, 0, 0, src_h, src_h, 0, 0 }; - MEMRQ = new ushort[] { 0, src_h, 0, 0, 0, src_h, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, src_h, 0, 0, src_h, src_h, 0, 0); + PopulateMEMRQ(0, src_h, 0, 0, 0, src_h, 0, 0); + IRQS = 8; } private void BIT_OP_IND(ushort operation, ushort bit, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, - WAIT, + WAIT, RD, ALU, src_l, src_h, operation, bit, ALU, IDLE, WAIT, - WR, src_l, src_h, ALU }; + WR, src_l, src_h, ALU); - BUSRQ = new ushort[] { 0, src_h, 0, 0, src_h, src_h, 0, 0 }; - MEMRQ = new ushort[] { 0, src_h, 0, 0, 0, src_h, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, src_h, 0, 0, src_h, src_h, 0, 0); + PopulateMEMRQ(0, src_h, 0, 0, 0, src_h, 0, 0); + IRQS = 8; } // Note that this operation uses I_BIT, same as indexed BIT. @@ -42,62 +42,62 @@ // even though WZ is not assigned to, letting it's value from other operations show through private void BIT_TE_IND(ushort operation, ushort bit, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD, ALU, src_l, src_h, - I_BIT, bit, ALU }; + I_BIT, bit, ALU); - BUSRQ = new ushort[] { 0, src_h, 0, 0, src_h }; - MEMRQ = new ushort[] { 0, src_h, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, src_h, 0, 0, src_h); + PopulateMEMRQ(0, src_h, 0, 0, 0); + IRQS = 5; } private void REG_OP_IND_INC(ushort operation, ushort dest, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, - IDLE, - WAIT, - RD_OP, 1, ALU, src_l, src_h, operation, dest, ALU }; + PopulateCURINSTR + (IDLE, + IDLE, + WAIT, + RD_OP, 1, ALU, src_l, src_h, operation, dest, ALU); - BUSRQ = new ushort[] { 0, src_h, 0, 0 }; - MEMRQ = new ushort[] { 0, src_h, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 1}; + PopulateBUSRQ(0, src_h, 0, 0); + PopulateMEMRQ(0, src_h, 0, 0); + IRQS = 4; } private void REG_OP_IND(ushort operation, ushort dest, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, TR16, Z, W, src_l, src_h, WAIT, - RD_OP, 1, ALU, Z, W, operation, dest, ALU }; + RD_OP, 1, ALU, Z, W, operation, dest, ALU); - BUSRQ = new ushort[] { 0, src_h, 0, 0 }; - MEMRQ = new ushort[] { 0, src_h, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 1 }; + PopulateBUSRQ(0, src_h, 0, 0); + PopulateMEMRQ(0, src_h, 0, 0); + IRQS = 4; } // different because HL doesn't effect WZ private void REG_OP_IND_HL(ushort operation, ushort dest) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, - RD_OP, 0, ALU, L, H, operation, dest, ALU }; + RD_OP, 0, ALU, L, H, operation, dest, ALU); - BUSRQ = new ushort[] { 0, H, 0, 0 }; - MEMRQ = new ushort[] { 0, H, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 1 }; + PopulateBUSRQ(0, H, 0, 0); + PopulateMEMRQ(0, H, 0, 0); + IRQS = 4; } private void LD_16_IND_nn(ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, PCl, PCh, @@ -109,17 +109,17 @@ WR_INC, Z, W, src_l, IDLE, WAIT, - WR, Z, W, src_h }; + WR, Z, W, src_h); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0); + IRQS = 13; } private void LD_IND_16_nn(ushort dest_l, ushort dest_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, PCl, PCh, @@ -131,17 +131,17 @@ RD_INC, dest_l, Z, W, IDLE, WAIT, - RD, dest_h, Z, W }; + RD, dest_h, Z, W); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0); + IRQS = 13; } private void LD_8_IND_nn(ushort src) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, PCl, PCh, @@ -150,17 +150,17 @@ RD_INC, W, PCl, PCh, IDLE, WAIT, - WR_INC_WA, Z, W, src }; + WR_INC_WA, Z, W, src); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, 0, 0, W, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0, PCh, 0, 0, W, 0, 0); + IRQS = 10; } private void LD_IND_8_nn(ushort dest) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, PCl, PCh, @@ -169,172 +169,172 @@ RD_INC, W, PCl, PCh, IDLE, WAIT, - RD_INC, dest, Z, W }; + RD_INC, dest, Z, W); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, 0, 0, W, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0, PCh, 0, 0, W, 0, 0); + IRQS = 10; } private void LD_8_IND(ushort dest_l, ushort dest_h, ushort src) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, TR16, Z, W, dest_l, dest_h, WAIT, - WR_INC_WA, Z, W, src }; + WR_INC_WA, Z, W, src); - BUSRQ = new ushort[] { 0, dest_h, 0, 0 }; - MEMRQ = new ushort[] { 0, dest_h, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 1 }; + PopulateBUSRQ(0, dest_h, 0, 0); + PopulateMEMRQ(0, dest_h, 0, 0); + IRQS = 4; } // seperate HL needed since it doesn't effect the WZ pair private void LD_8_IND_HL(ushort src) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, - WR, L, H, src }; + WR, L, H, src); - BUSRQ = new ushort[] { 0, H, 0, 0 }; - MEMRQ = new ushort[] { 0, H, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 1 }; + PopulateBUSRQ(0, H, 0, 0); + PopulateMEMRQ(0, H, 0, 0); + IRQS = 4; } private void LD_8_IND_IND(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, ALU, src_l, src_h, IDLE, WAIT, - WR, dest_l, dest_h, ALU }; + WR, dest_l, dest_h, ALU); - BUSRQ = new ushort[] { 0, src_h, 0, 0, dest_h, 0, 0 }; - MEMRQ = new ushort[] { 0, src_h, 0, 0, dest_h, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, src_h, 0, 0, dest_h, 0, 0); + PopulateMEMRQ(0, src_h, 0, 0, dest_h, 0, 0); + IRQS = 7; } private void LD_IND_8_INC(ushort dest, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, - RD_INC, dest, src_l, src_h }; + RD_INC, dest, src_l, src_h); - BUSRQ = new ushort[] { 0, src_h, 0, 0 }; - MEMRQ = new ushort[] { 0, src_h, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 1 }; + PopulateBUSRQ(0, src_h, 0, 0); + PopulateMEMRQ(0, src_h, 0, 0); + IRQS = 4; } private void LD_IND_16(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, dest_l, src_l, src_h, IDLE, WAIT, - RD_INC, dest_h, src_l, src_h }; + RD_INC, dest_h, src_l, src_h); - BUSRQ = new ushort[] { 0, src_h, 0, 0, src_h, 0, 0 }; - MEMRQ = new ushort[] { 0, src_h, 0, 0, src_h, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, src_h, 0, 0, src_h, 0, 0); + PopulateMEMRQ(0, src_h, 0, 0, src_h, 0, 0); + IRQS = 7; } private void INC_8_IND(ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, - WAIT, + WAIT, RD, ALU, src_l, src_h, INC8, ALU, IDLE, WAIT, - WR, src_l, src_h, ALU }; + WR, src_l, src_h, ALU); - BUSRQ = new ushort[] { 0, src_h, 0, 0, src_h, src_h, 0, 0 }; - MEMRQ = new ushort[] { 0, src_h, 0, 0, 0, src_h, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, src_h, 0, 0, src_h, src_h, 0, 0); + PopulateMEMRQ(0, src_h, 0, 0, 0, src_h, 0, 0); + IRQS = 8; } private void DEC_8_IND(ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, - WAIT, + WAIT, RD, ALU, src_l, src_h, DEC8, ALU, IDLE, WAIT, - WR, src_l, src_h, ALU }; + WR, src_l, src_h, ALU); - BUSRQ = new ushort[] { 0, src_h, 0, 0, src_h, src_h, 0, 0 }; - MEMRQ = new ushort[] { 0, src_h, 0, 0, 0, src_h, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, src_h, 0, 0, src_h, src_h, 0, 0); + PopulateMEMRQ(0, src_h, 0, 0, 0, src_h, 0, 0); + IRQS = 8; } // NOTE: WZ implied for the wollowing 3 functions private void I_INT_OP(ushort operation, ushort dest) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD, ALU, Z, W, operation, ALU, TR, dest, ALU, WAIT, - WR, Z, W, ALU }; + WR, Z, W, ALU); - BUSRQ = new ushort[] { 0, W, 0, 0, W, W, 0, 0 }; - MEMRQ = new ushort[] { 0, W, 0, 0, 0, W, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, W, 0, 0, W, W, 0, 0); + PopulateMEMRQ(0, W, 0, 0, 0, W, 0, 0); + IRQS = 8; } private void I_BIT_OP(ushort operation, ushort bit, ushort dest) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD, ALU, Z, W, operation, bit, ALU, TR, dest, ALU, WAIT, - WR, Z, W, ALU }; + WR, Z, W, ALU); - BUSRQ = new ushort[] { 0, W, 0, 0, W, W, 0, 0 }; - MEMRQ = new ushort[] { 0, W, 0, 0, 0, W, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1}; + PopulateBUSRQ(0, W, 0, 0, W, W, 0, 0); + PopulateMEMRQ(0, W, 0, 0, 0, W, 0, 0); + IRQS = 8; } private void I_BIT_TE(ushort bit) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD, ALU, Z, W, - I_BIT, bit, ALU }; + I_BIT, bit, ALU); - BUSRQ = new ushort[] { 0, W, 0, 0, W }; - MEMRQ = new ushort[] { 0, W, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, W, 0, 0, W); + PopulateMEMRQ(0, W, 0, 0, 0); + IRQS = 5; } private void I_OP_n(ushort operation, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD, ALU, PCl, PCh, @@ -349,17 +349,17 @@ operation, ALU, IDLE, WAIT, - WR, Z, W, ALU }; + WR, Z, W, ALU); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, W, 0, 0, W, W, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, 0, 0, 0, 0, 0, W, 0, 0, 0, W, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, W, 0, 0, W, W, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0, 0, 0, 0, 0, 0, W, 0, 0, 0, W, 0, 0); + IRQS = 16; } private void I_OP_n_n(ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, TR16, Z, W, src_l, src_h, WAIT, RD_INC, ALU, PCl, PCh, @@ -370,17 +370,17 @@ IDLE, INC16, PCl, PCh, WAIT, - WR, Z, W, ALU }; + WR, Z, W, ALU); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, PCh, PCh, W, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, 0, 0, W, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, 0, 0, PCh, PCh, W, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0, PCh, 0, 0, 0, 0, W, 0, 0); + IRQS = 12; } private void I_REG_OP_IND_n(ushort operation, ushort dest, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD, ALU, PCl, PCh, @@ -391,38 +391,38 @@ IDLE, INC16, PCl, PCh, WAIT, - RD_OP, 0, ALU, Z, W, operation, dest, ALU }; + RD_OP, 0, ALU, Z, W, operation, dest, ALU); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, W, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, 0, 0, 0, 0, 0, W, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, W, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0, 0, 0, 0, 0, 0, W, 0, 0); + IRQS = 12; } private void I_LD_8_IND_n(ushort dest_l, ushort dest_h, ushort src) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD, ALU, PCl, PCh, IDLE, - IDLE, + IDLE, TR16, Z, W, dest_l, dest_h, ADDS, Z, W, ALU, ZERO, IDLE, INC16, PCl, PCh, WAIT, - WR, Z, W, src }; + WR, Z, W, src); - BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, Z, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, 0, 0, 0, 0, 0, Z, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, Z, 0, 0); + PopulateMEMRQ(0, PCh, 0, 0, 0, 0, 0, 0, 0, Z, 0, 0); + IRQS = 12; } private void LD_OP_R(ushort operation, ushort repeat_instr) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD, ALU, L, H, @@ -430,17 +430,17 @@ WAIT, WR, E, D, ALU, IDLE, - SET_FL_LD_R, 0, operation, repeat_instr}; + SET_FL_LD_R, 0, operation, repeat_instr); - BUSRQ = new ushort[] { 0, H, 0, 0, D, 0, 0, D, D }; - MEMRQ = new ushort[] { 0, H, 0, 0, D, 0, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, H, 0, 0, D, 0, 0, D, D); + PopulateMEMRQ(0, H, 0, 0, D, 0, 0, 0, 0); + IRQS = 9; } private void CP_OP_R(ushort operation, ushort repeat_instr) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD, ALU, L, H, @@ -448,17 +448,17 @@ DEC16, C, B, operation, Z, W, IDLE, - SET_FL_CP_R, 1, operation, repeat_instr}; + SET_FL_CP_R, 1, operation, repeat_instr); - BUSRQ = new ushort[] { 0, H, 0, 0, H, H, H, H, H }; - MEMRQ = new ushort[] { 0, H, 0, 0, 0, 0, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, H, 0, 0, H, H, H, H, H); + PopulateMEMRQ(0, H, 0, 0, 0, 0, 0, 0, 0); + IRQS = 9; } private void IN_OP_R(ushort operation, ushort repeat_instr) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, IDLE, WAIT, @@ -466,55 +466,55 @@ IN, ALU, C, B, IDLE, WAIT, - REP_OP_I, L, H, ALU, operation, 2, operation, repeat_instr }; + REP_OP_I, L, H, ALU, operation, 2, operation, repeat_instr); - BUSRQ = new ushort[] { 0, I, BIO1, BIO2, BIO3, BIO4, H, 0, 0}; - MEMRQ = new ushort[] { 0, 0, BIO1, BIO2, BIO3, BIO4, H, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, I, BIO1, BIO2, BIO3, BIO4, H, 0, 0); + PopulateMEMRQ(0, 0, BIO1, BIO2, BIO3, BIO4, H, 0, 0); + IRQS = 9; } private void OUT_OP_R(ushort operation, ushort repeat_instr) { - cur_instr = new ushort[] - {IDLE, - IDLE, + PopulateCURINSTR + (IDLE, + IDLE, IDLE, WAIT, RD, ALU, L, H, IDLE, WAIT, - WAIT, - REP_OP_O, C, B, ALU, operation, 3, operation, repeat_instr }; + WAIT, + REP_OP_O, C, B, ALU, operation, 3, operation, repeat_instr); - BUSRQ = new ushort[] { 0, I, H, 0, 0, BIO1, BIO2, BIO3, BIO4 }; - MEMRQ = new ushort[] { 0, 0, H, 0, 0, BIO1, BIO2, BIO3, BIO4 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, I, H, 0, 0, BIO1, BIO2, BIO3, BIO4); + PopulateMEMRQ(0, 0, H, 0, 0, BIO1, BIO2, BIO3, BIO4); + IRQS = 9; } // this is an indirect change of a a 16 bit register with memory private void EXCH_16_IND_(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, WAIT, RD_INC, Z, dest_l, dest_h, - IDLE, + IDLE, WAIT, RD, W, dest_l, dest_h, IDLE, IDLE, WAIT, WR_DEC, dest_l, dest_h, src_h, - IDLE, + IDLE, WAIT, WR, dest_l, dest_h, src_l, IDLE, - TR16, src_l, src_h, Z, W }; + TR16, src_l, src_h, Z, W); - BUSRQ = new ushort[] { 0, dest_h, 0, 0, dest_h, 0, 0, dest_h, dest_h, 0, 0, dest_h, 0, 0, dest_h, dest_h }; - MEMRQ = new ushort[] { 0, dest_h, 0, 0, dest_h, 0, 0, 0, dest_h, 0, 0, dest_h, 0, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + PopulateBUSRQ(0, dest_h, 0, 0, dest_h, 0, 0, dest_h, dest_h, 0, 0, dest_h, 0, 0, dest_h, dest_h); + PopulateMEMRQ(0, dest_h, 0, 0, dest_h, 0, 0, 0, dest_h, 0, 0, dest_h, 0, 0, 0, 0); + IRQS = 16; } } } diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs index 6c7c9f3e50..6de41ae296 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs @@ -104,14 +104,15 @@ namespace BizHawk.Emulation.Cores.Components.Z80A ResetRegisters(); ResetInterrupts(); TotalExecutedCycles = 0; - cur_instr = new ushort[] - {IDLE, - DEC16, F, A, - DEC16, SPl, SPh }; - BUSRQ = new ushort[] { 0, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 1 }; + PopulateCURINSTR + (IDLE, + DEC16, F, A, + DEC16, SPl, SPh); + + PopulateBUSRQ(0, 0, 0); + PopulateMEMRQ(0, 0, 0); + IRQS = 3; instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; NO_prefix = true; } @@ -459,16 +460,16 @@ namespace BizHawk.Emulation.Cores.Components.Z80A if (((Regs[C] | (Regs[B] << 8)) != 0) && (Ztemp3 > 0)) { - cur_instr = new ushort[] - {DEC16, PCl, PCh, + PopulateCURINSTR + (DEC16, PCl, PCh, DEC16, PCl, PCh, TR16, Z, W, PCl, PCh, INC16, Z, W, - Ztemp2, E, D }; + Ztemp2, E, D); - BUSRQ = new ushort[] { D, D, D, D, D }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 1 }; + PopulateBUSRQ(D, D, D, D, D); + PopulateMEMRQ(0, 0, 0, 0, 0); + IRQS = 5; instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; I_skip = true; @@ -488,16 +489,17 @@ namespace BizHawk.Emulation.Cores.Components.Z80A if (((Regs[C] | (Regs[B] << 8)) != 0) && (Ztemp3 > 0) && !FlagZ) { - cur_instr = new ushort[] - {DEC16, PCl, PCh, + + PopulateCURINSTR + (DEC16, PCl, PCh, DEC16, PCl, PCh, TR16, Z, W, PCl, PCh, - INC16, Z, W, - Ztemp2, L, H }; + INC16, Z, W, + Ztemp2, L, H); - BUSRQ = new ushort[] { H, H, H, H, H }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 1 }; + PopulateBUSRQ(H, H, H, H, H); + PopulateMEMRQ(0, 0, 0, 0, 0); + IRQS = 5; instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; I_skip = true; @@ -562,16 +564,16 @@ namespace BizHawk.Emulation.Cores.Components.Z80A if ((Regs[B] != 0) && (Ztemp3 > 0)) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, DEC16, PCl, PCh, DEC16, PCl, PCh, - Ztemp2, L, H }; + Ztemp2, L, H); - BUSRQ = new ushort[] { H, H, H, H, H }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 1 }; + PopulateBUSRQ(H, H, H, H, H); + PopulateMEMRQ(0, 0, 0, 0, 0); + IRQS = 5; instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; I_skip = true; @@ -613,16 +615,16 @@ namespace BizHawk.Emulation.Cores.Components.Z80A if ((Regs[B] != 0) && (Ztemp3 > 0)) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, IDLE, DEC16, PCl, PCh, DEC16, PCl, PCh, - IDLE }; + IDLE); - BUSRQ = new ushort[] { B, B, B, B, B }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 0, 1 }; + PopulateBUSRQ(B, B, B, B, B); + PopulateMEMRQ(0, 0, 0, 0, 0); + IRQS = 5; instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; I_skip = true; @@ -638,7 +640,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { I_skip = false; } - else if (IRQS[irq_pntr++] == 1) + else if (++irq_pntr == IRQS) { if (EI_pending > 0) { @@ -707,15 +709,15 @@ namespace BizHawk.Emulation.Cores.Components.Z80A // otherwise start a new normal access else if (!halted) { - cur_instr = new ushort[] - {IDLE, + PopulateCURINSTR + (IDLE, WAIT, OP_F, - OP}; + OP); - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; - IRQS = new ushort[] { 0, 0, 0, 1 }; + PopulateBUSRQ(PCh, 0, 0, 0); + PopulateMEMRQ(PCh, 0, 0, 0); + IRQS = 4; instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; } @@ -781,6 +783,59 @@ namespace BizHawk.Emulation.Cores.Components.Z80A }; } + /// + /// Optimization method to set BUSRQ + /// + private void PopulateBUSRQ(ushort d0 = 0, ushort d1 = 0, ushort d2 = 0, ushort d3 = 0, ushort d4 = 0, ushort d5 = 0, ushort d6 = 0, ushort d7 = 0, ushort d8 = 0, + ushort d9 = 0, ushort d10 = 0, ushort d11 = 0, ushort d12 = 0, ushort d13 = 0, ushort d14 = 0, ushort d15 = 0, ushort d16 = 0, ushort d17 = 0, ushort d18 = 0) + { + BUSRQ[0] = d0; BUSRQ[1] = d1; BUSRQ[2] = d2; + BUSRQ[3] = d3; BUSRQ[4] = d4; BUSRQ[5] = d5; + BUSRQ[6] = d6; BUSRQ[7] = d7; BUSRQ[8] = d8; + BUSRQ[9] = d9; BUSRQ[10] = d10; BUSRQ[11] = d11; + BUSRQ[12] = d12; BUSRQ[13] = d13; BUSRQ[14] = d14; + BUSRQ[15] = d15; BUSRQ[16] = d16; BUSRQ[17] = d17; + BUSRQ[18] = d18; + } + + /// + /// Optimization method to set MEMRQ + /// + private void PopulateMEMRQ(ushort d0 = 0, ushort d1 = 0, ushort d2 = 0, ushort d3 = 0, ushort d4 = 0, ushort d5 = 0, ushort d6 = 0, ushort d7 = 0, ushort d8 = 0, + ushort d9 = 0, ushort d10 = 0, ushort d11 = 0, ushort d12 = 0, ushort d13 = 0, ushort d14 = 0, ushort d15 = 0, ushort d16 = 0, ushort d17 = 0, ushort d18 = 0) + { + MEMRQ[0] = d0; MEMRQ[1] = d1; MEMRQ[2] = d2; + MEMRQ[3] = d3; MEMRQ[4] = d4; MEMRQ[5] = d5; + MEMRQ[6] = d6; MEMRQ[7] = d7; MEMRQ[8] = d8; + MEMRQ[9] = d9; MEMRQ[10] = d10; MEMRQ[11] = d11; + MEMRQ[12] = d12; MEMRQ[13] = d13; MEMRQ[14] = d14; + MEMRQ[15] = d15; MEMRQ[16] = d16; MEMRQ[17] = d17; + MEMRQ[18] = d18; + } + + /// + /// Optimization method to set cur_instr + /// + private void PopulateCURINSTR(ushort d0 = 0, ushort d1 = 0, ushort d2 = 0, ushort d3 = 0, ushort d4 = 0, ushort d5 = 0, ushort d6 = 0, ushort d7 = 0, ushort d8 = 0, + ushort d9 = 0, ushort d10 = 0, ushort d11 = 0, ushort d12 = 0, ushort d13 = 0, ushort d14 = 0, ushort d15 = 0, ushort d16 = 0, ushort d17 = 0, ushort d18 = 0, + ushort d19 = 0, ushort d20 = 0, ushort d21 = 0, ushort d22 = 0, ushort d23 = 0, ushort d24 = 0, ushort d25 = 0, ushort d26 = 0, ushort d27 = 0, ushort d28 = 0, + ushort d29 = 0, ushort d30 = 0, ushort d31 = 0, ushort d32 = 0, ushort d33 = 0, ushort d34 = 0, ushort d35 = 0, ushort d36 = 0, ushort d37 = 0) + { + cur_instr[0] = d0; cur_instr[1] = d1; cur_instr[2] = d2; + cur_instr[3] = d3; cur_instr[4] = d4; cur_instr[5] = d5; + cur_instr[6] = d6; cur_instr[7] = d7; cur_instr[8] = d8; + cur_instr[9] = d9; cur_instr[10] = d10; cur_instr[11] = d11; + cur_instr[12] = d12; cur_instr[13] = d13; cur_instr[14] = d14; + cur_instr[15] = d15; cur_instr[16] = d16; cur_instr[17] = d17; + cur_instr[18] = d18; cur_instr[19] = d19; cur_instr[20] = d20; + cur_instr[21] = d21; cur_instr[22] = d22; cur_instr[23] = d23; + cur_instr[24] = d24; cur_instr[25] = d25; cur_instr[26] = d26; + cur_instr[27] = d27; cur_instr[28] = d28; cur_instr[29] = d29; + cur_instr[30] = d30; cur_instr[31] = d31; cur_instr[32] = d32; + cur_instr[33] = d33; cur_instr[34] = d34; cur_instr[35] = d35; + cur_instr[36] = d36; cur_instr[37] = d37; + } + // State Save/Load public void SyncState(Serializer ser) { @@ -802,7 +857,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A ser.Sync("irq_pntr", ref irq_pntr); ser.Sync("cur_instr", ref cur_instr, false); ser.Sync("BUSRQ", ref BUSRQ, false); - ser.Sync("IRQS", ref IRQS, false); + ser.Sync("IRQS", ref IRQS); ser.Sync("MEMRQ", ref MEMRQ, false); ser.Sync("opcode", ref opcode); ser.Sync("FlagI", ref FlagI); diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllers.cs b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllers.cs index 3241e128ca..85f62dc6bc 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllers.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllers.cs @@ -158,7 +158,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk private static readonly string[] BaseDefinition = { - "Up", "Down", "Left", "Right", "Trigger" + "Up", "Down", "Left", "Right", "Button" }; private static byte[] HandControllerButtons = diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs index e6de37117d..7c679ab952 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs @@ -1,5 +1,4 @@ using System; -using BizHawk.Emulation.Common; using BizHawk.Common.NumberExtensions; using BizHawk.Common; @@ -138,8 +137,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk LYC = value; if (LCDC.Bit(7)) { - if (LY != LYC) { STAT &= 0xFB; } - else { STAT |= 0x4; } + if (LY != LYC) { STAT &= 0xFB; LYC_INT = false; } + else { STAT |= 0x4; LYC_INT = true; } + + // special case: at cycle 454, some strange things are happening, and it appears as though LY becomes LY + 1 + // two cycles ahead of where it's supposed to. this is probably related to strange behaviour around cycle 452 + if ((LY_inc == 0) && cycle == 6) + { + //if (0 == LYC) { STAT |= 0x4; LYC_INT = true; } + //else { STAT &= 0xFB; LYC_INT = false; } + } } break; case 0xFF46: // DMA @@ -362,7 +369,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk LY_inc = 1; Core.in_vblank = false; - STAT &= 0xFC; + //STAT &= 0xFC; // special note here, the y coordiate of the window is kept if the window is deactivated // meaning it will pick up where it left off if re-enabled later @@ -396,14 +403,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk STAT &= 0xFC; // also the LCD doesn't turn on right away - // also, the LCD does not enter mode 2 on scanline 0 when first turned on no_scan = true; cycle = 8; } // the VBL stat is continuously asserted - if ((LY >= 144)) + if (LY >= 144) { if (STAT.Bit(4)) { @@ -440,7 +446,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (STAT.Bit(5)) { VBL_INT = false; } } - if ((cycle == 6) && (LY == 153)) + if ((cycle == 8) && (LY == 153)) { LY = 0; LY_inc = 0; @@ -506,6 +512,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (LY != 0) { HBL_INT = false; + if (STAT.Bit(5)) { OAM_INT = true; } } } @@ -513,7 +520,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { // apparently, writes can make it to OAM one cycle longer then reads OAM_access_write = false; - + // here mode 2 will be set to true and interrupts fired if enabled STAT &= 0xFC; STAT |= 0x2; @@ -539,6 +546,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk OAM_INT = false; OAM_access_write = false; VRAM_access_write = false; + + // x-scroll is expected to be latched one cycle later + // this is fine since nothing has started in the rendering until the second cycle + // calculate the column number of the tile to start with + x_tile = (int)Math.Floor((float)(scroll_x) / 8); + render_offset = scroll_x % 8; } // render the screen and handle hblank @@ -646,10 +659,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // window X is latched for the scanline, mid-line changes have no effect window_x_latch = window_x; - // calculate the column number of the tile to start with - x_tile = (int)Math.Floor((float)(scroll_x) / 8); - render_offset = scroll_x % 8; - OAM_scan_index = 0; read_case = 0; internal_cycle = 0; @@ -661,6 +670,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk fetch_sprite = false; going_to_fetch = false; first_fetch = true; + consecutive_sprite = -render_offset + 8; no_sprites = false; evaled_sprites = 0; window_pre_render = false; @@ -682,7 +692,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (SL_sprites_index == 0) { no_sprites = true; } // it is much easier to process sprites if we order them according to the rules of sprite priority first if (!no_sprites) { reorder_and_assemble_sprites(); } - } // before anything else, we have to check if windowing is in effect @@ -846,7 +855,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (pixel_counter == 160) { read_case = 8; - hbl_countdown = 1; } } else if (pixel_counter < 0) @@ -1093,23 +1101,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 8: // done reading, we are now in phase 0 pre_render = true; - // the other interrupts appear to be delayed by 1 CPU cycle, so do the same here - if (hbl_countdown > 0) - { - hbl_countdown--; - STAT &= 0xFC; - STAT |= 0x00; + STAT &= 0xFC; + STAT |= 0x00; - if (hbl_countdown == 0) - { - if (STAT.Bit(3)) { HBL_INT = true; } + if (STAT.Bit(3)) { HBL_INT = true; } - OAM_access_read = true; - OAM_access_write = true; - VRAM_access_read = true; - VRAM_access_write = true; - } - } + OAM_access_read = true; + OAM_access_write = true; + VRAM_access_read = true; + VRAM_access_write = true; break; case 9: @@ -1155,21 +1155,29 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } } + // x scroll offsets the penalty table // there is no penalty if the next sprites to be fetched are within the currentfetch block (8 pixels) if (first_fetch || (last_eval >= consecutive_sprite)) { - if ((last_eval % 8) == 0) { sprite_fetch_counter += 5; } - else if ((last_eval % 8) == 1) { sprite_fetch_counter += 4; } - else if ((last_eval % 8) == 2) { sprite_fetch_counter += 3; } - else if ((last_eval % 8) == 3) { sprite_fetch_counter += 2; } - else if ((last_eval % 8) == 4) { sprite_fetch_counter += 1; } - else if ((last_eval % 8) == 5) { sprite_fetch_counter += 0; } - else if ((last_eval % 8) == 6) { sprite_fetch_counter += 0; } - else if ((last_eval % 8) == 7) { sprite_fetch_counter += 0; } + if (((last_eval + render_offset) % 8) == 0) { sprite_fetch_counter += 5; } + else if (((last_eval + render_offset) % 8) == 1) { sprite_fetch_counter += 4; } + else if (((last_eval + render_offset) % 8) == 2) { sprite_fetch_counter += 3; } + else if (((last_eval + render_offset) % 8) == 3) { sprite_fetch_counter += 2; } + else if (((last_eval + render_offset) % 8) == 4) { sprite_fetch_counter += 1; } + else if (((last_eval + render_offset) % 8) == 5) { sprite_fetch_counter += 0; } + else if (((last_eval + render_offset) % 8) == 6) { sprite_fetch_counter += 0; } + else if (((last_eval + render_offset) % 8) == 7) { sprite_fetch_counter += 0; } + + consecutive_sprite = (int)Math.Floor((double)(last_eval + render_offset) / 8) * 8 + 8 - render_offset; + + // special case exists here for sprites at zero with non-zero x-scroll. Not sure exactly the reason for it. + if (last_eval == 0 && render_offset != 0) + { + sprite_fetch_counter += render_offset; + } } total_counter += sprite_fetch_counter; - consecutive_sprite = last_eval + (8 - (last_eval % 8)); first_fetch = false; } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs index 7b6a0ce9cc..a436d4045b 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs @@ -1,7 +1,5 @@ using System; -using BizHawk.Emulation.Common; using BizHawk.Common.NumberExtensions; -using BizHawk.Common; namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { @@ -75,13 +73,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk //if (!STAT.Bit(6)) { LYC_INT = false; } if (!STAT.Bit(4)) { VBL_INT = false; } - break; + break; case 0xFF42: // SCY scroll_y = value; - break; + break; case 0xFF43: // SCX scroll_x = value; - break; + break; case 0xFF44: // LY LY = 0; /*reset*/ break; @@ -197,7 +195,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } // the VBL stat is continuously asserted - if ((LY >= 144)) + if (LY >= 144) { if (STAT.Bit(4)) { @@ -333,6 +331,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk OAM_INT = false; OAM_access_write = false; VRAM_access_write = false; + + // x-scroll is expected to be latched one cycle later + // this is fine since nothing has started in the rendering until the second cycle + // calculate the column number of the tile to start with + x_tile = (int)Math.Floor((float)(scroll_x) / 8); + render_offset = scroll_x % 8; } // render the screen and handle hblank @@ -422,7 +426,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // might be needed, not sure yet public override void latch_delay() { - //BGP_l = BGP; + } public override void render(int render_cycle) @@ -440,10 +444,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // window X is latched for the scanline, mid-line changes have no effect window_x_latch = window_x; - // calculate the column number of the tile to start with - x_tile = (int)Math.Floor((float)(scroll_x) / 8); - render_offset = scroll_x % 8; - OAM_scan_index = 0; read_case = 0; internal_cycle = 0; @@ -455,6 +455,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk fetch_sprite = false; going_to_fetch = false; first_fetch = true; + consecutive_sprite = -render_offset + 8; no_sprites = false; evaled_sprites = 0; window_pre_render = false; @@ -478,7 +479,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (SL_sprites_index == 0) { no_sprites = true; } // it is much easier to process sprites if we order them according to the rules of sprite priority first if (!no_sprites) { reorder_and_assemble_sprites(); } - } // before anything else, we have to check if windowing is in effect @@ -591,7 +591,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (pixel_counter == 160) { read_case = 8; - hbl_countdown = 1; } } else if (pixel_counter < 0) @@ -817,23 +816,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 8: // done reading, we are now in phase 0 pre_render = true; - // the other interrupts appear to be delayed by 1 CPU cycle, so do the same here - if (hbl_countdown > 0) - { - hbl_countdown--; - STAT &= 0xFC; - STAT |= 0x00; + STAT &= 0xFC; + STAT |= 0x00; - if (hbl_countdown == 0) - { - if (STAT.Bit(3)) { HBL_INT = true; } + if (STAT.Bit(3)) { HBL_INT = true; } - OAM_access_read = true; - OAM_access_write = true; - VRAM_access_read = true; - VRAM_access_write = true; - } - } + OAM_access_read = true; + OAM_access_write = true; + VRAM_access_read = true; + VRAM_access_write = true; break; case 9: @@ -852,8 +843,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk tile_data_latch[0] = tile_data[0]; tile_data_latch[1] = tile_data[1]; } - - if (consecutive_sprite > 0) { consecutive_sprite -= 1; } } // every in range sprite takes 6 cycles to process @@ -892,10 +881,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk else if (((last_eval + render_offset) % 8) == 5) { sprite_fetch_counter += 0; } else if (((last_eval + render_offset) % 8) == 6) { sprite_fetch_counter += 0; } else if (((last_eval + render_offset) % 8) == 7) { sprite_fetch_counter += 0; } + + consecutive_sprite = (int)Math.Floor((double)(last_eval + render_offset) / 8) * 8 + 8 - render_offset; + + // special case exists here for sprites at zero with non-zero x-scroll. Not sure exactly the reason for it. + if (last_eval == 0 && render_offset != 0) + { + sprite_fetch_counter += render_offset; + } } total_counter += sprite_fetch_counter; - consecutive_sprite = last_eval + (8 - (last_eval % 8)); first_fetch = false; } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs index bbb583efda..249c8e3ddf 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs @@ -112,7 +112,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk break; case 0xFF4F: // VBK - if (is_GBC) + if (GBC_compat) { ret = VRAM_Bank; } @@ -137,7 +137,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 0xFF69: case 0xFF6A: case 0xFF6B: - if (is_GBC) + if (GBC_compat) { ret = ppu.ReadReg(addr); } @@ -331,7 +331,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // VBK case 0xFF4F: - if (is_GBC && !ppu.HDMA_active) + if (GBC_compat && !ppu.HDMA_active) { VRAM_Bank = (byte)(value & 1); } @@ -356,7 +356,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 0xFF69: case 0xFF6A: case 0xFF6B: - if (is_GBC) + if (GBC_compat) { ppu.WriteReg(addr, value); } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs index 37ffb9078e..520db111e1 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs @@ -1,6 +1,4 @@ using System; -using BizHawk.Emulation.Common; -using BizHawk.Common.NumberExtensions; using BizHawk.Common; namespace BizHawk.Emulation.Cores.Nintendo.GBHawk @@ -12,7 +10,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk public uint[] BG_palette = new uint[32]; public uint[] OBJ_palette = new uint[32]; - public bool HDMA_active; // register variables @@ -44,7 +41,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk public bool LCD_was_off; public bool stat_line; public bool stat_line_old; - public int hbl_countdown; // OAM scan public bool DMA_OAM_access; public bool OAM_access_read; @@ -151,7 +147,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } - public virtual void Reset() { @@ -166,7 +161,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk public virtual void SyncState(Serializer ser) { - ser.Sync("BG_palette", ref BG_palette, false); ser.Sync("OBJ_palette", ref OBJ_palette, false); ser.Sync("HDMA_active", ref HDMA_active); @@ -197,7 +191,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk ser.Sync("OAM_INT", ref OAM_INT); ser.Sync("stat_line", ref stat_line); ser.Sync("stat_line_old", ref stat_line_old); - ser.Sync("hbl_countdown", ref hbl_countdown); ser.Sync("LCD_was_off", ref LCD_was_off); ser.Sync("OAM_scan_index", ref OAM_scan_index); ser.Sync("SL_sprites_index", ref SL_sprites_index); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs index feb338ad42..5d5a01ed83 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs @@ -1,3 +1,5 @@ +// NOTE: to match Mesen timings, set idleSynch to true at power on, and set start_up_offset to -3 + using System; using System.Linq; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.cs index 320113d52f..36df0ab4c3 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.cs @@ -1,5 +1,4 @@ using System; -using System.Runtime.CompilerServices; using BizHawk.Common; namespace BizHawk.Emulation.Cores.Nintendo.NES @@ -131,7 +130,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES return sum >= 2000; } - //when the ppu issues a write it goes through here and into the game board public void ppubus_write(int addr, byte value) { @@ -236,6 +234,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES ser.Sync("spriteHeight", ref spriteHeight); ser.Sync("install_2006", ref install_2006); ser.Sync("race_2006", ref race_2006); + ser.Sync("race_2006_2", ref race_2006_2); ser.Sync("install_2001", ref install_2001); ser.Sync("show_bg_new", ref show_bg_new); ser.Sync("show_obj_new", ref show_obj_new); @@ -270,6 +269,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES ser.Sync("do_pre_vbl", ref do_pre_vbl); ser.Sync("nmi_destiny", ref nmi_destiny); + ser.Sync("evenOddDestiny", ref evenOddDestiny); + ser.Sync("NMI_offset", ref NMI_offset); ser.Sync("yp_shift", ref yp_shift); ser.Sync("sprite_eval_cycle", ref sprite_eval_cycle); ser.Sync("xt", ref xt); @@ -278,7 +279,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES ser.Sync("rasterpos", ref rasterpos); ser.Sync("renderspritenow", ref renderspritenow); ser.Sync("renderbgnow", ref renderbgnow); - ser.Sync("hit_pending", ref hit_pending); ser.Sync("s", ref s); ser.Sync("ppu_aux_index", ref ppu_aux_index); ser.Sync("junksprite", ref junksprite); @@ -332,13 +332,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES { //run one ppu cycle at a time so we can interact with the ppu and clockPPU at high granularity - race_2006 = false; + if (install_2006>0) { install_2006--; if (install_2006==0) { - ppur.install_latches(); + if (!race_2006) { ppur.install_latches(); } + else { race_2006_2 = true; } //nes.LogLine("addr wrote vt = {0}, ht = {1}", ppur._vt, ppur._ht); //normally the address isnt observed by the board till it gets clocked by a read or write. @@ -347,11 +348,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES //ONLY if the ppu is not rendering if (ppur.status.sl >= 241 || !PPUON) nes.Board.AddressPPU(ppur.get_2007access()); - - race_2006 = true; } } + race_2006 = false; + if (install_2001 > 0) { install_2001--; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.regs.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.regs.cs index a0aed3f502..0fa0bc98cd 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.regs.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.regs.cs @@ -9,7 +9,6 @@ using System; using BizHawk.Common; - namespace BizHawk.Emulation.Cores.Nintendo.NES { sealed partial class PPU @@ -307,6 +306,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES public Reg_2000 reg_2000; public Reg_2001 reg_2001; byte reg_2003; + public byte reg_2006_2; void regs_reset() { @@ -450,12 +450,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES { OAM[reg_2003] = value; reg_2003++; - } - + } } + byte read_2004() { byte ret; + // Console.WriteLine("read 2004"); // behaviour depends on whether things are being rendered or not if (PPUON) { @@ -526,6 +527,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES ppur._v = (value >> 3) & 1; ppur._fv = (value >> 4) & 3; //nes.LogLine("addr wrote fv = {0}", ppur._fv); + reg_2006_2 = value; } else { @@ -534,13 +536,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES ppur._ht = value & 31; // testing indicates that this operation is delayed by 3 pixels - // ppur.install_latches(); - + //ppur.install_latches(); install_2006 = 3; } vtoggle ^= true; - } byte read_2006() { return ppu_open_bus; } byte peek_2006() { return ppu_open_bus; } @@ -835,4 +835,4 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES //Palette Gaps and Mirrors // 3F04h,3F08h,3F0Ch - Three general purpose 6bit data registers. // 3F10h,3F14h,3F18h,3F1Ch - Mirrors of 3F00h,3F04h,3F08h,3F0Ch. -// 3F20h-3FFFh - Mirrors of 3F00h-3F1Fh. \ No newline at end of file +// 3F20h-3FFFh - Mirrors of 3F00h-3F1Fh. diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.run.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.run.cs index 63e65192ff..3b2199bf06 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.run.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.run.cs @@ -1,8 +1,8 @@ //TODO - correctly emulate PPU OFF state +using System; using BizHawk.Common; using BizHawk.Common.NumberExtensions; -using System; namespace BizHawk.Emulation.Cores.Nintendo.NES { @@ -40,7 +40,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES // installing vram address is delayed after second write to 2006, set this up here public int install_2006; - public bool race_2006; + public bool race_2006, race_2006_2; public int install_2001; public bool show_bg_new; //Show background public bool show_obj_new; //Show sprites @@ -62,20 +62,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES // attempt to emulate graphics pipeline behaviour // experimental int pixelcolor_latch_1; - int pixelcolor_latch_2; + void pipeline(int pixelcolor, int row_check) { - if (row_check > 1) + if (row_check > 0) { if (reg_2001.color_disable) - pixelcolor_latch_2 &= 0x30; + pixelcolor_latch_1 &= 0x30; //TODO - check flashing sirens in werewolf //tack on the deemph bits. THESE MAY BE ORDERED WRONG. PLEASE CHECK IN THE PALETTE CODE - xbuf[(target - 2)] = (short)(pixelcolor_latch_2 | reg_2001.intensity_lsl_6); + xbuf[(target - 1)] = (short)(pixelcolor_latch_1 | reg_2001.intensity_lsl_6); } - - pixelcolor_latch_2 = pixelcolor_latch_1; + pixelcolor_latch_1 = pixelcolor; } @@ -125,6 +124,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES public bool do_pre_vbl; bool nmi_destiny; + bool evenOddDestiny; + static int start_up_offset = 2; + int NMI_offset; int yp_shift; int sprite_eval_cycle; int xt; @@ -133,7 +135,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES int rasterpos; bool renderspritenow; bool renderbgnow; - bool hit_pending; int s; int ppu_aux_index; bool junksprite; @@ -148,24 +149,41 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES ppur.status.cycle = 0; // These things happen at the start of every frame - - Reg2002_vblank_active_pending = true; + //Reg2002_vblank_active = true; + //Reg2002_vblank_active_pending = true; ppuphase = PPUPHASE.VBL; bgdata = new BGDataRecord[34]; } public void TickPPU_VBL() { - if (ppur.status.cycle == 3 && ppur.status.sl == 241 + preNMIlines) + if (ppur.status.cycle == 0 && ppur.status.sl == 241 + preNMIlines) { nmi_destiny = reg_2000.vblank_nmi_gen && Reg2002_vblank_active; + if (cpu_stepcounter == 2) { NMI_offset = 1; } + else if (cpu_stepcounter == 1) { NMI_offset = 2; } + else { NMI_offset = 0; } } - else if (ppur.status.cycle == 6 && ppur.status.sl == 241 + preNMIlines) + else if (ppur.status.cycle <= 2 && nmi_destiny) + { + nmi_destiny &= reg_2000.vblank_nmi_gen && Reg2002_vblank_active; + } + else if (ppur.status.cycle == (3 + NMI_offset) && ppur.status.sl == 241 + preNMIlines) { if (nmi_destiny) { nes.cpu.NMI = true; } nes.Board.AtVsyncNMI(); } + if (ppur.status.cycle == 340) + { + if (ppur.status.sl == 241 + preNMIlines + postNMIlines - 1) + { + Reg2002_vblank_clear_pending = true; + idleSynch ^= true; + Reg2002_objhit = Reg2002_objoverflow = 0; + } + } + runppu(); // note cycle ticks inside runppu if (ppur.status.cycle == 341) @@ -174,10 +192,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES ppur.status.sl++; if (ppur.status.sl == 241 + preNMIlines + postNMIlines) { - Reg2002_objhit = Reg2002_objoverflow = 0; - Reg2002_vblank_clear_pending = true; - idleSynch ^= true; - do_vbl = false; ppur.status.sl = 0; } @@ -232,8 +246,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES //check all the conditions that can cause things to render in these 8px renderspritenow = show_obj_new && (xt > 0 || reg_2001.show_obj_leftmost); - hit_pending = false; - } if (ppur.status.cycle < 256) @@ -332,8 +344,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES { if (yp >= read_value && yp < read_value + spriteHeight && PPUON) { - hit_pending = true; - //Reg2002_objoverflow = true; + Reg2002_objoverflow = true; } if (yp >= read_value && yp < read_value + spriteHeight && spr_true_count == 0) @@ -379,30 +390,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES // due to the cpu not running while the sprite renders below if (PPUON) { Read_bgdata(xp, ref bgdata[xt + 2]); } - runppu(); - - if (PPUON && xp == 6) - { - ppu_was_on = true; - } - - if (PPUON && xp == 7) - { - if (!race_2006) - ppur.increment_hsc(); - - if (ppur.status.cycle == 256 && !race_2006) - ppur.increment_vs(); - - ppu_was_on = false; - } - - if (hit_pending) - { - hit_pending = false; - Reg2002_objoverflow = true; - } - renderbgnow = show_bg_new && (xt > 0 || reg_2001.show_bg_leftmost); //bg pos is different from raster pos due to its offsetability. //so adjust for that here @@ -467,14 +454,53 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES } } //oamcount loop + runppu(); + + if (PPUON && xp == 6) + { + ppu_was_on = true; + if (ppur.status.cycle == 255) { race_2006 = true; } + } + + if (PPUON && xp == 7) + { + ppur.increment_hsc(); + + if (ppur.status.cycle == 256) + { + ppur.increment_vs(); + } + + if (race_2006_2) + { + if (ppur.status.cycle == 256) + { + ppur.fv &= ppur._fv; + ppur.v &= ppur._v; + ppur.h &= ppur._h; + ppur.vt &= ppur._vt; + ppur.ht &= ppur._ht; + } + else + { + ppur.fv = ppur._fv; + ppur.v = ppur._v; + ppur.h &= ppur._h; + ppur.vt = ppur._vt; + ppur.ht &= ppur._ht; + } + } + + ppu_was_on = false; + } + + race_2006_2 = false; pipeline(pixelcolor, xt * 8 + xp); target++; // clear out previous sprites from scanline buffer - //sl_sprites[xt * 8 + xp] = 0; sl_sprites[256 + xt * 8 + xp] = 0; - //sl_sprites[512 + xt * 8 + xp] = 0; // end of visible part of the scanline sprite_eval_cycle++; @@ -494,9 +520,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES //check all the conditions that can cause things to render in these 8px renderspritenow = show_obj_new && (xt > 0 || reg_2001.show_obj_leftmost); - hit_pending = false; - - } + } } else { @@ -508,19 +532,44 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES if (PPUON && xp == 6) { ppu_was_on = true; + if (ppur.status.cycle == 255) { race_2006 = true; } + } if (PPUON && xp == 7) { - if (!race_2006) - ppur.increment_hsc(); + ppur.increment_hsc(); - if (ppur.status.cycle == 256 && !race_2006) + if (ppur.status.cycle == 256) + { ppur.increment_vs(); + } + + if(race_2006_2) + { + if (ppur.status.cycle == 256) + { + ppur.fv &= ppur._fv; + ppur.v &= ppur._v; + ppur.h &= ppur._h; + ppur.vt &= ppur._vt; + ppur.ht &= ppur._ht; + } + else + { + ppur.fv = ppur._fv; + ppur.v = ppur._v; + ppur.h &= ppur._h; + ppur.vt = ppur._vt; + ppur.ht &= ppur._ht; + } + } ppu_was_on = false; } + race_2006_2 = false; + xp++; if (xp == 8) @@ -625,35 +674,40 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES if (target <= 61441 && target > 0 && s == 0) { - pipeline(0, 256); + pipeline(0, 256); // last pipeline call option 1 of 2 target++; } //at 257: 3d world runner is ugly if we do this at 256 - if (PPUON) ppur.install_h_latches(); + if (PPUON/* && !race_2006_2*/) { ppur.install_h_latches(); } + race_2006_2 = false; read_value = t_oam[s].oam_ind; runppu(); + /* if (target <= 61441 && target > 0 && s == 0) { - pipeline(0, 257); // last pipeline call option 1 of 2 + //pipeline(0, 257); } + */ } else { if (target <= 61441 && target > 0 && s == 0) { - pipeline(0, 256); + pipeline(0, 256); // last pipeline call option 2 of 2 target++; } read_value = t_oam[s].oam_ind; runppu(); + /* if (target <= 61441 && target > 0 && s == 0) { - pipeline(0, 257); // last pipeline call option 2 of 2 + //pipeline(0, 257); } + */ } break; @@ -910,12 +964,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES } else if (ppur.status.cycle < 340) { + if (ppur.status.cycle == 339) + { + evenOddDestiny = PPUON; + } + runppu(); } else { - bool evenOddDestiny = PPUON; - // After memory access 170, the PPU simply rests for 4 cycles (or the // equivelant of half a memory access cycle) before repeating the whole // pixel/scanline rendering process. If the scanline being rendered is the very @@ -941,6 +998,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES public void TickPPU_preVBL() { + if (ppur.status.cycle == 340) + { + Reg2002_vblank_active_pending = true; + } + runppu(); if (ppur.status.cycle == 341) @@ -961,9 +1023,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES //to wait for vblank public void NewDeadPPU() { + if (ppur.status.cycle == 241 * 341 - start_up_offset - 1) + { + Reg2002_vblank_active_pending = true; + } + runppu(); - if (ppur.status.cycle == 241 * 341 - 3) + if (ppur.status.cycle == 241 * 341 - start_up_offset) { ppudead--; } diff --git a/libmupen64plus/GLideN64 b/libmupen64plus/GLideN64 index d6915e13c4..57ba873c5e 160000 --- a/libmupen64plus/GLideN64 +++ b/libmupen64plus/GLideN64 @@ -1 +1 @@ -Subproject commit d6915e13c4904e38d221bd49f5efe9b16845a367 +Subproject commit 57ba873c5e117a42f94299cb7ddaa1066249b416 diff --git a/output/dll/mupen64plus-video-GLideN64.dll b/output/dll/mupen64plus-video-GLideN64.dll index a2cb0a6269..054dc854c1 100644 Binary files a/output/dll/mupen64plus-video-GLideN64.dll and b/output/dll/mupen64plus-video-GLideN64.dll differ