Size hints are now passed to the disassembly output, so that the cycle

counts are aligned after the disassembly text with as little space as
necessary.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2042 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2010-06-05 01:17:03 +00:00
parent 4735feda13
commit ffae9a0d56
6 changed files with 71 additions and 54 deletions

View File

@ -213,7 +213,7 @@ bool CartDebug::disassemble(const string& resolvedata, bool force)
uInt16 search = PC; uInt16 search = PC;
if(!(PC & 0x1000)) if(!(PC & 0x1000))
{ {
if(myDisassembly.size() == 0) if(myDisassembly.list.size() == 0)
search = start; search = start;
else else
return false; return false;
@ -240,15 +240,16 @@ bool CartDebug::fillDisassemblyList(uInt16 start, bool resolvedata, uInt16 searc
{ {
bool found = false; bool found = false;
myDisassembly.clear(); myDisassembly.list.clear();
DiStella distella(*this, myDisassembly, start, resolvedata); myDisassembly.fieldwidth = 10 + myLabelLength;
DiStella distella(*this, myDisassembly.list, start, resolvedata);
// Parts of the disassembly will be accessed later in different ways // Parts of the disassembly will be accessed later in different ways
// We place those parts in separate maps, to speed up access // We place those parts in separate maps, to speed up access
myAddrToLineList.clear(); 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 // Only non-zero addresses are valid
if(tag.address != 0) if(tag.address != 0)
@ -274,25 +275,37 @@ int CartDebug::addressToLine(uInt16 address) const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartDebug::disassemble(uInt16 start, uInt16 lines) const string CartDebug::disassemble(uInt16 start, uInt16 lines) const
{ {
DisassemblyList list; Disassembly disasm;
DiStella distella(*this, list, start, false); DiStella distella(*this, disasm.list, start, false);
// Fill the string with disassembled data // Fill the string with disassembled data
start &= 0xFFF; start &= 0xFFF;
ostringstream buffer; 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) if((tag.address & 0xfff) >= start)
{ {
buffer << uppercase << hex << setw(4) << setfill('0') << tag.address if(begin == 0) begin = end;
<< ": " << tag.disasm << setw(myLabelLength - tag.disasm.length() + 10) length = BSPF_max(length, (uInt32)tag.label.length());
<< setfill(' ') << " "
<< tag.ccount << " " << tag.bytes << endl;
--lines; --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(); return buffer.str();
} }

View File

@ -58,6 +58,10 @@ class CartDebug : public DebuggerSystem
string bytes; string bytes;
}; };
typedef Common::Array<DisassemblyTag> DisassemblyList; typedef Common::Array<DisassemblyTag> DisassemblyList;
typedef struct {
DisassemblyList list;
int fieldwidth;
} Disassembly;
public: public:
CartDebug(Debugger& dbg, Console& console, const RamAreaList& areas); 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() 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. 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 // Used for the disassembly display, and mapping from addresses
// to corresponding lines of text in that display // to corresponding lines of text in that display
DisassemblyList myDisassembly; Disassembly myDisassembly;
map<uInt16, int> myAddrToLineList; map<uInt16, int> myAddrToLineList;
// Mappings from label to address (and vice versa) for items // Mappings from label to address (and vice versa) for items

View File

@ -1113,7 +1113,7 @@ void DebuggerParser::executeRun()
void DebuggerParser::executeRunTo() void DebuggerParser::executeRunTo()
{ {
const CartDebug& cartdbg = debugger->cartDebug(); const CartDebug& cartdbg = debugger->cartDebug();
const CartDebug::DisassemblyList& list = cartdbg.disassemblyList(); const CartDebug::DisassemblyList& list = cartdbg.disassembly().list;
uInt32 count = 0; uInt32 count = 0;
bool done = false; bool done = false;
@ -1147,7 +1147,7 @@ void DebuggerParser::executeRunTo()
void DebuggerParser::executeRunToPc() void DebuggerParser::executeRunToPc()
{ {
const CartDebug& cartdbg = debugger->cartDebug(); const CartDebug& cartdbg = debugger->cartDebug();
const CartDebug::DisassemblyList& list = cartdbg.disassemblyList(); const CartDebug::DisassemblyList& list = cartdbg.disassembly().list;
uInt32 count = 0; uInt32 count = 0;
bool done = false; bool done = false;

View File

@ -105,10 +105,10 @@ RomListWidget::~RomListWidget()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomListWidget::setList(const CartDebug::DisassemblyList& list, void RomListWidget::setList(const CartDebug::Disassembly& disasm,
const PackedBitArray& state) const PackedBitArray& state)
{ {
myList = &list; myDisasm = &disasm;
myBPState = &state; myBPState = &state;
// Enable all checkboxes // Enable all checkboxes
@ -116,8 +116,8 @@ void RomListWidget::setList(const CartDebug::DisassemblyList& list,
myCheckList[i]->setFlags(WIDGET_ENABLED); myCheckList[i]->setFlags(WIDGET_ENABLED);
// Then turn off any extras // Then turn off any extras
if((int)myList->size() < _rows) if((int)myDisasm->list.size() < _rows)
for(int i = myList->size(); i < _rows; ++i) for(int i = myDisasm->list.size(); i < _rows; ++i)
myCheckList[i]->clearFlags(WIDGET_ENABLED); myCheckList[i]->clearFlags(WIDGET_ENABLED);
recalc(); recalc();
@ -126,7 +126,7 @@ void RomListWidget::setList(const CartDebug::DisassemblyList& list,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomListWidget::setHighlighted(int item) void RomListWidget::setHighlighted(int item)
{ {
if(item < -1 || item >= (int)myList->size()) if(item < -1 || item >= (int)myDisasm->list.size())
return; return;
if(isEnabled()) if(isEnabled())
@ -149,7 +149,7 @@ void RomListWidget::setHighlighted(int item)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string& RomListWidget::getEditString() const const string& RomListWidget::getEditString() const
{ {
if(_selectedItem < -1 || _selectedItem >= (int)myList->size()) if(_selectedItem < -1 || _selectedItem >= (int)myDisasm->list.size())
return EmptyString; return EmptyString;
else else
return _editString; return _editString;
@ -164,7 +164,7 @@ int RomListWidget::findItem(int x, int y) const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomListWidget::recalc() void RomListWidget::recalc()
{ {
int size = myList->size(); int size = myDisasm->list.size();
if (_currentPos >= size) if (_currentPos >= size)
_currentPos = size - 1; _currentPos = size - 1;
@ -176,7 +176,7 @@ void RomListWidget::recalc()
_editMode = false; _editMode = false;
myScrollBar->_numEntries = myList->size(); myScrollBar->_numEntries = myDisasm->list.size();
myScrollBar->_entriesPerPage = _rows; myScrollBar->_entriesPerPage = _rows;
// Reset to normal data entry // Reset to normal data entry
@ -198,10 +198,10 @@ void RomListWidget::scrollToCurrent(int item)
_currentPos = item - _rows + 1; _currentPos = item - _rows + 1;
} }
if (_currentPos < 0 || _rows > (int)myList->size()) if (_currentPos < 0 || _rows > (int)myDisasm->list.size())
_currentPos = 0; _currentPos = 0;
else if (_currentPos + _rows > (int)myList->size()) else if (_currentPos + _rows > (int)myDisasm->list.size())
_currentPos = myList->size() - _rows; _currentPos = myDisasm->list.size() - _rows;
myScrollBar->_currentPos = _currentPos; myScrollBar->_currentPos = _currentPos;
myScrollBar->recalc(); myScrollBar->recalc();
@ -228,7 +228,7 @@ void RomListWidget::handleMouseDown(int x, int y, int button, int clickCount)
// First check whether the selection changed // First check whether the selection changed
int newSelectedItem; int newSelectedItem;
newSelectedItem = findItem(x, y); newSelectedItem = findItem(x, y);
if (newSelectedItem > (int)myList->size() - 1) if (newSelectedItem > (int)myDisasm->list.size() - 1)
newSelectedItem = -1; newSelectedItem = -1;
if (_selectedItem != newSelectedItem) if (_selectedItem != newSelectedItem)
@ -337,7 +337,7 @@ bool RomListWidget::handleEvent(Event::Type e)
break; break;
case Event::UIDown: case Event::UIDown:
if (_selectedItem < (int)myList->size() - 1) if (_selectedItem < (int)myDisasm->list.size() - 1)
_selectedItem++; _selectedItem++;
break; break;
@ -349,8 +349,8 @@ bool RomListWidget::handleEvent(Event::Type e)
case Event::UIPgDown: case Event::UIPgDown:
_selectedItem += _rows - 1; _selectedItem += _rows - 1;
if (_selectedItem >= (int)myList->size() ) if (_selectedItem >= (int)myDisasm->list.size())
_selectedItem = myList->size() - 1; _selectedItem = myDisasm->list.size() - 1;
break; break;
case Event::UIHome: case Event::UIHome:
@ -358,7 +358,7 @@ bool RomListWidget::handleEvent(Event::Type e)
break; break;
case Event::UIEnd: case Event::UIEnd:
_selectedItem = myList->size() - 1; _selectedItem = myDisasm->list.size() - 1;
break; break;
default: default:
@ -409,7 +409,7 @@ void RomListWidget::drawWidget(bool hilite)
{ {
//cerr << "RomListWidget::drawWidget\n"; //cerr << "RomListWidget::drawWidget\n";
FBSurface& s = _boss->dialog().surface(); 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 i, pos, xpos, ypos, len = dlist.size();
int deltax; int deltax;
@ -423,8 +423,13 @@ void RomListWidget::drawWidget(bool hilite)
s.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor); s.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor);
// Draw the list items // Draw the list items
int large_disasmw = _w - l.x() - _labelWidth, int ccountw = _fontWidth << 1,
small_disasmw = large_disasmw - r.width() - 4 * _fontWidth; 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; xpos = _x + CheckboxWidget::boxSize() + 10; ypos = _y + 2;
for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++, ypos += _fontHeight) 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 // Draw highlighted item in a frame
if (_highlightedItem == pos) if (_highlightedItem == pos)
{ s.frameRect(_x + l.x() - 3, ypos - 1, _w - l.x(), _fontHeight, kDbgColorHi);
s.frameRect(_x + l.x() - 3, _y + 1 + _fontHeight * i,
_w - l.x(), _fontHeight, kDbgColorHi);
}
// Draw the selected item inverted, on a highlighted background. // Draw the selected item inverted, on a highlighted background.
if (_selectedItem == pos && _hasFocus) if (_selectedItem == pos && _hasFocus)
{ {
if (!_editMode) if (!_editMode)
s.fillRect(_x + r.x() - 3, _y + 1 + _fontHeight * i, s.fillRect(_x + r.x() - 3, ypos - 1, r.width(), _fontHeight, kTextColorHi);
r.width(), _fontHeight, kTextColorHi);
else else
s.frameRect(_x + r.x() - 3, _y + 1 + _fontHeight * i, s.frameRect(_x + r.x() - 3, ypos - 1, r.width(), _fontHeight, kTextColorHi);
r.width(), _fontHeight, kTextColorHi);
} }
// Draw labels // Draw labels
@ -463,7 +463,7 @@ void RomListWidget::drawWidget(bool hilite)
s.drawString(_font, dlist[pos].disasm, xpos + _labelWidth, ypos, s.drawString(_font, dlist[pos].disasm, xpos + _labelWidth, ypos,
small_disasmw, kTextColor); small_disasmw, kTextColor);
s.drawString(_font, dlist[pos].ccount, xpos + _labelWidth + small_disasmw, ypos, s.drawString(_font, dlist[pos].ccount, xpos + _labelWidth + small_disasmw, ypos,
2*_fontWidth, kTextColor); ccountw, kTextColor);
// Draw separator // Draw separator
s.vLine(_x + r.x() - 7, ypos, ypos + _fontHeight - 1, kColor); s.vLine(_x + r.x() - 7, ypos, ypos + _fontHeight - 1, kColor);
@ -544,14 +544,14 @@ void RomListWidget::startEditMode()
if (_editable && !_editMode && _selectedItem >= 0) if (_editable && !_editMode && _selectedItem >= 0)
{ {
// Does this line represent an editable area? // Does this line represent an editable area?
if((*myList)[_selectedItem].bytes == "") if(myDisasm->list[_selectedItem].bytes == "")
return; return;
_editMode = true; _editMode = true;
// Widget gets raw data while editing // Widget gets raw data while editing
EditableWidget::startEditMode(); EditableWidget::startEditMode();
setEditString((*myList)[_selectedItem].bytes); setEditString(myDisasm->list[_selectedItem].bytes);
} }
} }

View File

@ -49,7 +49,7 @@ class RomListWidget : public EditableWidget
int x, int y, int w, int h); int x, int y, int w, int h);
virtual ~RomListWidget(); 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 getSelected() const { return _selectedItem; }
int getHighlighted() const { return _highlightedItem; } int getHighlighted() const { return _highlightedItem; }
@ -99,7 +99,7 @@ class RomListWidget : public EditableWidget
int _currentKeyDown; int _currentKeyDown;
bool _editMode; bool _editMode;
const CartDebug::DisassemblyList* myList; const CartDebug::Disassembly* myDisasm;
const PackedBitArray* myBPState; const PackedBitArray* myBPState;
Common::Array<CheckboxWidget*> myCheckList; Common::Array<CheckboxWidget*> myCheckList;
}; };

View File

@ -124,7 +124,7 @@ void RomWidget::loadConfig()
myListIsDirty |= cart.disassemble(myResolveData->getSelectedTag(), myListIsDirty); myListIsDirty |= cart.disassemble(myResolveData->getSelectedTag(), myListIsDirty);
if(myListIsDirty) if(myListIsDirty)
{ {
myRomList->setList(cart.disassemblyList(), dbg.breakpoints()); myRomList->setList(cart.disassembly(), dbg.breakpoints());
myListIsDirty = false; 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) void RomWidget::setBreak(int disasm_line, bool state)
{ {
const CartDebug::DisassemblyList& list = const CartDebug::DisassemblyList& list =
instance().debugger().cartDebug().disassemblyList(); instance().debugger().cartDebug().disassembly().list;
if(disasm_line >= (int)list.size()) return; if(disasm_line >= (int)list.size()) return;
if(list[disasm_line].address != 0 && list[disasm_line].bytes != "") 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) void RomWidget::setPC(int disasm_line)
{ {
const CartDebug::DisassemblyList& list = const CartDebug::DisassemblyList& list =
instance().debugger().cartDebug().disassemblyList(); instance().debugger().cartDebug().disassembly().list;
if(disasm_line >= (int)list.size()) return; if(disasm_line >= (int)list.size()) return;
if(list[disasm_line].address != 0) if(list[disasm_line].address != 0)
@ -228,7 +228,7 @@ void RomWidget::setPC(int disasm_line)
void RomWidget::runtoPC(int disasm_line) void RomWidget::runtoPC(int disasm_line)
{ {
const CartDebug::DisassemblyList& list = const CartDebug::DisassemblyList& list =
instance().debugger().cartDebug().disassemblyList(); instance().debugger().cartDebug().disassembly().list;
if(disasm_line >= (int)list.size()) return; if(disasm_line >= (int)list.size()) return;
if(list[disasm_line].address != 0) 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) void RomWidget::patchROM(int disasm_line, const string& bytes)
{ {
const CartDebug::DisassemblyList& list = const CartDebug::DisassemblyList& list =
instance().debugger().cartDebug().disassemblyList(); instance().debugger().cartDebug().disassembly().list;
if(disasm_line >= (int)list.size()) return; if(disasm_line >= (int)list.size()) return;
if(list[disasm_line].address != 0) if(list[disasm_line].address != 0)