mirror of https://github.com/stella-emu/stella.git
enhanced debugger option "Re-disassemble" into "Disassemble @ current line" (resolves #652)
This commit is contained in:
parent
c8f71125f4
commit
78419f10d6
|
@ -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!
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 |
Binary file not shown.
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
const uInt16 address = getAddress(disasm_line);
|
||||||
|
|
||||||
|
if (address != 0)
|
||||||
|
{
|
||||||
Debugger& debugger = instance().debugger();
|
Debugger& debugger = instance().debugger();
|
||||||
const CartDebug::DisassemblyList& list =
|
|
||||||
debugger.cartDebug().disassembly().list;
|
|
||||||
|
|
||||||
if(disasm_line >= int(list.size())) return;
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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};
|
||||||
|
|
Loading…
Reference in New Issue