NESHawk: Tweaks to APU timing
This commit is contained in:
parent
726f1f3f11
commit
335c8104b6
|
@ -652,17 +652,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
}
|
||||
} // class TriangleUnit
|
||||
|
||||
private sealed class DMCUnit
|
||||
public sealed class DMCUnit
|
||||
{
|
||||
private readonly APU apu;
|
||||
private readonly NES nes;
|
||||
private readonly int[] DMC_RATE;
|
||||
public DMCUnit(APU apu, bool pal)
|
||||
{
|
||||
this.apu = apu;
|
||||
this.nes = apu.nes;
|
||||
out_silence = true;
|
||||
DMC_RATE = pal ? DMC_RATE_PAL : DMC_RATE_NTSC;
|
||||
timer_reload = DMC_RATE[0];
|
||||
timer = 1021; // confirmed in VisualNES although aligning controller read glitches still doesn't work
|
||||
timer = 1020; // confirmed in VisualNES although aligning controller read glitches still doesn't work
|
||||
sample_buffer_filled = false;
|
||||
out_deltacounter = 64;
|
||||
out_bits_remaining = 7; //confirmed in VisualNES
|
||||
|
@ -732,7 +734,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
if (!apu.call_from_write)
|
||||
{
|
||||
// when called due to empty bueffer while DMC running, there is no delay
|
||||
delay = 1;
|
||||
delay = 0;
|
||||
nes.cpu.RDY = false;
|
||||
nes.dmc_dma_exec = true;
|
||||
apu.dmc_dma_countdown = 3; // 3 here but this actually stops 4 cpu cycles because it starts before the cpu is run
|
||||
apu.DMC_RDY_check = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -763,7 +769,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
apu.dmc_dma_countdown = 3;
|
||||
apu.DMC_RDY_check = 2;
|
||||
apu.call_from_write = false;
|
||||
|
@ -945,7 +950,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
public PulseUnit[] pulse = new PulseUnit[2];
|
||||
public TriangleUnit triangle;
|
||||
public NoiseUnit noise;
|
||||
private readonly DMCUnit dmc;
|
||||
public readonly DMCUnit dmc;
|
||||
|
||||
private bool irq_pending;
|
||||
private bool dmc_irq;
|
||||
|
|
|
@ -282,6 +282,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
|
||||
private bool resetSignal;
|
||||
private bool hardResetSignal;
|
||||
|
||||
public bool FrameAdvance(IController controller, bool render, bool rendersound)
|
||||
{
|
||||
_controller = controller;
|
||||
|
@ -454,7 +455,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
{
|
||||
if (cpu_deadcounter == 0)
|
||||
{
|
||||
|
||||
if (oam_dma_index % 2 == 0)
|
||||
{
|
||||
oam_dma_byte = ReadMemory(oam_dma_addr);
|
||||
|
@ -465,8 +465,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
WriteMemory(0x2004, oam_dma_byte);
|
||||
}
|
||||
oam_dma_index++;
|
||||
if (oam_dma_index == 512) oam_dma_exec = false;
|
||||
|
||||
if (oam_dma_index == 512)
|
||||
{
|
||||
oam_dma_exec = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -495,7 +497,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
// By this point the cpu should be frozen, if it is not, then we are in a multi-write opcode, add another cycle delay
|
||||
if (!cpu.RDY && !cpu.rdy_freeze && (apu.dmc_dma_countdown == apu.DMC_RDY_check))
|
||||
{
|
||||
//Console.WriteLine("dmc RDY false " + cpu.TotalExecutedCycles + " " + apu.call_from_write + " " + cpu.opcode + " " + oam_dma_exec);
|
||||
//Console.WriteLine("dmc double " + cpu.TotalExecutedCycles + " " + cpu.opcode + " " + cpu.mi);
|
||||
apu.dmc_dma_countdown += 2;
|
||||
apu.DMC_RDY_check = -1;
|
||||
}
|
||||
|
@ -509,9 +511,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
dmc_dma_exec = false;
|
||||
apu.dmc_dma_countdown = -1;
|
||||
do_the_reread = true;
|
||||
}
|
||||
|
||||
//Console.WriteLine("dmc RDY false " + cpu.TotalExecutedCycles + " " + apu.call_from_write + " " + cpu.opcode);
|
||||
|
||||
//Console.WriteLine("dmc RDY false " + cpu.TotalExecutedCycles + " " + (apu.dmc.timer & 1));
|
||||
}
|
||||
//Console.WriteLine("dmc RDY false " + cpu.TotalExecutedCycles + " " + cpu.opcode + " " + cpu.mi + " " + apu.dmc_dma_countdown);
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
|
@ -598,14 +601,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
{
|
||||
// special hardware glitch case
|
||||
ret_spec = read_joyport(addr);
|
||||
|
||||
if (do_the_reread && ppu.region==PPU.Region.NTSC)
|
||||
{
|
||||
ret_spec = read_joyport(addr);
|
||||
do_the_reread = false;
|
||||
Console.WriteLine("DMC glitch player 1");
|
||||
do_the_reread = false;
|
||||
Console.WriteLine("DMC glitch player 1 ");
|
||||
}
|
||||
return ret_spec;
|
||||
|
||||
return ret_spec;
|
||||
}
|
||||
case 0x4017:
|
||||
if (_isVS)
|
||||
|
@ -617,7 +621,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
ret = (byte)(ret | (VS_dips[2] << 2) | (VS_dips[3] << 3) | (VS_dips[4] << 4) | (VS_dips[5] << 5) | (VS_dips[6] << 6) | (VS_dips[7] << 7));
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -714,7 +717,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
sprdma_countdown--;
|
||||
if (sprdma_countdown == 0)
|
||||
{
|
||||
if (cpu.TotalExecutedCycles % 2 == 0)
|
||||
if (apu.dmc.timer % 2 == 0)
|
||||
{
|
||||
cpu_deadcounter = 2;
|
||||
}
|
||||
|
|
|
@ -288,8 +288,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
|
||||
private Bit Reg2002_objoverflow; //Sprite overflow. The PPU can handle only eight sprites on one scanline and sets this bit if it starts drawing sprites.
|
||||
private Bit Reg2002_objhit; //Sprite 0 overlap. Set when a nonzero pixel of sprite 0 is drawn overlapping a nonzero background pixel. Used for raster timing.
|
||||
private Bit Reg2002_vblank_active; //Vertical blank start (0: has not started; 1: has started)
|
||||
private bool Reg2002_vblank_active_pending; //set if Reg2002_vblank_active is pending
|
||||
public Bit Reg2002_vblank_active; //Vertical blank start (0: has not started; 1: has started)
|
||||
public bool Reg2002_vblank_active_pending; //set if Reg2002_vblank_active is pending
|
||||
private bool Reg2002_vblank_clear_pending; //ppu's clear of vblank flag is pending
|
||||
public PPUREGS ppur;
|
||||
public Reg_2000 reg_2000;
|
||||
|
|
|
@ -133,7 +133,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
|
||||
private bool nmi_destiny;
|
||||
private bool evenOddDestiny;
|
||||
private int start_up_offset;
|
||||
public int start_up_offset;
|
||||
private int NMI_offset;
|
||||
private int yp_shift;
|
||||
private int sprite_eval_cycle;
|
||||
|
@ -532,7 +532,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
{
|
||||
if (ppu_was_on_spr && !PPUON)
|
||||
{
|
||||
Console.WriteLine("oam addr glitch " + ppur.status.sl + " " + ppur.status.cycle);
|
||||
//Console.WriteLine("oam addr glitch " + ppur.status.sl + " " + ppur.status.cycle);
|
||||
reg_2003++;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue