diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx index 6f927c65f..e695d8682 100644 --- a/src/debugger/CartDebug.cxx +++ b/src/debugger/CartDebug.cxx @@ -213,7 +213,7 @@ bool CartDebug::disassemble(const string& resolvedata, bool force) uInt16 search = PC; if(!(PC & 0x1000)) { - if(myDisassembly.size() == 0) + if(myDisassembly.list.size() == 0) search = start; else return false; @@ -240,15 +240,16 @@ bool CartDebug::fillDisassemblyList(uInt16 start, bool resolvedata, uInt16 searc { bool found = false; - myDisassembly.clear(); - DiStella distella(*this, myDisassembly, start, resolvedata); + myDisassembly.list.clear(); + myDisassembly.fieldwidth = 10 + myLabelLength; + DiStella distella(*this, myDisassembly.list, start, resolvedata); // Parts of the disassembly will be accessed later in different ways // We place those parts in separate maps, to speed up access myAddrToLineList.clear(); - for(uInt32 i = 0; i < myDisassembly.size(); ++i) + for(uInt32 i = 0; i < myDisassembly.list.size(); ++i) { - const DisassemblyTag& tag = myDisassembly[i]; + const DisassemblyTag& tag = myDisassembly.list[i]; // Only non-zero addresses are valid if(tag.address != 0) @@ -274,25 +275,37 @@ int CartDebug::addressToLine(uInt16 address) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string CartDebug::disassemble(uInt16 start, uInt16 lines) const { - DisassemblyList list; - DiStella distella(*this, list, start, false); + Disassembly disasm; + DiStella distella(*this, disasm.list, start, false); // Fill the string with disassembled data start &= 0xFFF; ostringstream buffer; - for(uInt32 i = 0; i < list.size() && lines > 0; ++i) + + // First find the lines in the range, and determine the longest string + uInt32 begin = 0, end = 0, length = 0; + for(end = 0; end < disasm.list.size() && lines > 0; ++end) { - const CartDebug::DisassemblyTag& tag = list[i]; + const CartDebug::DisassemblyTag& tag = disasm.list[end]; if((tag.address & 0xfff) >= start) { - buffer << uppercase << hex << setw(4) << setfill('0') << tag.address - << ": " << tag.disasm << setw(myLabelLength - tag.disasm.length() + 10) - << setfill(' ') << " " - << tag.ccount << " " << tag.bytes << endl; + if(begin == 0) begin = end; + length = BSPF_max(length, (uInt32)tag.label.length()); + --lines; } } + // Now output the disassembly, using as little space as possible + for(uInt32 i = begin; i < end; ++i) + { + const CartDebug::DisassemblyTag& tag = disasm.list[i]; + buffer << uppercase << hex << setw(4) << setfill('0') << tag.address + << ": " << tag.disasm << setw(length - tag.disasm.length() + 10) + << setfill(' ') << " " + << tag.ccount << " " << tag.bytes << endl; + } + return buffer.str(); } diff --git a/src/debugger/CartDebug.hxx b/src/debugger/CartDebug.hxx index afcdad219..24dadf012 100644 --- a/src/debugger/CartDebug.hxx +++ b/src/debugger/CartDebug.hxx @@ -58,6 +58,10 @@ class CartDebug : public DebuggerSystem string bytes; }; typedef Common::Array DisassemblyList; + typedef struct { + DisassemblyList list; + int fieldwidth; + } Disassembly; public: CartDebug(Debugger& dbg, Console& console, const RamAreaList& areas); @@ -115,7 +119,7 @@ class CartDebug : public DebuggerSystem /** Get the results from the most recent call to disassemble() */ - const DisassemblyList& disassemblyList() const { return myDisassembly; } + const Disassembly& disassembly() const { return myDisassembly; } /** Determine the line in the disassembly that corresponds to the given address. @@ -222,7 +226,7 @@ class CartDebug : public DebuggerSystem // Used for the disassembly display, and mapping from addresses // to corresponding lines of text in that display - DisassemblyList myDisassembly; + Disassembly myDisassembly; map myAddrToLineList; // Mappings from label to address (and vice versa) for items diff --git a/src/debugger/DebuggerParser.cxx b/src/debugger/DebuggerParser.cxx index 92d13eb7d..e3b305098 100644 --- a/src/debugger/DebuggerParser.cxx +++ b/src/debugger/DebuggerParser.cxx @@ -1113,7 +1113,7 @@ void DebuggerParser::executeRun() void DebuggerParser::executeRunTo() { const CartDebug& cartdbg = debugger->cartDebug(); - const CartDebug::DisassemblyList& list = cartdbg.disassemblyList(); + const CartDebug::DisassemblyList& list = cartdbg.disassembly().list; uInt32 count = 0; bool done = false; @@ -1147,7 +1147,7 @@ void DebuggerParser::executeRunTo() void DebuggerParser::executeRunToPc() { const CartDebug& cartdbg = debugger->cartDebug(); - const CartDebug::DisassemblyList& list = cartdbg.disassemblyList(); + const CartDebug::DisassemblyList& list = cartdbg.disassembly().list; uInt32 count = 0; bool done = false; diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 81c6f9d59..7e847a559 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -105,10 +105,10 @@ RomListWidget::~RomListWidget() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void RomListWidget::setList(const CartDebug::DisassemblyList& list, +void RomListWidget::setList(const CartDebug::Disassembly& disasm, const PackedBitArray& state) { - myList = &list; + myDisasm = &disasm; myBPState = &state; // Enable all checkboxes @@ -116,8 +116,8 @@ void RomListWidget::setList(const CartDebug::DisassemblyList& list, myCheckList[i]->setFlags(WIDGET_ENABLED); // Then turn off any extras - if((int)myList->size() < _rows) - for(int i = myList->size(); i < _rows; ++i) + if((int)myDisasm->list.size() < _rows) + for(int i = myDisasm->list.size(); i < _rows; ++i) myCheckList[i]->clearFlags(WIDGET_ENABLED); recalc(); @@ -126,7 +126,7 @@ void RomListWidget::setList(const CartDebug::DisassemblyList& list, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomListWidget::setHighlighted(int item) { - if(item < -1 || item >= (int)myList->size()) + if(item < -1 || item >= (int)myDisasm->list.size()) return; if(isEnabled()) @@ -149,7 +149,7 @@ void RomListWidget::setHighlighted(int item) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const string& RomListWidget::getEditString() const { - if(_selectedItem < -1 || _selectedItem >= (int)myList->size()) + if(_selectedItem < -1 || _selectedItem >= (int)myDisasm->list.size()) return EmptyString; else return _editString; @@ -164,7 +164,7 @@ int RomListWidget::findItem(int x, int y) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomListWidget::recalc() { - int size = myList->size(); + int size = myDisasm->list.size(); if (_currentPos >= size) _currentPos = size - 1; @@ -176,7 +176,7 @@ void RomListWidget::recalc() _editMode = false; - myScrollBar->_numEntries = myList->size(); + myScrollBar->_numEntries = myDisasm->list.size(); myScrollBar->_entriesPerPage = _rows; // Reset to normal data entry @@ -198,10 +198,10 @@ void RomListWidget::scrollToCurrent(int item) _currentPos = item - _rows + 1; } - if (_currentPos < 0 || _rows > (int)myList->size()) + if (_currentPos < 0 || _rows > (int)myDisasm->list.size()) _currentPos = 0; - else if (_currentPos + _rows > (int)myList->size()) - _currentPos = myList->size() - _rows; + else if (_currentPos + _rows > (int)myDisasm->list.size()) + _currentPos = myDisasm->list.size() - _rows; myScrollBar->_currentPos = _currentPos; myScrollBar->recalc(); @@ -228,7 +228,7 @@ void RomListWidget::handleMouseDown(int x, int y, int button, int clickCount) // First check whether the selection changed int newSelectedItem; newSelectedItem = findItem(x, y); - if (newSelectedItem > (int)myList->size() - 1) + if (newSelectedItem > (int)myDisasm->list.size() - 1) newSelectedItem = -1; if (_selectedItem != newSelectedItem) @@ -337,7 +337,7 @@ bool RomListWidget::handleEvent(Event::Type e) break; case Event::UIDown: - if (_selectedItem < (int)myList->size() - 1) + if (_selectedItem < (int)myDisasm->list.size() - 1) _selectedItem++; break; @@ -349,8 +349,8 @@ bool RomListWidget::handleEvent(Event::Type e) case Event::UIPgDown: _selectedItem += _rows - 1; - if (_selectedItem >= (int)myList->size() ) - _selectedItem = myList->size() - 1; + if (_selectedItem >= (int)myDisasm->list.size()) + _selectedItem = myDisasm->list.size() - 1; break; case Event::UIHome: @@ -358,7 +358,7 @@ bool RomListWidget::handleEvent(Event::Type e) break; case Event::UIEnd: - _selectedItem = myList->size() - 1; + _selectedItem = myDisasm->list.size() - 1; break; default: @@ -409,7 +409,7 @@ void RomListWidget::drawWidget(bool hilite) { //cerr << "RomListWidget::drawWidget\n"; FBSurface& s = _boss->dialog().surface(); - const CartDebug::DisassemblyList& dlist = *myList; + const CartDebug::DisassemblyList& dlist = myDisasm->list; int i, pos, xpos, ypos, len = dlist.size(); int deltax; @@ -423,8 +423,13 @@ void RomListWidget::drawWidget(bool hilite) s.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor); // Draw the list items - int large_disasmw = _w - l.x() - _labelWidth, - small_disasmw = large_disasmw - r.width() - 4 * _fontWidth; + int ccountw = _fontWidth << 1, + large_disasmw = _w - l.x() - _labelWidth, + small_disasmw = large_disasmw - r.width() - (ccountw << 1), + actualwidth = myDisasm->fieldwidth * _fontWidth; + if(actualwidth < small_disasmw) + small_disasmw = actualwidth; + xpos = _x + CheckboxWidget::boxSize() + 10; ypos = _y + 2; for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++, ypos += _fontHeight) { @@ -435,20 +440,15 @@ void RomListWidget::drawWidget(bool hilite) // Draw highlighted item in a frame if (_highlightedItem == pos) - { - s.frameRect(_x + l.x() - 3, _y + 1 + _fontHeight * i, - _w - l.x(), _fontHeight, kDbgColorHi); - } + s.frameRect(_x + l.x() - 3, ypos - 1, _w - l.x(), _fontHeight, kDbgColorHi); // Draw the selected item inverted, on a highlighted background. if (_selectedItem == pos && _hasFocus) { if (!_editMode) - s.fillRect(_x + r.x() - 3, _y + 1 + _fontHeight * i, - r.width(), _fontHeight, kTextColorHi); + s.fillRect(_x + r.x() - 3, ypos - 1, r.width(), _fontHeight, kTextColorHi); else - s.frameRect(_x + r.x() - 3, _y + 1 + _fontHeight * i, - r.width(), _fontHeight, kTextColorHi); + s.frameRect(_x + r.x() - 3, ypos - 1, r.width(), _fontHeight, kTextColorHi); } // Draw labels @@ -463,7 +463,7 @@ void RomListWidget::drawWidget(bool hilite) s.drawString(_font, dlist[pos].disasm, xpos + _labelWidth, ypos, small_disasmw, kTextColor); s.drawString(_font, dlist[pos].ccount, xpos + _labelWidth + small_disasmw, ypos, - 2*_fontWidth, kTextColor); + ccountw, kTextColor); // Draw separator s.vLine(_x + r.x() - 7, ypos, ypos + _fontHeight - 1, kColor); @@ -544,14 +544,14 @@ void RomListWidget::startEditMode() if (_editable && !_editMode && _selectedItem >= 0) { // Does this line represent an editable area? - if((*myList)[_selectedItem].bytes == "") + if(myDisasm->list[_selectedItem].bytes == "") return; _editMode = true; // Widget gets raw data while editing EditableWidget::startEditMode(); - setEditString((*myList)[_selectedItem].bytes); + setEditString(myDisasm->list[_selectedItem].bytes); } } diff --git a/src/debugger/gui/RomListWidget.hxx b/src/debugger/gui/RomListWidget.hxx index ab157d15a..55ee8da35 100644 --- a/src/debugger/gui/RomListWidget.hxx +++ b/src/debugger/gui/RomListWidget.hxx @@ -49,7 +49,7 @@ class RomListWidget : public EditableWidget int x, int y, int w, int h); virtual ~RomListWidget(); - void setList(const CartDebug::DisassemblyList& list, const PackedBitArray& state); + void setList(const CartDebug::Disassembly& disasm, const PackedBitArray& state); int getSelected() const { return _selectedItem; } int getHighlighted() const { return _highlightedItem; } @@ -99,7 +99,7 @@ class RomListWidget : public EditableWidget int _currentKeyDown; bool _editMode; - const CartDebug::DisassemblyList* myList; + const CartDebug::Disassembly* myDisasm; const PackedBitArray* myBPState; Common::Array myCheckList; }; diff --git a/src/debugger/gui/RomWidget.cxx b/src/debugger/gui/RomWidget.cxx index 2e5dd77fa..527668039 100644 --- a/src/debugger/gui/RomWidget.cxx +++ b/src/debugger/gui/RomWidget.cxx @@ -124,7 +124,7 @@ void RomWidget::loadConfig() myListIsDirty |= cart.disassemble(myResolveData->getSelectedTag(), myListIsDirty); if(myListIsDirty) { - myRomList->setList(cart.disassemblyList(), dbg.breakpoints()); + myRomList->setList(cart.disassembly(), dbg.breakpoints()); myListIsDirty = false; } @@ -202,7 +202,7 @@ void RomWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) void RomWidget::setBreak(int disasm_line, bool state) { const CartDebug::DisassemblyList& list = - instance().debugger().cartDebug().disassemblyList(); + instance().debugger().cartDebug().disassembly().list; if(disasm_line >= (int)list.size()) return; if(list[disasm_line].address != 0 && list[disasm_line].bytes != "") @@ -213,7 +213,7 @@ void RomWidget::setBreak(int disasm_line, bool state) void RomWidget::setPC(int disasm_line) { const CartDebug::DisassemblyList& list = - instance().debugger().cartDebug().disassemblyList(); + instance().debugger().cartDebug().disassembly().list; if(disasm_line >= (int)list.size()) return; if(list[disasm_line].address != 0) @@ -228,7 +228,7 @@ void RomWidget::setPC(int disasm_line) void RomWidget::runtoPC(int disasm_line) { const CartDebug::DisassemblyList& list = - instance().debugger().cartDebug().disassemblyList(); + instance().debugger().cartDebug().disassembly().list; if(disasm_line >= (int)list.size()) return; if(list[disasm_line].address != 0) @@ -243,7 +243,7 @@ void RomWidget::runtoPC(int disasm_line) void RomWidget::patchROM(int disasm_line, const string& bytes) { const CartDebug::DisassemblyList& list = - instance().debugger().cartDebug().disassemblyList(); + instance().debugger().cartDebug().disassembly().list; if(disasm_line >= (int)list.size()) return; if(list[disasm_line].address != 0)