mirror of https://github.com/stella-emu/stella.git
progress...
This commit is contained in:
parent
61bf556e5b
commit
f862e1c97d
|
@ -171,7 +171,7 @@ int CartDebug::readFromWritePort()
|
|||
// port address space AND the last access was actually a read (the latter
|
||||
// differentiates between reads that are normally part of a write cycle vs.
|
||||
// ones that are illegal)
|
||||
if(mySystem.m6502().lastReadAddress() &&
|
||||
if(mySystem.m6502().lastRealReadAddress() &&
|
||||
(mySystem.getPageAccessType(addr) & System::PA_WRITE) == System::PA_WRITE)
|
||||
return addr;
|
||||
else
|
||||
|
|
|
@ -30,6 +30,7 @@ class CartDebugWidget;
|
|||
#include "Cart.hxx"
|
||||
#include "DebuggerSystem.hxx"
|
||||
#include "System.hxx"
|
||||
#include "M6502.hxx"
|
||||
|
||||
// Function type for CartDebug instance methods
|
||||
class CartDebug;
|
||||
|
@ -127,6 +128,11 @@ class CartDebug : public DebuggerSystem
|
|||
// write port area.
|
||||
int readFromWritePort();
|
||||
|
||||
// Return the address of the last CPU read
|
||||
int lastReadAddress() { return mySystem.m6502().lastReadAddress(); }
|
||||
// Return the address of the last CPU write
|
||||
int lastWriteAddress() { return mySystem.m6502().lastWriteAddress(); }
|
||||
|
||||
// The following two methods are meant to be used together
|
||||
// First, a call is made to disassemble(), which updates the disassembly
|
||||
// list; it will figure out when an actual complete disassembly is
|
||||
|
|
|
@ -85,7 +85,6 @@ static const char* const builtin_functions[][3] = {
|
|||
{ "_diff0a", "*SWCHB & $40", "Left diff. set to A (hard)" },
|
||||
{ "_diff1b", "!(*SWCHB & $80)", "Right diff. set to B (easy)" },
|
||||
{ "_diff1a", "*SWCHB & $80", "Right diff. set to A (hard)" },
|
||||
|
||||
// empty string marks end of list, do not remove
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
@ -105,6 +104,9 @@ static const char* const pseudo_registers[][2] = {
|
|||
{ "_scan", "Current scanline count" },
|
||||
{ "_vblank", "Whether vertical blank is enabled (1 or 0)" },
|
||||
{ "_vsync", "Whether vertical sync is enabled (1 or 0)" },
|
||||
// CPU address access functions:
|
||||
{ "_lastread", "last CPU read address" },
|
||||
{ "_lastwrite", "last CPU write address" },
|
||||
|
||||
// empty string marks end of list, do not remove
|
||||
{ 0, 0 }
|
||||
|
|
|
@ -1571,21 +1571,36 @@ void DebuggerParser::executeTraps(bool read, bool write, bool cond, string comma
|
|||
return;
|
||||
}
|
||||
|
||||
/*if(cond)
|
||||
uInt32 beg = args[ofs];
|
||||
uInt32 end = argCount == ofs + 2 ? args[ofs + 1] : beg;
|
||||
|
||||
if(cond)
|
||||
{
|
||||
int res = YaccParser::parse(argStrings[0].c_str());
|
||||
// create: (condition) && (_lastread >= f000 && _lastread <= f100)
|
||||
// add address range condition(s) to provided condition
|
||||
stringstream buf;
|
||||
buf << "(" << argStrings[0] << ")&&(";
|
||||
if(read)
|
||||
buf << "_lastread>=" << Base::toString(beg) << "&&_lastread<=" << Base::toString(end);
|
||||
if (read && write)
|
||||
buf << "||";
|
||||
if (write)
|
||||
buf << "_lastwrite>=" << Base::toString(beg) << "&&_lastwrite<=" << Base::toString(end);
|
||||
buf << ")";
|
||||
string condition = buf.str();
|
||||
|
||||
//int res = YaccParser::parse(argStrings[0].c_str());
|
||||
int res = YaccParser::parse(condition.c_str());
|
||||
if(res == 0)
|
||||
{
|
||||
uInt32 ret = debugger.cpuDebug().m6502().addCondTrap(
|
||||
YaccParser::getResult(), argStrings[0]);
|
||||
commandResult << "Added " << command << " " << Base::toString(ret) << ", ";
|
||||
YaccParser::getResult(), condition);
|
||||
commandResult << "Added " << command << " " << Base::toString(ret);
|
||||
}
|
||||
else
|
||||
commandResult << red("invalid expression");
|
||||
}*/
|
||||
}
|
||||
|
||||
uInt32 beg = args[ofs];
|
||||
uInt32 end = argCount == ofs + 2 ? args[ofs + 1] : beg;
|
||||
if(beg > 0xFFFF || end > 0xFFFF)
|
||||
{
|
||||
commandResult << red("One or more addresses are invalid") << endl;
|
||||
|
|
|
@ -459,10 +459,10 @@ const StringList& M6502::getCondBreakNames() const
|
|||
return myBreakCondNames;
|
||||
}
|
||||
|
||||
/*// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 M6502::addCondTrap(Expression* e, const string& name)
|
||||
{
|
||||
//myTrapConds.emplace_back(e);
|
||||
myTrapConds.emplace_back(e);
|
||||
myTrapCondNames.push_back(name);
|
||||
return uInt32(myTrapConds.size() - 1);
|
||||
}
|
||||
|
@ -472,8 +472,7 @@ void M6502::delCondTrap(uInt32 brk)
|
|||
{
|
||||
if(brk < myTrapConds.size())
|
||||
{
|
||||
myTrapConds.erase(brk);
|
||||
//Vec::removeAt(myTrapConds, brk);
|
||||
Vec::removeAt(myTrapConds, brk);
|
||||
Vec::removeAt(myTrapCondNames, brk);
|
||||
}
|
||||
}
|
||||
|
@ -489,5 +488,5 @@ void M6502::clearCondTraps()
|
|||
const StringList& M6502::getCondTrapNames() const
|
||||
{
|
||||
return myTrapCondNames;
|
||||
}*/
|
||||
}
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
|
|
@ -145,12 +145,26 @@ class M6502 : public Serializable
|
|||
|
||||
@return The address of the last read
|
||||
*/
|
||||
uInt16 lastReadAddress() const {
|
||||
uInt16 lastRealReadAddress() const {
|
||||
return myLastPokeAddress ?
|
||||
(myLastPokeAddress != myLastPeekAddress ? myLastPeekAddress : 0) :
|
||||
myLastPeekAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
Return the last address that was part of a read/peek.
|
||||
|
||||
@return The address of the last read
|
||||
*/
|
||||
uInt16 lastReadAddress() const { return myLastPeekAddress; }
|
||||
|
||||
/**
|
||||
Return the last address that was part of a write/poke.
|
||||
|
||||
@return The address of the last write
|
||||
*/
|
||||
uInt16 lastWriteAddress() const { return myLastPokeAddress; }
|
||||
|
||||
/**
|
||||
Return the source of the address that was used for a write/poke.
|
||||
Note that this isn't the same as the address that is poked, but
|
||||
|
@ -215,16 +229,17 @@ class M6502 : public Serializable
|
|||
TrapArray& readTraps() { return myReadTraps; }
|
||||
TrapArray& writeTraps() { return myWriteTraps; }
|
||||
|
||||
// methods for 'breakif' handling
|
||||
uInt32 addCondBreak(Expression* e, const string& name);
|
||||
void delCondBreak(uInt32 brk);
|
||||
void clearCondBreaks();
|
||||
const StringList& getCondBreakNames() const;
|
||||
|
||||
/*uInt32 addCondTrap(Expression* e, const string& name);
|
||||
// methods for 'trapif' handling
|
||||
uInt32 addCondTrap(Expression* e, const string& name);
|
||||
void delCondTrap(uInt32 brk);
|
||||
void clearCondTraps();
|
||||
const StringList& getCondTrapNames() const;*/
|
||||
|
||||
const StringList& getCondTrapNames() const;
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
||||
private:
|
||||
|
@ -370,14 +385,14 @@ class M6502 : public Serializable
|
|||
return -1; // no break hit
|
||||
}
|
||||
|
||||
/*Int32 evalCondTraps()
|
||||
Int32 evalCondTraps()
|
||||
{
|
||||
for(uInt32 i = 0; i < myTrapConds.size(); i++)
|
||||
if(myTrapConds[i]->evaluate())
|
||||
return i;
|
||||
|
||||
return -1; // no trapif hit
|
||||
}*/
|
||||
}
|
||||
|
||||
/// Pointer to the debugger for this processor or the null pointer
|
||||
Debugger* myDebugger;
|
||||
|
@ -396,8 +411,8 @@ class M6502 : public Serializable
|
|||
|
||||
vector<unique_ptr<Expression>> myBreakConds;
|
||||
StringList myBreakCondNames;
|
||||
//std::map<uInt32, unique_ptr<Expression>> myTrapConds;
|
||||
//StringList myTrapCondNames;
|
||||
vector<unique_ptr<Expression>> myTrapConds;
|
||||
StringList myTrapCondNames;
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
||||
private:
|
||||
|
|
|
@ -206,6 +206,10 @@ CartMethod getCartSpecial(char* ch)
|
|||
return &CartDebug::getBank;
|
||||
else if(BSPF::equalsIgnoreCase(ch, "_rwport"))
|
||||
return &CartDebug::readFromWritePort;
|
||||
else if(BSPF::equalsIgnoreCase(ch, "_lastread"))
|
||||
return &CartDebug::lastReadAddress;
|
||||
else if(BSPF::equalsIgnoreCase(ch, "_lastwrite"))
|
||||
return &CartDebug::lastWriteAddress;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue