mirror of https://github.com/stella-emu/stella.git
Further improvements to adding directives to the disassembler.
There was a bug in the linked list code causing directives to be added incorrectly. Also, merging is now done when possible instead of creating new nodes. This keeps the directive count as small as possible, and also helps with memory (less allocations happening). Fixed bug in printing the 'ORG' directive; it was being printed before the bank was disassembled, so on the first run it was always 0. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2122 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
f8b2621ab5
commit
00d64f9f02
|
@ -24,7 +24,7 @@
|
|||
#include "CpuDebug.hxx"
|
||||
#include "CartDebug.hxx"
|
||||
|
||||
#define HEX4 setw(4) << setfill('0') << hex
|
||||
#define HEX4 uppercase << hex << setw(4) << setfill('0')
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartDebug::CartDebug(Debugger& dbg, Console& console, const RamAreaList& areas)
|
||||
|
@ -343,6 +343,18 @@ string CartDebug::disassemble(uInt16 start, uInt16 lines) const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartDebug::addDirective(CartDebug::DisasmType type, uInt16 start, uInt16 end)
|
||||
{
|
||||
#define PRINT_TAG(d) \
|
||||
cerr << (d.type == CartDebug::CODE ? "CODE" : \
|
||||
d.type == CartDebug::DATA ? "DATA" : \
|
||||
"GFX") \
|
||||
<< " " << hex << d.start << " - " << hex << d.end << endl;
|
||||
|
||||
#define PRINT_LIST(header) \
|
||||
cerr << header << endl; \
|
||||
for(DirectiveList::const_iterator d = list.begin(); d != list.end(); ++d) \
|
||||
PRINT_TAG((*d)); \
|
||||
cerr << endl;
|
||||
|
||||
BankInfo& info = (myDebugger.cpuDebug().pc() & 0x1000) ?
|
||||
myBankInfo[getBank()] : myBankInfo[myBankInfo.size()-1];
|
||||
|
||||
|
@ -373,13 +385,17 @@ bool CartDebug::addDirective(CartDebug::DisasmType type, uInt16 start, uInt16 en
|
|||
for(i = list.begin(); i != list.end(); ++i)
|
||||
{
|
||||
// Case 1: remove range that is completely inside new range
|
||||
if(i->start >= tag.start && i->end <= tag.end)
|
||||
if(tag.start <= i->start && tag.end >= i->end)
|
||||
{
|
||||
i = list.erase(i);
|
||||
list.erase(i);
|
||||
}
|
||||
// Case 2: split the old range
|
||||
else if(i->start <= tag.start && i->end >= tag.end)
|
||||
else if(tag.start >= i->start && tag.end <= i->end)
|
||||
{
|
||||
// Only split when necessary
|
||||
if(tag.type == i->type)
|
||||
return true; // node is fine as-is
|
||||
|
||||
// Create new endpoint
|
||||
DirectiveTag tag2;
|
||||
tag2.type = i->type;
|
||||
|
@ -391,27 +407,63 @@ bool CartDebug::addDirective(CartDebug::DisasmType type, uInt16 start, uInt16 en
|
|||
|
||||
// Insert new endpoint
|
||||
i++;
|
||||
i = list.insert(i, tag2);
|
||||
list.insert(i, tag2);
|
||||
break; // no need to go further; this is the insertion point
|
||||
}
|
||||
// Case 3: truncate end of old range
|
||||
else if(i->end >= tag.start)
|
||||
else if(tag.start >= i->start && tag.start <= i->end)
|
||||
{
|
||||
i->end = tag.start - 1;
|
||||
}
|
||||
// Case 4: truncate start of old range
|
||||
else if(i->start <= tag.end)
|
||||
else if(tag.end >= i->start && tag.end <= i->end)
|
||||
{
|
||||
i->start = tag.end + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// We now know that the new range can be inserted without overlap
|
||||
// Where possible, consecutive ranges should be merged rather than
|
||||
// new nodes created
|
||||
for(i = list.begin(); i != list.end(); ++i)
|
||||
{
|
||||
if(tag.end < i->start)
|
||||
if(tag.end < i->start) // node should be inserted *before* this one
|
||||
{
|
||||
i = list.insert(i, tag);
|
||||
bool createNode = true;
|
||||
|
||||
// Is the new range ending consecutive with the old range beginning?
|
||||
// If so, a merge will suffice
|
||||
if(i->type == tag.type && tag.end + 1 == i->start)
|
||||
{
|
||||
i->start = tag.start;
|
||||
createNode = false; // a merge was done, so a new node isn't needed
|
||||
}
|
||||
|
||||
// Can we also merge with the previous range (if any)?
|
||||
if(i != list.begin())
|
||||
{
|
||||
DirectiveList::iterator p = i;
|
||||
--p;
|
||||
if(p->type == tag.type && p->end + 1 == tag.start)
|
||||
{
|
||||
if(createNode) // a merge with right-hand range didn't previously occur
|
||||
{
|
||||
p->end = tag.end;
|
||||
createNode = false; // a merge was done, so a new node isn't needed
|
||||
}
|
||||
else // merge all three ranges
|
||||
{
|
||||
i->start = p->start;
|
||||
i = list.erase(p);
|
||||
createNode = false; // a merge was done, so a new node isn't needed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the node only when necessary
|
||||
if(createNode)
|
||||
i = list.insert(i, tag);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -696,9 +748,6 @@ CartDebug::AddrType CartDebug::addressType(uInt16 addr) const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartDebug::getBankDirectives(ostringstream& buf, BankInfo& info) const
|
||||
{
|
||||
// Start with the offset for this bank
|
||||
buf << "ORG " << HEX4 << info.offset << endl;
|
||||
|
||||
// Disassemble the bank, then scan it for an up-to-date description
|
||||
DisassemblyList list;
|
||||
uInt16 banksize =
|
||||
|
@ -708,6 +757,9 @@ void CartDebug::getBankDirectives(ostringstream& buf, BankInfo& info) const
|
|||
if(list.size() == 0)
|
||||
return;
|
||||
|
||||
// Start with the offset for this bank
|
||||
buf << "ORG " << HEX4 << info.offset << endl;
|
||||
|
||||
DisasmType type = list[0].type;
|
||||
uInt16 start = list[0].address, last = list[1].address;
|
||||
if(start == 0) start = info.offset;
|
||||
|
|
|
@ -1577,7 +1577,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
|
|||
"code",
|
||||
"Mark 'CODE' range in disassembly",
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
{ kARG_WORD, kARG_MULTI_BYTE },
|
||||
&DebuggerParser::executeCode
|
||||
},
|
||||
|
@ -1604,7 +1604,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
|
|||
"data",
|
||||
"Mark 'DATA' range in disassembly",
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
{ kARG_WORD, kARG_MULTI_BYTE },
|
||||
&DebuggerParser::executeData
|
||||
},
|
||||
|
@ -1694,7 +1694,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
|
|||
"gfx",
|
||||
"Mark 'CFX' range in disassembly",
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
{ kARG_WORD, kARG_MULTI_BYTE },
|
||||
&DebuggerParser::executeGfx
|
||||
},
|
||||
|
|
|
@ -728,7 +728,7 @@ bool DiStella::check_range(uInt32 beg, uInt32 end)
|
|||
if(beg > end)
|
||||
{
|
||||
cerr << "Beginning of range greater than end: start = " << hex << beg
|
||||
<< ", end = " << hex << endl;
|
||||
<< ", end = " << hex << end << endl;
|
||||
return false;
|
||||
}
|
||||
else if(beg > myAppData.end + myOffset)
|
||||
|
@ -843,6 +843,7 @@ DONE_WITH_ADD:
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DiStella::processDirectives(const CartDebug::DirectiveList& directives)
|
||||
{
|
||||
|
||||
for(CartDebug::DirectiveList::const_iterator i = directives.begin();
|
||||
i != directives.end(); ++i)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue