mirror of https://github.com/stella-emu/stella.git
Made M6502 own all breakpoint/trap info instead of sharing pointers to
it with the debugger (this eliminates more new's and empties another d'tor. Re-wrote PackedBitArray to use a bitset instead of home-made code. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@3075 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
c997fc3001
commit
29fe39dd99
|
@ -115,9 +115,6 @@ Debugger::Debugger(OSystem& osystem, Console& console)
|
|||
myConsole(console),
|
||||
mySystem(console.system()),
|
||||
myDialog(nullptr),
|
||||
myBreakPoints(nullptr),
|
||||
myReadTraps(nullptr),
|
||||
myWriteTraps(nullptr),
|
||||
myWidth(DebuggerDialog::kSmallFontMinW),
|
||||
myHeight(DebuggerDialog::kSmallFontMinH)
|
||||
{
|
||||
|
@ -130,10 +127,6 @@ Debugger::Debugger(OSystem& osystem, Console& console)
|
|||
myRiotDebug = make_ptr<RiotDebug>(*this, myConsole);
|
||||
myTiaDebug = make_ptr<TIADebug>(*this, myConsole);
|
||||
|
||||
myBreakPoints = new PackedBitArray(0x10000);
|
||||
myReadTraps = new PackedBitArray(0x10000);
|
||||
myWriteTraps = new PackedBitArray(0x10000);
|
||||
|
||||
// Allow access to this object from any class
|
||||
// Technically this violates pure OO programming, but since I know
|
||||
// there will only be ever one instance of debugger in Stella,
|
||||
|
@ -144,9 +137,6 @@ Debugger::Debugger(OSystem& osystem, Console& console)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Debugger::~Debugger()
|
||||
{
|
||||
delete myBreakPoints;
|
||||
delete myReadTraps;
|
||||
delete myWriteTraps;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -362,41 +352,39 @@ int Debugger::trace()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Debugger::toggleBreakPoint(int bp)
|
||||
{
|
||||
mySystem.m6502().setBreakPoints(myBreakPoints);
|
||||
breakPoints().initialize();
|
||||
if(bp < 0) bp = myCpuDebug->pc();
|
||||
myBreakPoints->toggle(bp);
|
||||
breakPoints().toggle(bp);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Debugger::setBreakPoint(int bp, bool set)
|
||||
{
|
||||
mySystem.m6502().setBreakPoints(myBreakPoints);
|
||||
breakPoints().initialize();
|
||||
if(bp < 0) bp = myCpuDebug->pc();
|
||||
if(set)
|
||||
myBreakPoints->set(bp);
|
||||
else
|
||||
myBreakPoints->clear(bp);
|
||||
if(set) breakPoints().set(bp);
|
||||
else breakPoints().clear(bp);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Debugger::breakPoint(int bp)
|
||||
{
|
||||
if(bp < 0) bp = myCpuDebug->pc();
|
||||
return myBreakPoints->isSet(bp) != 0;
|
||||
return breakPoints().isSet(bp);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Debugger::toggleReadTrap(int t)
|
||||
{
|
||||
mySystem.m6502().setTraps(myReadTraps, myWriteTraps);
|
||||
myReadTraps->toggle(t);
|
||||
readTraps().initialize();
|
||||
readTraps().toggle(t);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Debugger::toggleWriteTrap(int t)
|
||||
{
|
||||
mySystem.m6502().setTraps(myReadTraps, myWriteTraps);
|
||||
myWriteTraps->toggle(t);
|
||||
writeTraps().initialize();
|
||||
writeTraps().toggle(t);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -409,13 +397,13 @@ void Debugger::toggleTrap(int t)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Debugger::readTrap(int t)
|
||||
{
|
||||
return myReadTraps->isSet(t) != 0;
|
||||
return readTraps().isInitialized() && readTraps().isSet(t);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Debugger::writeTrap(int t)
|
||||
{
|
||||
return myWriteTraps->isSet(t) != 0;
|
||||
return writeTraps().isInitialized() && writeTraps().isSet(t);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -463,19 +451,14 @@ bool Debugger::rewindState()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Debugger::clearAllBreakPoints()
|
||||
{
|
||||
delete myBreakPoints;
|
||||
myBreakPoints = new PackedBitArray(0x10000);
|
||||
mySystem.m6502().setBreakPoints(nullptr);
|
||||
breakPoints().clearAll();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Debugger::clearAllTraps()
|
||||
{
|
||||
delete myReadTraps;
|
||||
delete myWriteTraps;
|
||||
myReadTraps = new PackedBitArray(0x10000);
|
||||
myWriteTraps = new PackedBitArray(0x10000);
|
||||
mySystem.m6502().setTraps(nullptr, nullptr);
|
||||
readTraps().clearAll();
|
||||
writeTraps().clearAll();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -527,7 +510,7 @@ void Debugger::setQuitState()
|
|||
// execute one instruction on quit. If we're
|
||||
// sitting at a breakpoint/trap, this will get us past it.
|
||||
// Somehow this feels like a hack to me, but I don't know why
|
||||
// if(myBreakPoints->isSet(myCpuDebug->pc()))
|
||||
// if(breakPoints().isSet(myCpuDebug->pc()))
|
||||
mySystem.m6502().execute(1);
|
||||
}
|
||||
|
||||
|
@ -548,6 +531,11 @@ bool Debugger::delFunction(const string& name)
|
|||
if(iter == myFunctions.end())
|
||||
return false;
|
||||
|
||||
// We never want to delete built-in functions
|
||||
for(int i = 0; builtin_functions[i][0] != 0; ++i)
|
||||
if(name == builtin_functions[i][0])
|
||||
return false;
|
||||
|
||||
myFunctions.erase(name);
|
||||
|
||||
const auto& def_iter = myFunctionDefs.find(name);
|
||||
|
|
|
@ -26,7 +26,6 @@ class CartDebug;
|
|||
class CpuDebug;
|
||||
class RiotDebug;
|
||||
class TIADebug;
|
||||
class M6502;
|
||||
class TiaInfoWidget;
|
||||
class TiaOutputWidget;
|
||||
class TiaZoomWidget;
|
||||
|
@ -44,6 +43,7 @@ class ButtonWidget;
|
|||
#include "DialogContainer.hxx"
|
||||
#include "DebuggerDialog.hxx"
|
||||
#include "DebuggerParser.hxx"
|
||||
#include "M6502.hxx"
|
||||
#include "System.hxx"
|
||||
#include "Stack.hxx"
|
||||
#include "bspf.hxx"
|
||||
|
@ -158,13 +158,14 @@ class Debugger : public DialogContainer
|
|||
const GUI::Font& lfont() const { return myDialog->lfont(); }
|
||||
const GUI::Font& nlfont() const { return myDialog->nfont(); }
|
||||
DebuggerParser& parser() const { return *myParser; }
|
||||
PackedBitArray& breakpoints() const { return *myBreakPoints; }
|
||||
PackedBitArray& readtraps() const { return *myReadTraps; }
|
||||
PackedBitArray& writetraps() const { return *myWriteTraps; }
|
||||
PromptWidget& prompt() const { return myDialog->prompt(); }
|
||||
RomWidget& rom() const { return myDialog->rom(); }
|
||||
TiaOutputWidget& tiaOutput() const { return myDialog->tiaOutput(); }
|
||||
|
||||
PackedBitArray& breakPoints() const { return mySystem.m6502().breakPoints(); }
|
||||
PackedBitArray& readTraps() const { return mySystem.m6502().readTraps(); }
|
||||
PackedBitArray& writeTraps() const { return mySystem.m6502().writeTraps(); }
|
||||
|
||||
/**
|
||||
Run the debugger command and return the result.
|
||||
*/
|
||||
|
@ -302,10 +303,6 @@ class Debugger : public DialogContainer
|
|||
unique_ptr<RiotDebug> myRiotDebug;
|
||||
unique_ptr<TIADebug> myTiaDebug;
|
||||
|
||||
PackedBitArray* myBreakPoints;
|
||||
PackedBitArray* myReadTraps;
|
||||
PackedBitArray* myWriteTraps;
|
||||
|
||||
static Debugger* myStaticDebugger;
|
||||
|
||||
FunctionMap myFunctions;
|
||||
|
|
|
@ -869,7 +869,7 @@ void DebuggerParser::executeDelfunction()
|
|||
if(debugger.delFunction(argStrings[0]))
|
||||
commandResult << "removed function " << argStrings[0];
|
||||
else
|
||||
commandResult << "function " << argStrings[0] << " not found";
|
||||
commandResult << "function " << argStrings[0] << " built-in or not found";
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -1042,7 +1042,7 @@ void DebuggerParser::executeListbreaks()
|
|||
|
||||
for(uInt32 i = 0; i < 0x10000; i++)
|
||||
{
|
||||
if(debugger.breakpoints().isSet(i))
|
||||
if(debugger.breakPoints().isSet(i))
|
||||
{
|
||||
buf << debugger.cartDebug().getLabel(i, true, 4) << " ";
|
||||
if(! (++count % 8) ) buf << "\n";
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2014 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "PackedBitArray.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
PackedBitArray::PackedBitArray(uInt32 length)
|
||||
: words(length / WORD_SIZE + 1)
|
||||
{
|
||||
bits = new uInt32[ words ];
|
||||
|
||||
for(uInt32 i = 0; i < words; ++i)
|
||||
bits[i] = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
PackedBitArray::~PackedBitArray()
|
||||
{
|
||||
delete[] bits;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 PackedBitArray::isSet(uInt32 bit) const
|
||||
{
|
||||
uInt32 word = bit / WORD_SIZE;
|
||||
bit %= WORD_SIZE;
|
||||
|
||||
return (bits[word] & (1 << bit));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 PackedBitArray::isClear(uInt32 bit) const
|
||||
{
|
||||
uInt32 word = bit / WORD_SIZE;
|
||||
bit %= WORD_SIZE;
|
||||
|
||||
return !(bits[word] & (1 << bit));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PackedBitArray::toggle(uInt32 bit)
|
||||
{
|
||||
uInt32 word = bit / WORD_SIZE;
|
||||
bit %= WORD_SIZE;
|
||||
|
||||
bits[word] ^= (1 << bit);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PackedBitArray::set(uInt32 bit)
|
||||
{
|
||||
uInt32 word = bit / WORD_SIZE;
|
||||
bit %= WORD_SIZE;
|
||||
|
||||
bits[word] |= (1 << bit);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PackedBitArray::clear(uInt32 bit)
|
||||
{
|
||||
uInt32 word = bit / WORD_SIZE;
|
||||
bit %= WORD_SIZE;
|
||||
|
||||
bits[word] &= (~(1 << bit));
|
||||
}
|
|
@ -17,36 +17,40 @@
|
|||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef PACKEDBITARRAY_HXX
|
||||
#define PACKEDBITARRAY_HXX
|
||||
#ifndef PACKED_BIT_ARRAY_HXX
|
||||
#define PACKED_BIT_ARRAY_HXX
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#include "bspf.hxx"
|
||||
|
||||
class PackedBitArray
|
||||
{
|
||||
public:
|
||||
PackedBitArray(uInt32 length);
|
||||
~PackedBitArray();
|
||||
PackedBitArray() : myInitialized(false) { }
|
||||
|
||||
uInt32 isSet(uInt32 bit) const;
|
||||
uInt32 isClear(uInt32 bit) const;
|
||||
bool isSet(uInt32 bit) const { return myBits[bit]; }
|
||||
bool isClear(uInt32 bit) const { return !myBits[bit]; }
|
||||
|
||||
void set(uInt32 bit);
|
||||
void clear(uInt32 bit);
|
||||
void toggle(uInt32 bit);
|
||||
void set(uInt32 bit) { myBits[bit] = true; }
|
||||
void clear(uInt32 bit) { myBits[bit] = false; }
|
||||
void toggle(uInt32 bit) { myBits.flip(bit); }
|
||||
|
||||
void initialize() { myInitialized = true; }
|
||||
void clearAll() { myInitialized = false; myBits.reset(); }
|
||||
|
||||
bool isInitialized() const { return myInitialized; }
|
||||
|
||||
private:
|
||||
// Copy constructor and assignment operator not supported
|
||||
PackedBitArray(const PackedBitArray&);
|
||||
PackedBitArray& operator = (const PackedBitArray&);
|
||||
|
||||
// number of unsigned ints (size/wordSize):
|
||||
uInt32 words;
|
||||
// The actual bits
|
||||
bitset<0x10000> myBits;
|
||||
|
||||
// the array itself:
|
||||
uInt32* bits;
|
||||
|
||||
static const uInt32 WORD_SIZE = sizeof(uInt32) * 8;
|
||||
// Indicates whether we should treat this bitset as initialized
|
||||
bool myInitialized;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -78,7 +78,7 @@ void RomWidget::loadConfig()
|
|||
myListIsDirty |= cart.disassemble(myListIsDirty);
|
||||
if(myListIsDirty)
|
||||
{
|
||||
myRomList->setList(cart.disassembly(), dbg.breakpoints());
|
||||
myRomList->setList(cart.disassembly(), dbg.breakPoints());
|
||||
myListIsDirty = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ MODULE := src/debugger
|
|||
MODULE_OBJS := \
|
||||
src/debugger/Debugger.o \
|
||||
src/debugger/DebuggerParser.o \
|
||||
src/debugger/PackedBitArray.o \
|
||||
src/debugger/CartDebug.o \
|
||||
src/debugger/CpuDebug.o \
|
||||
src/debugger/DiStella.o \
|
||||
|
|
|
@ -62,11 +62,7 @@ M6502::M6502(const Settings& settings)
|
|||
myDataAddressForPoke(0)
|
||||
{
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myDebugger = nullptr;
|
||||
myBreakPoints = nullptr;
|
||||
myReadTraps = nullptr;
|
||||
myWriteTraps = nullptr;
|
||||
|
||||
myDebugger = nullptr;
|
||||
myJustHitTrapFlag = false;
|
||||
#endif
|
||||
}
|
||||
|
@ -130,14 +126,13 @@ inline uInt8 M6502::peek(uInt16 address, uInt8 flags)
|
|||
mySystem->incrementCycles(SYSTEM_CYCLES_PER_CPU);
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
if(myReadTraps != nullptr && myReadTraps->isSet(address))
|
||||
if(myReadTraps.isInitialized() && myReadTraps.isSet(address))
|
||||
{
|
||||
myJustHitTrapFlag = true;
|
||||
myHitTrapInfo.message = "RTrap: ";
|
||||
myHitTrapInfo.address = address;
|
||||
}
|
||||
//cerr << "addr = " << HEX4 << address << ", flags = " << Debugger::to_bin_8(flags) << endl;
|
||||
#endif
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
||||
uInt8 result = mySystem->peek(address, flags);
|
||||
myLastAccessWasRead = true;
|
||||
|
@ -159,13 +154,13 @@ inline void M6502::poke(uInt16 address, uInt8 value)
|
|||
mySystem->incrementCycles(SYSTEM_CYCLES_PER_CPU);
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
if(myWriteTraps != nullptr && myWriteTraps->isSet(address))
|
||||
if(myWriteTraps.isInitialized() && myWriteTraps.isSet(address))
|
||||
{
|
||||
myJustHitTrapFlag = true;
|
||||
myHitTrapInfo.message = "WTrap: ";
|
||||
myHitTrapInfo.address = address;
|
||||
}
|
||||
#endif
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
||||
mySystem->poke(address, value);
|
||||
myLastAccessWasRead = false;
|
||||
|
@ -193,10 +188,9 @@ bool M6502::execute(uInt32 number)
|
|||
}
|
||||
}
|
||||
|
||||
if(myBreakPoints)
|
||||
if(myBreakPoints->isSet(PC))
|
||||
if(myDebugger && myDebugger->start("BP: ", PC))
|
||||
return true;
|
||||
if(myBreakPoints.isInitialized() && myBreakPoints.isSet(PC))
|
||||
if(myDebugger && myDebugger->start("BP: ", PC))
|
||||
return true;
|
||||
|
||||
int cond = evalCondBreaks();
|
||||
if(cond > -1)
|
||||
|
@ -392,7 +386,7 @@ void M6502::attach(Debugger& debugger)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 M6502::addCondBreak(Expression *e, const string& name)
|
||||
uInt32 M6502::addCondBreak(Expression* e, const string& name)
|
||||
{
|
||||
myBreakConds.emplace_back(unique_ptr<Expression>(e));
|
||||
myBreakCondNames.push_back(name);
|
||||
|
@ -421,27 +415,4 @@ const StringList& M6502::getCondBreakNames() const
|
|||
{
|
||||
return myBreakCondNames;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Int32 M6502::evalCondBreaks()
|
||||
{
|
||||
for(uInt32 i = 0; i < myBreakConds.size(); i++)
|
||||
if(myBreakConds[i]->evaluate())
|
||||
return i;
|
||||
|
||||
return -1; // no break hit
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void M6502::setBreakPoints(PackedBitArray *bp)
|
||||
{
|
||||
myBreakPoints = bp;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void M6502::setTraps(PackedBitArray *read, PackedBitArray *write)
|
||||
{
|
||||
myReadTraps = read;
|
||||
myWriteTraps = write;
|
||||
}
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
|
|
@ -20,19 +20,20 @@
|
|||
#ifndef M6502_HXX
|
||||
#define M6502_HXX
|
||||
|
||||
class M6502;
|
||||
class Debugger;
|
||||
class CpuDebug;
|
||||
class Expression;
|
||||
class PackedBitArray;
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
class Debugger;
|
||||
class CpuDebug;
|
||||
|
||||
#include "Expression.hxx"
|
||||
#include "PackedBitArray.hxx"
|
||||
#endif
|
||||
|
||||
class Settings;
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "System.hxx"
|
||||
#include "Serializable.hxx"
|
||||
|
||||
typedef vector<unique_ptr<Expression>> ExpressionList;
|
||||
|
||||
/**
|
||||
The 6502 is an 8-bit microprocessor that has a 64K addressing space.
|
||||
This class provides a high compatibility 6502 microprocessor emulator.
|
||||
|
@ -202,22 +203,18 @@ class M6502 : public Serializable
|
|||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
public:
|
||||
/**
|
||||
Attach the specified debugger.
|
||||
|
||||
@param debugger The debugger to attach to the microprocessor.
|
||||
*/
|
||||
// Attach the specified debugger.
|
||||
void attach(Debugger& debugger);
|
||||
|
||||
void setBreakPoints(PackedBitArray* bp);
|
||||
void setTraps(PackedBitArray* read, PackedBitArray* write);
|
||||
PackedBitArray& breakPoints() { return myBreakPoints; }
|
||||
PackedBitArray& readTraps() { return myReadTraps; }
|
||||
PackedBitArray& writeTraps() { return myWriteTraps; }
|
||||
|
||||
uInt32 addCondBreak(Expression* e, const string& name);
|
||||
void delCondBreak(uInt32 brk);
|
||||
void clearCondBreaks();
|
||||
const StringList& getCondBreakNames() const;
|
||||
Int32 evalCondBreaks();
|
||||
#endif
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -349,12 +346,19 @@ class M6502 : public Serializable
|
|||
static constexpr uInt32 SYSTEM_CYCLES_PER_CPU = 1;
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
Int32 evalCondBreaks() {
|
||||
for(uInt32 i = 0; i < myBreakConds.size(); i++)
|
||||
if(myBreakConds[i]->evaluate())
|
||||
return i;
|
||||
|
||||
return -1; // no break hit
|
||||
};
|
||||
|
||||
/// Pointer to the debugger for this processor or the null pointer
|
||||
Debugger* myDebugger;
|
||||
|
||||
PackedBitArray* myBreakPoints;
|
||||
PackedBitArray* myReadTraps;
|
||||
PackedBitArray* myWriteTraps;
|
||||
// Addresses for which the specified action should occur
|
||||
PackedBitArray myBreakPoints, myReadTraps, myWriteTraps;
|
||||
|
||||
// Did we just now hit a trap?
|
||||
bool myJustHitTrapFlag;
|
||||
|
@ -364,9 +368,9 @@ class M6502 : public Serializable
|
|||
};
|
||||
HitTrapInfo myHitTrapInfo;
|
||||
|
||||
vector<unique_ptr<Expression>> myBreakConds;
|
||||
StringList myBreakCondNames;
|
||||
ExpressionList myBreakConds;
|
||||
#endif
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue