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