From 2ef2f8f11928213796e7f73c8b3f7b20ce7da770 Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Wed, 29 Apr 2020 09:38:27 -0400 Subject: [PATCH] NESHawk: various loop optimizations, 5-10 fps improvement --- .../CPUs/MOS 6502X/Execute.cs | 48 +++++++------- .../Consoles/Nintendo/NES/NES.Core.cs | 62 +++++++++---------- .../Consoles/Nintendo/NES/PPU.cs | 1 + .../Consoles/Nintendo/NES/PPU.regs.cs | 10 +-- .../Consoles/Nintendo/NES/PPU.run.cs | 39 +++++------- 5 files changed, 76 insertions(+), 84 deletions(-) diff --git a/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs b/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs index 0b545341be..7e76474994 100644 --- a/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs @@ -706,7 +706,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); Y++; NZ_Y(); + _link.DummyReadMemory(PC); Y++; NZ_Y(); } } void Imp_DEY() @@ -714,7 +714,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); Y--; NZ_Y(); + _link.DummyReadMemory(PC); ; Y--; NZ_Y(); } } void Imp_INX() @@ -722,7 +722,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); X++; NZ_X(); + _link.DummyReadMemory(PC); X++; NZ_X(); } } void Imp_DEX() @@ -730,7 +730,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); X--; NZ_X(); + _link.DummyReadMemory(PC); X--; NZ_X(); } } void NZ_A() @@ -751,7 +751,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); X = S; NZ_X(); + _link.DummyReadMemory(PC); X = S; NZ_X(); } } void Imp_TXS() @@ -759,7 +759,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); S = X; + _link.DummyReadMemory(PC); S = X; } } void Imp_TAX() @@ -767,7 +767,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); X = A; NZ_X(); + _link.DummyReadMemory(PC); X = A; NZ_X(); } } void Imp_TAY() @@ -775,7 +775,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); Y = A; NZ_Y(); + _link.DummyReadMemory(PC); Y = A; NZ_Y(); } } void Imp_TYA() @@ -783,7 +783,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); A = Y; NZ_A(); + _link.DummyReadMemory(PC); A = Y; NZ_A(); } } void Imp_TXA() @@ -791,7 +791,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); A = X; NZ_A(); + _link.DummyReadMemory(PC); A = X; NZ_A(); } } @@ -803,7 +803,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); + _link.DummyReadMemory(PC); } } void Imp_CLI() @@ -814,7 +814,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); + _link.DummyReadMemory(PC); } } void Imp_SEC() @@ -822,7 +822,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); FlagC = true; + _link.DummyReadMemory(PC); FlagC = true; } } void Imp_CLC() @@ -830,7 +830,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); FlagC = false; + _link.DummyReadMemory(PC); FlagC = false; } } void Imp_SED() @@ -838,7 +838,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); FlagD = true; + _link.DummyReadMemory(PC); FlagD = true; } } void Imp_CLD() @@ -846,7 +846,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); FlagD = false; + _link.DummyReadMemory(PC); FlagD = false; } } void Imp_CLV() @@ -854,7 +854,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); FlagV = false; + _link.DummyReadMemory(PC); FlagV = false; } } @@ -1159,7 +1159,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); + _link.DummyReadMemory(PC); alu_temp = (byte)PC + (int)(sbyte)opcode2; PC &= 0xFF00; PC |= (ushort)((alu_temp & 0xFF)); @@ -1183,7 +1183,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); + _link.DummyReadMemory(PC); if (alu_temp.Bit(31)) PC = (ushort)(PC - 0x100); else PC = (ushort)(PC + 0x100); @@ -1194,7 +1194,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); + _link.DummyReadMemory(PC); } } void DecS() @@ -2064,7 +2064,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); + _link.DummyReadMemory(PC); FlagC = (A & 0x80) != 0; A = (byte)(A << 1); NZ_A(); @@ -2075,7 +2075,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); + _link.DummyReadMemory(PC); temp8 = A; A = (byte)((A << 1) | (P & 1)); FlagC = (temp8 & 0x80) != 0; @@ -2087,7 +2087,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); + _link.DummyReadMemory(PC); temp8 = A; A = (byte)((A >> 1) | ((P & 1) << 7)); FlagC = (temp8 & 1) != 0; @@ -2099,7 +2099,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502 rdy_freeze = !RDY; if (RDY) { - FetchDummy(); + _link.DummyReadMemory(PC); FlagC = (A & 1) != 0; A = (byte)(A >> 1); NZ_A(); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs index 6f333506d7..996d8563f3 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs @@ -450,26 +450,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES // OAM DMA start /////////////////////////// - if (sprdma_countdown > 0) - { - sprdma_countdown--; - if (sprdma_countdown == 0) - { - if (cpu.TotalExecutedCycles % 2 == 0) - { - cpu_deadcounter = 2; - } - else - { - cpu_deadcounter = 1; - } - oam_dma_exec = true; - cpu.RDY = false; - oam_dma_index = 0; - special_case_delay = true; - } - } - if (oam_dma_exec && apu.dmc_dma_countdown != 1 && !dmc_realign) { if (cpu_deadcounter == 0) @@ -493,14 +473,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES cpu_deadcounter--; } } - else if (apu.dmc_dma_countdown == 1) - { - dmc_realign = true; - } - else if (dmc_realign) - { - dmc_realign = false; - } + + dmc_realign = false; + ///////////////////////////// // OAM DMA end ///////////////////////////// @@ -512,6 +487,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES if (apu.dmc_dma_countdown > 0) { + if (apu.dmc_dma_countdown == 1) + { + dmc_realign = true; + } + cpu.RDY = false; dmc_dma_exec = true; apu.dmc_dma_countdown--; @@ -553,14 +533,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES apu.RunOneLast(); - if (ppu.double_2007_read > 0) - ppu.double_2007_read--; - if (do_the_reread && cpu.RDY) do_the_reread = false; - if (IRQ_delay) - IRQ_delay = false; + IRQ_delay = false; if (!dmc_dma_exec && !oam_dma_exec && !cpu.RDY) { @@ -720,6 +696,26 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES //this receives 2 because that's just the way it works out. oam_dma_addr = (ushort)(val << 8); sprdma_countdown = 1; + + if (sprdma_countdown > 0) + { + sprdma_countdown--; + if (sprdma_countdown == 0) + { + if (cpu.TotalExecutedCycles % 2 == 0) + { + cpu_deadcounter = 2; + } + else + { + cpu_deadcounter = 1; + } + oam_dma_exec = true; + cpu.RDY = false; + oam_dma_index = 0; + special_case_delay = true; + } + } break; case 0x4015: apu.WriteReg(addr, val); break; case 0x4016: diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.cs index 60393f2b24..1727746385 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.cs @@ -353,6 +353,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES idleSynch = false; ppu_open_bus = 0; ppu_open_bus_decay_timer = new int[8]; + double_2007_read = 0; } void runppu() diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.regs.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.regs.cs index 460226ca9c..d16193b2f0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.regs.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.regs.cs @@ -51,7 +51,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES // this byte is used to simulate open bus reads and writes // it should be modified by every read and write to a ppu register public byte ppu_open_bus=0; - public int double_2007_read; // emulates a hardware bug of back to back 2007 reads + public long double_2007_read; // emulates a hardware bug of back to back 2007 reads public int[] ppu_open_bus_decay_timer = new int[8]; public byte[] glitchy_reads_2003 = new byte[8]; @@ -660,14 +660,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES case 6: return read_2006(); case 7: { - if (double_2007_read>0) + if (nes.cpu.TotalExecutedCycles == double_2007_read) { - double_2007_read = 0; return ppu_open_bus; - } else + } + else { ret_spec = read_2007(); - double_2007_read = 2; + double_2007_read = nes.cpu.TotalExecutedCycles + 1; } if (nes.do_the_reread) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.run.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.run.cs index 5b8f6e3f52..62236c9a0d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.run.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/PPU.run.cs @@ -97,18 +97,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES case 1: break; case 2: - { - ppu_addr_temp = ppur.get_atread(); - byte at = ppubus_read(ppu_addr_temp, true, true); + ppu_addr_temp = ppur.get_atread(); + byte at = ppubus_read(ppu_addr_temp, true, true); - //modify at to get appropriate palette shift - if ((ppur.vt & 2) != 0) at >>= 4; - if ((ppur.ht & 2) != 0) at >>= 2; - at &= 0x03; - at <<= 2; - bgdata[i].at = at; - break; - } + //modify at to get appropriate palette shift + if ((ppur.vt & 2) != 0) at >>= 4; + if ((ppur.ht & 2) != 0) at >>= 2; + at &= 0x03; + at <<= 2; + bgdata[i].at = at; + break; case 3: break; case 4: @@ -123,7 +121,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES break; case 7: break; - } //switch(cycle) + } } // these are states for the ppu incrementer @@ -979,18 +977,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES { ppur.status.cycle++; } // increment cycle without running ppu else { runppu(); } - } - } - if (ppur.status.cycle == 341) - { - ppur.status.cycle = 0; - ppur.status.sl++; + ppur.status.cycle = 0; + ppur.status.sl++; - if (ppur.status.sl == 241) - { - do_active_sl = false; - do_pre_vbl = true; + if (ppur.status.sl == 241) + { + do_active_sl = false; + do_pre_vbl = true; + } } } }