diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx index aeeafc42c..c3d1b0e64 100644 --- a/src/debugger/CartDebug.cxx +++ b/src/debugger/CartDebug.cxx @@ -352,10 +352,14 @@ string CartDebug::disassemble(uInt16 start, uInt16 lines) const bool CartDebug::addDirective(CartDebug::DisasmType type, uInt16 start, uInt16 end, int bank) { +#define PRINT_TAG(tag) \ + disasmTypeAsString(cerr, tag.type); \ + cerr << ": start = " << tag.start << ", end = " << tag.end << endl; + #define PRINT_LIST(header) \ cerr << header << endl; \ - for(DirectiveList::const_iterator d = list.begin(); d != list.end(); ++d) \ - PRINT_TAG((*d)); \ + for(DirectiveList::const_iterator d = list.begin(); d != list.end(); ++d) { \ + PRINT_TAG((*d)); } \ cerr << endl; if(end < start || start == 0 || end == 0) @@ -396,7 +400,7 @@ bool CartDebug::addDirective(CartDebug::DisasmType type, // Case 1: remove range that is completely inside new range if(tag.start <= i->start && tag.end >= i->end) { - list.erase(i); + i = list.erase(i); } // Case 2: split the old range else if(tag.start >= i->start && tag.end <= i->end) @@ -1000,13 +1004,12 @@ void CartDebug::disasmTypeAsString(ostream& buf, DisasmType type) const { switch(type) { - case CartDebug::NONE: buf << "NONE"; break; - case CartDebug::VALID: buf << "VALID"; break; case CartDebug::SKIP: buf << "SKIP"; break; case CartDebug::CODE: buf << "CODE"; break; case CartDebug::GFX: buf << "GFX"; break; case CartDebug::DATA: buf << "DATA"; break; case CartDebug::ROW: buf << "ROW"; break; + default: break; } } diff --git a/src/debugger/CartDebug.hxx b/src/debugger/CartDebug.hxx index 2259d4517..72d212639 100644 --- a/src/debugger/CartDebug.hxx +++ b/src/debugger/CartDebug.hxx @@ -54,15 +54,22 @@ class CartDebug : public DebuggerSystem public: enum DisasmType { - NONE = 0, - VALID = 1 << 0, /* addresses that can have a label placed in front of it. A good counterexample - would be "FF00: LDA $FE00"; $FF01 would be in the middle of a multi-byte - instruction, and therefore cannot be labelled. */ - SKIP = 1 << 1, /* TODO - document this */ - CODE = 1 << 2, /* disassemble-able code segments */ - GFX = 1 << 3, /* addresses loaded into GRPx registers */ - DATA = 1 << 4, /* code somewhere in the program references it, i.e. LDA $F372 referenced $F372 */ - ROW = 1 << 5 /* all other addresses */ + NONE = 0, + VALID_ENTRY = 1 << 0, /* addresses that can have a label placed in front of it. + A good counterexample would be "FF00: LDA $FE00"; $FF01 + would be in the middle of a multi-byte instruction, and + therefore cannot be labelled. */ + REFERENCED = 1 << 1, /* code somewhere in the program references it, + i.e. LDA $F372 referenced $F372 */ + + // The following correspond to specific types that can be set within the + // debugger, or specified in a Distella cfg file + // + SKIP = 1 << 2, // TODO - document this + CODE = 1 << 3, // disassemble-able code segments + GFX = 1 << 4, // addresses loaded into GRPx registers + DATA = 1 << 5, // addresses loaded into registers other than GRPx + ROW = 1 << 6 // all other addresses }; struct DisassemblyTag { DisasmType type; diff --git a/src/debugger/DiStella.cxx b/src/debugger/DiStella.cxx index 32b0fbb99..311a1d8bb 100644 --- a/src/debugger/DiStella.cxx +++ b/src/debugger/DiStella.cxx @@ -123,7 +123,7 @@ DiStella::DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list, while(it != addresses.end()) { uInt16 addr = *it; - if(!check_bit(labels[addr-myOffset], CartDebug::CODE)) + if(!check_bit(addr-myOffset, CartDebug::CODE)) { cerr << "(list) marking " << HEX4 << addr << " as CODE\n"; myAddressQueue.push(addr); @@ -135,11 +135,11 @@ cerr << "(list) marking " << HEX4 << addr << " as CODE\n"; } // Stella itself can provide hints on whether an address has ever - // been referenced as CartDebug::CODE + // been referenced as CODE while(it == addresses.end() && codeAccessPoint <= myAppData.end) { if(Debugger::debugger().isCode(codeAccessPoint+myOffset) && - !check_bit(labels[codeAccessPoint], CartDebug::CODE)) + !check_bit(codeAccessPoint, CartDebug::CODE)) { cerr << "(emul) marking " << HEX4 << (codeAccessPoint+myOffset) << " as CODE\n"; myAddressQueue.push(codeAccessPoint+myOffset); @@ -153,7 +153,7 @@ cerr << "(emul) marking " << HEX4 << (codeAccessPoint+myOffset) << " as CODE\n"; for (int k = 0; k <= myAppData.end; k++) { - if (!check_bit(labels[k], CartDebug::CODE)) + if (!check_bit(k, CartDebug::CODE)) mark(k+myOffset, CartDebug::ROW); } } @@ -189,14 +189,14 @@ void DiStella::disasm(uInt32 distart, int pass) myPC = distart - myOffset; while(myPC <= myAppData.end) { - if(check_bit(labels[myPC], CartDebug::GFX)) - /* && !check_bit(labels[myPC], CartDebug::CODE))*/ + if(check_bit(myPC, CartDebug::GFX)) + /* && !check_bit(myPC, CartDebug::CODE))*/ { if (pass == 2) - mark(myPC+myOffset, CartDebug::VALID); + mark(myPC+myOffset, CartDebug::VALID_ENTRY); else if (pass == 3) { - if (check_bit(labels[myPC], CartDebug::DATA)) + if (check_bit(myPC, CartDebug::REFERENCED)) myDisasmBuf << HEX4 << myPC+myOffset << "'L" << HEX4 << myPC+myOffset << "'"; else myDisasmBuf << HEX4 << myPC+myOffset << "' '"; @@ -214,10 +214,31 @@ void DiStella::disasm(uInt32 distart, int pass) } myPC++; } - else if (check_bit(labels[myPC], CartDebug::ROW) && !check_bit(labels[myPC], CartDebug::GFX)) - /* && !check_bit(labels[myPC], CartDebug::CODE)) { */ + else if (check_bit(myPC, CartDebug::DATA) && + !check_bit(myPC, CartDebug::CODE|CartDebug::GFX)) { - mark(myPC+myOffset, CartDebug::VALID); + if (pass == 2) + mark(myPC+myOffset, CartDebug::VALID_ENTRY); + else if (pass == 3) + { + if (check_bit(myPC, CartDebug::REFERENCED)) + myDisasmBuf << HEX4 << myPC+myOffset << "'L" << HEX4 << myPC+myOffset << "'"; + else + myDisasmBuf << HEX4 << myPC+myOffset << "' '"; + + uInt8 byte = Debugger::debugger().peek(myPC+myOffset); + myDisasmBuf << ".byte $" << HEX2 << (int)byte << " $" + << HEX4 << myPC+myOffset << "'" + << HEX2 << (int)byte; +cerr << myDisasmBuf.str() << endl; + addEntry(CartDebug::DATA); + } + myPC++; + } + else if (check_bit(myPC, CartDebug::ROW) && !check_bit(myPC, CartDebug::GFX)) + /* && !check_bit(myPC, CartDebug::CODE)) { */ + { + mark(myPC+myOffset, CartDebug::VALID_ENTRY); if (pass == 3) { bytes = 1; @@ -226,21 +247,20 @@ void DiStella::disasm(uInt32 distart, int pass) } myPC++; - while (check_bit(labels[myPC], CartDebug::ROW) && !check_bit(labels[myPC], CartDebug::DATA) - && !check_bit(labels[myPC], CartDebug::GFX) && pass == 3 && myPC <= myAppData.end) + while (check_bit(myPC, CartDebug::ROW) && + !check_bit(myPC, CartDebug::REFERENCED|CartDebug::DATA|CartDebug::GFX) + && pass == 3 && myPC <= myAppData.end) { - if (pass == 3) + bytes++; + if (bytes == 17) { - bytes++; - if (bytes == 17) - { - addEntry(CartDebug::ROW); - myDisasmBuf << " ' '.byte $" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset); - bytes = 1; - } - else - myDisasmBuf << ",$" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset); + addEntry(CartDebug::ROW); + myDisasmBuf << " ' '.byte $" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset); + bytes = 1; } + else + myDisasmBuf << ",$" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset); + myPC++; } @@ -256,10 +276,10 @@ void DiStella::disasm(uInt32 distart, int pass) op = Debugger::debugger().peek(myPC+myOffset); /* version 2.1 bug fix */ if (pass == 2) - mark(myPC+myOffset, CartDebug::VALID); + mark(myPC+myOffset, CartDebug::VALID_ENTRY); else if (pass == 3) { - if (check_bit(labels[myPC], CartDebug::DATA)) + if (check_bit(myPC, CartDebug::REFERENCED)) myDisasmBuf << HEX4 << myPC+myOffset << "'L" << HEX4 << myPC+myOffset << "'"; else myDisasmBuf << HEX4 << myPC+myOffset << "' '"; @@ -312,7 +332,7 @@ void DiStella::disasm(uInt32 distart, int pass) if (myPC == myAppData.end) { - if (check_bit(labels[myPC], CartDebug::DATA)) + if (check_bit(myPC, CartDebug::REFERENCED)) myDisasmBuf << HEX4 << myPC+myOffset << "'L" << HEX4 << myPC+myOffset << "'"; else myDisasmBuf << HEX4 << myPC+myOffset << "' '"; @@ -376,10 +396,10 @@ void DiStella::disasm(uInt32 distart, int pass) case ABSOLUTE: { ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2; - labfound = mark(ad, CartDebug::DATA); + labfound = mark(ad, CartDebug::REFERENCED); if (pass == 1) { - if ((addbranch) && !check_bit(labels[ad & myAppData.end], CartDebug::CODE)) + if ((addbranch) && !check_bit(ad & myAppData.end, CartDebug::CODE)) { if (ad > 0xfff) myAddressQueue.push((ad & myAppData.end) + myOffset); @@ -422,7 +442,7 @@ void DiStella::disasm(uInt32 distart, int pass) case ZERO_PAGE: { d1 = Debugger::debugger().peek(myPC+myOffset); myPC++; - labfound = mark(d1, CartDebug::DATA); + labfound = mark(d1, CartDebug::REFERENCED); if (pass == 3) { if (labfound == 2) @@ -450,7 +470,7 @@ void DiStella::disasm(uInt32 distart, int pass) case ABSOLUTE_X: { ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2; - labfound = mark(ad, CartDebug::DATA); + labfound = mark(ad, CartDebug::REFERENCED); if (pass == 3) { if (ad < 0x100) @@ -486,7 +506,7 @@ void DiStella::disasm(uInt32 distart, int pass) case ABSOLUTE_Y: { ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2; - labfound = mark(ad, CartDebug::DATA); + labfound = mark(ad, CartDebug::REFERENCED); if (pass == 3) { if (ad < 0x100) @@ -544,7 +564,7 @@ void DiStella::disasm(uInt32 distart, int pass) case ZERO_PAGE_X: { d1 = Debugger::debugger().peek(myPC+myOffset); myPC++; - labfound = mark(d1, CartDebug::DATA); + labfound = mark(d1, CartDebug::REFERENCED); if (pass == 3) { if (labfound == 2) @@ -561,7 +581,7 @@ void DiStella::disasm(uInt32 distart, int pass) case ZERO_PAGE_Y: { d1 = Debugger::debugger().peek(myPC+myOffset); myPC++; - labfound = mark(d1, CartDebug::DATA); + labfound = mark(d1, CartDebug::REFERENCED); if (pass == 3) { if (labfound == 2) @@ -583,10 +603,10 @@ void DiStella::disasm(uInt32 distart, int pass) d1 = Debugger::debugger().peek(myPC+myOffset); myPC++; ad = ((myPC + (Int8)d1) & 0xfff) + myOffset; - labfound = mark(ad, CartDebug::DATA); + labfound = mark(ad, CartDebug::REFERENCED); if (pass == 1) { - if ((addbranch) && !check_bit(labels[ad-myOffset], CartDebug::CODE)) + if ((addbranch) && !check_bit(ad-myOffset, CartDebug::CODE)) { myAddressQueue.push(ad); mark(ad, CartDebug::CODE); @@ -609,7 +629,7 @@ void DiStella::disasm(uInt32 distart, int pass) case ABS_INDIRECT: { ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2; - labfound = mark(ad, CartDebug::DATA); + labfound = mark(ad, CartDebug::REFERENCED); if (pass == 3) { if (ad < 0x100) @@ -666,7 +686,7 @@ void DiStella::disasm(uInt32 distart, int pass) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int DiStella::mark(uInt16 address, uInt8 bit) +int DiStella::mark(uInt16 address, uInt8 mask) { /*----------------------------------------------------------------------- For any given offset and code range... @@ -717,7 +737,7 @@ int DiStella::mark(uInt16 address, uInt8 bit) if (address >= myOffset && address <= myAppData.end + myOffset) { - labels[address-myOffset] = labels[address-myOffset] | bit; + labels[address-myOffset] = labels[address-myOffset] | mask; return 1; } else if (address >= 0 && address <= 0x3f) @@ -731,13 +751,19 @@ int DiStella::mark(uInt16 address, uInt8 bit) else if (address > 0x1000) { /* 2K & 4K case */ - labels[address & myAppData.end] = labels[address & myAppData.end] | bit; + labels[address & myAppData.end] = labels[address & myAppData.end] | mask; return 4; } else return 0; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool DiStella::check_bit(uInt16 address, uInt8 mask) const +{ + return (labels[address] & mask) == mask; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool DiStella::check_range(uInt16 beg, uInt16 end) const { @@ -818,8 +844,9 @@ void DiStella::addEntry(CartDebug::DisasmType type) getline(myDisasmBuf, tag.disasm, '\''); getline(myDisasmBuf, tag.bytes); break; - case CartDebug::DATA: // TODO - handle this - tag.disasm = " "; + case CartDebug::DATA: + getline(myDisasmBuf, tag.disasm, '\''); + getline(myDisasmBuf, tag.bytes); break; case CartDebug::ROW: getline(myDisasmBuf, tag.disasm); diff --git a/src/debugger/DiStella.hxx b/src/debugger/DiStella.hxx index 0d0a3c146..74b4155ca 100644 --- a/src/debugger/DiStella.hxx +++ b/src/debugger/DiStella.hxx @@ -83,9 +83,9 @@ class DiStella // These functions are part of the original Distella code void disasm(uInt32 distart, int pass); - int mark(uInt16 address, uInt8 bit); bool check_range(uInt16 start, uInt16 end) const; - inline uInt8 check_bit(uInt8 bitflags, uInt8 i) const { return (bitflags & i); } + int mark(uInt16 address, uInt8 mask); + bool check_bit(uInt16 address, uInt8 mask) const; private: const CartDebug& myDbg; diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 99a0c9613..1c1374799 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -477,9 +477,9 @@ void RomListWidget::drawWidget(bool hilite) // Draw labels s.drawString(_font, dlist[pos].label, xpos, ypos, _labelWidth, kTextColor); - // Bytes are only editable if they represent code or graphics + // 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)) + if(dlist[pos].type & (CartDebug::CODE | CartDebug::GFX | CartDebug::DATA)) { if(dlist[pos].type == CartDebug::CODE) {