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,
which Stella can use directly.
* Replaced "Re-disassemble" with "Disassemble @ current line" in debugger
-Have fun!

View File

@ -1496,13 +1496,13 @@ anywhere in the listing:</p>
<p>The following options are available:</p>
<ul>
<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
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
disassembled, regardless of whether anything has changed.</li>
<li><b>Disassemble @ current line</b>: Disassemble from the disassembly line where the mouse was clicked.
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>

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();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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)
{
uInt16 PC = myDebugger.cpuDebug().pc();
// ROM/RAM bank or ZP-RAM?
int bank = (PC & 0x1000) ? getBank(PC) : int(myBankInfo.size()) - 1;
return disassemble(bank, PC, force);
return (disassembleAddr(myDebugger.cpuDebug().pc()));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -94,10 +94,38 @@ class CartDebug : public DebuggerSystem
// Return the base (= non-mirrored) address of the last CPU write
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);
/**
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);
// First, a call is made to disassemble(), which updates the disassembly
// list, is required; it will figure out when an actual complete
// 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);
// Actually call DiStella to fill the DisassemblyList structure
// Return whether the search address was actually in the list
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()),
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;
int xpos = 8, ypos = 8;
WidgetArray wid;
@ -52,7 +52,7 @@ RomListSettings::RomListSettings(GuiObject* boss, const GUI::Font& font)
ypos += buttonHeight + 4;
ButtonWidget* disasm =
new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Re-disassemble", RomListWidget::kDisassembleCmd);
"Disassemble @ current line", RomListWidget::kDisassembleCmd);
wid.push_back(disasm);
// Settings for Distella
@ -151,7 +151,7 @@ void RomListSettings::handleCommand(CommandSender* sender, int cmd, int data, in
}
case RomListWidget::kDisassembleCmd:
{
sendCommand(cmd, -1, -1);
sendCommand(cmd, _item, -1);
break;
}
case RomListWidget::kTentativeCodeCmd:

View File

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

View File

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