diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/APU.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/APU.cs index c43fd0817c..eb049b0c8b 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/APU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/APU.cs @@ -746,6 +746,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES // when called due to empty bueffer while DMC running, there is no delay nes.cpu.RDY = false; nes.dmc_dma_exec = true; + nes.DMC_just_started = true; if (fill_glitch_2) { @@ -945,7 +946,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES sample_address = user_address; sample_length = user_length; } - else if (irq_enabled) apu.dmc_irq = true; + else if (irq_enabled) { apu.dmc_irq_countdown = 3; } } // Console.WriteLine("fetching dmc byte: {0:X2}", sample_buffer); } @@ -955,6 +956,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES { ser.Sync(nameof(irq_pending), ref irq_pending); ser.Sync(nameof(dmc_irq), ref dmc_irq); + ser.Sync(nameof(dmc_irq_countdown), ref dmc_irq_countdown); ser.Sync(nameof(pending_reg), ref pending_reg); ser.Sync(nameof(pending_val), ref pending_val); @@ -995,6 +997,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES public readonly DMCUnit dmc; private bool irq_pending; + public int dmc_irq_countdown; private bool dmc_irq; private int pending_reg = -1; private bool doing_tick_quarter = false; @@ -1350,6 +1353,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES } } + if (dmc_irq_countdown > 0) + { + dmc_irq_countdown--; + if (dmc_irq_countdown == 0) + { + dmc_irq = true; + } + } + SyncIRQ(); nes._irq_apu = irq_pending; 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 ca97d8fcdb..79be2fb0c4 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs @@ -453,6 +453,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES public int do_the_reread_2002, do_the_reread_2007, do_the_reread_cont_1, do_the_reread_cont_2; public int reread_opp_4016, reread_opp_4017; public byte DB; //old data bus values from previous reads + public bool DMC_just_started; internal void RunCpuOne() { @@ -510,6 +511,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES apu.dmc_dma_countdown += 2; apu.DMC_RDY_check = -1; } + + if (!dmc_dma_exec) { DMC_just_started = true; } cpu.RDY = false; dmc_dma_exec = true; @@ -589,10 +592,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES { cpu.IRQ = _irq_apu || Board.IrqSignal; } - else if (special_case_delay || apu.dmc_dma_countdown == 3) + else if (special_case_delay || DMC_just_started) { cpu.IRQ = _irq_apu || Board.IrqSignal; special_case_delay = false; + DMC_just_started = false; } cpu.ExecuteOne(); @@ -618,8 +622,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES reread_opp_4016 = 0; reread_opp_4017 = 0; reread_trigger = false; - } - + } IRQ_delay = false; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.IStatable.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.IStatable.cs index 7b28199731..b141ccd7f6 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.IStatable.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.IStatable.cs @@ -38,6 +38,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES ser.Sync(nameof(do_the_reread_cont_2), ref do_the_reread_cont_2); ser.Sync(nameof(reread_opp_4016), ref reread_opp_4016); ser.Sync(nameof(reread_opp_4017), ref reread_opp_4017); + ser.Sync(nameof(DMC_just_started), ref DMC_just_started); // VS related ser.Sync("VS", ref _isVS);