mirror of https://github.com/stella-emu/stella.git
Partial TIA updates are, well, partially supported :)
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@658 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
453c7fff22
commit
55d57ed1ea
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: TIA.cxx,v 1.48 2005-07-15 18:19:29 stephena Exp $
|
||||
// $Id: TIA.cxx,v 1.49 2005-07-16 16:09:37 urchlay Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <cassert>
|
||||
|
@ -148,6 +148,7 @@ void TIA::reset()
|
|||
myClocksToEndOfScanLine = 228;
|
||||
myVSYNCFinishClock = 0x7FFFFFFF;
|
||||
myScanlineCountForLastFrame = 0;
|
||||
myCurrentScanline = 0;
|
||||
|
||||
// Currently no objects are enabled
|
||||
myEnabledObjects = 0;
|
||||
|
@ -307,6 +308,7 @@ bool TIA::save(Serializer& out)
|
|||
out.putLong(myClockAtLastUpdate);
|
||||
out.putLong(myClocksToEndOfScanLine);
|
||||
out.putLong(myScanlineCountForLastFrame);
|
||||
out.putLong(myCurrentScanline);
|
||||
out.putLong(myVSYNCFinishClock);
|
||||
|
||||
out.putLong(myEnabledObjects);
|
||||
|
@ -403,6 +405,7 @@ bool TIA::load(Deserializer& in)
|
|||
myClockAtLastUpdate = (Int32) in.getLong();
|
||||
myClocksToEndOfScanLine = (Int32) in.getLong();
|
||||
myScanlineCountForLastFrame = (Int32) in.getLong();
|
||||
myCurrentScanline = (Int32) in.getLong();
|
||||
myVSYNCFinishClock = (Int32) in.getLong();
|
||||
|
||||
myEnabledObjects = (uInt8) in.getLong();
|
||||
|
@ -487,62 +490,82 @@ bool TIA::load(Deserializer& in)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TIA::update()
|
||||
void TIA::update(int cpuCycles)
|
||||
{
|
||||
uInt8* tmp = myCurrentFrameBuffer;
|
||||
myCurrentFrameBuffer = myPreviousFrameBuffer;
|
||||
myPreviousFrameBuffer = tmp;
|
||||
|
||||
// Remember the number of clocks which have passed on the current scanline
|
||||
// so that we can adjust the frame's starting clock by this amount. This
|
||||
// is necessary since some games position objects during VSYNC and the
|
||||
// TIA's internal counters are not reset by VSYNC.
|
||||
uInt32 clocks = ((mySystem->cycles() * 3) - myClockWhenFrameStarted) % 228;
|
||||
|
||||
// Ask the system to reset the cycle count so it doesn't overflow
|
||||
mySystem->resetCycles();
|
||||
|
||||
// Setup clocks that'll be used for drawing this frame
|
||||
myClockWhenFrameStarted = -1 * clocks;
|
||||
myClockStartDisplay = myClockWhenFrameStarted + myStartDisplayOffset;
|
||||
myClockStopDisplay = myClockWhenFrameStarted + myStopDisplayOffset;
|
||||
myClockAtLastUpdate = myClockStartDisplay;
|
||||
myClocksToEndOfScanLine = 228;
|
||||
|
||||
// Reset frame buffer pointer
|
||||
myFramePointer = myCurrentFrameBuffer;
|
||||
|
||||
// If color loss is enabled then update the color registers based on
|
||||
// the number of scanlines in the last frame that was generated
|
||||
if(myColorLossEnabled)
|
||||
{
|
||||
if(myScanlineCountForLastFrame & 0x01)
|
||||
if(!myPartialFrameFlag) {
|
||||
// This stuff should only happen at the beginning of a new frame.
|
||||
uInt8* tmp = myCurrentFrameBuffer;
|
||||
myCurrentFrameBuffer = myPreviousFrameBuffer;
|
||||
myPreviousFrameBuffer = tmp;
|
||||
|
||||
// Remember the number of clocks which have passed on the current scanline
|
||||
// so that we can adjust the frame's starting clock by this amount. This
|
||||
// is necessary since some games position objects during VSYNC and the
|
||||
// TIA's internal counters are not reset by VSYNC.
|
||||
uInt32 clocks = ((mySystem->cycles() * 3) - myClockWhenFrameStarted) % 228;
|
||||
|
||||
// Ask the system to reset the cycle count so it doesn't overflow
|
||||
mySystem->resetCycles();
|
||||
|
||||
// Setup clocks that'll be used for drawing this frame
|
||||
myClockWhenFrameStarted = -1 * clocks;
|
||||
myClockStartDisplay = myClockWhenFrameStarted + myStartDisplayOffset;
|
||||
myClockStopDisplay = myClockWhenFrameStarted + myStopDisplayOffset;
|
||||
myClockAtLastUpdate = myClockStartDisplay;
|
||||
myClocksToEndOfScanLine = 228;
|
||||
|
||||
// Reset frame buffer pointer
|
||||
myFramePointer = myCurrentFrameBuffer;
|
||||
|
||||
// If color loss is enabled then update the color registers based on
|
||||
// the number of scanlines in the last frame that was generated
|
||||
if(myColorLossEnabled)
|
||||
{
|
||||
myCOLUP0 |= 0x01010101;
|
||||
myCOLUP1 |= 0x01010101;
|
||||
myCOLUPF |= 0x01010101;
|
||||
myCOLUBK |= 0x01010101;
|
||||
}
|
||||
else
|
||||
{
|
||||
myCOLUP0 &= 0xfefefefe;
|
||||
myCOLUP1 &= 0xfefefefe;
|
||||
myCOLUPF &= 0xfefefefe;
|
||||
myCOLUBK &= 0xfefefefe;
|
||||
}
|
||||
}
|
||||
if(myScanlineCountForLastFrame & 0x01)
|
||||
{
|
||||
myCOLUP0 |= 0x01010101;
|
||||
myCOLUP1 |= 0x01010101;
|
||||
myCOLUPF |= 0x01010101;
|
||||
myCOLUBK |= 0x01010101;
|
||||
}
|
||||
else
|
||||
{
|
||||
myCOLUP0 &= 0xfefefefe;
|
||||
myCOLUP1 &= 0xfefefefe;
|
||||
myCOLUPF &= 0xfefefefe;
|
||||
myCOLUBK &= 0xfefefefe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Execute instructions until frame is finished
|
||||
mySystem->m6502().execute(25000);
|
||||
// Partial frame flag starts out true here. When then 6502 strobes VSYNC,
|
||||
// TIA::poke() will set this flag to false, so we'll know whether the
|
||||
// frame got finished or interrupted by the debugger hitting a break/trap.
|
||||
myPartialFrameFlag = true;
|
||||
|
||||
// Execute instructions until frame is finished, or a breakpoint/trap hits
|
||||
mySystem->m6502().execute(cpuCycles);
|
||||
cerr << "myPartialFrameFlag==" << myPartialFrameFlag << endl;
|
||||
|
||||
// TODO: have code here that handles errors....
|
||||
|
||||
// Compute the number of scanlines in the frame
|
||||
uInt32 totalClocks = (mySystem->cycles() * 3) - myClockWhenFrameStarted;
|
||||
myScanlineCountForLastFrame = totalClocks / 228;
|
||||
myCurrentScanline = totalClocks / 228;
|
||||
|
||||
// Stats counters
|
||||
myFrameCounter++;
|
||||
// This stuff should only happen at the end of a frame
|
||||
if(!myPartialFrameFlag) {
|
||||
// Compute the number of scanlines in the frame
|
||||
myScanlineCountForLastFrame = myCurrentScanline;
|
||||
|
||||
// Stats counters
|
||||
myFrameCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TIA::update()
|
||||
{
|
||||
update(25000);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -551,62 +574,7 @@ void TIA::updateScanline()
|
|||
// FIXME - extend this method to draw partial scanlines
|
||||
// ie, when step/trace is called from the debugger
|
||||
|
||||
uInt8* tmp = myCurrentFrameBuffer;
|
||||
myCurrentFrameBuffer = myPreviousFrameBuffer;
|
||||
myPreviousFrameBuffer = tmp;
|
||||
|
||||
// Remember the number of clocks which have passed on the current scanline
|
||||
// so that we can adjust the frame's starting clock by this amount. This
|
||||
// is necessary since some games position objects during VSYNC and the
|
||||
// TIA's internal counters are not reset by VSYNC.
|
||||
uInt32 clocks = ((mySystem->cycles() * 3) - myClockWhenFrameStarted) % 228;
|
||||
|
||||
// Ask the system to reset the cycle count so it doesn't overflow
|
||||
mySystem->resetCycles();
|
||||
|
||||
// Setup clocks that'll be used for drawing this frame
|
||||
myClockWhenFrameStarted = -1 * clocks;
|
||||
myClockStartDisplay = myClockWhenFrameStarted + myStartDisplayOffset;
|
||||
myClockStopDisplay = myClockWhenFrameStarted + myStopDisplayOffset;
|
||||
myClockAtLastUpdate = myClockStartDisplay;
|
||||
myClocksToEndOfScanLine = 228;
|
||||
|
||||
// Reset frame buffer pointer
|
||||
myFramePointer = myCurrentFrameBuffer;
|
||||
|
||||
// If color loss is enabled then update the color registers based on
|
||||
// the number of scanlines in the last frame that was generated
|
||||
if(myColorLossEnabled)
|
||||
{
|
||||
if(myScanlineCountForLastFrame & 0x01)
|
||||
{
|
||||
myCOLUP0 |= 0x01010101;
|
||||
myCOLUP1 |= 0x01010101;
|
||||
myCOLUPF |= 0x01010101;
|
||||
myCOLUBK |= 0x01010101;
|
||||
}
|
||||
else
|
||||
{
|
||||
myCOLUP0 &= 0xfefefefe;
|
||||
myCOLUP1 &= 0xfefefefe;
|
||||
myCOLUPF &= 0xfefefefe;
|
||||
myCOLUBK &= 0xfefefefe;
|
||||
}
|
||||
}
|
||||
|
||||
// Execute instructions until scanline is finished
|
||||
mySystem->m6502().execute(76);
|
||||
|
||||
// TODO: have code here that handles errors....
|
||||
|
||||
// Compute the number of scanlines in the frame
|
||||
uInt32 totalClocks = (mySystem->cycles() * 3) - myClockWhenFrameStarted;
|
||||
myScanlineCountForLastFrame = totalClocks / 228;
|
||||
|
||||
cerr << "myScanlineCountForLastFrame = " << myScanlineCountForLastFrame << endl;
|
||||
|
||||
// Stats counters
|
||||
myFrameCounter++;
|
||||
update(76);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -641,7 +609,7 @@ uInt32 TIA::height() const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 TIA::scanlines() const
|
||||
{
|
||||
return (uInt32)myScanlineCountForLastFrame;
|
||||
return (uInt32)myCurrentScanline;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -2062,6 +2030,7 @@ void TIA::poke(uInt16 addr, uInt8 value)
|
|||
if(((clock - myClockWhenFrameStarted) / 228) > myMaximumNumberOfScanlines)
|
||||
{
|
||||
mySystem->m6502().stop();
|
||||
myPartialFrameFlag = false;
|
||||
}
|
||||
|
||||
switch(addr)
|
||||
|
@ -2084,6 +2053,7 @@ void TIA::poke(uInt16 addr, uInt8 value)
|
|||
|
||||
// Since we're finished with the frame tell the processor to halt
|
||||
mySystem->m6502().stop();
|
||||
myPartialFrameFlag = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: TIA.hxx,v 1.26 2005-07-15 18:19:29 stephena Exp $
|
||||
// $Id: TIA.hxx,v 1.27 2005-07-16 16:09:37 urchlay Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef TIA_HXX
|
||||
|
@ -42,7 +42,7 @@ class Settings;
|
|||
be displayed on screen.
|
||||
|
||||
@author Bradford W. Mott
|
||||
@version $Id: TIA.hxx,v 1.26 2005-07-15 18:19:29 stephena Exp $
|
||||
@version $Id: TIA.hxx,v 1.27 2005-07-16 16:09:37 urchlay Exp $
|
||||
*/
|
||||
class TIA : public Device , public MediaSource
|
||||
{
|
||||
|
@ -129,6 +129,11 @@ class TIA : public Device , public MediaSource
|
|||
*/
|
||||
virtual void update();
|
||||
|
||||
/* The backend update method. Currently pointless to make this public, as
|
||||
we don't support partial scanline updates, but give it time :)
|
||||
*/
|
||||
void update(int cpuCycles);
|
||||
|
||||
/**
|
||||
This method should be called to update the media source with
|
||||
a new scanline.
|
||||
|
@ -264,6 +269,10 @@ class TIA : public Device , public MediaSource
|
|||
// contains an odd number of scanlines.
|
||||
bool myColorLossEnabled;
|
||||
|
||||
// Indicates whether we're done with the current frame. poke() clears this
|
||||
// when VSYNC is strobed or the max scanlines/frame limit is hit.
|
||||
bool myPartialFrameFlag;
|
||||
|
||||
private:
|
||||
// Number of frames displayed by this TIA
|
||||
int myFrameCounter;
|
||||
|
@ -317,6 +326,9 @@ class TIA : public Device , public MediaSource
|
|||
// Indicates the total number of scanlines generated by the last frame
|
||||
Int32 myScanlineCountForLastFrame;
|
||||
|
||||
// Indicates the current scanline during a partial frame.
|
||||
Int32 myCurrentScanline;
|
||||
|
||||
// Indicates the maximum number of scanlines to be generated for a frame
|
||||
Int32 myMaximumNumberOfScanlines;
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: PromptWidget.cxx,v 1.26 2005-07-08 14:36:18 stephena Exp $
|
||||
// $Id: PromptWidget.cxx,v 1.27 2005-07-16 16:09:38 urchlay Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -610,6 +610,11 @@ void PromptWidget::addToHistory(const char *str)
|
|||
_historySize++;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int PromptWidget::compareHistory(const char *histLine) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PromptWidget::historyScroll(int direction)
|
||||
{
|
||||
|
@ -629,6 +634,18 @@ void PromptWidget::historyScroll(int direction)
|
|||
int line = _historyLine + direction;
|
||||
if ((direction < 0 && line < 0) || (direction > 0 && line > _historySize))
|
||||
return;
|
||||
|
||||
// If they press arrow-up with anything in the buffer, search backwards
|
||||
// in the history.
|
||||
/*
|
||||
if(direction < 0 && _currentPos > _promptStartPos) {
|
||||
for(;line > 0; line--) {
|
||||
if(compareHistory(_history[line]) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
_historyLine = line;
|
||||
|
||||
// Remove the current user text
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: PromptWidget.hxx,v 1.7 2005-07-05 15:25:44 stephena Exp $
|
||||
// $Id: PromptWidget.hxx,v 1.8 2005-07-16 16:09:38 urchlay Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -108,6 +108,8 @@ class PromptWidget : public Widget, public CommandSender
|
|||
OverlayColor textColor;
|
||||
OverlayColor bgColor;
|
||||
bool _inverse;
|
||||
|
||||
int compareHistory(const char *histLine);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue