diff --git a/src/emucore/TIA.cxx b/src/emucore/TIA.cxx index 62db05de4..ead2d04ea 100644 --- a/src/emucore/TIA.cxx +++ b/src/emucore/TIA.cxx @@ -646,6 +646,7 @@ inline void TIA::startFrame() myColor[_BK] &= 0xfefefefe; } } + myStartScanline = 0x7FFFFFFF; myFrameGreyed = false; } @@ -661,7 +662,8 @@ inline void TIA::endFrame() myFrameCounter++; // Recalculate framerate. attempting to auto-correct for scanline 'jumps' - if(myFrameCounter % 8 == 0 && myAutoFrameEnabled) + if(myFrameCounter % 8 == 0 && myAutoFrameEnabled && + myScanlineCountForLastFrame < myMaximumNumberOfScanlines) { myFramerate = (myScanlineCountForLastFrame > 285 ? 15600.0 : 15720.0) / myScanlineCountForLastFrame; @@ -671,10 +673,26 @@ inline void TIA::endFrame() // We always accommodate the highest # of scanlines, up to the maximum // size of the buffer (currently, 320 lines) uInt32 offset = 228 * myScanlineCountForLastFrame; - if(offset > myStopDisplayOffset && offset <= 228 * 320) + if(offset > myStopDisplayOffset && offset < 228 * 320) myStopDisplayOffset = offset; } + // This is a bit of a hack for those ROMs which generate too many + // scanlines each frame, usually caused by VBLANK taking too long + // When this happens, the frame pointers sometimes get 'confused', + // and the framebuffer class doesn't properly overwrite data from + // the previous frame, causing graphical garbage + // + // We basically erase the entire contents of both buffers, making + // sure that they're also different from one another + // This will force the framebuffer class to completely re-render + // the screen + if(myScanlineCountForLastFrame > myMaximumNumberOfScanlines) + { + memset(myCurrentFrameBuffer, 0, 160 * 320); + memset(myPreviousFrameBuffer, 1, 160 * 320); + } + myFrameGreyed = false; } @@ -1743,14 +1761,20 @@ void TIA::poke(uInt16 addr, uInt8 value) { myDumpEnabled = true; } - // Is the dump to ground path being removed from I0, I1, I2, and I3? - if((myVBLANK & 0x80) && !(value & 0x80)) + else if((myVBLANK & 0x80) && !(value & 0x80)) { myDumpEnabled = false; myDumpDisabledCycle = mySystem->cycles(); } +#if 0 // TODO - this isn't yet complete + // Check for the first scanline at which VBLANK is disabled. + // Usually, this will be the first scanline to start drawing. + if(myStartScanline == 0x7FFFFFFF && !(value & 0x10)) + myStartScanline = scanlines(); +#endif + myVBLANK = value; break; } diff --git a/src/emucore/TIA.hxx b/src/emucore/TIA.hxx index f6d866ea6..72c115ff5 100644 --- a/src/emucore/TIA.hxx +++ b/src/emucore/TIA.hxx @@ -213,6 +213,13 @@ class TIA : public Device inline uInt32 scanlines() const { return ((mySystem->cycles() * 3) - myClockWhenFrameStarted) / 228; } + /** + Answers the first scanline at which drawing occured in the last frame. + + @return The starting scanline + */ + inline uInt32 startScanline() const { return myStartScanline; } + /** Enables/disables all TIABit bits. @@ -363,6 +370,9 @@ class TIA : public Device // Indicates the maximum number of scanlines to be generated for a frame uInt32 myMaximumNumberOfScanlines; + // Indicates potentially the first scanline at which drawing occurs + uInt32 myStartScanline; + // Color clock when VSYNC ending causes a new frame to be started Int32 myVSYNCFinishClock;