Fixed TIA partial scanline updates when stepping/tracing. Now a

step/trace will continue updating the TIA from the last position.
If we haven't entered 'scanline advance' mode yet, step/trace will
now do so.  This was accomplished by moving all CPU updates to TIA, so
that the TIA device now throttles/controls the M6502.

There's now some code bloat in TIA, since there are three methods
updateScanline(), updateScanlinebyStep(), updateScanlinebyTrace() that
are very similar.  But it works, and I'm satisfied to leave it alone
for now.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@825 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-10-11 19:38:10 +00:00
parent 568713ee45
commit ceec3433f4
7 changed files with 138 additions and 39 deletions

View File

@ -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: Debugger.cxx,v 1.96 2005-10-06 17:28:54 stephena Exp $
// $Id: Debugger.cxx,v 1.97 2005-10-11 19:38:10 stephena Exp $
//============================================================================
#include "bspf.hxx"
@ -674,7 +674,7 @@ int Debugger::step()
int cyc = mySystem->cycles();
mySystem->unlockDataBus();
mySystem->m6502().execute(1);
myOSystem->console().mediaSource().updateScanlineByStep();
mySystem->lockDataBus();
return mySystem->cycles() - cyc;
@ -693,7 +693,6 @@ int Debugger::step()
int Debugger::trace()
{
// 32 is the 6502 JSR instruction:
if(mySystem->peek(myCpuDebug->pc()) == 32) {
saveOldState();
@ -702,10 +701,7 @@ int Debugger::trace()
int targetPC = myCpuDebug->pc() + 3; // return address
mySystem->unlockDataBus();
while(myCpuDebug->pc() != targetPC)
mySystem->m6502().execute(1);
myOSystem->console().mediaSource().updateScanlineByTrace(targetPC);
mySystem->lockDataBus();
return mySystem->cycles() - cyc;
@ -835,7 +831,8 @@ void Debugger::disassemble(IntArray& addr, StringList& addrLabel,
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::nextScanline(int lines) {
void Debugger::nextScanline(int lines)
{
saveOldState();
mySystem->unlockDataBus();
myTiaOutput->advanceScanline(lines);
@ -843,7 +840,8 @@ void Debugger::nextScanline(int lines) {
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::nextFrame(int frames) {
void Debugger::nextFrame(int frames)
{
saveOldState();
mySystem->unlockDataBus();
myTiaOutput->advance(frames);

View File

@ -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: TiaOutputWidget.cxx,v 1.6 2005-09-23 17:38:27 stephena Exp $
// $Id: TiaOutputWidget.cxx,v 1.7 2005-10-11 19:38:10 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -101,6 +101,8 @@ void TiaOutputWidget::handleMouseDown(int x, int y, int button, int clickCount)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
{
int ystart = atoi(instance()->console().properties().get("Display.YStart").c_str());
switch(cmd)
{
case kCMenuItemSelectedCmd:
@ -109,8 +111,8 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
case 0:
{
ostringstream command;
int ystart = atoi(instance()->console().properties().get("Display.YStart").c_str());
int lines = myClickY + ystart - instance()->debugger().tiaDebug().scanlines();
int lines = myClickY + ystart -
instance()->debugger().tiaDebug().scanlines();
if(lines > 0)
{
command << "scanline #" << lines;
@ -122,7 +124,6 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
case 1:
{
ostringstream command;
int ystart = atoi(instance()->console().properties().get("Display.YStart").c_str());
int scanline = myClickY + ystart;
command << "breakif _scan==#" << scanline;
instance()->debugger().parser()->run(command.str());

View File

@ -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: MediaSrc.hxx,v 1.12 2005-07-15 18:19:29 stephena Exp $
// $Id: MediaSrc.hxx,v 1.13 2005-10-11 19:38:10 stephena Exp $
//============================================================================
#ifndef MEDIASOURCE_HXX
@ -30,7 +30,7 @@ class Sound;
This class provides an interface for accessing graphics and audio data.
@author Bradford W. Mott
@version $Id: MediaSrc.hxx,v 1.12 2005-07-15 18:19:29 stephena Exp $
@version $Id: MediaSrc.hxx,v 1.13 2005-10-11 19:38:10 stephena Exp $
*/
class MediaSource
{
@ -54,13 +54,6 @@ class MediaSource
*/
virtual void update() = 0;
/**
This method should be called whenever a new scanline is to be drawn.
Invoking this method will update the graphics buffer and generate
the corresponding audio samples.
*/
virtual void updateScanline() = 0;
/**
Answers the current frame buffer
@ -75,6 +68,29 @@ class MediaSource
*/
virtual uInt8* previousFrameBuffer() const = 0;
#ifdef DEVELOPER_SUPPORT
/**
This method should be called whenever a new scanline is to be drawn.
Invoking this method will update the graphics buffer and generate
the corresponding audio samples.
*/
virtual void updateScanline() = 0;
/**
This method should be called whenever a new partial scanline is to be
drawn by stepping one CPU instruction. Invoking this method will update the
graphics buffer and generate the corresponding audio samples.
*/
virtual void updateScanlineByStep() = 0;
/**
This method should be called whenever a new partial scanline is to be
drawn by tracing to target address. Invoking this method will update the
graphics buffer and generate the corresponding audio samples.
*/
virtual void updateScanlineByTrace(int target) = 0;
#endif
public:
/**
Get the palette which maps frame data to RGB values.

View File

@ -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.63 2005-10-11 03:22:43 urchlay Exp $
// $Id: TIA.cxx,v 1.64 2005-10-11 19:38:10 stephena Exp $
//============================================================================
#include <cassert>
@ -527,7 +527,8 @@ void TIA::update()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline void TIA::startFrame() {
inline void TIA::startFrame()
{
// This stuff should only happen at the beginning of a new frame.
uInt8* tmp = myCurrentFrameBuffer;
myCurrentFrameBuffer = myPreviousFrameBuffer;
@ -576,7 +577,8 @@ inline void TIA::startFrame() {
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline void TIA::endFrame() {
inline void TIA::endFrame()
{
// This stuff should only happen at the end of a frame
// Compute the number of scanlines in the frame
myScanlineCountForLastFrame = myCurrentScanline;
@ -587,6 +589,7 @@ inline void TIA::endFrame() {
myFrameGreyed = false;
}
#ifdef DEVELOPER_SUPPORT
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::updateScanline()
{
@ -620,6 +623,67 @@ void TIA::updateScanline()
endFrame();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::updateScanlineByStep()
{
// Start a new frame if the old one was finished
if(!myPartialFrameFlag) {
startFrame();
}
// grey out old frame contents
if(!myFrameGreyed) greyOutFrame();
myFrameGreyed = true;
// true either way:
myPartialFrameFlag = true;
int totalClocks = (mySystem->cycles() * 3) - myClockWhenFrameStarted;
// Update frame by one CPU instruction/color clock
mySystem->m6502().execute(1);
updateFrame(mySystem->cycles() * 3);
totalClocks = (mySystem->cycles() * 3) - myClockWhenFrameStarted;
myCurrentScanline = totalClocks / 228;
// if we finished the frame, get ready for the next one
if(!myPartialFrameFlag)
endFrame();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::updateScanlineByTrace(int target)
{
// Start a new frame if the old one was finished
if(!myPartialFrameFlag) {
startFrame();
}
// grey out old frame contents
if(!myFrameGreyed) greyOutFrame();
myFrameGreyed = true;
// true either way:
myPartialFrameFlag = true;
int totalClocks = (mySystem->cycles() * 3) - myClockWhenFrameStarted;
while(mySystem->m6502().getPC() != target)
{
mySystem->m6502().execute(1);
updateFrame(mySystem->cycles() * 3);
}
totalClocks = (mySystem->cycles() * 3) - myClockWhenFrameStarted;
myCurrentScanline = totalClocks / 228;
// if we finished the frame, get ready for the next one
if(!myPartialFrameFlag)
endFrame();
}
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt32* TIA::palette() const
{

View File

@ -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.32 2005-10-11 03:22:43 urchlay Exp $
// $Id: TIA.hxx,v 1.33 2005-10-11 19:38:10 stephena Exp $
//============================================================================
#ifndef TIA_HXX
@ -42,7 +42,7 @@ class Settings;
be displayed on screen.
@author Bradford W. Mott
@version $Id: TIA.hxx,v 1.32 2005-10-11 03:22:43 urchlay Exp $
@version $Id: TIA.hxx,v 1.33 2005-10-11 19:38:10 stephena Exp $
*/
class TIA : public Device , public MediaSource
{
@ -129,12 +129,6 @@ class TIA : public Device , public MediaSource
*/
virtual void update();
/**
This method should be called to update the media source with
a new scanline.
*/
virtual void updateScanline();
/**
Answers the current frame buffer
@ -221,6 +215,26 @@ class TIA : public Device , public MediaSource
*/
void enableBits(bool mode) { for(uInt8 i = 0; i < 6; ++i) myBitEnabled[i] = mode; }
#ifdef DEVELOPER_SUPPORT
/**
This method should be called to update the media source with
a new scanline.
*/
virtual void updateScanline();
/**
This method should be called to update the media source with
a new partial scanline by stepping one CPU instruction.
*/
virtual void updateScanlineByStep();
/**
This method should be called to update the media source with
a new partial scanline by tracing to target address.
*/
virtual void updateScanlineByTrace(int target);
#endif
private:
// Compute the ball mask table
void computeBallMaskTable();

View File

@ -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: M6502.hxx,v 1.14 2005-09-20 19:09:10 stephena Exp $
// $Id: M6502.hxx,v 1.15 2005-10-11 19:38:10 stephena Exp $
//============================================================================
#ifndef M6502_HXX
@ -41,7 +41,7 @@ typedef GUI::Array<Expression*> ExpressionList;
has a 64K addressing space.
@author Bradford W. Mott
@version $Id: M6502.hxx,v 1.14 2005-09-20 19:09:10 stephena Exp $
@version $Id: M6502.hxx,v 1.15 2005-10-11 19:38:10 stephena Exp $
*/
class M6502
{
@ -164,6 +164,13 @@ class M6502
return myExecutionStatus & FatalErrorBit;
}
/**
Get the 16-bit value of the Program Counter register.
@return The program counter register
*/
uInt16 getPC() const { return PC; }
public:
/**
Overload the ostream output operator for addressing modes.

View File

@ -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: M6502Hi.cxx,v 1.13 2005-09-20 19:09:10 stephena Exp $
// $Id: M6502Hi.cxx,v 1.14 2005-10-11 19:38:10 stephena Exp $
//============================================================================
#include "M6502Hi.hxx"
@ -90,8 +90,6 @@ inline void M6502High::poke(uInt16 address, uInt8 value)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool M6502High::execute(uInt32 number)
{
int cond = -1;
// Clear all of the execution status bits except for the fatal error bit
myExecutionStatus &= FatalErrorBit;
@ -122,7 +120,8 @@ bool M6502High::execute(uInt32 number)
}
}
if((cond = evalCondBreaks()) > -1)
int cond = evalCondBreaks();
if(cond > -1)
{
string buf = "CBP: " + myBreakCondNames[cond];
if(myDebugger->start(buf))