mirror of https://github.com/stella-emu/stella.git
Added versions of the debugger trap commands that trap on all mirrors,
not just the specified address. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@3317 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
883971985e
commit
2832fbeccb
|
@ -21,6 +21,10 @@
|
|||
Thanks to Omegamatrix of AtariAge for the bug report and patch to fix
|
||||
the issue.
|
||||
|
||||
* Added 'trapm', 'trapreadm', 'trapwritem' commands to debugger prompt.
|
||||
These are similar to the non-'m' versions, except that they also trap
|
||||
on all mirrors of the given address.
|
||||
|
||||
* Fixed bug in debugger 'reset' command; it wasn't resetting the
|
||||
bankswitching, so after a reset the banks were in an undefined state.
|
||||
|
||||
|
|
2
Makefile
2
Makefile
|
@ -26,7 +26,7 @@
|
|||
|
||||
srcdir ?= .
|
||||
|
||||
DEFINES :=
|
||||
DEFINES := -D_GLIBCXX_USE_CXX11_ABI=1
|
||||
LDFLAGS :=
|
||||
INCLUDES :=
|
||||
LIBS :=
|
||||
|
|
|
@ -87,6 +87,15 @@ class CartDebug : public DebuggerSystem
|
|||
int fieldwidth;
|
||||
};
|
||||
|
||||
// Determine 'type' of address (ie, what part of the system accessed)
|
||||
enum AddrType {
|
||||
ADDR_TIA,
|
||||
ADDR_IO,
|
||||
ADDR_ZPRAM,
|
||||
ADDR_ROM
|
||||
};
|
||||
AddrType addressType(uInt16 addr) const;
|
||||
|
||||
public:
|
||||
CartDebug(Debugger& dbg, Console& console, const OSystem& osystem);
|
||||
virtual ~CartDebug() = default;
|
||||
|
@ -266,15 +275,6 @@ class CartDebug : public DebuggerSystem
|
|||
using AddrToLabel = std::map<uInt16, string>;
|
||||
using LabelToAddr = std::map<string, uInt16>;
|
||||
|
||||
// Determine 'type' of address (ie, what part of the system accessed)
|
||||
enum AddrType {
|
||||
ADDR_TIA,
|
||||
ADDR_IO,
|
||||
ADDR_ZPRAM,
|
||||
ADDR_ROM
|
||||
};
|
||||
AddrType addressType(uInt16 addr) const;
|
||||
|
||||
struct DirectiveTag {
|
||||
DisasmType type;
|
||||
uInt16 start;
|
||||
|
|
|
@ -567,9 +567,9 @@ string DebuggerParser::trapStatus(int addr)
|
|||
else if(r)
|
||||
result += "read";
|
||||
else if(w)
|
||||
result += " write";
|
||||
result += "write";
|
||||
else
|
||||
result += " none ";
|
||||
result += "none";
|
||||
|
||||
// TODO - technically, we should determine if the label is read or write
|
||||
const string& l = debugger.cartDebug().getLabel(addr, true);
|
||||
|
@ -585,9 +585,8 @@ string DebuggerParser::trapStatus(int addr)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool DebuggerParser::saveScriptFile(string file)
|
||||
{
|
||||
if( file.find_last_of('.') == string::npos ) {
|
||||
if( file.find_last_of('.') == string::npos )
|
||||
file += ".stella";
|
||||
}
|
||||
|
||||
ofstream out(file);
|
||||
|
||||
|
@ -1440,36 +1439,26 @@ void DebuggerParser::executeTrace()
|
|||
// "trap"
|
||||
void DebuggerParser::executeTrap()
|
||||
{
|
||||
uInt32 beg = args[0];
|
||||
uInt32 end = argCount >= 2 ? args[1] : beg;
|
||||
if(beg > end) std::swap(beg, end);
|
||||
|
||||
for(uInt32 i = beg; i <= end; ++i)
|
||||
{
|
||||
debugger.toggleReadTrap(i);
|
||||
debugger.toggleWriteTrap(i);
|
||||
commandResult << trapStatus(i) << endl;
|
||||
}
|
||||
executeTrapRW(true, true);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// "trapread"
|
||||
void DebuggerParser::executeTrapread()
|
||||
{
|
||||
uInt32 beg = args[0];
|
||||
uInt32 end = argCount >= 2 ? args[1] : beg;
|
||||
if(beg > end) std::swap(beg, end);
|
||||
|
||||
for(uInt32 i = beg; i <= end; ++i)
|
||||
{
|
||||
debugger.toggleReadTrap(i);
|
||||
commandResult << trapStatus(i) << endl;
|
||||
}
|
||||
executeTrapRW(true, false);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// "trapwrite"
|
||||
void DebuggerParser::executeTrapwrite()
|
||||
{
|
||||
executeTrapRW(false, true);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// wrapper function for trap/trapread/trapwrite commands
|
||||
void DebuggerParser::executeTrapRW(bool read, bool write)
|
||||
{
|
||||
uInt32 beg = args[0];
|
||||
uInt32 end = argCount >= 2 ? args[1] : beg;
|
||||
|
@ -1477,11 +1466,116 @@ void DebuggerParser::executeTrapwrite()
|
|||
|
||||
for(uInt32 i = beg; i <= end; ++i)
|
||||
{
|
||||
debugger.toggleWriteTrap(i);
|
||||
if(read) debugger.toggleReadTrap(i);
|
||||
if(write) debugger.toggleWriteTrap(i);
|
||||
commandResult << trapStatus(i) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// "trapm"
|
||||
void DebuggerParser::executeTrapM()
|
||||
{
|
||||
executeTrapMRW(true, true);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// "trapreadm"
|
||||
void DebuggerParser::executeTrapreadM()
|
||||
{
|
||||
executeTrapMRW(true, false);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// "trapwritem"
|
||||
void DebuggerParser::executeTrapwriteM()
|
||||
{
|
||||
executeTrapMRW(false, true);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// wrapper function for trapm/trapreadm/trapwritem commands
|
||||
void DebuggerParser::executeTrapMRW(bool read, bool write)
|
||||
{
|
||||
uInt32 addr = args[0];
|
||||
uInt32 beg = argCount > 1 ? args[1] : 0;
|
||||
uInt32 end = argCount > 2 ? args[2] : 0xFFFF;
|
||||
if(beg > end) std::swap(beg, end);
|
||||
|
||||
switch(debugger.cartDebug().addressType(addr))
|
||||
{
|
||||
case CartDebug::ADDR_TIA:
|
||||
{
|
||||
for(uInt32 i = beg; i <= end; ++i)
|
||||
{
|
||||
if((i & 0x1080) == 0x0000 && (i & 0x003F) == addr)
|
||||
{
|
||||
if(read) debugger.toggleReadTrap(i);
|
||||
if(write) debugger.toggleWriteTrap(i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CartDebug::ADDR_IO:
|
||||
{
|
||||
for(uInt32 i = beg; i <= end; ++i)
|
||||
{
|
||||
if((i & 0x1080) == 0x0080 && (i & 0x0200) != 0x0000 && (i & 0x02FF) == addr)
|
||||
{
|
||||
if(read) debugger.toggleReadTrap(i);
|
||||
if(write) debugger.toggleWriteTrap(i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CartDebug::ADDR_ZPRAM:
|
||||
{
|
||||
for(uInt32 i = beg; i <= end; ++i)
|
||||
{
|
||||
if((i & 0x1080) == 0x0080 && (i & 0x0200) == 0x0000 && (i & 0x00FF) == addr)
|
||||
{
|
||||
if(read) debugger.toggleReadTrap(i);
|
||||
if(write) debugger.toggleWriteTrap(i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CartDebug::ADDR_ROM:
|
||||
{
|
||||
// Enforce range?
|
||||
if(argCount > 1)
|
||||
{
|
||||
if(beg < addr) beg = addr & 0xF000;
|
||||
if(end < beg) beg = end;
|
||||
}
|
||||
else
|
||||
{
|
||||
beg = 0x1000;
|
||||
end = 0xFFFF;
|
||||
}
|
||||
|
||||
// Are we in range?
|
||||
if(!(addr >= beg && addr <= end))
|
||||
{
|
||||
commandResult << "Address " << addr << " is outside range" << endl;
|
||||
return;
|
||||
}
|
||||
for(uInt32 i = beg; i <= end; ++i)
|
||||
{
|
||||
if((i % 0x2000 >= 0x1000) && (i & 0x0FFF) == (addr & 0x0FFF))
|
||||
{
|
||||
if(read) debugger.toggleReadTrap(i);
|
||||
if(write) debugger.toggleWriteTrap(i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
commandResult << trapStatus(addr) << " + mirrors from $"
|
||||
<< Base::HEX4 << beg << " - $" << end << endl;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// "type"
|
||||
void DebuggerParser::executeType()
|
||||
|
@ -2128,6 +2222,33 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
|
|||
std::mem_fn(&DebuggerParser::executeTrapwrite)
|
||||
},
|
||||
|
||||
{
|
||||
"trapm",
|
||||
"Trap read/write access to address xx (+mirrors)",
|
||||
true,
|
||||
false,
|
||||
{ kARG_WORD, kARG_MULTI_WORD },
|
||||
std::mem_fn(&DebuggerParser::executeTrapM)
|
||||
},
|
||||
|
||||
{
|
||||
"trapreadm",
|
||||
"Trap read access to address xx (+mirrors)",
|
||||
true,
|
||||
false,
|
||||
{ kARG_WORD, kARG_MULTI_WORD },
|
||||
std::mem_fn(&DebuggerParser::executeTrapreadM)
|
||||
},
|
||||
|
||||
{
|
||||
"trapwritem",
|
||||
"Trap write access to address xx (+mirrors)",
|
||||
true,
|
||||
false,
|
||||
{ kARG_WORD, kARG_MULTI_WORD },
|
||||
std::mem_fn(&DebuggerParser::executeTrapwriteM)
|
||||
},
|
||||
|
||||
{
|
||||
"type",
|
||||
"Show disassembly type for address xx [to yy]",
|
||||
|
|
|
@ -70,9 +70,7 @@ class DebuggerParser
|
|||
bool saveScriptFile(string file);
|
||||
|
||||
private:
|
||||
enum {
|
||||
kNumCommands = 70
|
||||
};
|
||||
enum { kNumCommands = 73 };
|
||||
|
||||
// Constants for argument processing
|
||||
enum {
|
||||
|
@ -182,6 +180,11 @@ class DebuggerParser
|
|||
void executeTrap();
|
||||
void executeTrapread();
|
||||
void executeTrapwrite();
|
||||
void executeTrapRW(bool read, bool write); // not exposed by debugger
|
||||
void executeTrapM();
|
||||
void executeTrapreadM();
|
||||
void executeTrapwriteM();
|
||||
void executeTrapMRW(bool read, bool write); // not exposed by debugger
|
||||
void executeType();
|
||||
void executeUHex();
|
||||
void executeUndef();
|
||||
|
|
Loading…
Reference in New Issue