mirror of https://github.com/stella-emu/stella.git
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:
parent
bb47a4b341
commit
88108e44f0
|
@ -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.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"
|
||||
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "Console.hxx"
|
||||
#include "System.hxx"
|
||||
#include "M6502.hxx"
|
||||
#include "D6502.hxx"
|
||||
|
||||
#include "Debugger.hxx"
|
||||
|
@ -475,13 +476,13 @@ bool Debugger::breakPoint(int bp) {
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Debugger::toggleReadTrap(int t) {
|
||||
mySystem->setTraps(readTraps, writeTraps, this);
|
||||
mySystem->m6502().setTraps(readTraps, writeTraps);
|
||||
readTraps->toggle(t);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Debugger::toggleWriteTrap(int t) {
|
||||
mySystem->setTraps(readTraps, writeTraps, this);
|
||||
mySystem->m6502().setTraps(readTraps, writeTraps);
|
||||
writeTraps->toggle(t);
|
||||
}
|
||||
|
||||
|
@ -579,7 +580,7 @@ void Debugger::clearAllTraps() {
|
|||
delete writeTraps;
|
||||
readTraps = new PackedBitArray(0x10000);
|
||||
writeTraps = new PackedBitArray(0x10000);
|
||||
mySystem->setTraps(NULL, NULL, NULL);
|
||||
mySystem->m6502().setTraps(NULL, NULL);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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.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"
|
||||
|
@ -27,6 +27,8 @@ M6502::M6502(uInt32 systemCyclesPerProcessorCycle)
|
|||
{
|
||||
uInt16 t;
|
||||
breakPoints = NULL;
|
||||
readTraps = NULL;
|
||||
writeTraps = NULL;
|
||||
|
||||
// Compute the BCD lookup table
|
||||
for(t = 0; t < 256; ++t)
|
||||
|
@ -345,3 +347,10 @@ const char* M6502::ourInstructionMnemonicTable[256] = {
|
|||
void M6502::setBreakPoints(PackedBitArray *bp) {
|
||||
breakPoints = bp;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void M6502::setTraps(PackedBitArray *read, PackedBitArray *write) {
|
||||
readTraps = read;
|
||||
writeTraps = write;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.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
|
||||
|
@ -35,7 +35,7 @@ class Debugger;
|
|||
has a 64K addressing space.
|
||||
|
||||
@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
|
||||
{
|
||||
|
@ -177,6 +177,7 @@ class M6502
|
|||
|
||||
public:
|
||||
void setBreakPoints(PackedBitArray *bp);
|
||||
void setTraps(PackedBitArray *read, PackedBitArray *write);
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -210,6 +211,8 @@ class M6502
|
|||
bool C; // C flag for processor status register
|
||||
|
||||
PackedBitArray *breakPoints;
|
||||
PackedBitArray *readTraps;
|
||||
PackedBitArray *writeTraps;
|
||||
|
||||
/**
|
||||
Bit fields used to indicate that certain conditions need to be
|
||||
|
@ -256,5 +259,8 @@ class M6502
|
|||
|
||||
/// Table of instruction mnemonics
|
||||
static const char* ourInstructionMnemonicTable[256];
|
||||
|
||||
// did we just now hit a trap?
|
||||
bool justHitTrap;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -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.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"
|
||||
|
@ -29,6 +29,7 @@ M6502High::M6502High(uInt32 systemCyclesPerProcessorCycle)
|
|||
{
|
||||
myNumberOfDistinctAccesses = 0;
|
||||
myLastAddress = 0;
|
||||
justHitTrap = false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -45,6 +46,12 @@ inline uInt8 M6502High::peek(uInt16 address)
|
|||
myLastAddress = address;
|
||||
}
|
||||
mySystem->incrementCycles(mySystemCyclesPerProcessorCycle);
|
||||
|
||||
if(readTraps != NULL) {
|
||||
if(readTraps->isSet(address))
|
||||
justHitTrap = true;
|
||||
}
|
||||
|
||||
return mySystem->peek(address);
|
||||
}
|
||||
|
||||
|
@ -57,6 +64,12 @@ inline void M6502High::poke(uInt16 address, uInt8 value)
|
|||
myLastAddress = address;
|
||||
}
|
||||
mySystem->incrementCycles(mySystemCyclesPerProcessorCycle);
|
||||
|
||||
if(writeTraps != NULL) {
|
||||
if(writeTraps->isSet(address))
|
||||
justHitTrap = true;
|
||||
}
|
||||
|
||||
mySystem->poke(address, value);
|
||||
}
|
||||
|
||||
|
@ -74,6 +87,13 @@ bool M6502High::execute(uInt32 number)
|
|||
uInt16 operandAddress = 0;
|
||||
uInt8 operand = 0;
|
||||
|
||||
if(justHitTrap)
|
||||
{
|
||||
if(myDebugger->start()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(breakPoints != NULL)
|
||||
{
|
||||
if(breakPoints->isSet(PC)) {
|
||||
|
|
|
@ -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.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>
|
||||
|
@ -24,7 +24,6 @@
|
|||
#include "System.hxx"
|
||||
#include "Serializer.hxx"
|
||||
#include "Deserializer.hxx"
|
||||
#include "Debugger.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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
|
||||
serializer = new Serializer();
|
||||
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;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void System::setTraps(PackedBitArray *read, PackedBitArray *write, Debugger *debugger) {
|
||||
readTraps = read;
|
||||
writeTraps = write;
|
||||
myDebugger = debugger;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 System::peek(uInt16 addr)
|
||||
{
|
||||
|
@ -340,16 +329,6 @@ uInt8 System::peek(uInt16 addr)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -369,12 +348,4 @@ void System::poke(uInt16 addr, uInt8 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.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
|
||||
|
@ -29,9 +29,6 @@ class Deserializer;
|
|||
#include "Device.hxx"
|
||||
#include "NullDev.hxx"
|
||||
#include "PackedBitArray.hxx"
|
||||
//#include "Debugger.hxx"
|
||||
|
||||
class Debugger;
|
||||
|
||||
/**
|
||||
This class represents a system consisting of a 6502 microprocessor
|
||||
|
@ -50,7 +47,7 @@ class Debugger;
|
|||
dynamic code for that page of memory.
|
||||
|
||||
@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
|
||||
{
|
||||
|
@ -133,9 +130,6 @@ class System
|
|||
*/
|
||||
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:
|
||||
/**
|
||||
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.
|
||||
Deserializer* deserializer;
|
||||
|
||||
// Trap arrays
|
||||
PackedBitArray *readTraps;
|
||||
PackedBitArray *writeTraps;
|
||||
|
||||
// Debugger (set via setTraps())
|
||||
Debugger *myDebugger;
|
||||
|
||||
private:
|
||||
// Copy constructor isn't supported by this class so make it private
|
||||
System(const System&);
|
||||
|
|
Loading…
Reference in New Issue