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:
stephena 2016-09-04 23:03:01 +00:00
parent 883971985e
commit 2832fbeccb
5 changed files with 165 additions and 37 deletions

View File

@ -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.

View File

@ -26,7 +26,7 @@
srcdir ?= .
DEFINES :=
DEFINES := -D_GLIBCXX_USE_CXX11_ABI=1
LDFLAGS :=
INCLUDES :=
LIBS :=

View File

@ -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;

View File

@ -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]",

View File

@ -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();