mirror of https://github.com/stella-emu/stella.git
Fixed scanline => framerate calulation bug for those ROMs that generate
many more scanlines than a real TV would allow. This fixes both graphical corruption and slowdowns in Q-Bert ROM (which contains code to do a tight loop extending VBLANK time, in effect generating a 'frame' with 1000's of scanlines). First pass at a method to determine the first 'relevant' scanline of a TIA frame. This isn't easy, because there are many conditions for this to occur. The eventual goal is to eliminate Display.YStart tweaks in the properties file, and have the TIA code itself figure out the best value. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1858 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
c962560606
commit
ef5c5de54f
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue