diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx index 4d2f2b91c..ac96abe5c 100644 --- a/src/debugger/CartDebug.cxx +++ b/src/debugger/CartDebug.cxx @@ -970,8 +970,8 @@ string CartDebug::saveDisassembly() ostringstream buf; buf << "\n\n;***********************************************************\n" << "; Bank " << myConsole.cartridge().getBank(); - if (myConsole.cartridge().bankCount() > 0) - buf << " / (0.." << myConsole.cartridge().bankCount() - 1 << ")"; + if (myConsole.cartridge().bankCount() > 1) + buf << " / 0.." << myConsole.cartridge().bankCount() - 1; buf << "\n;***********************************************************\n\n"; // Use specific settings for disassembly output @@ -1084,9 +1084,9 @@ string CartDebug::saveDisassembly() bool addrUsed = false; for(uInt16 addr = 0x00; addr <= 0x0F; ++addr) - addrUsed = addrUsed || myReserved.TIARead[addr]; + addrUsed = addrUsed || myReserved.TIARead[addr] || (mySystem.getAccessFlags(addr) & WRITE); for(uInt16 addr = 0x00; addr <= 0x3F; ++addr) - addrUsed = addrUsed || myReserved.TIAWrite[addr]; + addrUsed = addrUsed || myReserved.TIAWrite[addr] || (mySystem.getAccessFlags(addr) & DATA); for(uInt16 addr = 0x00; addr <= 0x17; ++addr) addrUsed = addrUsed || myReserved.IOReadWrite[addr]; if(addrUsed) @@ -1094,16 +1094,28 @@ string CartDebug::saveDisassembly() out << "\n;-----------------------------------------------------------\n" << "; TIA and IO constants accessed\n" << ";-----------------------------------------------------------\n\n"; + + // TIA read access for(uInt16 addr = 0x00; addr <= 0x0F; ++addr) if(myReserved.TIARead[addr] && ourTIAMnemonicR[addr]) out << ALIGN(16) << ourTIAMnemonicR[addr] << "= $" << Base::HEX2 << right << addr << " ; (R)\n"; + else if (mySystem.getAccessFlags(addr) & DATA) + out << ";" << ALIGN(16-1) << ourTIAMnemonicR[addr] << "= $" + << Base::HEX2 << right << addr << " ; (Ri)\n"; out << "\n"; + + // TIA write access for(uInt16 addr = 0x00; addr <= 0x3F; ++addr) if(myReserved.TIAWrite[addr] && ourTIAMnemonicW[addr]) out << ALIGN(16) << ourTIAMnemonicW[addr] << "= $" << Base::HEX2 << right << addr << " ; (W)\n"; + else if (mySystem.getAccessFlags(addr) & WRITE) + out << ";" << ALIGN(16-1) << ourTIAMnemonicW[addr] << "= $" + << Base::HEX2 << right << addr << " ; (Wi)\n"; out << "\n"; + + // RIOT IO access for(uInt16 addr = 0x00; addr <= 0x17; ++addr) if(myReserved.IOReadWrite[addr] && ourIOMnemonic[addr]) out << ALIGN(16) << ourIOMnemonic[addr] << "= $" @@ -1126,7 +1138,6 @@ string CartDebug::saveDisassembly() bool ramUsed = (mySystem.getAccessFlags(addr) & (DATA | WRITE)); bool codeUsed = (mySystem.getAccessFlags(addr) & CODE); bool stackUsed = (mySystem.getAccessFlags(addr|0x100) & (DATA | WRITE)); - ramUsed = true; if (myReserved.ZPRAM[addr - 0x80] && myUserLabels.find(addr) == myUserLabels.end()) { @@ -1427,7 +1438,7 @@ void CartDebug::disasmTypeAsString(ostream& buf, uInt8 flags) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const char* const CartDebug::ourTIAMnemonicR[16] = { "CXM0P", "CXM1P", "CXP0FB", "CXP1FB", "CXM0FB", "CXM1FB", "CXBLPF", "CXPPMM", - "INPT0", "INPT1", "INPT2", "INPT3", "INPT4", "INPT5", 0, 0 + "INPT0", "INPT1", "INPT2", "INPT3", "INPT4", "INPT5", "$1e", "$1f" }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1437,8 +1448,9 @@ const char* const CartDebug::ourTIAMnemonicW[64] = { "RESP0", "RESP1", "RESM0", "RESM1", "RESBL", "AUDC0", "AUDC1", "AUDF0", "AUDF1", "AUDV0", "AUDV1", "GRP0", "GRP1", "ENAM0", "ENAM1", "ENABL", "HMP0", "HMP1", "HMM0", "HMM1", "HMBL", "VDELP0", "VDELP1", "VDELBL", - "RESMP0", "RESMP1", "HMOVE", "HMCLR", "CXCLR", 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + "RESMP0", "RESMP1", "HMOVE", "HMCLR", "CXCLR", "$2d", "$2e", "$2f", + "$30", "$31", "$32", "$33", "$34", "$35", "$36", "$37", + "$38", "$39", "$3a", "$3b", "$3c", "$3d", "$3e", "$3f" }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/CartDebug.hxx b/src/debugger/CartDebug.hxx index e14a95252..fae5a9b45 100644 --- a/src/debugger/CartDebug.hxx +++ b/src/debugger/CartDebug.hxx @@ -63,14 +63,14 @@ class CartDebug : public DebuggerSystem // debugger, or specified in a Distella cfg file, and are listed in order // of decreasing hierarchy // - CODE = 1 << 7, // 0x80, disassemble-able code segments - TCODE = 1 << 6, // 0x40, (tentative) disassemble-able code segments - GFX = 1 << 5, // 0x20, addresses loaded into GRPx registers - PGFX = 1 << 4, // 0x10, addresses loaded into PFx registers - DATA = 1 << 3, // 0x08, addresses loaded into registers other than GRPx / PFx - ROW = 1 << 2, // 0x04, all other addresses + CODE = 1 << 7, // 0x80, disassemble-able code segments + TCODE = 1 << 6, // 0x40, (tentative) disassemble-able code segments + GFX = 1 << 5, // 0x20, addresses loaded into GRPx registers + PGFX = 1 << 4, // 0x10, addresses loaded into PFx registers + DATA = 1 << 3, // 0x08, addresses loaded into registers other than GRPx / PFx + ROW = 1 << 2, // 0x04, all other addresses // special type for poke() - WRITE = TCODE // 0x40, address written to + WRITE = TCODE // 0x40, address written to }; struct DisassemblyTag { DisasmType type; diff --git a/src/emucore/M6532.cxx b/src/emucore/M6532.cxx index fa779aa31..557ba5c71 100644 --- a/src/emucore/M6532.cxx +++ b/src/emucore/M6532.cxx @@ -78,7 +78,9 @@ void M6532::reset() myConsole.leftController().reset(); myConsole.rightController().reset(); +#ifdef DEBUGGER_SUPPORT createAccessBases(); +#endif // DEBUGGER_SUPPORT } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -166,7 +168,6 @@ void M6532::installDelegate(System& system, Device& device) // (addr & 0x0300) == 0x0000 is ZP RAM (A8 is 0, A9 is 0) for (uInt16 addr = 0; addr < 0x1000; addr += System::PAGE_SIZE) if ((addr & 0x0080) == 0x0080) { - //access.codeAccessBase = &myRAMAccessBase[addr & 0x7f]; mySystem->setPageAccess(addr, access); } } @@ -456,6 +457,7 @@ uInt32 M6532::timerClocks() const return uInt32(mySystem->cycles() - mySetTimerCycle); } +#ifdef DEBUGGER_SUPPORT // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void M6532::createAccessBases() { @@ -466,6 +468,9 @@ void M6532::createAccessBases() memset(myStackAccessBase.get(), CartDebug::NONE, STACK_SIZE); myIOAccessBase = make_unique(IO_SIZE); memset(myIOAccessBase.get(), CartDebug::NONE, IO_SIZE); + + myZPAccessDelay = make_unique(RAM_SIZE); + memset(myZPAccessDelay.get(), ZP_DELAY, RAM_SIZE); #else myRAMAccessBase = myStackAccessBase = myIOAccessBase = nullptr; #endif @@ -492,19 +497,13 @@ void M6532::setAccessFlags(uInt16 address, uInt8 flags) myIOAccessBase[address & IO_MASK] |= flags; else { // the first access, either by direct RAM or stack access is assumed as initialization - bool initialized = (myStackAccessBase[address & STACK_MASK] & CartDebug::ROW) != 0 - || (myRAMAccessBase[address & RAM_MASK] & CartDebug::ROW) != 0; - - if (address & STACK_BIT) - if (!initialized) - myStackAccessBase[address & STACK_MASK] |= CartDebug::ROW; - else - myStackAccessBase[address & STACK_MASK] |= flags; + if (myZPAccessDelay[address & RAM_MASK]) + myZPAccessDelay[address & RAM_MASK]--; + else if (address & STACK_BIT) + myStackAccessBase[address & STACK_MASK] |= flags; else - if (!initialized) - myRAMAccessBase[address & RAM_MASK] |= CartDebug::ROW; - else - myRAMAccessBase[address & RAM_MASK] |= flags; + myRAMAccessBase[address & RAM_MASK] |= flags; } } -} \ No newline at end of file +} +#endif // DEBUGGER_SUPPORT \ No newline at end of file diff --git a/src/emucore/M6532.hxx b/src/emucore/M6532.hxx index 0174760ae..fbffb4b12 100644 --- a/src/emucore/M6532.hxx +++ b/src/emucore/M6532.hxx @@ -209,16 +209,21 @@ class M6532 : public Device // Last value written to the timer registers uInt8 myOutTimer[4]; +#ifdef DEBUGGER_SUPPORT // The arrays containing information about every byte of RIOT // indicating whether and how (RW) it is used. BytePtr myRAMAccessBase; BytePtr myStackAccessBase; BytePtr myIOAccessBase; + // The array used to skip the first ZP access tracking + BytePtr myZPAccessDelay; static constexpr uInt16 RAM_SIZE = 0x80, RAM_MASK = RAM_SIZE - 1, - STACK_SIZE = 0x80, STACK_MASK = STACK_SIZE - 1, STACK_BIT = 0x100, - IO_SIZE = 0x20, IO_MASK = IO_SIZE - 1, IO_BIT = 0x200; + STACK_SIZE = RAM_SIZE, STACK_MASK = RAM_MASK, STACK_BIT = 0x100, + IO_SIZE = 0x20, IO_MASK = IO_SIZE - 1, IO_BIT = 0x200, + ZP_DELAY = 1; +#endif // DEBUGGER_SUPPORT private: // Following constructors and assignment operators not supported diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index 9ea834a1a..250304ca4 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -152,6 +152,10 @@ void TIA::reset() // Must be done last, after all other items have reset enableFixedColors(false); setFixedColorPalette(mySettings.getString("tia.dbgcolors")); + +#ifdef DEBUGGER_SUPPORT + createAccessBase(); +#endif // DEBUGGER_SUPPORT } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -181,7 +185,7 @@ void TIA::installDelegate(System& system, Device& device) // That is, all mirrors of ($00 - $3F) in the lower 4K of the 2600 // address space are mapped here for(uInt16 addr = 0; addr < 0x1000; addr += System::PAGE_SIZE) - if((addr & 0x0080) == 0x0000) + if((addr & TIA_BIT) == 0x0000) mySystem->setPageAccess(addr, access); mySystem->m6502().setOnHaltCallback( @@ -1584,3 +1588,40 @@ uInt8 TIA::collCXBLPF() const { return (myCollisionMask & CollisionMask::ball & CollisionMask::playfield) ? 0x80 : 0; } + +#ifdef DEBUGGER_SUPPORT +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TIA::createAccessBase() +{ +#ifdef DEBUGGER_SUPPORT + myAccessBase = make_unique(TIA_SIZE); + memset(myAccessBase.get(), CartDebug::NONE, TIA_SIZE); + myAccessDelay = make_unique(TIA_SIZE); + memset(myAccessDelay.get(), TIA_DELAY, TIA_SIZE); +#else + myAccessBase = nullptr; +#endif +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt8 TIA::getAccessFlags(uInt16 address) const +{ + return myAccessBase[address & TIA_MASK]; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TIA::setAccessFlags(uInt16 address, uInt8 flags) +{ + // ignore none flag + if (flags != CartDebug::NONE) { + if (flags == CartDebug::WRITE) { + // the first two write accesses are assumed as initialization + if (myAccessDelay[address & TIA_MASK]) + myAccessDelay[address & TIA_MASK]--; + else + myAccessBase[address & TIA_MASK] |= flags; + } else + myAccessBase[address & TIA_READ_MASK] |= flags; + } +} +#endif // DEBUGGER_SUPPORT \ No newline at end of file diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index 96855e909..657006557 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -540,6 +540,18 @@ class TIA : public Device uInt8 collCXPPMM() const; uInt8 collCXBLPF() const; +#ifdef DEBUGGER_SUPPORT + void createAccessBase(); + /** + Query/change the given address type to use the given disassembly flags + + @param address The address to modify + @param flags A bitfield of DisasmType directives for the given address + */ + uInt8 getAccessFlags(uInt16 address) const override; + void setAccessFlags(uInt16 address, uInt8 flags) override; +#endif // DEBUGGER_SUPPORT + private: Console& myConsole; @@ -711,6 +723,17 @@ class TIA : public Device */ uInt64 myCyclesAtFrameStart; +#ifdef DEBUGGER_SUPPORT + // The arrays containing information about every byte of TIA + // indicating whether and how (RW) it is used. + BytePtr myAccessBase; + // The array used to skip the first two TIA access trackings + BytePtr myAccessDelay; + + static constexpr uInt16 + TIA_SIZE = 0x40, TIA_MASK = TIA_SIZE - 1, TIA_READ_MASK = 0x0f, TIA_BIT = 0x080, TIA_DELAY = 2; +#endif // DEBUGGER_SUPPORT + private: TIA() = delete; TIA(const TIA&) = delete;