From c7403e7fe77729084b0038f69e04e18280b4718b Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Mon, 3 Jan 2022 16:49:36 -0500 Subject: [PATCH] NESHawk: fix some DMC edge cases --- .../Consoles/Nintendo/NES/APU.cs | 12 ++++++++---- .../Consoles/Nintendo/NES/NES.Core.cs | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/APU.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/APU.cs index ac3fe068fb..65b41873a1 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/APU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/APU.cs @@ -857,20 +857,24 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES public void set_lenctr_en(bool en) { - // should this be delayed by two/three cycles? - if(!en) { // in these cases, the disable happens right as the reload begins, it is cancelled similar to a write triggered reload // cancelling an automatic reload, and has the same timing (still uses fill_glitch_2) - if (((timer == 4) || (timer == 3)) && (out_bits_remaining == 0) && (sample_length != 0)) + if (((timer == 3) || (timer == 2)) && (out_bits_remaining == 0) && (sample_length != 0)) { + //Console.WriteLine("glitch 3 " + timer); + sample_length = 0; fill_glitch_2 = true; + apu.dmc_irq = false; + apu.SyncIRQ(); + return; } // in these cases the disable happens too late and the reload (andpotential IRQ) still happen - if ((timer <= 2) && (out_bits_remaining == 0) && (sample_length != 0)) + if ((timer == 1) && (out_bits_remaining == 0) && (sample_length != 0)) { + //Console.WriteLine("glitch 4 " + timer); pending_disable = true; apu.dmc_irq = false; apu.SyncIRQ(); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs index 03354c87f3..4eebd00573 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs @@ -567,7 +567,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES } } - if ((apu.dmc.timer == 4) && (apu.dmc.out_bits_remaining == 0) && (apu.dmc.sample_length == 0)) + if ((apu.dmc.timer == 4) && (apu.dmc.out_bits_remaining == 0) && (apu.dmc.sample_length == 1)) { //Console.WriteLine("close 2 " + cpu.TotalExecutedCycles + " " + apu.dmc.timer + " " + apu.dmc.sample_length + " " + cpu.opcode + " " + cpu.mi); apu.dmc.fill_glitch_2 = true;