From ceec3433f4e740a99d75d1ab5d3cb71c13b242b4 Mon Sep 17 00:00:00 2001 From: stephena Date: Tue, 11 Oct 2005 19:38:10 +0000 Subject: [PATCH] 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 --- stella/src/debugger/Debugger.cxx | 16 +++-- stella/src/debugger/gui/TiaOutputWidget.cxx | 9 +-- stella/src/emucore/MediaSrc.hxx | 34 +++++++--- stella/src/emucore/TIA.cxx | 70 ++++++++++++++++++++- stella/src/emucore/TIA.hxx | 30 ++++++--- stella/src/emucore/m6502/src/M6502.hxx | 11 +++- stella/src/emucore/m6502/src/M6502Hi.cxx | 7 +-- 7 files changed, 138 insertions(+), 39 deletions(-) diff --git a/stella/src/debugger/Debugger.cxx b/stella/src/debugger/Debugger.cxx index 2a3281582..0cb24f048 100644 --- a/stella/src/debugger/Debugger.cxx +++ b/stella/src/debugger/Debugger.cxx @@ -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); diff --git a/stella/src/debugger/gui/TiaOutputWidget.cxx b/stella/src/debugger/gui/TiaOutputWidget.cxx index 99f0fd7d6..c30b55463 100644 --- a/stella/src/debugger/gui/TiaOutputWidget.cxx +++ b/stella/src/debugger/gui/TiaOutputWidget.cxx @@ -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()); diff --git a/stella/src/emucore/MediaSrc.hxx b/stella/src/emucore/MediaSrc.hxx index dbe56722b..b411367ae 100644 --- a/stella/src/emucore/MediaSrc.hxx +++ b/stella/src/emucore/MediaSrc.hxx @@ -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. diff --git a/stella/src/emucore/TIA.cxx b/stella/src/emucore/TIA.cxx index 450898120..a7f70f179 100644 --- a/stella/src/emucore/TIA.cxx +++ b/stella/src/emucore/TIA.cxx @@ -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 @@ -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 { diff --git a/stella/src/emucore/TIA.hxx b/stella/src/emucore/TIA.hxx index b84d809f8..e91b8821e 100644 --- a/stella/src/emucore/TIA.hxx +++ b/stella/src/emucore/TIA.hxx @@ -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(); diff --git a/stella/src/emucore/m6502/src/M6502.hxx b/stella/src/emucore/m6502/src/M6502.hxx index 99f6f12a2..95ef2ee18 100644 --- a/stella/src/emucore/m6502/src/M6502.hxx +++ b/stella/src/emucore/m6502/src/M6502.hxx @@ -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 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. diff --git a/stella/src/emucore/m6502/src/M6502Hi.cxx b/stella/src/emucore/m6502/src/M6502Hi.cxx index b1843be1f..b4ef3f5ab 100644 --- a/stella/src/emucore/m6502/src/M6502Hi.cxx +++ b/stella/src/emucore/m6502/src/M6502Hi.cxx @@ -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))