conditional savestates in debugger added

This commit is contained in:
thrust26 2017-11-19 18:52:27 +01:00
parent b098f29e9d
commit 01d3a29f66
5 changed files with 187 additions and 21 deletions

View File

@ -65,6 +65,7 @@ class Debugger : public DialogContainer
// directly, and not touch the instance variables
friend class DebuggerParser;
friend class EventHandler;
friend class M6502;
public:
/**

View File

@ -652,6 +652,10 @@ string DebuggerParser::saveScriptFile(string file)
for(const auto& cond : conds)
out << "breakif {" << cond << "}" << endl;
conds = debugger.m6502().getCondSaveStateNames();
for(const auto& cond : conds)
out << "savestateif {" << cond << "}" << endl;
StringList names = debugger.m6502().getCondTrapNames();
for(uInt32 i = 0; i < myTraps.size(); ++i)
{
@ -807,6 +811,14 @@ void DebuggerParser::executeClearconfig()
commandResult << debugger.cartDebug().clearConfig();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "clearbreaks"
void DebuggerParser::executeClearsavestateifs()
{
debugger.m6502().clearCondSaveStates();
commandResult << "all savestate points cleared";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "cleartraps"
void DebuggerParser::executeCleartraps()
@ -932,6 +944,16 @@ void DebuggerParser::executeDelfunction()
commandResult << "function " << argStrings[0] << " built-in or not found";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "delsavestateif"
void DebuggerParser::executeDelsavestateif()
{
if(debugger.m6502().delCondSaveState(args[0]))
commandResult << "removed savestateif " << Base::toString(args[0]);
else
commandResult << red("no such savestateif");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "deltrap"
void DebuggerParser::executeDeltrap()
@ -1212,6 +1234,31 @@ void DebuggerParser::executeListfunctions()
commandResult << "no user-defined functions";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "listsavestateifs"
void DebuggerParser::executeListsavestateifs()
{
ostringstream buf;
int count = 0;
StringList conds = debugger.m6502().getCondSaveStateNames();
if(conds.size() > 0)
{
if(count)
commandResult << endl;
commandResult << "savestateif:" << endl;
for(uInt32 i = 0; i < conds.size(); i++)
{
commandResult << Base::toString(i) << ": " << conds[i];
if(i != (conds.size() - 1)) commandResult << endl;
}
}
if(commandResult.str() == "")
commandResult << "no savestateifs defined";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "listtraps"
void DebuggerParser::executeListtraps()
@ -1542,6 +1589,21 @@ void DebuggerParser::executeSavestate()
commandResult << red("invalid slot (must be 0-9)");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "savestateif"
void DebuggerParser::executeSavestateif()
{
int res = YaccParser::parse(argStrings[0].c_str());
if(res == 0)
{
uInt32 ret = debugger.m6502().addCondSaveState(
YaccParser::getResult(), argStrings[0]);
commandResult << "Added savestateif " << Base::toString(ret);
}
else
commandResult << red("invalid expression");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "scanline"
void DebuggerParser::executeScanline()
@ -1981,6 +2043,16 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
std::mem_fn(&DebuggerParser::executeClearbreaks)
},
{
"clearsavestateifs",
"Clear all savestate points",
"Example: clearsavestateifss (no parameters)",
false,
true,
{ kARG_END_ARGS },
std::mem_fn(&DebuggerParser::executeClearsavestateifs)
},
{
"clearconfig",
"Clear Distella config directives [bank xx]",
@ -2101,6 +2173,16 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
std::mem_fn(&DebuggerParser::executeDelfunction)
},
{
"delsavestateif",
"Delete conditional savestate point <xx>",
"Example: delsavestateif 0",
true,
false,
{ kARG_WORD, kARG_END_ARGS },
std::mem_fn(&DebuggerParser::executeDelsavestateif)
},
{
"deltrap",
"Delete trap <xx>",
@ -2245,6 +2327,16 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
std::mem_fn(&DebuggerParser::executeListfunctions)
},
{
"listsavestateifs",
"List savestate points",
"Example: listsavestateifs (no parameters)",
false,
false,
{ kARG_END_ARGS },
std::mem_fn(&DebuggerParser::executeListsavestateifs)
},
{
"listtraps",
"List traps",
@ -2502,6 +2594,16 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
std::mem_fn(&DebuggerParser::executeSavestate)
},
{
"savestateif",
"Create savestate on <condition>",
"Condition can include multiple items, see documentation\nExample: savestateif pc==f000",
true,
false,
{ kARG_WORD, kARG_END_ARGS },
std::mem_fn(&DebuggerParser::executeSavestateif)
},
{
"scanline",
"Advance emulation by <xx> scanlines (default=1)",

View File

@ -66,7 +66,7 @@ class DebuggerParser
string saveScriptFile(string file);
private:
enum { kNumCommands = 77 };
enum { kNumCommands = 81 };
// Constants for argument processing
enum {
@ -142,6 +142,7 @@ class DebuggerParser
void executeCheat();
void executeClearbreaks();
void executeClearconfig();
void executeClearsavestateifs();
void executeCleartraps();
void executeClearwatches();
void executeCls();
@ -153,6 +154,7 @@ class DebuggerParser
void executeDefine();
void executeDelbreakif();
void executeDelfunction();
void executeDelsavestateif();
void executeDeltrap();
void executeDelwatch();
void executeDisasm();
@ -167,6 +169,7 @@ class DebuggerParser
void executeListbreaks();
void executeListconfig();
void executeListfunctions();
void executeListsavestateifs();
void executeListtraps();
void executeLoadconfig();
void executeLoadstate();
@ -192,6 +195,7 @@ class DebuggerParser
void executeSaveses();
void executeSavesnap();
void executeSavestate();
void executeSavestateif();
void executeScanline();
void executeStep();
void executeTia();

View File

@ -219,10 +219,16 @@ bool M6502::execute(uInt32 number)
int cond = evalCondBreaks();
if(cond > -1)
{
string buf = "CBP: " + myBreakCondNames[cond];
string buf = "CBP: " + myCondBreakNames[cond];
if(myDebugger && myDebugger->start(buf))
return true;
}
cond = evalCondSaveStates();
if(cond > -1)
{
myDebugger->saveOldState("conditional savestate");
}
#endif // DEBUGGER_SUPPORT
uInt16 operandAddress = 0, intermediateAddress = 0;
@ -424,18 +430,18 @@ void M6502::attach(Debugger& debugger)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 M6502::addCondBreak(Expression* e, const string& name)
{
myBreakConds.emplace_back(e);
myBreakCondNames.push_back(name);
return uInt32(myBreakConds.size() - 1);
myCondBreaks.emplace_back(e);
myCondBreakNames.push_back(name);
return uInt32(myCondBreaks.size() - 1);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool M6502::delCondBreak(uInt32 brk)
bool M6502::delCondBreak(uInt32 idx)
{
if(brk < myBreakConds.size())
if(idx < myCondBreaks.size())
{
Vec::removeAt(myBreakConds, brk);
Vec::removeAt(myBreakCondNames, brk);
Vec::removeAt(myCondBreaks, idx);
Vec::removeAt(myCondBreakNames, idx);
return true;
}
return false;
@ -444,14 +450,47 @@ bool M6502::delCondBreak(uInt32 brk)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::clearCondBreaks()
{
myBreakConds.clear();
myBreakCondNames.clear();
myCondBreaks.clear();
myCondBreakNames.clear();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const StringList& M6502::getCondBreakNames() const
{
return myBreakCondNames;
return myCondBreakNames;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 M6502::addCondSaveState(Expression* e, const string& name)
{
myCondSaveStates.emplace_back(e);
myCondSaveStateNames.push_back(name);
return uInt32(myCondSaveStates.size() - 1);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool M6502::delCondSaveState(uInt32 idx)
{
if(idx < myCondSaveStates.size())
{
Vec::removeAt(myCondSaveStates, idx);
Vec::removeAt(myCondSaveStateNames, idx);
return true;
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::clearCondSaveStates()
{
myCondSaveStates.clear();
myCondSaveStateNames.clear();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const StringList& M6502::getCondSaveStateNames() const
{
return myCondSaveStateNames;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -222,19 +222,21 @@ class M6502 : public Serializable
void attach(Debugger& debugger);
PackedBitArray& breakPoints() { return myBreakPoints; }
//PackedBitArray& readTraps() { return myReadTraps; }
//PackedBitArray& writeTraps() { return myWriteTraps; }
//PackedBitArray& readTrapIfs() { return myReadTrapIfs; }
//PackedBitArray& writeTrapIfs() { return myWriteTrapIfs; }
TrapArray& readTraps() { return myReadTraps; }
TrapArray& writeTraps() { return myWriteTraps; }
// methods for 'breakif' handling
uInt32 addCondBreak(Expression* e, const string& name);
bool delCondBreak(uInt32 brk);
bool delCondBreak(uInt32 idx);
void clearCondBreaks();
const StringList& getCondBreakNames() const;
// methods for 'savestateif' handling
uInt32 addCondSaveState(Expression* e, const string& name);
bool delCondSaveState(uInt32 idx);
void clearCondSaveStates();
const StringList& getCondSaveStateNames() const;
// methods for 'trapif' handling
uInt32 addCondTrap(Expression* e, const string& name);
bool delCondTrap(uInt32 brk);
@ -380,14 +382,29 @@ class M6502 : public Serializable
bool myHaltRequested;
#ifdef DEBUGGER_SUPPORT
enum CondAction
{
breakAction,
saveStateAction
};
Int32 evalCondBreaks() {
for(uInt32 i = 0; i < myBreakConds.size(); i++)
if(myBreakConds[i]->evaluate())
for(uInt32 i = 0; i < myCondBreaks.size(); i++)
if(myCondBreaks[i]->evaluate())
return i;
return -1; // no break hit
}
Int32 evalCondSaveStates()
{
for(uInt32 i = 0; i < myCondSaveStates.size(); i++)
if(myCondSaveStates[i]->evaluate())
return i;
return -1; // no save state point hit
}
Int32 evalCondTraps()
{
for(uInt32 i = 0; i < myTrapConds.size(); i++)
@ -413,10 +430,13 @@ class M6502 : public Serializable
};
HitTrapInfo myHitTrapInfo;
vector<unique_ptr<Expression>> myBreakConds;
StringList myBreakCondNames;
vector<unique_ptr<Expression>> myCondBreaks;
StringList myCondBreakNames;
vector<unique_ptr<Expression>> myCondSaveStates;
StringList myCondSaveStateNames;
vector<unique_ptr<Expression>> myTrapConds;
StringList myTrapCondNames;
#endif // DEBUGGER_SUPPORT
private: