From bea8ac0ffd107a7dd211bb7bb253efdf52675c55 Mon Sep 17 00:00:00 2001 From: stephena Date: Sat, 23 Oct 2010 20:57:31 +0000 Subject: [PATCH] Properly implemented an hierarchy wrt marking an address in the disassembly in a consistent way. Directives set manually have top priority, then the results from a dynamic analysis (aka, from actually running the code), and finally from a static analysis (aka, Distella itself). Sometimes Distella will mark a section as CODE even if it hasn't been marked as such dynamically. This occurs after a relative branch, which Distella has no idea how to evaluate. It's possible that the code will be executed eventually, but also that it will never be executed. As such, these lines are marked with a '*', indicating that disassembly results are tentative. If you get weird looking disassembly for these addresses, it's probably a hint that it isn't really code at all. PC addresses in the disassembly labels are now aligned with labels, and shown in a lighter color. These can still be toggled on and off. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2162 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- src/debugger/CartDebug.hxx | 1 + src/debugger/DiStella.cxx | 52 +++++++++++++++++++----------- src/debugger/DiStella.hxx | 9 ++++-- src/debugger/gui/RomListWidget.cxx | 7 ++-- src/emucore/Cart.cxx | 2 +- 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/debugger/CartDebug.hxx b/src/debugger/CartDebug.hxx index 1e11156fd..712b3cee7 100644 --- a/src/debugger/CartDebug.hxx +++ b/src/debugger/CartDebug.hxx @@ -79,6 +79,7 @@ class CartDebug : public DebuggerSystem string disasm; string ccount; string bytes; + bool hllabel; }; typedef Common::Array DisassemblyList; typedef struct { diff --git a/src/debugger/DiStella.cxx b/src/debugger/DiStella.cxx index e41228373..3e559a972 100644 --- a/src/debugger/DiStella.cxx +++ b/src/debugger/DiStella.cxx @@ -83,6 +83,7 @@ DiStella::DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list, info.offset = myOffset; memset(labels, 0, 0x1000); + memset(directives, 0, 0x1000); myAddressQueue.push(start); // Process any directives first, as they override automatic code determination @@ -126,7 +127,7 @@ DiStella::DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list, uInt16 addr = *it; if(!check_bit(addr-myOffset, CartDebug::CODE)) { -cerr << "(list) marking " << HEX4 << addr << " as CODE\n"; +//cerr << "(list) marking " << HEX4 << addr << " as CODE\n"; myAddressQueue.push(addr); ++it; break; @@ -142,7 +143,7 @@ cerr << "(list) marking " << HEX4 << addr << " as CODE\n"; if((Debugger::debugger().getAddressDisasmType(codeAccessPoint+myOffset) & CartDebug::CODE) && !(labels[codeAccessPoint & myAppData.end] & CartDebug::CODE)) { -cerr << "(emul) marking " << HEX4 << (codeAccessPoint+myOffset) << " as CODE\n"; +//cerr << "(emul) marking " << HEX4 << (codeAccessPoint+myOffset) << " as CODE\n"; myAddressQueue.push(codeAccessPoint+myOffset); ++codeAccessPoint; break; @@ -729,7 +730,7 @@ void DiStella::disasm(uInt32 distart, int pass) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int DiStella::mark(uInt32 address, uInt8 mask) +int DiStella::mark(uInt32 address, uInt8 mask, bool directive) { /*----------------------------------------------------------------------- For any given offset and code range... @@ -780,8 +781,8 @@ int DiStella::mark(uInt32 address, uInt8 mask) if (address >= myOffset && address <= myAppData.end + myOffset) { -// Debugger::debugger().setAddressDisasmType(address | myOffset, mask); labels[address-myOffset] = labels[address-myOffset] | mask; + if(directive) directives[address-myOffset] = mask; return 1; } else if (address >= 0 && address <= 0x3f) @@ -795,8 +796,8 @@ int DiStella::mark(uInt32 address, uInt8 mask) else if (address > 0x1000) { /* 2K & 4K case */ -// Debugger::debugger().setAddressDisasmType(address | myOffset, mask); labels[address & myAppData.end] = labels[address & myAppData.end] | mask; + if(directive) directives[address & myAppData.end] = mask; return 4; } else @@ -806,10 +807,24 @@ int DiStella::mark(uInt32 address, uInt8 mask) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool DiStella::check_bit(uInt16 address, uInt8 mask) const { - if(Debugger::debugger().getAddressDisasmType(address | myOffset) & mask) + // The REFERENCED and VALID_ENTRY flags are needed for any inspection of + // an address + // Since they're set only in the labels array (as the lower two bits), + // they must be included in the other bitfields + uInt8 label = labels[address & myAppData.end], + lastbits = label & 0x03, + directive = directives[address & myAppData.end] & 0xFC, + debugger = Debugger::debugger().getAddressDisasmType(address | myOffset) & 0xFC; + + // Any address marked by a manual directive always takes priority + if(directive) + return (directive | lastbits) & mask; + // Next, the results from a dynamic/runtime analysis are used + else if((debugger | lastbits) & mask) return true; + // Otherwise, default to static analysis from Distella else - return labels[address & myAppData.end] & mask; + return label & mask; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -860,6 +875,7 @@ void DiStella::addEntry(CartDebug::DisasmType type) if(tag.address) { tag.label = myDbg.getLabel(tag.address, true); + tag.hllabel = true; if(tag.label == EmptyString) { if(myDisasmBuf.peek() != ' ') @@ -868,8 +884,9 @@ void DiStella::addEntry(CartDebug::DisasmType type) { // Have addresses indented, to differentiate from actual labels char address[8]; - sprintf(address, " $%X", tag.address); + sprintf(address, " %X", tag.address); tag.label = address; + tag.hllabel = false; } } } @@ -887,6 +904,14 @@ void DiStella::addEntry(CartDebug::DisasmType type) getline(myDisasmBuf, tag.disasm, '\''); getline(myDisasmBuf, tag.ccount, '\''); getline(myDisasmBuf, tag.bytes); + + // Make note of when we override CODE sections from the debugger + // It could mean that the code hasn't been accessed up to this point, + // but it could also indicate that code will *never* be accessed + // Since it is impossible to tell the difference, marking the address + // in the disassembly at least tells the user about it + if(!(Debugger::debugger().getAddressDisasmType(tag.address) & CartDebug::CODE)) + tag.ccount += " *"; break; case CartDebug::GFX: case CartDebug::PGFX: @@ -909,15 +934,6 @@ void DiStella::addEntry(CartDebug::DisasmType type) DONE_WITH_ADD: myDisasmBuf.clear(); myDisasmBuf.str(""); - -#if 0 - // debugging output - cerr << (tag.type == CartDebug::CODE ? "CartDebug::CODE" : (tag.type == CartDebug::ROW ? "CartDebug::ROW" : - (tag.type == CartDebug::GFX ? "CartDebug::GFX " : "NONE"))) << "|" - << hex << setw(4) << setfill('0') << tag.address << "|" - << tag.label << "|" << tag.disasm << "|" << tag.ccount << "|" << "|" - << tag.bytes << endl; -#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -929,7 +945,7 @@ void DiStella::processDirectives(const CartDebug::DirectiveList& directives) const CartDebug::DirectiveTag tag = *i; if(check_range(tag.start, tag.end)) for(uInt32 k = tag.start; k <= tag.end; ++k) - mark(k, tag.type); + mark(k, tag.type, true); } } diff --git a/src/debugger/DiStella.hxx b/src/debugger/DiStella.hxx index 42cea1c57..7e064cbe6 100644 --- a/src/debugger/DiStella.hxx +++ b/src/debugger/DiStella.hxx @@ -84,7 +84,7 @@ class DiStella // These functions are part of the original Distella code void disasm(uInt32 distart, int pass); bool check_range(uInt16 start, uInt16 end) const; - int mark(uInt32 address, uInt8 mask); + int mark(uInt32 address, uInt8 mask, bool directive = false); bool check_bit(uInt16 address, uInt8 mask) const; private: @@ -100,8 +100,11 @@ class DiStella uInt16 length; } myAppData; - /* Stores info on how each address is marked */ - uInt8 labels[0x1000]; + /* Stores info on how each address is marked, both in the general + case as well as when manual directives are enabled (in which case + the directives take priority + The address mark type is defined in CartDebug.hxx */ + uInt8 labels[0x1000], directives[0x1000]; /** Enumeration of the 6502 addressing modes diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 2d0d3c390..a8157286d 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -446,7 +446,7 @@ void RomListWidget::drawWidget(bool hilite) s.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor); // Draw the list items - int ccountw = _fontWidth << 1, + int ccountw = _fontWidth << 2, large_disasmw = _w - l.x() - _labelWidth, medium_disasmw = large_disasmw - r.width(), small_disasmw = medium_disasmw - (ccountw << 1), @@ -476,11 +476,12 @@ void RomListWidget::drawWidget(bool hilite) } // Draw labels - s.drawString(_font, dlist[pos].label, xpos, ypos, _labelWidth, kTextColor); + s.drawString(_font, dlist[pos].label, xpos, ypos, _labelWidth, + dlist[pos].hllabel ? kTextColor : kColor); // Bytes are only editable if they represent code, graphics, or accessible data // Otherwise, the disassembly should get all remaining space - if(dlist[pos].type & (CartDebug::CODE | CartDebug::GFX | CartDebug::DATA)) + if(dlist[pos].type & (CartDebug::CODE|CartDebug::GFX|CartDebug::PGFX|CartDebug::DATA)) { if(dlist[pos].type == CartDebug::CODE) { diff --git a/src/emucore/Cart.cxx b/src/emucore/Cart.cxx index 7613a4c7d..ef48275ce 100644 --- a/src/emucore/Cart.cxx +++ b/src/emucore/Cart.cxx @@ -302,7 +302,7 @@ void Cartridge::createCodeAccessBase(uInt32 size) { #ifdef DEBUGGER_SUPPORT myCodeAccessBase = new uInt8[size]; - memset(myCodeAccessBase, 0, size); + memset(myCodeAccessBase, CartDebug::ROW, size); #else myCodeAccessBase = NULL; #endif