Traps now work. Had to be done in the M6502 class, not System.

Unfortunately, there's no way to trap a memory access before it happens.
Unlike breakpoints, traps can occur in mid-instruction. We can't stop
the 6502 in mid-instruction, and wouldn't want to if we could (for one
thing there's no way to continue from that point). This means that, when
you hit a trap, the current instruction is the one *after* the one that
triggered the trap. (This is different from a breakpoint: when you hit
a breakpoint, the current instruction will be the one at the breakpoint,
which hasn't executed yet).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@538 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
urchlay 2005-06-21 05:00:46 +00:00
parent bb47a4b341
commit 88108e44f0
6 changed files with 47 additions and 53 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Debugger.cxx,v 1.23 2005-06-21 04:30:49 urchlay Exp $ // $Id: Debugger.cxx,v 1.24 2005-06-21 05:00:45 urchlay Exp $
//============================================================================ //============================================================================
#include "bspf.hxx" #include "bspf.hxx"
@ -28,6 +28,7 @@
#include "Console.hxx" #include "Console.hxx"
#include "System.hxx" #include "System.hxx"
#include "M6502.hxx"
#include "D6502.hxx" #include "D6502.hxx"
#include "Debugger.hxx" #include "Debugger.hxx"
@ -475,13 +476,13 @@ bool Debugger::breakPoint(int bp) {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::toggleReadTrap(int t) { void Debugger::toggleReadTrap(int t) {
mySystem->setTraps(readTraps, writeTraps, this); mySystem->m6502().setTraps(readTraps, writeTraps);
readTraps->toggle(t); readTraps->toggle(t);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::toggleWriteTrap(int t) { void Debugger::toggleWriteTrap(int t) {
mySystem->setTraps(readTraps, writeTraps, this); mySystem->m6502().setTraps(readTraps, writeTraps);
writeTraps->toggle(t); writeTraps->toggle(t);
} }
@ -579,7 +580,7 @@ void Debugger::clearAllTraps() {
delete writeTraps; delete writeTraps;
readTraps = new PackedBitArray(0x10000); readTraps = new PackedBitArray(0x10000);
writeTraps = new PackedBitArray(0x10000); writeTraps = new PackedBitArray(0x10000);
mySystem->setTraps(NULL, NULL, NULL); mySystem->m6502().setTraps(NULL, NULL);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: M6502.cxx,v 1.6 2005-06-16 12:28:54 stephena Exp $ // $Id: M6502.cxx,v 1.7 2005-06-21 05:00:45 urchlay Exp $
//============================================================================ //============================================================================
#include "M6502.hxx" #include "M6502.hxx"
@ -27,6 +27,8 @@ M6502::M6502(uInt32 systemCyclesPerProcessorCycle)
{ {
uInt16 t; uInt16 t;
breakPoints = NULL; breakPoints = NULL;
readTraps = NULL;
writeTraps = NULL;
// Compute the BCD lookup table // Compute the BCD lookup table
for(t = 0; t < 256; ++t) for(t = 0; t < 256; ++t)
@ -345,3 +347,10 @@ const char* M6502::ourInstructionMnemonicTable[256] = {
void M6502::setBreakPoints(PackedBitArray *bp) { void M6502::setBreakPoints(PackedBitArray *bp) {
breakPoints = bp; breakPoints = bp;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::setTraps(PackedBitArray *read, PackedBitArray *write) {
readTraps = read;
writeTraps = write;
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: M6502.hxx,v 1.5 2005-06-16 12:28:54 stephena Exp $ // $Id: M6502.hxx,v 1.6 2005-06-21 05:00:45 urchlay Exp $
//============================================================================ //============================================================================
#ifndef M6502_HXX #ifndef M6502_HXX
@ -35,7 +35,7 @@ class Debugger;
has a 64K addressing space. has a 64K addressing space.
@author Bradford W. Mott @author Bradford W. Mott
@version $Id: M6502.hxx,v 1.5 2005-06-16 12:28:54 stephena Exp $ @version $Id: M6502.hxx,v 1.6 2005-06-21 05:00:45 urchlay Exp $
*/ */
class M6502 class M6502
{ {
@ -177,6 +177,7 @@ class M6502
public: public:
void setBreakPoints(PackedBitArray *bp); void setBreakPoints(PackedBitArray *bp);
void setTraps(PackedBitArray *read, PackedBitArray *write);
protected: protected:
/** /**
@ -210,6 +211,8 @@ class M6502
bool C; // C flag for processor status register bool C; // C flag for processor status register
PackedBitArray *breakPoints; PackedBitArray *breakPoints;
PackedBitArray *readTraps;
PackedBitArray *writeTraps;
/** /**
Bit fields used to indicate that certain conditions need to be Bit fields used to indicate that certain conditions need to be
@ -256,5 +259,8 @@ class M6502
/// Table of instruction mnemonics /// Table of instruction mnemonics
static const char* ourInstructionMnemonicTable[256]; static const char* ourInstructionMnemonicTable[256];
// did we just now hit a trap?
bool justHitTrap;
}; };
#endif #endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: M6502Hi.cxx,v 1.6 2005-06-17 03:49:09 urchlay Exp $ // $Id: M6502Hi.cxx,v 1.7 2005-06-21 05:00:46 urchlay Exp $
//============================================================================ //============================================================================
#include "M6502Hi.hxx" #include "M6502Hi.hxx"
@ -29,6 +29,7 @@ M6502High::M6502High(uInt32 systemCyclesPerProcessorCycle)
{ {
myNumberOfDistinctAccesses = 0; myNumberOfDistinctAccesses = 0;
myLastAddress = 0; myLastAddress = 0;
justHitTrap = false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -45,6 +46,12 @@ inline uInt8 M6502High::peek(uInt16 address)
myLastAddress = address; myLastAddress = address;
} }
mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); mySystem->incrementCycles(mySystemCyclesPerProcessorCycle);
if(readTraps != NULL) {
if(readTraps->isSet(address))
justHitTrap = true;
}
return mySystem->peek(address); return mySystem->peek(address);
} }
@ -57,6 +64,12 @@ inline void M6502High::poke(uInt16 address, uInt8 value)
myLastAddress = address; myLastAddress = address;
} }
mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); mySystem->incrementCycles(mySystemCyclesPerProcessorCycle);
if(writeTraps != NULL) {
if(writeTraps->isSet(address))
justHitTrap = true;
}
mySystem->poke(address, value); mySystem->poke(address, value);
} }
@ -74,6 +87,13 @@ bool M6502High::execute(uInt32 number)
uInt16 operandAddress = 0; uInt16 operandAddress = 0;
uInt8 operand = 0; uInt8 operand = 0;
if(justHitTrap)
{
if(myDebugger->start()) {
return true;
}
}
if(breakPoints != NULL) if(breakPoints != NULL)
{ {
if(breakPoints->isSet(PC)) { if(breakPoints->isSet(PC)) {

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: System.cxx,v 1.9 2005-06-21 04:30:49 urchlay Exp $ // $Id: System.cxx,v 1.10 2005-06-21 05:00:46 urchlay Exp $
//============================================================================ //============================================================================
#include <assert.h> #include <assert.h>
@ -24,7 +24,6 @@
#include "System.hxx" #include "System.hxx"
#include "Serializer.hxx" #include "Serializer.hxx"
#include "Deserializer.hxx" #include "Deserializer.hxx"
#include "Debugger.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
System::System(uInt16 n, uInt16 m) System::System(uInt16 n, uInt16 m)
@ -56,9 +55,6 @@ System::System(uInt16 n, uInt16 m)
// Set up (de)serializer in case we are asked to save/load state // Set up (de)serializer in case we are asked to save/load state
serializer = new Serializer(); serializer = new Serializer();
deserializer = new Deserializer(); deserializer = new Deserializer();
// Start out with traps disabled (the normal case)
setTraps(NULL, NULL, NULL);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -314,13 +310,6 @@ System& System::operator = (const System&)
return *this; return *this;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void System::setTraps(PackedBitArray *read, PackedBitArray *write, Debugger *debugger) {
readTraps = read;
writeTraps = write;
myDebugger = debugger;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 System::peek(uInt16 addr) uInt8 System::peek(uInt16 addr)
{ {
@ -340,16 +329,6 @@ uInt8 System::peek(uInt16 addr)
myDataBusState = result; myDataBusState = result;
// Check for read traps, but only if there's a Debugger
if(myDebugger != NULL && readTraps != NULL) {
cerr << "peek(" << addr << ")" << endl;
if(readTraps->isSet(addr)) {
cerr << "read trap at " << addr << endl;
myDebugger->start();
cerr << "tried to start debugger" << endl;
}
}
return result; return result;
} }
@ -369,12 +348,4 @@ void System::poke(uInt16 addr, uInt8 value)
} }
myDataBusState = value; myDataBusState = value;
// Check for write traps, but only if there's a Debugger
if(myDebugger != NULL && writeTraps != NULL) {
if(writeTraps->isSet(addr)) {
myDebugger->start();
}
}
} }

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: System.hxx,v 1.6 2005-06-21 04:30:49 urchlay Exp $ // $Id: System.hxx,v 1.7 2005-06-21 05:00:46 urchlay Exp $
//============================================================================ //============================================================================
#ifndef SYSTEM_HXX #ifndef SYSTEM_HXX
@ -29,9 +29,6 @@ class Deserializer;
#include "Device.hxx" #include "Device.hxx"
#include "NullDev.hxx" #include "NullDev.hxx"
#include "PackedBitArray.hxx" #include "PackedBitArray.hxx"
//#include "Debugger.hxx"
class Debugger;
/** /**
This class represents a system consisting of a 6502 microprocessor This class represents a system consisting of a 6502 microprocessor
@ -50,7 +47,7 @@ class Debugger;
dynamic code for that page of memory. dynamic code for that page of memory.
@author Bradford W. Mott @author Bradford W. Mott
@version $Id: System.hxx,v 1.6 2005-06-21 04:30:49 urchlay Exp $ @version $Id: System.hxx,v 1.7 2005-06-21 05:00:46 urchlay Exp $
*/ */
class System class System
{ {
@ -133,9 +130,6 @@ class System
*/ */
int loadState(const string& fileName, const string& md5sum); int loadState(const string& fileName, const string& md5sum);
// set trap bit arrays. Pass NULL, NULL to disable traps.
void System::setTraps(PackedBitArray *read, PackedBitArray *write, Debugger *debugger);
public: public:
/** /**
Answer the 6502 microprocessor attached to the system. If a Answer the 6502 microprocessor attached to the system. If a
@ -333,13 +327,6 @@ class System
// The deserializer for the system. Used to load state. // The deserializer for the system. Used to load state.
Deserializer* deserializer; Deserializer* deserializer;
// Trap arrays
PackedBitArray *readTraps;
PackedBitArray *writeTraps;
// Debugger (set via setTraps())
Debugger *myDebugger;
private: private:
// Copy constructor isn't supported by this class so make it private // Copy constructor isn't supported by this class so make it private
System(const System&); System(const System&);