enhanced debugger option "Re-disassemble" into "Disassemble @ current line" (resolves #652)

This commit is contained in:
thrust26 2020-07-24 11:09:01 +02:00
parent c8f71125f4
commit 78419f10d6
10 changed files with 93 additions and 37 deletions

View File

@ -24,6 +24,8 @@
the ROM. This allows to distribute ROM and properties in one file, the ROM. This allows to distribute ROM and properties in one file,
which Stella can use directly. which Stella can use directly.
* Replaced "Re-disassemble" with "Disassemble @ current line" in debugger
-Have fun! -Have fun!

View File

@ -1496,13 +1496,13 @@ anywhere in the listing:</p>
<p>The following options are available:</p> <p>The following options are available:</p>
<ul> <ul>
<li><b>Set PC @ current line</b>: Set the Program Counter to the address of the <li><b>Set PC @ current line</b>: Set the Program Counter to the address of the
disassembly line where the mouse was clicked (highlighted in yellow).</li> disassembly line where the mouse was clicked.</li>
<li><b>RunTo PC @ current line</b>: Single-step through code until the Program Counter <li><b>RunTo PC @ current line</b>: Single-step through code until the Program Counter
matches the address of the disassembly line where the mouse was clicked (highlighted in yellow)</li> matches the address of the disassembly line where the mouse was clicked.</li>
<li><b>Re-disassemble</b>: Self-explanatory; force the current bank to be <li><b>Disassemble @ current line</b>: Disassemble from the disassembly line where the mouse was clicked.
disassembled, regardless of whether anything has changed.</li> This allows to fill gaps in the disassembly and is most useful for bankswitched ROMs.</li>
<li><b>Show tentative code</b>: Allow Distella to do a static analysis/disassembly.</li> <li><b>Show tentative code</b>: Allow Distella to do a static analysis/disassembly.</li>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -241,14 +241,19 @@ string CartDebug::toString()
return buf.str(); return buf.str();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDebug::disassembleAddr(uInt16 address, bool force)
{
// ROM/RAM bank or ZP-RAM?
int bank = (address & 0x1000) ? getBank(address) : int(myBankInfo.size()) - 1;
return disassemble(bank, address, force);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDebug::disassemblePC(bool force) bool CartDebug::disassemblePC(bool force)
{ {
uInt16 PC = myDebugger.cpuDebug().pc(); return (disassembleAddr(myDebugger.cpuDebug().pc()));
// ROM/RAM bank or ZP-RAM?
int bank = (PC & 0x1000) ? getBank(PC) : int(myBankInfo.size()) - 1;
return disassemble(bank, PC, force);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -94,10 +94,38 @@ class CartDebug : public DebuggerSystem
// Return the base (= non-mirrored) address of the last CPU write // Return the base (= non-mirrored) address of the last CPU write
int lastWriteBaseAddress(); int lastWriteBaseAddress();
// TODO /**
Disassemble from the given address and its bank using the Distella disassembler
Address-to-label mappings (and vice-versa) are also determined here
@param address The address to start with
@param force Force a re-disassembly, even if the state hasn't changed
@return True if disassembly changed from previous call, else false
*/
bool disassembleAddr(uInt16 address, bool force = false);
/**
Disassemble from the current PC and its bank using the Distella disassembler
Address-to-label mappings (and vice-versa) are also determined here
@param force Force a re-disassembly, even if the state hasn't changed
@return True if disassembly changed from previous call, else false
*/
bool disassemblePC(bool force = false); bool disassemblePC(bool force = false);
/**
Disassemble the given bank using the Distella disassembler
Address-to-label mappings (and vice-versa) are also determined here
@param bank The bank to disassemble
@return True if disassembly changed from previous call, else false
*/
bool disassembleBank(int bank); bool disassembleBank(int bank);
// First, a call is made to disassemble(), which updates the disassembly // First, a call is made to disassemble(), which updates the disassembly
// list, is required; it will figure out when an actual complete // list, is required; it will figure out when an actual complete
// disassembly is required, and when the previous results can be used // disassembly is required, and when the previous results can be used
@ -288,7 +316,6 @@ class CartDebug : public DebuggerSystem
*/ */
bool disassemble(int bank, uInt16 PC, bool force = false); bool disassemble(int bank, uInt16 PC, bool force = false);
// Actually call DiStella to fill the DisassemblyList structure // Actually call DiStella to fill the DisassemblyList structure
// Return whether the search address was actually in the list // Return whether the search address was actually in the list
bool fillDisassemblyList(BankInfo& bankinfo, uInt16 search); bool fillDisassemblyList(BankInfo& bankinfo, uInt16 search);

View File

@ -30,7 +30,7 @@ RomListSettings::RomListSettings(GuiObject* boss, const GUI::Font& font)
: Dialog(boss->instance(), boss->parent()), : Dialog(boss->instance(), boss->parent()),
CommandSender(boss) CommandSender(boss)
{ {
const int buttonWidth = font.getStringWidth("RunTo PC @ current line") + 20, const int buttonWidth = font.getStringWidth("Disassemble @ current line") + 20,
buttonHeight = font.getLineHeight() + 4; buttonHeight = font.getLineHeight() + 4;
int xpos = 8, ypos = 8; int xpos = 8, ypos = 8;
WidgetArray wid; WidgetArray wid;
@ -52,7 +52,7 @@ RomListSettings::RomListSettings(GuiObject* boss, const GUI::Font& font)
ypos += buttonHeight + 4; ypos += buttonHeight + 4;
ButtonWidget* disasm = ButtonWidget* disasm =
new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Re-disassemble", RomListWidget::kDisassembleCmd); "Disassemble @ current line", RomListWidget::kDisassembleCmd);
wid.push_back(disasm); wid.push_back(disasm);
// Settings for Distella // Settings for Distella
@ -151,7 +151,7 @@ void RomListSettings::handleCommand(CommandSender* sender, int cmd, int data, in
} }
case RomListWidget::kDisassembleCmd: case RomListWidget::kDisassembleCmd:
{ {
sendCommand(cmd, -1, -1); sendCommand(cmd, _item, -1);
break; break;
} }
case RomListWidget::kTentativeCodeCmd: case RomListWidget::kTentativeCodeCmd:

View File

@ -113,7 +113,8 @@ void RomWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
break; break;
case RomListWidget::kDisassembleCmd: case RomListWidget::kDisassembleCmd:
invalidate(); // 'data' is the line in the disassemblylist to be accessed
disassemble(data);
break; break;
case RomListWidget::kTentativeCodeCmd: case RomListWidget::kTentativeCodeCmd:
@ -165,29 +166,25 @@ void RomWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomWidget::toggleBreak(int disasm_line) void RomWidget::toggleBreak(int disasm_line)
{ {
Debugger& debugger = instance().debugger(); const uInt16 address = getAddress(disasm_line);
const CartDebug::DisassemblyList& list =
debugger.cartDebug().disassembly().list;
if(disasm_line >= int(list.size())) return; if (address != 0)
{
Debugger& debugger = instance().debugger();
const uInt16 address = list[disasm_line].address;
if(address != 0)
debugger.toggleBreakPoint(address, debugger.cartDebug().getBank(address)); debugger.toggleBreakPoint(address, debugger.cartDebug().getBank(address));
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomWidget::setPC(int disasm_line) void RomWidget::setPC(int disasm_line)
{ {
const CartDebug::DisassemblyList& list = const uInt16 address = getAddress(disasm_line);
instance().debugger().cartDebug().disassembly().list;
if(disasm_line >= int(list.size())) return;
if(list[disasm_line].address != 0) if(address != 0)
{ {
ostringstream command; ostringstream command;
command << "pc #" << list[disasm_line].address; command << "pc #" << address;
instance().debugger().run(command.str()); instance().debugger().run(command.str());
} }
} }
@ -195,28 +192,39 @@ void RomWidget::setPC(int disasm_line)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomWidget::runtoPC(int disasm_line) void RomWidget::runtoPC(int disasm_line)
{ {
const CartDebug::DisassemblyList& list = const uInt16 address = getAddress(disasm_line);
instance().debugger().cartDebug().disassembly().list;
if(disasm_line >= int(list.size())) return;
if(list[disasm_line].address != 0) if(address != 0)
{ {
ostringstream command; ostringstream command;
command << "runtopc #" << list[disasm_line].address; command << "runtopc #" << address;
string msg = instance().debugger().run(command.str()); string msg = instance().debugger().run(command.str());
instance().frameBuffer().showMessage(msg); instance().frameBuffer().showMessage(msg);
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomWidget::disassemble(int disasm_line)
{
const uInt16 address = getAddress(disasm_line);
if(address != 0)
{
CartDebug& cart = instance().debugger().cartDebug();
cart.disassembleAddr(address, true);
invalidate();
scrollTo(cart.addressToLine(address)); // the line might have been changed
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomWidget::patchROM(int disasm_line, const string& bytes, void RomWidget::patchROM(int disasm_line, const string& bytes,
Common::Base::Fmt base) Common::Base::Fmt base)
{ {
const CartDebug::DisassemblyList& list = const uInt16 address = getAddress(disasm_line);
instance().debugger().cartDebug().disassembly().list;
if(disasm_line >= int(list.size())) return;
if(list[disasm_line].address != 0) if(address != 0)
{ {
ostringstream command; ostringstream command;
@ -225,7 +233,7 @@ void RomWidget::patchROM(int disasm_line, const string& bytes,
Common::Base::Fmt oldbase = Common::Base::format(); Common::Base::Fmt oldbase = Common::Base::format();
Common::Base::setFormat(base); Common::Base::setFormat(base);
command << "rom #" << list[disasm_line].address << " " << bytes; command << "rom #" << address << " " << bytes;
instance().debugger().run(command.str()); instance().debugger().run(command.str());
// Restore previous base // Restore previous base
@ -233,6 +241,18 @@ void RomWidget::patchROM(int disasm_line, const string& bytes,
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 RomWidget::getAddress(int disasm_line)
{
const CartDebug::DisassemblyList& list =
instance().debugger().cartDebug().disassembly().list;
if (disasm_line < int(list.size()) && list[disasm_line].address != 0)
return list[disasm_line].address;
else
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomWidget::scrollTo(int line) void RomWidget::scrollTo(int line)
{ {

View File

@ -51,8 +51,10 @@ class RomWidget : public Widget, public CommandSender
void toggleBreak(int disasm_line); void toggleBreak(int disasm_line);
void setPC(int disasm_line); void setPC(int disasm_line);
void runtoPC(int disasm_line); void runtoPC(int disasm_line);
void disassemble(int disasm_line);
void patchROM(int disasm_line, const string& bytes, void patchROM(int disasm_line, const string& bytes,
Common::Base::Fmt base); Common::Base::Fmt base);
uInt16 getAddress(int disasm_line);
private: private:
RomListWidget* myRomList{nullptr}; RomListWidget* myRomList{nullptr};