From 6ef90324bf01e671edbf50d71434edd37547e1b1 Mon Sep 17 00:00:00 2001 From: urchlay Date: Sat, 9 Jul 2005 23:44:08 +0000 Subject: [PATCH] Implemented data bus state locking, so the debugger won't disturb the System when it uses peek() to examine memory/TIA/etc. I'm not entirely sure I put a lockDataBus() call where it will get executed when the user presses ` to enter the debugger: I put it in Debugger::start() (does everything call this, or does EventHandler do something else?), and again in Debugger::state() (which gets called to build every prompt string). There are unlockDataBus() calls everywhere in the Debugger where we execute 6502 code, including Debugger::quit(). Does the EventHandler call quit() when it exits the debugger (if the user presses ` I mean)? git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@630 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/debugger/Debugger.cxx | 20 +++++++++++++++++++- stella/src/debugger/TIADebug.cxx | 6 +++--- stella/src/emucore/m6502/src/System.cxx | 22 +++++++++++++++++++--- stella/src/emucore/m6502/src/System.hxx | 21 +++++++++++++++++++-- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/stella/src/debugger/Debugger.cxx b/stella/src/debugger/Debugger.cxx index fb3793389..eba4fadfa 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.57 2005-07-08 17:22:40 stephena Exp $ +// $Id: Debugger.cxx,v 1.58 2005-07-09 23:44:07 urchlay Exp $ //============================================================================ #include "bspf.hxx" @@ -216,6 +216,9 @@ const string Debugger::cpuState() string result; char buf[255]; + // Lock the bus before every prompt, so we don't disturb anything: + mySystem->lockDataBus(); + CpuState state = (CpuState&) myCpuDebug->getState(); CpuState oldstate = (CpuState&) myCpuDebug->getOldState(); @@ -489,12 +492,17 @@ bool Debugger::start() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Debugger::quit() { + if(myOSystem->eventHandler().state() == EventHandler::S_DEBUGGER) { + mySystem->unlockDataBus(); + // execute one instruction on quit, IF we're // sitting at a breakpoint. This will get us past it. // Somehow this feels like a hack to me, but I don't know why + // FIXME: do this for traps, too if(breakPoints->isSet(myCpuDebug->pc())) mySystem->m6502().execute(1); + myOSystem->eventHandler().leaveDebugMode(); } } @@ -517,7 +525,9 @@ int Debugger::step() saveOldState(); int cyc = mySystem->cycles(); + mySystem->unlockDataBus(); mySystem->m6502().execute(1); + mySystem->lockDataBus(); // FIXME - this doesn't work yet, pending a partial rewrite of TIA class myTiaDebug->updateTIA(); @@ -542,15 +552,21 @@ int Debugger::step() int Debugger::trace() { + // 32 is the 6502 JSR instruction: if(mySystem->peek(myCpuDebug->pc()) == 32) { saveOldState(); int cyc = mySystem->cycles(); int targetPC = myCpuDebug->pc() + 3; // return address + + mySystem->unlockDataBus(); + while(myCpuDebug->pc() != targetPC) mySystem->m6502().execute(1); + mySystem->lockDataBus(); + // FIXME - this doesn't work yet, pending a partial rewrite of TIA class myTiaDebug->updateTIA(); myOSystem->frameBuffer().refreshTIA(true); @@ -645,7 +661,9 @@ string Debugger::disassemble(int start, int lines) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Debugger::nextFrame(int frames) { saveOldState(); + mySystem->unlockDataBus(); myOSystem->frameBuffer().advance(frames); + mySystem->lockDataBus(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/debugger/TIADebug.cxx b/stella/src/debugger/TIADebug.cxx index d842b0e1e..3530bee10 100644 --- a/stella/src/debugger/TIADebug.cxx +++ b/stella/src/debugger/TIADebug.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: TIADebug.cxx,v 1.9 2005-07-08 17:22:40 stephena Exp $ +// $Id: TIADebug.cxx,v 1.10 2005-07-09 23:44:07 urchlay Exp $ //============================================================================ #include "System.hxx" @@ -42,7 +42,7 @@ DebuggerState& TIADebug::getState() { myState.ram.clear(); for(int i = 0; i < 0x010; ++i) - myState.ram.push_back(mySystem->peek(i)); + myState.ram.push_back(myTIA->peek(i)); return myState; } @@ -52,7 +52,7 @@ void TIADebug::saveOldState() { myOldState.ram.clear(); for(int i = 0; i < 0x010; ++i) - myOldState.ram.push_back(mySystem->peek(i)); + myOldState.ram.push_back(myTIA->peek(i)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/emucore/m6502/src/System.cxx b/stella/src/emucore/m6502/src/System.cxx index 87ee82b14..76e53b8ab 100644 --- a/stella/src/emucore/m6502/src/System.cxx +++ b/stella/src/emucore/m6502/src/System.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: System.cxx,v 1.12 2005-07-09 12:52:46 stephena Exp $ +// $Id: System.cxx,v 1.13 2005-07-09 23:44:08 urchlay Exp $ //============================================================================ #include @@ -57,6 +57,9 @@ System::System(uInt16 n, uInt16 m) // Set up (de)serializer in case we are asked to save/load state serializer = new Serializer(); deserializer = new Deserializer(); + + // Bus starts out unlocked (in other words, peek() changes myDataBusState) + myDataBusLocked = false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -336,7 +339,8 @@ uInt8 System::peek(uInt16 addr) result = access.device->peek(addr); } - myDataBusState = result; + if(!myDataBusLocked) + myDataBusState = result; return result; } @@ -356,5 +360,17 @@ void System::poke(uInt16 addr, uInt8 value) access.device->poke(addr, value); } - myDataBusState = value; + if(!myDataBusLocked) + myDataBusState = value; } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void System::lockDataBus() { + myDataBusLocked = true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void System::unlockDataBus() { + myDataBusLocked = false; +} + diff --git a/stella/src/emucore/m6502/src/System.hxx b/stella/src/emucore/m6502/src/System.hxx index d3947d605..b0f25c2e2 100644 --- a/stella/src/emucore/m6502/src/System.hxx +++ b/stella/src/emucore/m6502/src/System.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: System.hxx,v 1.9 2005-07-09 12:52:46 stephena Exp $ +// $Id: System.hxx,v 1.10 2005-07-09 23:44:08 urchlay Exp $ //============================================================================ #ifndef SYSTEM_HXX @@ -48,7 +48,7 @@ class Deserializer; dynamic code for that page of memory. @author Bradford W. Mott - @version $Id: System.hxx,v 1.9 2005-07-09 12:52:46 stephena Exp $ + @version $Id: System.hxx,v 1.10 2005-07-09 23:44:08 urchlay Exp $ */ class System { @@ -261,6 +261,18 @@ class System */ void poke(uInt16 address, uInt8 value); + /** + Lock/unlock the data bus. When the bus is locked, peek() and + poke() don't update the bus state. The bus should be unlocked + while the CPU is running (normal emulation, or when the debugger + is stepping/advancing). It should be locked while the debugger + is active but not running the CPU. This is so the debugger can + use System.peek() to examine memory/registers without changing + the state of the system. + */ + void lockDataBus(); + void unlockDataBus(); + public: /** Structure used to specify access methods for a page @@ -343,6 +355,11 @@ class System // The current state of the Data Bus uInt8 myDataBusState; + // Whether or not peek() updates the data bus state. This + // is true during normal emulation, and false when the + // debugger is active. + bool myDataBusLocked; + // The serializer for the system. Used to save state. Serializer* serializer;