From 8ca34a4d9073594a09b25ba8b4ba8bac52b06d0e Mon Sep 17 00:00:00 2001 From: stephena Date: Sun, 7 Feb 2010 21:23:26 +0000 Subject: [PATCH] Checking in WIP for DiStella integration. The disassembly is now shown in the RomListWidget instead of being printed to the terminal. There are still graphical glitches with this, but for a first pass, it's nice to see actual Distella output in Stella. Partially working 'disasm' command from the PromptWidget. Currently, it only disassembles cart address space (aka, 0x1000 or above). Removed the old disassembly code from CartDebug. Still TODO is fix the label stuff, both in getting DiStella to use it, and adding/removing labels. This is greatly reduced now that we only have to worry about user labels. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1934 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- src/debugger/CartDebug.cxx | 610 +++-------------------------- src/debugger/CartDebug.hxx | 87 ++-- src/debugger/DiStella.cxx | 57 ++- src/debugger/DiStella.hxx | 12 +- src/debugger/gui/RomListWidget.cxx | 18 +- src/debugger/gui/RomListWidget.hxx | 7 +- src/debugger/gui/RomWidget.cxx | 112 +++--- src/debugger/gui/RomWidget.hxx | 15 +- 8 files changed, 183 insertions(+), 735 deletions(-) diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx index 6b45044ae..5b306f78c 100644 --- a/src/debugger/CartDebug.cxx +++ b/src/debugger/CartDebug.cxx @@ -169,177 +169,74 @@ string CartDebug::toString() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const string& CartDebug::disassemble(int start, int lines) +bool CartDebug::disassemble(bool autocode) { - static string result= ""; - ostringstream buffer; - string cpubuf; + bool changed = false; - if(start < 0x80 || start > 0xffff) - return result; + // Test current disassembly; don't re-disassemble if it hasn't changed + // ... + changed = true; // FIXME - do { - buffer << getLabel(start, true, 4) << ": "; - - int count = disassemble(start, cpubuf); - for(int i = 0; i < count; i++) - buffer << hex << setw(2) << setfill('0') << myDebugger.peek(start++) << " " << dec; - - if(count < 3) buffer << " "; - if(count < 2) buffer << " "; - - buffer << " " << cpubuf << "\n"; - } while(--lines > 0 && start <= 0xffff); - - result = buffer.str(); - return result; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartDebug::disassemble(IntArray& addr, StringList& addrLabel, - StringList& bytes, StringList& data, - int start, int end) -{ - if(start < 0x80 || end > 0xffff) - return; - - string cpubuf, tmp; - char buf[255]; - - do { - addr.push_back(start); - addrLabel.push_back(getLabel(start, true, 4) + ":"); - - cpubuf = ""; - int count = disassemble(start, cpubuf); - - tmp = ""; - for(int i = 0; i < count; i++) - { - sprintf(buf, "%02x ", myDebugger.peek(start++)); - tmp += buf; - } - bytes.push_back(tmp); - - data.push_back(cpubuf); - } - while(start <= end); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartDebug::disassemble(DisassemblyList& list, uInt16 start, bool autocode) -{ - DiStella distella; - distella.disassemble(list, start, autocode); - - // TODO - look at list, extract address to label mappings -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int CartDebug::disassemble(int address, string& result) -{ - ostringstream buf; - int count = 0; - int opcode = mySystem.peek(address); - - // Are we looking at a read or write operation? - // It will determine what type of label to use - bool isRead = (CartDebug::AccessModeTable[opcode] == CartDebug::Read); - - switch(CartDebug::AddressModeTable[opcode]) + if(changed) { - case CartDebug::Absolute: - buf << CartDebug::InstructionMnemonicTable[opcode] << " " - << getLabel(myDebugger.dpeek(address + 1), isRead, 4) << " ; " - << M6502::ourInstructionCycleTable[opcode]; - count = 3; - break; + myDisassembly.clear(); + myAddrToLineList.clear(); - case CartDebug::AbsoluteX: - buf << CartDebug::InstructionMnemonicTable[opcode] << " " - << getLabel(myDebugger.dpeek(address + 1), isRead, 4) << ",x ; " - << M6502::ourInstructionCycleTable[opcode]; - count = 3; - break; + // TODO - add logic to determine correct start address to use + // it will depend on the current bank and PC + uInt16 start = myDebugger.dpeek(0xfffc); - case CartDebug::AbsoluteY: - buf << CartDebug::InstructionMnemonicTable[opcode] << " " - << getLabel(myDebugger.dpeek(address + 1), isRead, 4) << ",y ; " - << M6502::ourInstructionCycleTable[opcode]; - count = 3; - break; + DiStella distella(myDisassembly, start, autocode); - case CartDebug::Immediate: - buf << CartDebug::InstructionMnemonicTable[opcode] << " #$" - << hex << setw(2) << setfill('0') << (int) mySystem.peek(address + 1) << " ; " - << dec << M6502::ourInstructionCycleTable[opcode]; - count = 2; - break; + // Parts of the disassembly will be accessed later in different ways + // We place those parts in separate maps, to speed up access + for(uInt32 i = 0; i < myDisassembly.size(); ++i) + { + const DisassemblyTag& tag = myDisassembly[i]; - case CartDebug::Implied: - buf << CartDebug::InstructionMnemonicTable[opcode] << " ; " - << M6502::ourInstructionCycleTable[opcode]; - count = 1; - break; + // Create a mapping from addresses to line numbers + if(tag.address != 0) + myAddrToLineList.insert(make_pair(tag.address, i)); - case CartDebug::Indirect: - buf << CartDebug::InstructionMnemonicTable[opcode] << " (" - << getLabel(myDebugger.dpeek(address + 1), isRead, 4) << ") ; " - << M6502::ourInstructionCycleTable[opcode]; - count = 3; - break; - - case CartDebug::IndirectX: - buf << CartDebug::InstructionMnemonicTable[opcode] << " (" - << getLabel(mySystem.peek(address + 1), isRead, 2) << ",x) ; " - << M6502::ourInstructionCycleTable[opcode]; - count = 2; - break; - - case CartDebug::IndirectY: - buf << CartDebug::InstructionMnemonicTable[opcode] << " (" - << getLabel(mySystem.peek(address + 1), isRead, 2) << "),y ; " - << M6502::ourInstructionCycleTable[opcode]; - count = 2; - break; - - case CartDebug::Relative: - buf << CartDebug::InstructionMnemonicTable[opcode] << " " - << getLabel(address + 2 + ((Int16)(Int8)mySystem.peek(address + 1)), isRead, 4) - << " ; " << M6502::ourInstructionCycleTable[opcode]; - count = 2; - break; - - case CartDebug::Zero: - buf << CartDebug::InstructionMnemonicTable[opcode] << " " - << getLabel(mySystem.peek(address + 1), isRead, 2) << " ; " - << M6502::ourInstructionCycleTable[opcode]; - count = 2; - break; - - case CartDebug::ZeroX: - buf << CartDebug::InstructionMnemonicTable[opcode] << " " - << getLabel(mySystem.peek(address + 1), isRead, 2) << ",x ; " - << M6502::ourInstructionCycleTable[opcode]; - count = 2; - break; - - case CartDebug::ZeroY: - buf << CartDebug::InstructionMnemonicTable[opcode] << " " - << getLabel(mySystem.peek(address + 1), isRead, 2) << ",y ; " - << M6502::ourInstructionCycleTable[opcode]; - count = 2; - break; - - default: - buf << "dc $" << hex << setw(2) << setfill('0') << (int) opcode << " ; " - << dec << M6502::ourInstructionCycleTable[opcode]; - count = 1; - break; + // TODO - look at list, extract address to label mappings + // we need these for label support in the UI and promptwidget + } } - result = buf.str(); - return count; + return changed; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int CartDebug::addressToLine(uInt16 address) const +{ + map::const_iterator iter = myAddrToLineList.find(address); + return iter != myAddrToLineList.end() ? iter->second : 0; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartDebug::disassemble(uInt16 start, uInt16 lines) const +{ + if(!(start & 0x1000)) + return "Disassembly below 0x1000 not yet supported"; + + DisassemblyList list; + DiStella distella(list, start, false); + + // Fill the string with disassembled data + start &= 0xFFF; + ostringstream buffer; + for(uInt32 i = 0; i < list.size() && lines > 0; ++i) + { + const CartDebug::DisassemblyTag& tag = list[i]; + if((tag.address & 0xfff) >= start) + { + buffer << uppercase << hex << setw(4) << setfill('0') << tag.address + << ": " << tag.disasm << " " << tag.bytes << endl; + --lines; + } + } + + return buffer.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -677,396 +574,3 @@ int CartDebug::extractValue(char *c) const } return ret; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const CartDebug::Equate CartDebug::ourSystemEquates[kSystemEquateSize] = { -// Standard $00-based TIA write locations: - { "VSYNC", 0x00, EQF_WRITE }, - { "VBLANK", 0x01, EQF_WRITE }, - { "WSYNC", 0x02, EQF_WRITE }, - { "RSYNC", 0x03, EQF_WRITE }, - { "NUSIZ0", 0x04, EQF_WRITE }, - { "NUSIZ1", 0x05, EQF_WRITE }, - { "COLUP0", 0x06, EQF_WRITE }, - { "COLUP1", 0x07, EQF_WRITE }, - { "COLUPF", 0x08, EQF_WRITE }, - { "COLUBK", 0x09, EQF_WRITE }, - { "CTRLPF", 0x0A, EQF_WRITE }, - { "REFP0", 0x0B, EQF_WRITE }, - { "REFP1", 0x0C, EQF_WRITE }, - { "PF0", 0x0D, EQF_WRITE }, - { "PF1", 0x0E, EQF_WRITE }, - { "PF2", 0x0F, EQF_WRITE }, - { "RESP0", 0x10, EQF_WRITE }, - { "RESP1", 0x11, EQF_WRITE }, - { "RESM0", 0x12, EQF_WRITE }, - { "RESM1", 0x13, EQF_WRITE }, - { "RESBL", 0x14, EQF_WRITE }, - { "AUDC0", 0x15, EQF_WRITE }, - { "AUDC1", 0x16, EQF_WRITE }, - { "AUDF0", 0x17, EQF_WRITE }, - { "AUDF1", 0x18, EQF_WRITE }, - { "AUDV0", 0x19, EQF_WRITE }, - { "AUDV1", 0x1A, EQF_WRITE }, - { "GRP0", 0x1B, EQF_WRITE }, - { "GRP1", 0x1C, EQF_WRITE }, - { "ENAM0", 0x1D, EQF_WRITE }, - { "ENAM1", 0x1E, EQF_WRITE }, - { "ENABL", 0x1F, EQF_WRITE }, - { "HMP0", 0x20, EQF_WRITE }, - { "HMP1", 0x21, EQF_WRITE }, - { "HMM0", 0x22, EQF_WRITE }, - { "HMM1", 0x23, EQF_WRITE }, - { "HMBL", 0x24, EQF_WRITE }, - { "VDELP0", 0x25, EQF_WRITE }, - { "VDEL01", 0x26, EQF_WRITE }, - { "VDELP1", 0x26, EQF_WRITE }, - { "VDELBL", 0x27, EQF_WRITE }, - { "RESMP0", 0x28, EQF_WRITE }, - { "RESMP1", 0x29, EQF_WRITE }, - { "HMOVE", 0x2A, EQF_WRITE }, - { "HMCLR", 0x2B, EQF_WRITE }, - { "CXCLR", 0x2C, EQF_WRITE }, - -// Mirrored $40-based TIA write locations: - { "VSYNC.40", 0x40, EQF_WRITE }, - { "VBLANK.40", 0x41, EQF_WRITE }, - { "WSYNC.40", 0x42, EQF_WRITE }, - { "RSYNC.40", 0x43, EQF_WRITE }, - { "NUSIZ0.40", 0x44, EQF_WRITE }, - { "NUSIZ1.40", 0x45, EQF_WRITE }, - { "COLUP0.40", 0x46, EQF_WRITE }, - { "COLUP1.40", 0x47, EQF_WRITE }, - { "COLUPF.40", 0x48, EQF_WRITE }, - { "COLUBK.40", 0x49, EQF_WRITE }, - { "CTRLPF.40", 0x4A, EQF_WRITE }, - { "REFP0.40", 0x4B, EQF_WRITE }, - { "REFP1.40", 0x4C, EQF_WRITE }, - { "PF0.40", 0x4D, EQF_WRITE }, - { "PF1.40", 0x4E, EQF_WRITE }, - { "PF2.40", 0x4F, EQF_WRITE }, - { "RESP0.40", 0x50, EQF_WRITE }, - { "RESP1.40", 0x51, EQF_WRITE }, - { "RESM0.40", 0x52, EQF_WRITE }, - { "RESM1.40", 0x53, EQF_WRITE }, - { "RESBL.40", 0x54, EQF_WRITE }, - { "AUDC0.40", 0x55, EQF_WRITE }, - { "AUDC1.40", 0x56, EQF_WRITE }, - { "AUDF0.40", 0x57, EQF_WRITE }, - { "AUDF1.40", 0x58, EQF_WRITE }, - { "AUDV0.40", 0x59, EQF_WRITE }, - { "AUDV1.40", 0x5A, EQF_WRITE }, - { "GRP0.40", 0x5B, EQF_WRITE }, - { "GRP1.40", 0x5C, EQF_WRITE }, - { "ENAM0.40", 0x5D, EQF_WRITE }, - { "ENAM1.40", 0x5E, EQF_WRITE }, - { "ENABL.40", 0x5F, EQF_WRITE }, - { "HMP0.40", 0x60, EQF_WRITE }, - { "HMP1.40", 0x61, EQF_WRITE }, - { "HMM0.40", 0x62, EQF_WRITE }, - { "HMM1.40", 0x63, EQF_WRITE }, - { "HMBL.40", 0x64, EQF_WRITE }, - { "VDELP0.40", 0x65, EQF_WRITE }, - { "VDEL01.40", 0x66, EQF_WRITE }, - { "VDELP1.40", 0x66, EQF_WRITE }, - { "VDELBL.40", 0x67, EQF_WRITE }, - { "RESMP0.40", 0x68, EQF_WRITE }, - { "RESMP1.40", 0x69, EQF_WRITE }, - { "HMOVE.40", 0x6A, EQF_WRITE }, - { "HMCLR.40", 0x6B, EQF_WRITE }, - { "CXCLR.40", 0x6C, EQF_WRITE }, - -// Standard $00-based TIA read locations: - { "CXM0P", 0x00, EQF_READ }, - { "CXM1P", 0x01, EQF_READ }, - { "CXP0FB", 0x02, EQF_READ }, - { "CXP1FB", 0x03, EQF_READ }, - { "CXM0FB", 0x04, EQF_READ }, - { "CXM1FB", 0x05, EQF_READ }, - { "CXBLPF", 0x06, EQF_READ }, - { "CXPPMM", 0x07, EQF_READ }, - { "INPT0", 0x08, EQF_READ }, - { "INPT1", 0x09, EQF_READ }, - { "INPT2", 0x0A, EQF_READ }, - { "INPT3", 0x0B, EQF_READ }, - { "INPT4", 0x0C, EQF_READ }, - { "INPT5", 0x0D, EQF_READ }, - -// Mirrored $10-based TIA read locations: - { "CXM0P.10", 0x10, EQF_READ }, - { "CXM1P.10", 0x11, EQF_READ }, - { "CXP0FB.10", 0x12, EQF_READ }, - { "CXP1FB.10", 0x13, EQF_READ }, - { "CXM0FB.10", 0x14, EQF_READ }, - { "CXM1FB.10", 0x15, EQF_READ }, - { "CXBLPF.10", 0x16, EQF_READ }, - { "CXPPMM.10", 0x17, EQF_READ }, - { "INPT0.10", 0x18, EQF_READ }, - { "INPT1.10", 0x19, EQF_READ }, - { "INPT2.10", 0x1A, EQF_READ }, - { "INPT3.10", 0x1B, EQF_READ }, - { "INPT4.10", 0x1C, EQF_READ }, - { "INPT5.10", 0x1D, EQF_READ }, - -// Mirrored $20-based TIA read locations: - { "CXM0P.20", 0x20, EQF_READ }, - { "CXM1P.20", 0x21, EQF_READ }, - { "CXP0FB.20", 0x22, EQF_READ }, - { "CXP1FB.20", 0x23, EQF_READ }, - { "CXM0FB.20", 0x24, EQF_READ }, - { "CXM1FB.20", 0x25, EQF_READ }, - { "CXBLPF.20", 0x26, EQF_READ }, - { "CXPPMM.20", 0x27, EQF_READ }, - { "INPT0.20", 0x28, EQF_READ }, - { "INPT1.20", 0x29, EQF_READ }, - { "INPT2.20", 0x2A, EQF_READ }, - { "INPT3.20", 0x2B, EQF_READ }, - { "INPT4.20", 0x2C, EQF_READ }, - { "INPT5.20", 0x2D, EQF_READ }, - -// Mirrored $30-based TIA read locations: - { "CXM0P.30", 0x30, EQF_READ }, - { "CXM1P.30", 0x31, EQF_READ }, - { "CXP0FB.30", 0x32, EQF_READ }, - { "CXP1FB.30", 0x33, EQF_READ }, - { "CXM0FB.30", 0x34, EQF_READ }, - { "CXM1FB.30", 0x35, EQF_READ }, - { "CXBLPF.30", 0x36, EQF_READ }, - { "CXPPMM.30", 0x37, EQF_READ }, - { "INPT0.30", 0x38, EQF_READ }, - { "INPT1.30", 0x39, EQF_READ }, - { "INPT2.30", 0x3A, EQF_READ }, - { "INPT3.30", 0x3B, EQF_READ }, - { "INPT4.30", 0x3C, EQF_READ }, - { "INPT5.30", 0x3D, EQF_READ }, - -// Standard RIOT locations (read, write, or both): - { "SWCHA", 0x280, EQF_RW }, - { "SWCHB", 0x282, EQF_RW }, - { "SWACNT", 0x281, EQF_WRITE }, - { "SWBCNT", 0x283, EQF_WRITE }, - { "INTIM", 0x284, EQF_READ }, - { "TIMINT", 0x285, EQF_READ }, - { "TIM1T", 0x294, EQF_WRITE }, - { "TIM8T", 0x295, EQF_WRITE }, - { "TIM64T", 0x296, EQF_WRITE }, - { "T1024T", 0x297, EQF_WRITE } -}; - -/////////////////////////////////////////////////////////////////// -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CartDebug::AddressingMode CartDebug::AddressModeTable[256] = { - Implied, IndirectX, Invalid, IndirectX, // 0x0? - Zero, Zero, Zero, Zero, - Implied, Immediate, Implied, Immediate, - Absolute, Absolute, Absolute, Absolute, - - Relative, IndirectY, Invalid, IndirectY, // 0x1? - ZeroX, ZeroX, ZeroX, ZeroX, - Implied, AbsoluteY, Implied, AbsoluteY, - AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, - - Absolute, IndirectX, Invalid, IndirectX, // 0x2? - Zero, Zero, Zero, Zero, - Implied, Immediate, Implied, Immediate, - Absolute, Absolute, Absolute, Absolute, - - Relative, IndirectY, Invalid, IndirectY, // 0x3? - ZeroX, ZeroX, ZeroX, ZeroX, - Implied, AbsoluteY, Implied, AbsoluteY, - AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, - - Implied, IndirectX, Invalid, IndirectX, // 0x4? - Zero, Zero, Zero, Zero, - Implied, Immediate, Implied, Immediate, - Absolute, Absolute, Absolute, Absolute, - - Relative, IndirectY, Invalid, IndirectY, // 0x5? - ZeroX, ZeroX, ZeroX, ZeroX, - Implied, AbsoluteY, Implied, AbsoluteY, - AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, - - Implied, IndirectX, Invalid, IndirectX, // 0x6? - Zero, Zero, Zero, Zero, - Implied, Immediate, Implied, Immediate, - Indirect, Absolute, Absolute, Absolute, - - Relative, IndirectY, Invalid, IndirectY, // 0x7? - ZeroX, ZeroX, ZeroX, ZeroX, - Implied, AbsoluteY, Implied, AbsoluteY, - AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, - - Immediate, IndirectX, Immediate, IndirectX, // 0x8? - Zero, Zero, Zero, Zero, - Implied, Immediate, Implied, Immediate, - Absolute, Absolute, Absolute, Absolute, - - Relative, IndirectY, Invalid, IndirectY, // 0x9? - ZeroX, ZeroX, ZeroY, ZeroY, - Implied, AbsoluteY, Implied, AbsoluteY, - AbsoluteX, AbsoluteX, AbsoluteY, AbsoluteY, - - Immediate, IndirectX, Immediate, IndirectX, // 0xA? - Zero, Zero, Zero, Zero, - Implied, Immediate, Implied, Immediate, - Absolute, Absolute, Absolute, Absolute, - - Relative, IndirectY, Invalid, IndirectY, // 0xB? - ZeroX, ZeroX, ZeroY, ZeroY, - Implied, AbsoluteY, Implied, AbsoluteY, - AbsoluteX, AbsoluteX, AbsoluteY, AbsoluteY, - - Immediate, IndirectX, Immediate, IndirectX, // 0xC? - Zero, Zero, Zero, Zero, - Implied, Immediate, Implied, Immediate, - Absolute, Absolute, Absolute, Absolute, - - Relative, IndirectY, Invalid, IndirectY, // 0xD? - ZeroX, ZeroX, ZeroX, ZeroX, - Implied, AbsoluteY, Implied, AbsoluteY, - AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, - - Immediate, IndirectX, Immediate, IndirectX, // 0xE? - Zero, Zero, Zero, Zero, - Implied, Immediate, Implied, Immediate, - Absolute, Absolute, Absolute, Absolute, - - Relative, IndirectY, Invalid, IndirectY, // 0xF? - ZeroX, ZeroX, ZeroX, ZeroX, - Implied, AbsoluteY, Implied, AbsoluteY, - AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX -}; - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CartDebug::AccessMode CartDebug::AccessModeTable[256] = { - None, Read, None, Write, // 0x0? - None, Read, Write, Write, - None, Read, Write, Read, - None, Read, Write, Write, - - Read, Read, None, Write, // 0x1? - None, Read, Write, Write, - None, Read, None, Write, - None, Read, Write, Write, - - Read, Read, None, Write, // 0x2? - Read, Read, Write, Write, - None, Read, Write, Read, - Read, Read, Write, Write, - - Read, Read, None, Write, // 0x3? - None, Read, Write, Write, - None, Read, None, Write, - None, Read, Write, Write, - - None, Read, None, Write, // 0x4? - None, Read, Write, Write, - None, Read, Write, Read, - Read, Read, Write, Write, - - Read, Read, None, Write, // 0x5? - None, Read, Write, Write, - None, Read, None, Write, - None, Read, Write, Write, - - None, Read, None, Write, // 0x6? - None, Read, Write, Write, - None, Read, Write, Read, - Read, Read, Write, Write, - - Read, Read, None, Write, // 0x7? - None, Read, Write, Write, - None, Read, None, Write, - None, Read, Write, Write, - - None, Write, None, Write, // 0x8? - Write, Write, Write, Write, - None, None, None, Read, - Write, Write, Write, Write, - - Read, Write, None, Write, // 0x9? - Write, Write, Write, Write, - None, Write, None, Write, - Write, Write, Write, Write, - - Read, Read, Read, Read, // 0xA? - Read, Read, Read, Read, - None, Read, None, Read, - Read, Read, Read, Read, - - Read, Read, None, Read, // 0xB? - Read, Read, Read, Read, - None, Read, None, Read, - Read, Read, Read, Read, - - Read, Read, None, Write, // 0xC? - Read, Read, Write, Write, - None, Read, None, Read, - Read, Read, Write, Write, - - Read, Read, None, Write, // 0xD? - None, Read, Write, Write, - None, Read, None, Write, - None, Read, Write, Write, - - Read, Read, None, Write, // 0xE? - Read, Read, Write, Write, - None, Read, None, Read, - Read, Read, Write, Write, - - Read, Read, None, Write, // 0xF? - None, Read, Write, Write, - None, Read, None, Write, - None, Read, Write, Write -}; - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const char* CartDebug::InstructionMnemonicTable[256] = { - "BRK", "ORA", "n/a", "slo", "nop", "ORA", "ASL", "slo", // 0x0? - "PHP", "ORA", "ASLA", "anc", "nop", "ORA", "ASL", "slo", - - "BPL", "ORA", "n/a", "slo", "nop", "ORA", "ASL", "slo", // 0x1? - "CLC", "ORA", "nop", "slo", "nop", "ORA", "ASL", "slo", - - "JSR", "AND", "n/a", "rla", "BIT", "AND", "ROL", "rla", // 0x2? - "PLP", "AND", "ROLA", "anc", "BIT", "AND", "ROL", "rla", - - "BMI", "AND", "n/a", "rla", "nop", "AND", "ROL", "rla", // 0x3? - "SEC", "AND", "nop", "rla", "nop", "AND", "ROL", "rla", - - "RTI", "EOR", "n/a", "sre", "nop", "EOR", "LSR", "sre", // 0x4? - "PHA", "EOR", "LSRA", "asr", "JMP", "EOR", "LSR", "sre", - - "BVC", "EOR", "n/a", "sre", "nop", "EOR", "LSR", "sre", // 0x5? - "CLI", "EOR", "nop", "sre", "nop", "EOR", "LSR", "sre", - - "RTS", "ADC", "n/a", "rra", "nop", "ADC", "ROR", "rra", // 0x6? - "PLA", "ADC", "RORA", "arr", "JMP", "ADC", "ROR", "rra", - - "BVS", "ADC", "n/a", "rra", "nop", "ADC", "ROR", "rra", // 0x7? - "SEI", "ADC", "nop", "rra", "nop", "ADC", "ROR", "rra", - - "nop", "STA", "nop", "sax", "STY", "STA", "STX", "sax", // 0x8? - "DEY", "nop", "TXA", "ane", "STY", "STA", "STX", "sax", - - "BCC", "STA", "n/a", "sha", "STY", "STA", "STX", "sax", // 0x9? - "TYA", "STA", "TXS", "shs", "shy", "STA", "shx", "sha", - - "LDY", "LDA", "LDX", "lax", "LDY", "LDA", "LDX", "lax", // 0xA? - "TAY", "LDA", "TAX", "lxa", "LDY", "LDA", "LDX", "lax", - - "BCS", "LDA", "n/a", "lax", "LDY", "LDA", "LDX", "lax", // 0xB? - "CLV", "LDA", "TSX", "las", "LDY", "LDA", "LDX", "lax", - - "CPY", "CMP", "nop", "dcp", "CPY", "CMP", "DEC", "dcp", // 0xC? - "INY", "CMP", "DEX", "sbx", "CPY", "CMP", "DEC", "dcp", - - "BNE", "CMP", "n/a", "dcp", "nop", "CMP", "DEC", "dcp", // 0xD? - "CLD", "CMP", "nop", "dcp", "nop", "CMP", "DEC", "dcp", - - "CPX", "SBC", "nop", "isb", "CPX", "SBC", "INC", "isb", // 0xE? - "INX", "SBC", "NOP", "sbc", "CPX", "SBC", "INC", "isb", - - "BEQ", "SBC", "n/a", "isb", "nop", "SBC", "INC", "isb", // 0xF? - "SED", "SBC", "nop", "isb", "nop", "SBC", "INC", "isb" -}; diff --git a/src/debugger/CartDebug.hxx b/src/debugger/CartDebug.hxx index db4234884..27f6b1a23 100644 --- a/src/debugger/CartDebug.hxx +++ b/src/debugger/CartDebug.hxx @@ -21,6 +21,8 @@ class System; +#include + #include "bspf.hxx" #include "Array.hxx" #include "Cart.hxx" @@ -83,32 +85,44 @@ class CartDebug : public DebuggerSystem */ void addRamArea(uInt16 start, uInt16 size, uInt16 roffset, uInt16 woffset); -//////////////////////////////////////// - /** - Disassemble from the starting address the specified number of lines - and place result in a string. - */ - const string& disassemble(int start, int lines); - - /** - Disassemble from the starting address to the ending address - and place addresses, bytes and data in given arrays. - */ - void disassemble(IntArray& addr, StringList& addrLabel, - StringList& bytes, StringList& data, - int start, int end); - + // The following two methods are meant to be used together + // First, a call is made to disassemble(), which updates the disassembly + // list; it will figure out when an actual complete disassembly is + // required, and when the previous results can be used + // + // Later, successive calls to disassemblyList() simply return the + // previous results; no disassembly is done in this case /** Disassemble from the given address using the Distella disassembler Address-to-label mappings (and vice-versa) are also determined here + + @return True if disassembly changed from previous call, else false */ - void disassemble(DisassemblyList& list, uInt16 start, bool autocode); + bool disassemble(bool autocode); + + /** + Get the results from the most recent call to disassemble() + */ + const DisassemblyList& disassemblyList() const { return myDisassembly; } + + /** + Determine the line in the disassembly that corresponds to the given + address. A value of zero indicates that no such address exists. + */ + int addressToLine(uInt16 address) const; + + /** + Disassemble from the starting address the specified number of lines. + Note that automatic code determination is turned off for this method; + it will treat all address contents as instructions. + */ + string disassemble(uInt16 start, uInt16 lines) const; int getBank(); int bankCount(); string getCartType(); -//////////////////////////////////////// +//////////////////////////////////////// /** Add a label and associated address */ @@ -148,9 +162,7 @@ class CartDebug : public DebuggerSystem int countCompletions(const char *in); const string& getCompletions() const { return myCompletions; } const string& getCompletionPrefix() const { return myCompPrefix; } - - private: - int disassemble(int address, string& result); +//////////////////////////////////////// private: enum equate_t { @@ -186,6 +198,7 @@ class CartDebug : public DebuggerSystem CartState myOldState; DisassemblyList myDisassembly; + map myAddrToLineList; LabelToAddr mySystemAddresses; AddrToLabel mySystemReadLabels; // labels used in a read context @@ -200,40 +213,6 @@ class CartDebug : public DebuggerSystem string myCompPrefix; uInt16 myRWPortAddress; - - enum { kSystemEquateSize = 158 }; - static const Equate ourSystemEquates[kSystemEquateSize]; - -////////////////////////////////////////////// - /** - Enumeration of the 6502 addressing modes - */ - enum AddressingMode - { - Absolute, AbsoluteX, AbsoluteY, Immediate, Implied, - Indirect, IndirectX, IndirectY, Invalid, Relative, - Zero, ZeroX, ZeroY - }; - - /** - Enumeration of the 6502 access modes - */ - enum AccessMode - { - Read, Write, None - }; - - /// Addressing mode for each of the 256 opcodes - /// This specifies how the opcode argument is addressed - static AddressingMode AddressModeTable[256]; - - /// Access mode for each of the 256 opcodes - /// This specifies how the opcode will access its argument - static AccessMode AccessModeTable[256]; - - /// Table of instruction mnemonics - static const char* InstructionMnemonicTable[256]; -////////////////////////////////////////////// }; #endif diff --git a/src/debugger/DiStella.cxx b/src/debugger/DiStella.cxx index c071d96df..888686029 100644 --- a/src/debugger/DiStella.cxx +++ b/src/debugger/DiStella.cxx @@ -25,19 +25,9 @@ #include "DiStella.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -DiStella::DiStella() +DiStella::DiStella(CartDebug::DisassemblyList& list, uInt16 start, + bool autocode) : labels(NULL) /* array of information about addresses-- can be from 2K-48K bytes in size */ -{ -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -DiStella::~DiStella() -{ -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 DiStella::disassemble(CartDebug::DisassemblyList& list, uInt16 start, - bool autocode) { while(!myAddressQueue.empty()) myAddressQueue.pop(); @@ -52,7 +42,7 @@ uInt32 DiStella::disassemble(CartDebug::DisassemblyList& list, uInt16 start, if (labels == NULL) { fprintf (stderr, "Malloc failed for 'labels' variable\n"); - return 0; + return; } memset(labels,0,myAppData.length); @@ -103,8 +93,11 @@ uInt32 DiStella::disassemble(CartDebug::DisassemblyList& list, uInt16 start, disasm(list, myOffset, 3); free(labels); /* Free dynamic memory before program ends */ +} - return list.size(); +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +DiStella::~DiStella() +{ } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -139,8 +132,8 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass else myBuf << HEX4 << myPC+myOffset << "' '"; - myBuf << ".byte $" << HEX2 << (int)Debugger::debugger().peek(myPC|0x1000) << " ; "; - showgfx(Debugger::debugger().peek(myPC|0x1000)); + myBuf << ".byte $" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset) << " ; "; + showgfx(Debugger::debugger().peek(myPC+myOffset)); myBuf << " $" << HEX4 << myPC+myOffset; addEntry(list); } @@ -154,7 +147,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass { bytes = 1; myBuf << HEX4 << myPC+myOffset << "'L" << myPC+myOffset << "'.byte " - << "$" << HEX2 << (int)Debugger::debugger().peek(myPC|0x1000); + << "$" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset); } myPC++; @@ -167,11 +160,11 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass if (bytes == 17) { addEntry(list); - myBuf << " ' '.byte $" << HEX2 << (int)Debugger::debugger().peek(myPC|0x1000); + myBuf << " ' '.byte $" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset); bytes = 1; } else - myBuf << ",$" << HEX2 << (int)Debugger::debugger().peek(myPC|0x1000); + myBuf << ",$" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset); } myPC++; } @@ -185,7 +178,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass } else { - op = Debugger::debugger().peek(myPC|0x1000); + op = Debugger::debugger().peek(myPC+myOffset); /* version 2.1 bug fix */ if (pass == 2) mark(myPC+myOffset, VALID_ENTRY); @@ -254,7 +247,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass else myBuf << HEX4 << myPC+myOffset << "' '"; - op = Debugger::debugger().peek(myPC|0x1000); myPC++; + op = Debugger::debugger().peek(myPC+myOffset); myPC++; myBuf << ".byte $" << HEX2 << (int)op; addEntry(list); } @@ -321,7 +314,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass case ABSOLUTE: { - ad = Debugger::debugger().dpeek(myPC|0x1000); myPC+=2; + ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2; labfound = mark(ad, REFERENCED); if (pass == 1) { @@ -380,7 +373,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass case ZERO_PAGE: { - d1 = Debugger::debugger().peek(myPC|0x1000); myPC++; + d1 = Debugger::debugger().peek(myPC+myOffset); myPC++; labfound = mark(d1, REFERENCED); if (pass == 3) { @@ -402,7 +395,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass case IMMEDIATE: { - d1 = Debugger::debugger().peek(myPC|0x1000); myPC++; + d1 = Debugger::debugger().peek(myPC+myOffset); myPC++; if (pass == 3) { sprintf(linebuff," #$%.2X ",d1); @@ -415,7 +408,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass case ABSOLUTE_X: { - ad = Debugger::debugger().dpeek(myPC|0x1000); myPC+=2; + ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2; labfound = mark(ad, REFERENCED); if (pass == 3) { @@ -465,7 +458,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass case ABSOLUTE_Y: { - ad = Debugger::debugger().dpeek(myPC|0x1000); myPC+=2; + ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2; labfound = mark(ad, REFERENCED); if (pass == 3) { @@ -514,7 +507,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass case INDIRECT_X: { - d1 = Debugger::debugger().peek(myPC|0x1000); myPC++; + d1 = Debugger::debugger().peek(myPC+myOffset); myPC++; if (pass == 3) { sprintf(linebuff," ($%.2X,X)",d1); @@ -527,7 +520,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass case INDIRECT_Y: { - d1 = Debugger::debugger().peek(myPC|0x1000); myPC++; + d1 = Debugger::debugger().peek(myPC+myOffset); myPC++; if (pass == 3) { sprintf(linebuff," ($%.2X),Y",d1); @@ -540,7 +533,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass case ZERO_PAGE_X: { - d1 = Debugger::debugger().peek(myPC|0x1000); myPC++; + d1 = Debugger::debugger().peek(myPC+myOffset); myPC++; labfound = mark(d1, REFERENCED); if (pass == 3) { @@ -562,7 +555,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass case ZERO_PAGE_Y: { - d1 = Debugger::debugger().peek(myPC|0x1000); myPC++; + d1 = Debugger::debugger().peek(myPC+myOffset); myPC++; labfound = mark(d1,REFERENCED); if (pass == 3) { @@ -584,7 +577,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass case RELATIVE: { - d1 = Debugger::debugger().peek(myPC|0x1000); myPC++; + d1 = Debugger::debugger().peek(myPC+myOffset); myPC++; ad = d1; if (d1 >= 128) ad = d1 - 256; @@ -620,7 +613,7 @@ void DiStella::disasm(CartDebug::DisassemblyList& list, uInt32 distart, int pass case ABS_INDIRECT: { - ad = Debugger::debugger().dpeek(myPC|0x1000); myPC+=2; + ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2; labfound = mark(ad, REFERENCED); if (pass == 3) { diff --git a/src/debugger/DiStella.hxx b/src/debugger/DiStella.hxx index 4f709e904..aa8123fdb 100644 --- a/src/debugger/DiStella.hxx +++ b/src/debugger/DiStella.hxx @@ -41,10 +41,6 @@ */ class DiStella { - public: - DiStella(); - ~DiStella(); - public: /** Disassemble the current state of the System from the given start address. @@ -52,11 +48,11 @@ class DiStella @param list The results of the disassembly are placed here @param start The address at which to start disassembly @param autocode If enabled, try to determine code vs. data sections - - @return The number of lines that were disassembled */ - uInt32 disassemble(CartDebug::DisassemblyList& list, uInt16 start, - bool autocode = true); + DiStella(CartDebug::DisassemblyList& list, uInt16 start, + bool autocode = true); + + ~DiStella(); private: // Marked bits diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index fff5b8a67..811d06c9e 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -52,12 +52,15 @@ RomListWidget::~RomListWidget() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void RomListWidget::setList(StringList& label, StringList& bytes, StringList& disasm, - BoolArray& state) +void RomListWidget::setList(const CartDebug::DisassemblyList& list, + const BoolArray& state) { - myLabel = label; - myDisasm = disasm; + myList = &list; + // TODO - maybe there's a better way than copying all the bytes again?? + StringList bytes; + for(uInt32 i = 0; i < list.size(); ++i) + bytes.push_back(list[i].bytes); CheckListWidget::setList(bytes, state); } @@ -85,7 +88,8 @@ void RomListWidget::drawWidget(bool hilite) { //cerr << "RomListWidget::drawWidget\n"; FBSurface& s = _boss->dialog().surface(); - int i, pos, xpos, ypos, len = _list.size(); + const CartDebug::DisassemblyList& dlist = *myList; + int i, pos, xpos, ypos, len = dlist.size(); string buffer; int deltax; @@ -126,11 +130,11 @@ void RomListWidget::drawWidget(bool hilite) } // Draw labels - s.drawString(_font, myLabel[pos], xpos, ypos, + s.drawString(_font, dlist[pos].label, xpos, ypos, myLabelWidth, kTextColor); // Draw disassembly - s.drawString(_font, myDisasm[pos], xpos + myLabelWidth, ypos, + s.drawString(_font, dlist[pos].disasm, xpos + myLabelWidth, ypos, r.left, kTextColor); // Draw editable bytes diff --git a/src/debugger/gui/RomListWidget.hxx b/src/debugger/gui/RomListWidget.hxx index b426f8dc5..076164c59 100644 --- a/src/debugger/gui/RomListWidget.hxx +++ b/src/debugger/gui/RomListWidget.hxx @@ -26,7 +26,7 @@ class CheckboxWidget; class ContextMenu; #include "CheckListWidget.hxx" - +#include "CartDebug.hxx" /** RomListWidget */ class RomListWidget : public CheckListWidget @@ -38,8 +38,7 @@ class RomListWidget : public CheckListWidget int x, int y, int w, int h); virtual ~RomListWidget(); - void setList(StringList& label, StringList& bytes, StringList& disasm, - BoolArray& state); + void setList(const CartDebug::DisassemblyList& list, const BoolArray& state); protected: void handleMouseDown(int x, int y, int button, int clickCount); @@ -56,7 +55,7 @@ class RomListWidget : public CheckListWidget int myLabelWidth; int myBytesWidth; - StringList myLabel, myDisasm; + const CartDebug::DisassemblyList* myList; }; #endif diff --git a/src/debugger/gui/RomWidget.cxx b/src/debugger/gui/RomWidget.cxx index 6a4c2b069..a2e17e213 100644 --- a/src/debugger/gui/RomWidget.cxx +++ b/src/debugger/gui/RomWidget.cxx @@ -100,9 +100,6 @@ RomWidget::RomWidget(GuiObject* boss, const GUI::Font& font, int x, int y) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RomWidget::~RomWidget() { - myAddrList.clear(); - myLineList.clear(); - delete mySaveRom; } @@ -166,71 +163,39 @@ void RomWidget::loadConfig() // Fill romlist the current bank of source or disassembly // Only reload full bank when necessary - if(myListIsDirty || bankChanged) + // TODO - bank changes aren't the only time that the disassembly needs to + // be redone; ROMs which dynamically change cart address space and + // have self-modifying code need to be taken into account + // As well, we don't always start from the 0xfffc; this only + // happens in the startup bank + myListIsDirty |= cart.disassemble(true); + if(myListIsDirty) { -/* - // Clear old mappings - myAddrList.clear(); - myLineList.clear(); - - StringList label, data, disasm; + const CartDebug::DisassemblyList& list = cart.disassemblyList(); BoolArray state; - // Disassemble zero-page RAM and entire bank and reset breakpoints - cart.disassemble(myAddrList, label, data, disasm, 0x80, 0xff); - cart.disassemble(myAddrList, label, data, disasm, 0xf000, 0xffff); - PackedBitArray& bp = dbg.breakpoints(); - for(unsigned int i = 0; i < data.size(); ++i) + for(uInt32 i = 0; i < list.size(); ++i) { - if(bp.isSet(myAddrList[i])) + const CartDebug::DisassemblyTag& tag = list[i]; + if(tag.address != 0 && bp.isSet(tag.address)) state.push_back(true); else state.push_back(false); } - // Create a mapping from addresses to line numbers - for(unsigned int i = 0; i < myAddrList.size(); ++i) - myLineList.insert(make_pair(myAddrList[i], i)); - - myRomList->setList(label, data, disasm, state); + myRomList->setList(list, state); // Restore the old bank, in case we inadvertently switched while reading. dbg.setBank(myCurrentBank); -*/ - CartDebug::DisassemblyList list; - cart.disassemble(list, dbg.dpeek(0xfffc), true); - - for(uInt32 i = 0; i < list.size(); ++i) - { - const CartDebug::DisassemblyTag& tag = list[i]; - printf("%.4X|%5s|%s|%s|\n", tag.address, tag.label.c_str(), tag.disasm.c_str(), tag.bytes.c_str()); - } - - myListIsDirty = false; } // Update romlist to point to current PC - // Take mirroring of PC into account, as well as zero-page RAM - int pc = dbg.cpuDebug().pc(); - if(pc & 0x1000) pc |= 0xe000; - AddrToLine::iterator iter = myLineList.find(pc); - - // if current PC not found, do an update (we're executing what - // we thought was an operand) - - // This doesn't help, and seems to actually hurt. - /* - if(iter == myLineList.end()) { - incrementalUpdate(myRomList->currentPos(), myRomList->rows()); - iter = myLineList.find(pc); - } - */ - - if(iter != myLineList.end()) - myRomList->setHighlighted(iter->second); + int pcline = cart.addressToLine(dbg.cpuDebug().pc()); + if(pcline > 0) + myRomList->setHighlighted(pcline); // Set current bank IntArray alist; @@ -249,34 +214,53 @@ void RomWidget::loadConfig() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomWidget::setBreak(int data) { + const CartDebug::DisassemblyList& list = + instance().debugger().cartDebug().disassemblyList(); + if(data >= (int)list.size()) return; + bool state = myRomList->getState(data); - instance().debugger().setBreakPoint(myAddrList[data], state); + if(list[data].address != 0) + instance().debugger().setBreakPoint(list[data].address, state); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomWidget::setPC(int data) { - ostringstream command; - command << "pc #" << myAddrList[data]; - instance().debugger().run(command.str()); + const CartDebug::DisassemblyList& list = + instance().debugger().cartDebug().disassemblyList(); + if(data >= (int)list.size()) return; + + if(list[data].address != 0) + { + ostringstream command; + command << "pc #" << list[data].address; + instance().debugger().run(command.str()); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomWidget::patchROM(int data, const string& bytes) { - ostringstream command; + const CartDebug::DisassemblyList& list = + instance().debugger().cartDebug().disassemblyList(); + if(data >= (int)list.size()) return; - // Temporarily set to base 16, since that's the format the disassembled - // byte string is in. This eliminates the need to prefix each byte with - // a '$' character - BaseFormat oldbase = instance().debugger().parser().base(); - instance().debugger().parser().setBase(kBASE_16); + if(list[data].address != 0) + { + ostringstream command; - command << "rom #" << myAddrList[data] << " " << bytes; - instance().debugger().run(command.str()); + // Temporarily set to base 16, since that's the format the disassembled + // byte string is in. This eliminates the need to prefix each byte with + // a '$' character + BaseFormat oldbase = instance().debugger().parser().base(); + instance().debugger().parser().setBase(kBASE_16); - // Restore previous base - instance().debugger().parser().setBase(oldbase); + command << "rom #" << list[data].address << " " << bytes; + instance().debugger().run(command.str()); + + // Restore previous base + instance().debugger().parser().setBase(oldbase); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/RomWidget.hxx b/src/debugger/gui/RomWidget.hxx index c0880dd39..0ac17fc98 100644 --- a/src/debugger/gui/RomWidget.hxx +++ b/src/debugger/gui/RomWidget.hxx @@ -29,14 +29,10 @@ class InputTextDialog; class RomListWidget; class StringList; -#include - #include "Array.hxx" #include "Widget.hxx" #include "Command.hxx" - -typedef map AddrToLine; - +#include "CartDebug.hxx" class RomWidget : public Widget, public CommandSender { @@ -60,14 +56,7 @@ class RomWidget : public Widget, public CommandSender kRomNameEntered = 'RWrn' }; - RomListWidget* myRomList; - - /** List of addresses indexed by line number */ - IntArray myAddrList; - - /** List of line numbers indexed by address */ - AddrToLine myLineList; - + RomListWidget* myRomList; DataGridWidget* myBank; EditTextWidget* myBankCount; InputTextDialog* mySaveRom;