From 756f370021768a0c11211b00ec6e443356c3d7f7 Mon Sep 17 00:00:00 2001 From: Brandon Wright Date: Sat, 2 Jun 2018 18:44:13 -0500 Subject: [PATCH] Go back to allowing writes to 4200 and vtimerpos to trigger immediately. --- cpuexec.cpp | 6 +++--- ppu.cpp | 50 +++++++++++++++++++++++++++----------------------- ppu.h | 2 +- snapshot.cpp | 2 +- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/cpuexec.cpp b/cpuexec.cpp index 33e2b917..fe7f53f9 100644 --- a/cpuexec.cpp +++ b/cpuexec.cpp @@ -245,11 +245,11 @@ void S9xMainLoop (void) if ((CPU.Cycles >= Timings.NextIRQTimer)) { - S9xUpdateIRQPositions(); + S9xUpdateIRQPositions(false); - #ifdef DEBUGGER + #ifdef DEBUGGER S9xTraceMessage ("Timer triggered\n"); - #endif + #endif if (CPU.WaitingForInterrupt) { diff --git a/ppu.cpp b/ppu.cpp index 15bbaf5f..0775ef9b 100644 --- a/ppu.cpp +++ b/ppu.cpp @@ -285,7 +285,7 @@ static int CyclesUntilNext (int hc, int vc) } else { - if (vc == vpos && (hc > CPU.Cycles || !PPU.HTimerEnabled)) + if (vc == vpos && (hc > CPU.Cycles)) { return hc; } @@ -304,7 +304,7 @@ static int CyclesUntilNext (int hc, int vc) return total; } -void S9xUpdateIRQPositions () +void S9xUpdateIRQPositions (bool initial) { PPU.HTimerPosition = PPU.IRQHBeamPos * ONE_DOT_CYCLE + Timings.IRQTriggerCycles; PPU.HTimerPosition -= PPU.IRQHBeamPos ? 0 : ONE_DOT_CYCLE; @@ -336,7 +336,10 @@ void S9xUpdateIRQPositions () } else if (!PPU.HTimerEnabled && PPU.VTimerEnabled) { - Timings.NextIRQTimer = CyclesUntilNext (Timings.IRQTriggerCycles, PPU.VTimerPosition); + if (CPU.V_Counter == PPU.VTimerPosition && initial) + Timings.NextIRQTimer = CPU.Cycles + Timings.IRQTriggerCycles; + else + Timings.NextIRQTimer = CyclesUntilNext (Timings.IRQTriggerCycles, PPU.VTimerPosition); } else { @@ -1545,15 +1548,17 @@ void S9xSetCPU (uint8 Byte, uint16 Address) case 0x4200: // NMITIMEN #ifdef DEBUGGER if (Settings.TraceHCEvent) - S9xTraceFormattedMessage("Write to 0x4200. Byte is %2x was %2x\n", Byte, Memory.FillRAM[Address]); + S9xTraceFormattedMessage("Write to 0x4200. Byte is %2x was %2x\n", Byte, Memory.FillRAM[Address]); #endif + if (Byte & 0x20) { PPU.VTimerEnabled = TRUE; - #ifdef DEBUGGER + + #ifdef DEBUGGER missing.virq = 1; missing.virq_pos = PPU.IRQVBeamPos; - #endif + #endif } else PPU.VTimerEnabled = FALSE; @@ -1561,10 +1566,11 @@ void S9xSetCPU (uint8 Byte, uint16 Address) if (Byte & 0x10) { PPU.HTimerEnabled = TRUE; - #ifdef DEBUGGER + + #ifdef DEBUGGER missing.hirq = 1; missing.hirq_pos = PPU.IRQHBeamPos; - #endif + #endif } else PPU.HTimerEnabled = FALSE; @@ -1575,29 +1581,27 @@ void S9xSetCPU (uint8 Byte, uint16 Address) CPU.IRQTransition = FALSE; } - S9xUpdateIRQPositions(); + S9xUpdateIRQPositions(true); // NMI can trigger immediately during VBlank as long as NMI_read ($4210) wasn't cleard. if ((Byte & 0x80) && !(Memory.FillRAM[0x4200] & 0x80) && (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE) && (Memory.FillRAM[0x4210] & 0x80)) { - // FIXME: triggered at HC+=6, checked just before the final CPU cycle, // then, when to call S9xOpcode_NMI()? CPU.NMIPending = TRUE; Timings.NMITriggerPos = CPU.Cycles + 6 + 6; -#ifdef DEBUGGER -if (Settings.TraceHCEvent) - S9xTraceFormattedMessage("NMI Triggered on low-to-high occurring at next HC=%d\n", Timings.NMITriggerPos); -#endif - + #ifdef DEBUGGER + if (Settings.TraceHCEvent) + S9xTraceFormattedMessage("NMI Triggered on low-to-high occurring at next HC=%d\n", Timings.NMITriggerPos); + #endif } - #ifdef DEBUGGER - S9xTraceFormattedMessage("--- IRQ Timer Enable HTimer:%d Pos:%04d VTimer:%d Pos:%03d", - PPU.HTimerEnabled, PPU.HTimerPosition, PPU.VTimerEnabled, PPU.VTimerPosition); - #endif + #ifdef DEBUGGER + S9xTraceFormattedMessage("--- IRQ Timer Enable HTimer:%d Pos:%04d VTimer:%d Pos:%03d", + PPU.HTimerEnabled, PPU.HTimerPosition, PPU.VTimerEnabled, PPU.VTimerPosition); + #endif break; @@ -1642,7 +1646,7 @@ if (Settings.TraceHCEvent) pos = PPU.IRQHBeamPos; PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xff00) | Byte; if (PPU.IRQHBeamPos != pos) - S9xUpdateIRQPositions(); + S9xUpdateIRQPositions(false); #ifdef DEBUGGER missing.hirq_pos = PPU.IRQHBeamPos; #endif @@ -1652,7 +1656,7 @@ if (Settings.TraceHCEvent) pos = PPU.IRQHBeamPos; PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xff) | ((Byte & 1) << 8); if (PPU.IRQHBeamPos != pos) - S9xUpdateIRQPositions(); + S9xUpdateIRQPositions(false); #ifdef DEBUGGER missing.hirq_pos = PPU.IRQHBeamPos; #endif @@ -1662,7 +1666,7 @@ if (Settings.TraceHCEvent) pos = PPU.IRQVBeamPos; PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xff00) | Byte; if (PPU.IRQVBeamPos != pos) - S9xUpdateIRQPositions(); + S9xUpdateIRQPositions(true); #ifdef DEBUGGER missing.virq_pos = PPU.IRQVBeamPos; #endif @@ -1672,7 +1676,7 @@ if (Settings.TraceHCEvent) pos = PPU.IRQVBeamPos; PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xff) | ((Byte & 1) << 8); if (PPU.IRQVBeamPos != pos) - S9xUpdateIRQPositions(); + S9xUpdateIRQPositions(true); #ifdef DEBUGGER missing.virq_pos = PPU.IRQVBeamPos; #endif diff --git a/ppu.h b/ppu.h index 51cf2536..4b0adc53 100644 --- a/ppu.h +++ b/ppu.h @@ -389,7 +389,7 @@ void S9xSetPPU (uint8, uint16); uint8 S9xGetPPU (uint16); void S9xSetCPU (uint8, uint16); uint8 S9xGetCPU (uint16); -void S9xUpdateIRQPositions (); +void S9xUpdateIRQPositions (bool initial); void S9xFixColourBrightness (void); void S9xDoAutoJoypad (void); diff --git a/snapshot.cpp b/snapshot.cpp index d7b9bc78..fe66e69c 100644 --- a/snapshot.cpp +++ b/snapshot.cpp @@ -1780,7 +1780,7 @@ int S9xUnfreezeFromStream (STREAM stream) ICPU.ShiftedDB = Registers.DB << 16; S9xSetPCBase(Registers.PBPC); S9xUnpackStatus(); - S9xUpdateIRQPositions(); + S9xUpdateIRQPositions(false); S9xFixCycles(); for (int d = 0; d < 8; d++)