diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index 98ed5ffa3..e11d73190 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -583,7 +583,6 @@ bool TIA::poke(uInt16 address, uInt8 value) updateDumpPorts(value); myDelayQueue.push(VBLANK, value, Delay::vblank); - break; case AUDV0: @@ -1936,7 +1935,7 @@ void TIA::delayedWrite(uInt8 address, uInt8 value) { case VBLANK: flushLineCache(); - myFrameManager->setVblank(value & 0x02); + myFrameManager->setVblank(value & 0x02, mySystem->cycles()); break; case HMOVE: diff --git a/src/emucore/tia/frame-manager/AbstractFrameManager.cxx b/src/emucore/tia/frame-manager/AbstractFrameManager.cxx index 0f5d51ec6..cbb1d5cef 100644 --- a/src/emucore/tia/frame-manager/AbstractFrameManager.cxx +++ b/src/emucore/tia/frame-manager/AbstractFrameManager.cxx @@ -62,13 +62,13 @@ void AbstractFrameManager::clearHandlers() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void AbstractFrameManager::setVblank(bool vblank) +void AbstractFrameManager::setVblank(bool vblank, uInt64 cycles) { if (vblank == myVblank) return; myVblank = vblank; - onSetVblank(); + onSetVblank(cycles); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/tia/frame-manager/AbstractFrameManager.hxx b/src/emucore/tia/frame-manager/AbstractFrameManager.hxx index 87a636146..4b892293c 100644 --- a/src/emucore/tia/frame-manager/AbstractFrameManager.hxx +++ b/src/emucore/tia/frame-manager/AbstractFrameManager.hxx @@ -63,7 +63,7 @@ class AbstractFrameManager : public Serializable /** * Called by TIA on VBLANK writes. */ - void setVblank(bool vblank); + void setVblank(bool vblank, uInt64 cycles); /** * Called by TIA on VSYNC writes. @@ -218,7 +218,7 @@ class AbstractFrameManager : public Serializable /** * Called if vblank changes. */ - virtual void onSetVblank() {} + virtual void onSetVblank(uInt64 cycles) {} /** * Called if vsync changes. diff --git a/src/emucore/tia/frame-manager/FrameManager.cxx b/src/emucore/tia/frame-manager/FrameManager.cxx index 63667c073..8a304df1d 100644 --- a/src/emucore/tia/frame-manager/FrameManager.cxx +++ b/src/emucore/tia/frame-manager/FrameManager.cxx @@ -34,7 +34,7 @@ void FrameManager::onReset() myState = State::waitForVsyncStart; myLineInState = 0; myTotalFrames = 0; - myVsyncLines = 0; + myVsyncLineCount = 0; myY = 0; myJitterEmulation.reset(); @@ -50,14 +50,19 @@ void FrameManager::onNextLine() { case State::waitForVsyncStart: if ((myCurrentFrameTotalLines > myFrameLines - 3) || myTotalFrames == 0) - ++myVsyncLines; + { + if (myVblank) + ++myVsyncLineCount; + } - if (myVsyncLines > Metrics::maxLinesVsync) setState(State::waitForFrameStart); + if (myVsyncLineCount > Metrics::maxLinesVsync) setState(State::waitForFrameStart); break; case State::waitForVsyncEnd: - if (++myVsyncLines > Metrics::maxLinesVsync) + if (myVblank) + ++myVsyncLineCount; + if (myVsyncLineCount > Metrics::maxLinesVsync) setState(State::waitForFrameStart); break; @@ -112,16 +117,38 @@ void FrameManager::setAdjustVSize(Int32 adjustVSize) recalculateMetrics(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FrameManager::onSetVblank(uInt64 cycles) +{ + if (myState == State::waitForVsyncEnd) + if (myVblank) // VBLANK switched on + { + myVblankStart = cycles; + cerr << ", VBLANK ON " << cycles; + } + else // VBLANK switched off + { + myVblankCycles += cycles - myVblankStart; + cerr << ", VBLANK OFF " << cycles; + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameManager::onSetVsync(uInt64 cycles) { if (myState == State::waitForVsyncEnd) { myVsyncEnd = cycles; + if(myVblankStart != INT64_MAX) + myVblankCycles += cycles - myVblankStart; setState(State::waitForFrameStart); + cerr << ", VSYNC waitForVsyncEnd " << cycles << " \n"; } else { myVsyncStart = cycles; + myVblankStart = myVblank ? cycles : INT64_MAX; + myVblankCycles = 0; setState(State::waitForVsyncEnd); + cerr << ", VSYNC waitForFrameStart " << cycles; } } @@ -139,15 +166,15 @@ void FrameManager::setState(FrameManager::State state) if (myTotalFrames > Metrics::initialGarbageFrames) myJitterEmulation.frameComplete(myCurrentFrameFinalLines, - static_cast(myVsyncEnd - myVsyncStart)); + static_cast(myVsyncEnd - myVsyncStart), static_cast(myVblankCycles)); notifyFrameStart(); - myVsyncLines = 0; + myVsyncLineCount = 0; break; case State::frame: - myVsyncLines = 0; + myVsyncLineCount = 0; myY = 0; break; @@ -176,7 +203,7 @@ bool FrameManager::onSave(Serializer& out) const out.putInt(static_cast(myState)); out.putInt(myLineInState); - out.putInt(myVsyncLines); + out.putInt(myVsyncLineCount); out.putInt(myY); out.putInt(myLastY); @@ -200,7 +227,7 @@ bool FrameManager::onLoad(Serializer& in) myState = static_cast(in.getInt()); myLineInState = in.getInt(); - myVsyncLines = in.getInt(); + myVsyncLineCount = in.getInt(); myY = in.getInt(); myLastY = in.getInt(); diff --git a/src/emucore/tia/frame-manager/FrameManager.hxx b/src/emucore/tia/frame-manager/FrameManager.hxx index 900bc3bae..6d71dc7fd 100644 --- a/src/emucore/tia/frame-manager/FrameManager.hxx +++ b/src/emucore/tia/frame-manager/FrameManager.hxx @@ -83,6 +83,8 @@ class FrameManager: public AbstractFrameManager { void setLayout(FrameLayout mode) override { layout(mode); } + void onSetVblank(uInt64 cycles) override; + void onSetVsync(uInt64 cycles) override; void onNextLine() override; @@ -116,7 +118,7 @@ class FrameManager: public AbstractFrameManager { State myState{State::waitForVsyncStart}; uInt32 myLineInState{0}; - uInt32 myVsyncLines{0}; + uInt32 myVsyncLineCount{0}; uInt32 myY{0}, myLastY{0}; uInt32 myVblankLines{0}; @@ -129,6 +131,8 @@ class FrameManager: public AbstractFrameManager { uInt64 myVsyncStart{0}; uInt64 myVsyncEnd{0}; + uInt64 myVblankStart{0}; + uInt64 myVblankCycles{0}; bool myJitterEnabled{false}; JitterEmulation myJitterEmulation; diff --git a/src/emucore/tia/frame-manager/JitterEmulation.cxx b/src/emucore/tia/frame-manager/JitterEmulation.cxx index 658557607..fc3758ec4 100644 --- a/src/emucore/tia/frame-manager/JitterEmulation.cxx +++ b/src/emucore/tia/frame-manager/JitterEmulation.cxx @@ -54,13 +54,16 @@ void JitterEmulation::setSensitivity(Int32 sensitivity) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void JitterEmulation::frameComplete(Int32 scanlineCount, Int32 vsyncCycles) +void JitterEmulation::frameComplete(Int32 scanlineCount, Int32 vsyncCycles, Int32 vblankCycles) { //#ifdef DEBUG_BUILD // const int vsyncLines = round((vsyncCycles - 2) / 76.0); // cerr << "TV jitter " << myJitter << " - " << scanlineCount << ", " << vsyncCycles << ", " << vsyncLines << '\n'; //#endif + if (mySensitivity >= 6) + vsyncCycles = std::min(vsyncCycles, vblankCycles); + // Check if current frame size is stable compared to previous frame const bool scanlinesStable = scanlineCount == myLastFrameScanlines; const bool vsyncCyclesStable = vsyncCycles >= myVsyncCycles; diff --git a/src/emucore/tia/frame-manager/JitterEmulation.hxx b/src/emucore/tia/frame-manager/JitterEmulation.hxx index 89d13131c..eec2dbc33 100644 --- a/src/emucore/tia/frame-manager/JitterEmulation.hxx +++ b/src/emucore/tia/frame-manager/JitterEmulation.hxx @@ -48,7 +48,7 @@ class JitterEmulation : public Serializable void setRecovery(Int32 recoveryFactor) { myJitterRecovery = recoveryFactor; } void setYStart(Int32 ystart) { myYStart = ystart; } - void frameComplete(Int32 scanlineCount, Int32 vsyncCycles); + void frameComplete(Int32 scanlineCount, Int32 vsyncCycles, Int32 vblankCycles); Int32 jitter() const { return myJitter; } bool vsyncCorrect() const { return myVsyncCorrect; }