From cf450bcdb74d6dc9243b49c593012415ef38ab08 Mon Sep 17 00:00:00 2001 From: Souryo Date: Sun, 14 Feb 2016 13:57:47 -0500 Subject: [PATCH] PPU: Scrolling increments use a "IsRendering" flag delayed by 1 ppu cycle. This fixes Battletoads freezes, but may be incorrect. --- Core/PPU.cpp | 10 +++++++++- Core/PPU.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Core/PPU.cpp b/Core/PPU.cpp index 839729f9..c508ad6a 100644 --- a/Core/PPU.cpp +++ b/Core/PPU.cpp @@ -35,6 +35,7 @@ PPU::~PPU() void PPU::Reset() { _sprite0HitCycle = -1; + _prevRenderingEnabled = false; _renderingEnabled = false; _ignoreVramRead = 0; @@ -605,7 +606,12 @@ void PPU::DrawPixel() void PPU::ProcessPreVBlankScanline() { //For pre-render scanline & all visible scanlines - if(IsRenderingEnabled()) { + if(_prevRenderingEnabled) { + //Use _prevRenderingEnabled to drive vert/horiz scrolling increments. + //This delays the flag by an extra cycle. So if rendering is disabled at cycle 254, + //the vertical scrolling increment will not be performed. + //This appears to fix freezes in Battletoads (Level 2), but may be incorrect. + //Update video ram address according to scrolling logic if((_cycle > 0 && _cycle < 256 && (_cycle & 0x07) == 0) || _cycle == 328 || _cycle == 336) { IncHorizontalScrolling(); @@ -848,6 +854,7 @@ void PPU::Exec() } //Rendering enabled flag is apparently set with a 1 cycle delay (i.e setting it at cycle 5 will render cycle 6 like cycle 5 and then take the new settings for cycle 7) + _prevRenderingEnabled = _renderingEnabled; _renderingEnabled = _flags.BackgroundEnabled || _flags.SpritesEnabled; } @@ -947,6 +954,7 @@ void PPU::StreamState(bool saving) Stream(_spriteDmaAddr); Stream(_spriteDmaCounter); + Stream(_prevRenderingEnabled); Stream(_renderingEnabled); Stream(_openBus); StreamArray(_openBusDecayStamp, 8); diff --git a/Core/PPU.h b/Core/PPU.h index 7943ad29..c9405014 100644 --- a/Core/PPU.h +++ b/Core/PPU.h @@ -148,6 +148,7 @@ class PPU : public IMemoryHandler, public Snapshotable bool _oamCopyDone; bool _renderingEnabled; + bool _prevRenderingEnabled; void UpdateStatusFlag();