From 34f1c644f599a2a0319d0edeeef5dd929ec7fa2c Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sun, 1 Mar 2020 17:07:17 +1000 Subject: [PATCH] GPU: Update GPUSTAT if raster has passed to the next line Fixes games which poll GPUSTAT, including The Next Tetris (Europe). --- src/core/gpu.cpp | 12 ++++++++++++ src/core/gpu.h | 3 +++ 2 files changed, 15 insertions(+) diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index 55aa9c8a2..db807a997 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -235,7 +235,14 @@ u32 GPU::ReadRegister(u32 offset) return ReadGPUREAD(); case 0x04: + { + // code can be dependent on the odd/even bit, so update the GPU state when reading. + // we can mitigate this slightly by only updating when the raster is actually hitting a new line + if (IsRasterScanlinePending()) + m_tick_event->InvokeEarly(true); + return m_GPUSTAT.bits; + } default: Log_ErrorPrintf("Unhandled register read: %02X", offset); @@ -455,6 +462,11 @@ void GPU::UpdateSliceTicks() m_tick_event->SetPeriod(GPUTicksToSystemTicks(ticks_until_hblank)); } +bool GPU::IsRasterScanlinePending() const +{ + return (GetPendingGPUTicks() + m_crtc_state.current_tick_in_scanline) >= m_crtc_state.horizontal_total; +} + void GPU::Execute(TickCount ticks) { // convert cpu/master clock to GPU ticks, accounting for partial cycles because of the non-integer divider diff --git a/src/core/gpu.h b/src/core/gpu.h index d2522c2bf..70bf8e1c7 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -310,6 +310,9 @@ protected: /// Returns the number of pending GPU ticks. TickCount GetPendingGPUTicks() const; + /// Returns true if enough ticks have passed for the raster to be on the next line. + bool IsRasterScanlinePending() const; + /// Returns true if scanout should be interlaced. bool IsDisplayInterlaced() const { return !m_force_progressive_scan && m_GPUSTAT.In480iMode(); }