From fe6e67de32b828ac751899c9a628f1ac89bd44cd Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Sun, 30 Jun 2024 17:16:32 +0200 Subject: [PATCH] Boot into overblank. --- src/cheat/RamCheat.cxx | 2 +- src/common/HighScoresManager.cxx | 2 +- src/debugger/Debugger.cxx | 20 ++-- src/debugger/RiotDebug.cxx | 26 ++--- src/debugger/TIADebug.cxx | 108 +++++++++---------- src/debugger/gui/DebuggerDialog.hxx | 2 +- src/emucore/CartAR.cxx | 6 +- src/emucore/CartELF.cxx | 156 +++++++++++++++++++++++----- src/emucore/CartELF.hxx | 27 +++-- src/emucore/CartEnhanced.cxx | 2 +- src/emucore/Console.cxx | 2 +- src/emucore/Device.hxx | 2 + src/emucore/System.cxx | 22 +++- src/emucore/System.hxx | 83 +++++++++++---- 14 files changed, 317 insertions(+), 143 deletions(-) diff --git a/src/cheat/RamCheat.cxx b/src/cheat/RamCheat.cxx index dbb45e545..5f9c94a5e 100644 --- a/src/cheat/RamCheat.cxx +++ b/src/cheat/RamCheat.cxx @@ -55,5 +55,5 @@ bool RamCheat::disable() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RamCheat::evaluate() { - myOSystem.console().system().poke(address, value); + myOSystem.console().system().pokeOob(address, value); } diff --git a/src/common/HighScoresManager.cxx b/src/common/HighScoresManager.cxx index 24b3cbaf8..1e645be1f 100644 --- a/src/common/HighScoresManager.cxx +++ b/src/common/HighScoresManager.cxx @@ -77,7 +77,7 @@ Int16 HighScoresManager::peek(uInt16 addr) const if (myOSystem.hasConsole()) { if(addr < 0x100U || myOSystem.console().cartridge().internalRamSize() == 0) - return myOSystem.console().system().peek(addr); + return myOSystem.console().system().peekOob(addr); else return myOSystem.console().cartridge().internalRamGetValue(addr); } diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index 18878a72d..3d3a9e401 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -98,7 +98,7 @@ void Debugger::initialize() delete myDialog; myDialog = nullptr; myDialog = new DebuggerDialog(myOSystem, *this, 0, 0, mySize.w, mySize.h); - myCartDebug->setDebugWidget(&(myDialog->cartDebug())); + myCartDebug->setDebugWidget(myDialog->cartDebug()); saveOldState(); } @@ -249,7 +249,7 @@ string Debugger::setRAM(IntArray& args) const size_t count = args.size(); int address = args[0]; for(size_t i = 1; i < count; ++i) - mySystem.poke(address++, args[i]); + mySystem.pokeOob(address++, args[i]); buf << "changed " << (count-1) << " location"; if(count != 2) @@ -327,7 +327,7 @@ int Debugger::step(bool save) int Debugger::trace() { // 32 is the 6502 JSR instruction: - if(mySystem.peek(myCpuDebug->pc()) == 32) + if(mySystem.peekOob(myCpuDebug->pc()) == 32) { saveOldState(); @@ -521,20 +521,20 @@ void Debugger::log(string_view triggerMsg) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 Debugger::peek(uInt16 addr, Device::AccessFlags flags) { - return mySystem.peek(addr, flags); + return mySystem.peekOob(addr, flags); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 Debugger::dpeek(uInt16 addr, Device::AccessFlags flags) { - return static_cast(mySystem.peek(addr, flags) | - (mySystem.peek(addr+1, flags) << 8)); + return static_cast(mySystem.peekOob(addr, flags) | + (mySystem.peekOob(addr+1, flags) << 8)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Debugger::poke(uInt16 addr, uInt8 value, Device::AccessFlags flags) { - mySystem.poke(addr, value, flags); + mySystem.pokeOob(addr, value, flags); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -546,14 +546,14 @@ M6502& Debugger::m6502() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int Debugger::peekAsInt(int addr, Device::AccessFlags flags) { - return mySystem.peek(static_cast(addr), flags); + return mySystem.peekOob(static_cast(addr), flags); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int Debugger::dpeekAsInt(int addr, Device::AccessFlags flags) { - return mySystem.peek(static_cast(addr), flags) | - (mySystem.peek(static_cast(addr+1), flags) << 8); + return mySystem.peekOob(static_cast(addr), flags) | + (mySystem.peekOob(static_cast(addr+1), flags) << 8); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/RiotDebug.cxx b/src/debugger/RiotDebug.cxx index 20ca78616..f76536f76 100644 --- a/src/debugger/RiotDebug.cxx +++ b/src/debugger/RiotDebug.cxx @@ -121,25 +121,25 @@ void RiotDebug::saveOldState() uInt8 RiotDebug::swcha(int newVal) { if(newVal > -1) - mySystem.poke(0x280, newVal); + mySystem.pokeOob(0x280, newVal); - return mySystem.peek(0x280); + return mySystem.peekOob(0x280); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 RiotDebug::swchb(int newVal) { if(newVal > -1) - mySystem.poke(0x282, newVal); + mySystem.pokeOob(0x282, newVal); - return mySystem.peek(0x282); + return mySystem.peekOob(0x282); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 RiotDebug::swacnt(int newVal) { if(newVal > -1) - mySystem.poke(0x281, newVal); + mySystem.pokeOob(0x281, newVal); return mySystem.m6532().myDDRA; } @@ -148,7 +148,7 @@ uInt8 RiotDebug::swacnt(int newVal) uInt8 RiotDebug::swbcnt(int newVal) { if(newVal > -1) - mySystem.poke(0x283, newVal); + mySystem.pokeOob(0x283, newVal); return mySystem.m6532().myDDRB; } @@ -159,7 +159,7 @@ uInt8 RiotDebug::inpt(int x) static constexpr std::array _inpt = { INPT0, INPT1, INPT2, INPT3, INPT4, INPT5 }; - return mySystem.peek(_inpt[x]); + return mySystem.peekOob(_inpt[x]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -177,7 +177,7 @@ bool RiotDebug::vblank(int bit) uInt8 RiotDebug::tim1T(int newVal) { if(newVal > -1) - mySystem.poke(0x294, newVal); + mySystem.pokeOob(0x294, newVal); return mySystem.m6532().myOutTimer[0]; } @@ -186,7 +186,7 @@ uInt8 RiotDebug::tim1T(int newVal) uInt8 RiotDebug::tim8T(int newVal) { if(newVal > -1) - mySystem.poke(0x295, newVal); + mySystem.pokeOob(0x295, newVal); return mySystem.m6532().myOutTimer[1]; } @@ -195,7 +195,7 @@ uInt8 RiotDebug::tim8T(int newVal) uInt8 RiotDebug::tim64T(int newVal) { if(newVal > -1) - mySystem.poke(0x296, newVal); + mySystem.pokeOob(0x296, newVal); return mySystem.m6532().myOutTimer[2]; } @@ -204,7 +204,7 @@ uInt8 RiotDebug::tim64T(int newVal) uInt8 RiotDebug::tim1024T(int newVal) { if(newVal > -1) - mySystem.poke(0x297, newVal); + mySystem.pokeOob(0x297, newVal); return mySystem.m6532().myOutTimer[3]; } @@ -410,10 +410,10 @@ string RiotDebug::toString() // Yes, the fire buttons are in the TIA, but we might as well // show them here for convenience. << "Left/P0 stick: " << dirP0String() - << ((mySystem.peek(0x03c) & 0x80) ? "" : "(button) ") + << ((mySystem.peekOob(0x03c) & 0x80) ? "" : "(button) ") << '\n' << "Right/P1 stick: " << dirP1String() - << ((mySystem.peek(0x03d) & 0x80) ? "" : "(button) "); + << ((mySystem.peekOob(0x03d) & 0x80) ? "" : "(button) "); return buf.str(); } diff --git a/src/debugger/TIADebug.cxx b/src/debugger/TIADebug.cxx index a1aa740d8..dde9d5247 100644 --- a/src/debugger/TIADebug.cxx +++ b/src/debugger/TIADebug.cxx @@ -267,7 +267,7 @@ void TIADebug::saveOldState() myOldState.info.push_back(frameWsyncCycles()); } -/* the set methods now use mySystem.poke(). This will save us the +/* the set methods now use mySystem.pokeOob(). This will save us the trouble of masking the values here, since TIA::poke() will do it for us. @@ -293,7 +293,7 @@ void TIADebug::saveOldState() bool TIADebug::vdelP0(int newVal) { if(newVal > -1) - mySystem.poke(VDELP0, static_cast(newVal)); + mySystem.pokeOob(VDELP0, static_cast(newVal)); return myTIA.registerValue(VDELP0) & 0x01; } @@ -302,7 +302,7 @@ bool TIADebug::vdelP0(int newVal) bool TIADebug::vdelP1(int newVal) { if(newVal > -1) - mySystem.poke(VDELP1, static_cast(newVal)); + mySystem.pokeOob(VDELP1, static_cast(newVal)); return myTIA.registerValue(VDELP1) & 0x01; } @@ -311,7 +311,7 @@ bool TIADebug::vdelP1(int newVal) bool TIADebug::vdelBL(int newVal) { if(newVal > -1) - mySystem.poke(VDELBL, static_cast(newVal)); + mySystem.pokeOob(VDELBL, static_cast(newVal)); return myTIA.registerValue(VDELBL) & 0x01; } @@ -320,7 +320,7 @@ bool TIADebug::vdelBL(int newVal) bool TIADebug::enaM0(int newVal) { if(newVal > -1) - mySystem.poke(ENAM0, static_cast(newVal) << 1); + mySystem.pokeOob(ENAM0, static_cast(newVal) << 1); return myTIA.registerValue(ENAM0) & 0x02; } @@ -329,7 +329,7 @@ bool TIADebug::enaM0(int newVal) bool TIADebug::enaM1(int newVal) { if(newVal > -1) - mySystem.poke(ENAM1, static_cast(newVal) << 1); + mySystem.pokeOob(ENAM1, static_cast(newVal) << 1); return myTIA.registerValue(ENAM1) & 0x02; } @@ -338,7 +338,7 @@ bool TIADebug::enaM1(int newVal) bool TIADebug::enaBL(int newVal) { if(newVal > -1) - mySystem.poke(ENABL, static_cast(newVal) << 1); + mySystem.pokeOob(ENABL, static_cast(newVal) << 1); return myTIA.registerValue(ENABL) & 0x02; } @@ -347,7 +347,7 @@ bool TIADebug::enaBL(int newVal) bool TIADebug::resMP0(int newVal) { if(newVal > -1) - mySystem.poke(RESMP0, static_cast(newVal) << 1); + mySystem.pokeOob(RESMP0, static_cast(newVal) << 1); return myTIA.registerValue(RESMP0) & 0x02; } @@ -356,7 +356,7 @@ bool TIADebug::resMP0(int newVal) bool TIADebug::resMP1(int newVal) { if(newVal > -1) - mySystem.poke(RESMP1, static_cast(newVal) << 1); + mySystem.pokeOob(RESMP1, static_cast(newVal) << 1); return myTIA.registerValue(RESMP1) & 0x02; } @@ -365,7 +365,7 @@ bool TIADebug::resMP1(int newVal) bool TIADebug::refP0(int newVal) { if(newVal > -1) - mySystem.poke(REFP0, static_cast(newVal) << 3); + mySystem.pokeOob(REFP0, static_cast(newVal) << 3); return myTIA.registerValue(REFP0) & 0x08; } @@ -374,7 +374,7 @@ bool TIADebug::refP0(int newVal) bool TIADebug::refP1(int newVal) { if(newVal > -1) - mySystem.poke(REFP1, static_cast(newVal) << 3); + mySystem.pokeOob(REFP1, static_cast(newVal) << 3); return myTIA.registerValue(REFP1) & 0x08; } @@ -389,7 +389,7 @@ bool TIADebug::refPF(int newVal) tmp |= 0x01; else tmp &= ~0x01; - mySystem.poke(CTRLPF, tmp); + mySystem.pokeOob(CTRLPF, tmp); } return myTIA.registerValue(CTRLPF) & 0x01; @@ -405,7 +405,7 @@ bool TIADebug::scorePF(int newVal) tmp |= 0x02; else tmp &= ~0x02; - mySystem.poke(CTRLPF, tmp); + mySystem.pokeOob(CTRLPF, tmp); } return myTIA.registerValue(CTRLPF) & 0x02; @@ -421,7 +421,7 @@ bool TIADebug::priorityPF(int newVal) tmp |= 0x04; else tmp &= ~0x04; - mySystem.poke(CTRLPF, tmp); + mySystem.pokeOob(CTRLPF, tmp); } return myTIA.registerValue(CTRLPF) & 0x04; @@ -515,7 +515,7 @@ bool TIADebug::collision(CollisionBit id, bool toggle) const uInt8 TIADebug::audC0(int newVal) { if(newVal > -1) - mySystem.poke(AUDC0, newVal); + mySystem.pokeOob(AUDC0, newVal); return myTIA.registerValue(AUDC0) & 0x0f; } @@ -524,7 +524,7 @@ uInt8 TIADebug::audC0(int newVal) uInt8 TIADebug::audC1(int newVal) { if(newVal > -1) - mySystem.poke(AUDC1, newVal); + mySystem.pokeOob(AUDC1, newVal); return myTIA.registerValue(AUDC1) & 0x0f; } @@ -533,7 +533,7 @@ uInt8 TIADebug::audC1(int newVal) uInt8 TIADebug::audV0(int newVal) { if(newVal > -1) - mySystem.poke(AUDV0, newVal); + mySystem.pokeOob(AUDV0, newVal); return myTIA.registerValue(AUDV0) & 0x0f; } @@ -542,7 +542,7 @@ uInt8 TIADebug::audV0(int newVal) uInt8 TIADebug::audV1(int newVal) { if(newVal > -1) - mySystem.poke(AUDV1, newVal); + mySystem.pokeOob(AUDV1, newVal); return myTIA.registerValue(AUDV1) & 0x0f; } @@ -551,7 +551,7 @@ uInt8 TIADebug::audV1(int newVal) uInt8 TIADebug::audF0(int newVal) { if(newVal > -1) - mySystem.poke(AUDF0, newVal); + mySystem.pokeOob(AUDF0, newVal); return myTIA.registerValue(AUDF0) & 0x1f; } @@ -560,7 +560,7 @@ uInt8 TIADebug::audF0(int newVal) uInt8 TIADebug::audF1(int newVal) { if(newVal > -1) - mySystem.poke(AUDF1, newVal); + mySystem.pokeOob(AUDF1, newVal); return myTIA.registerValue(AUDF1) & 0x1f; } @@ -569,7 +569,7 @@ uInt8 TIADebug::audF1(int newVal) uInt8 TIADebug::pf0(int newVal) { if(newVal > -1) - mySystem.poke(PF0, newVal << 4); + mySystem.pokeOob(PF0, newVal << 4); return myTIA.registerValue(PF0) >> 4; } @@ -578,7 +578,7 @@ uInt8 TIADebug::pf0(int newVal) uInt8 TIADebug::pf1(int newVal) { if(newVal > -1) - mySystem.poke(PF1, newVal); + mySystem.pokeOob(PF1, newVal); return myTIA.registerValue(PF1); } @@ -587,7 +587,7 @@ uInt8 TIADebug::pf1(int newVal) uInt8 TIADebug::pf2(int newVal) { if(newVal > -1) - mySystem.poke(PF2, newVal); + mySystem.pokeOob(PF2, newVal); return myTIA.registerValue(PF2); } @@ -596,7 +596,7 @@ uInt8 TIADebug::pf2(int newVal) uInt8 TIADebug::coluP0(int newVal) { if(newVal > -1) - mySystem.poke(COLUP0, newVal); + mySystem.pokeOob(COLUP0, newVal); return myTIA.registerValue(COLUP0); } @@ -605,7 +605,7 @@ uInt8 TIADebug::coluP0(int newVal) uInt8 TIADebug::coluP1(int newVal) { if(newVal > -1) - mySystem.poke(COLUP1, newVal); + mySystem.pokeOob(COLUP1, newVal); return myTIA.registerValue(COLUP1); } @@ -614,7 +614,7 @@ uInt8 TIADebug::coluP1(int newVal) uInt8 TIADebug::coluPF(int newVal) { if(newVal > -1) - mySystem.poke(COLUPF, newVal); + mySystem.pokeOob(COLUPF, newVal); return myTIA.registerValue(COLUPF); } @@ -623,7 +623,7 @@ uInt8 TIADebug::coluPF(int newVal) uInt8 TIADebug::coluBK(int newVal) { if(newVal > -1) - mySystem.poke(COLUBK, newVal); + mySystem.pokeOob(COLUBK, newVal); return myTIA.registerValue(COLUBK); } @@ -632,7 +632,7 @@ uInt8 TIADebug::coluBK(int newVal) uInt8 TIADebug::nusiz0(int newVal) { if(newVal > -1) - mySystem.poke(NUSIZ0, newVal); + mySystem.pokeOob(NUSIZ0, newVal); return myTIA.registerValue(NUSIZ0); } @@ -641,7 +641,7 @@ uInt8 TIADebug::nusiz0(int newVal) uInt8 TIADebug::nusiz1(int newVal) { if(newVal > -1) - mySystem.poke(NUSIZ1, newVal); + mySystem.pokeOob(NUSIZ1, newVal); return myTIA.registerValue(NUSIZ1); } @@ -653,7 +653,7 @@ uInt8 TIADebug::nusizP0(int newVal) { uInt8 tmp = myTIA.registerValue(NUSIZ0) & ~0x07; tmp |= (newVal & 0x07); - mySystem.poke(NUSIZ0, tmp); + mySystem.pokeOob(NUSIZ0, tmp); } return myTIA.registerValue(NUSIZ0) & 0x07; @@ -666,7 +666,7 @@ uInt8 TIADebug::nusizP1(int newVal) { uInt8 tmp = myTIA.registerValue(NUSIZ1) & ~0x07; tmp |= newVal & 0x07; - mySystem.poke(NUSIZ1, tmp); + mySystem.pokeOob(NUSIZ1, tmp); } return myTIA.registerValue(NUSIZ1) & 0x07; @@ -679,7 +679,7 @@ uInt8 TIADebug::nusizM0(int newVal) { uInt8 tmp = myTIA.registerValue(NUSIZ0) & ~0x30; tmp |= (newVal & 0x04) << 4; - mySystem.poke(NUSIZ0, tmp); + mySystem.pokeOob(NUSIZ0, tmp); } return (myTIA.registerValue(NUSIZ0) & 0x30) >> 4; @@ -692,7 +692,7 @@ uInt8 TIADebug::nusizM1(int newVal) { uInt8 tmp = myTIA.registerValue(NUSIZ1) & ~0x30; tmp |= (newVal & 0x04) << 4; - mySystem.poke(NUSIZ1, tmp); + mySystem.pokeOob(NUSIZ1, tmp); } return (myTIA.registerValue(NUSIZ1) & 0x30) >> 4; @@ -702,7 +702,7 @@ uInt8 TIADebug::nusizM1(int newVal) uInt8 TIADebug::grP0(int newVal) { if(newVal > -1) - mySystem.poke(GRP0, newVal); + mySystem.pokeOob(GRP0, newVal); return myTIA.registerValue(GRP0); } @@ -711,7 +711,7 @@ uInt8 TIADebug::grP0(int newVal) uInt8 TIADebug::grP1(int newVal) { if(newVal > -1) - mySystem.poke(GRP1, newVal); + mySystem.pokeOob(GRP1, newVal); return myTIA.registerValue(GRP1); } @@ -765,7 +765,7 @@ uInt8 TIADebug::posBL(int newVal) uInt8 TIADebug::ctrlPF(int newVal) { if(newVal > -1) - mySystem.poke(CTRLPF, newVal); + mySystem.pokeOob(CTRLPF, newVal); return myTIA.registerValue(CTRLPF); } @@ -777,7 +777,7 @@ uInt8 TIADebug::sizeBL(int newVal) { uInt8 tmp = myTIA.registerValue(CTRLPF) & ~0x30; tmp |= (newVal & 0x04) << 4; - mySystem.poke(CTRLPF, tmp); + mySystem.pokeOob(CTRLPF, tmp); } return (myTIA.registerValue(CTRLPF) & 0x30) >> 4; @@ -787,7 +787,7 @@ uInt8 TIADebug::sizeBL(int newVal) uInt8 TIADebug::hmP0(int newVal) { if(newVal > -1) - mySystem.poke(HMP0, newVal << 4); + mySystem.pokeOob(HMP0, newVal << 4); return myTIA.registerValue(HMP0) >> 4; } @@ -796,7 +796,7 @@ uInt8 TIADebug::hmP0(int newVal) uInt8 TIADebug::hmP1(int newVal) { if(newVal > -1) - mySystem.poke(HMP1, newVal << 4); + mySystem.pokeOob(HMP1, newVal << 4); return myTIA.registerValue(HMP1) >> 4; } @@ -805,7 +805,7 @@ uInt8 TIADebug::hmP1(int newVal) uInt8 TIADebug::hmM0(int newVal) { if(newVal > -1) - mySystem.poke(HMM0, newVal << 4); + mySystem.pokeOob(HMM0, newVal << 4); return myTIA.registerValue(HMM0) >> 4; } @@ -814,7 +814,7 @@ uInt8 TIADebug::hmM0(int newVal) uInt8 TIADebug::hmM1(int newVal) { if(newVal > -1) - mySystem.poke(HMM1, newVal << 4); + mySystem.pokeOob(HMM1, newVal << 4); return myTIA.registerValue(HMM1) >> 4; } @@ -823,7 +823,7 @@ uInt8 TIADebug::hmM1(int newVal) uInt8 TIADebug::hmBL(int newVal) { if(newVal > -1) - mySystem.poke(HMBL, newVal << 4); + mySystem.pokeOob(HMBL, newVal << 4); return myTIA.registerValue(HMBL) >> 4; } @@ -849,61 +849,61 @@ void TIADebug::setENABLOld(bool b) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIADebug::strobeWsync() { - mySystem.poke(WSYNC, 0); + mySystem.pokeOob(WSYNC, 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIADebug::strobeRsync() { - mySystem.poke(RSYNC, 0); + mySystem.pokeOob(RSYNC, 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIADebug::strobeResP0() { - mySystem.poke(RESP0, 0); + mySystem.pokeOob(RESP0, 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIADebug::strobeResP1() { - mySystem.poke(RESP1, 0); + mySystem.pokeOob(RESP1, 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIADebug::strobeResM0() { - mySystem.poke(RESM0, 0); + mySystem.pokeOob(RESM0, 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIADebug::strobeResM1() { - mySystem.poke(RESM1, 0); + mySystem.pokeOob(RESM1, 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIADebug::strobeResBL() { - mySystem.poke(RESBL, 0); + mySystem.pokeOob(RESBL, 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIADebug::strobeHmove() { - mySystem.poke(HMOVE, 0); + mySystem.pokeOob(HMOVE, 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIADebug::strobeHmclr() { - mySystem.poke(HMCLR, 0); + mySystem.pokeOob(HMCLR, 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIADebug::strobeCxclr() { - mySystem.poke(CXCLR, 0); + mySystem.pokeOob(CXCLR, 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -964,7 +964,7 @@ int TIADebug::cyclesThisLine() const bool TIADebug::vsync(int newVal) { if (newVal > -1) - mySystem.poke(VSYNC, newVal); + mySystem.pokeOob(VSYNC, newVal); return myTIA.registerValue(VSYNC) & 0x02; } @@ -979,7 +979,7 @@ bool TIADebug::vsync() const bool TIADebug::vblank(int newVal) { if (newVal > -1) - mySystem.poke(VBLANK, newVal); + mySystem.pokeOob(VBLANK, newVal); return myTIA.registerValue(VBLANK) & 0x02; } diff --git a/src/debugger/gui/DebuggerDialog.hxx b/src/debugger/gui/DebuggerDialog.hxx index 132ab983b..0291c62e4 100644 --- a/src/debugger/gui/DebuggerDialog.hxx +++ b/src/debugger/gui/DebuggerDialog.hxx @@ -67,7 +67,7 @@ class DebuggerDialog : public Dialog TiaOutputWidget& tiaOutput() const { return *myTiaOutput; } TiaZoomWidget& tiaZoom() const { return *myTiaZoom; } RomWidget& rom() const { return *myRom; } - CartDebugWidget& cartDebug() const { return *myCartDebug; } + CartDebugWidget* cartDebug() const { return myCartDebug; } CartRamWidget& cartRam() const { return *myCartRam; } EditTextWidget& message() const { return *myMessageBox; } ButtonWidget& rewindButton() const { return *myRewindButton; } diff --git a/src/emucore/CartAR.cxx b/src/emucore/CartAR.cxx index acdacd68d..2f7e78c07 100644 --- a/src/emucore/CartAR.cxx +++ b/src/emucore/CartAR.cxx @@ -337,9 +337,9 @@ void CartridgeAR::loadIntoRAM(uInt8 load) // Copy the bank switching byte and starting address into the 2600's // RAM for the "dummy" SC BIOS to access it - mySystem->poke(0xfe, myHeader[0]); - mySystem->poke(0xff, myHeader[1]); - mySystem->poke(0x80, myHeader[2]); + mySystem->pokeOob(0xfe, myHeader[0]); + mySystem->pokeOob(0xff, myHeader[1]); + mySystem->pokeOob(0x80, myHeader[2]); myBankChanged = true; if(success) diff --git a/src/emucore/CartELF.cxx b/src/emucore/CartELF.cxx index 462fbda6b..85b8d0a6b 100644 --- a/src/emucore/CartELF.cxx +++ b/src/emucore/CartELF.cxx @@ -23,7 +23,41 @@ #include "CartELF.hxx" namespace { - constexpr size_t READ_STREAM_CAPACITY = 512; + constexpr size_t READ_STREAM_CAPACITY = 1024; + + constexpr uInt8 OVERBLANK_PROGRAM[] = { + 0xa0,0x00, // ldy #0 + 0xa5,0xe0, // lda $e0 + // OverblankLoop: + 0x85,0x02, // sta WSYNC + 0x85,0x2d, // sta AUDV0 (currently using $2d instead to disable audio until fully implemented + 0x98, // tya + 0x18, // clc + 0x6a, // ror + 0xaa, // tax + 0xb5,0xe0, // lda $e0,x + 0x90,0x04, // bcc + 0x4a, // lsr + 0x4a, // lsr + 0x4a, // lsr + 0x4a, // lsr + 0xc8, // iny + 0xc0, 0x1d, // cpy #$1d + 0xd0, 0x04, // bne + 0xa2, 0x02, // ldx #2 + 0x86, 0x00, // stx VSYNC + 0xc0, 0x20, // cpy #$20 + 0xd0, 0x04, // bne SkipClearVSync + 0xa2, 0x00, // ldx #0 + 0x86, 0x00, // stx VSYNC + // SkipClearVSync: + 0xc0, 0x3f, // cpy #$3f + 0xd0, 0xdb, // bne OverblankLoop + // WaitForCart: + 0xae, 0xff, 0xff, // ldx $ffff + 0xd0, 0xfb, // bne WaitForCart + 0x4c, 0x00, 0x10 // jmp $1000 + }; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -34,6 +68,9 @@ CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5 myImage = make_unique(size); std::memcpy(myImage.get(), image.get(), size); + myLastPeekResult = make_unique(0x1000); + std::fill_n(myLastPeekResult.get(), 0x1000, 0); + createRomAccessArrays(0x1000); } @@ -44,7 +81,15 @@ CartridgeELF::~CartridgeELF() {} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeELF::reset() { - myReadStream.Reset(); + std::fill_n(myLastPeekResult.get(), 0x1000, 0); + + myReadStream.reset(); + myReadStream.push(0x00, 0x0ffc); + myReadStream.push(0x10); + myReadStream.setNextPushAddress(0); + + vcsCopyOverblankToRiotRam(); + vcsStartOverblank(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -76,7 +121,16 @@ bool CartridgeELF::load(Serializer& in) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeELF::peek(uInt16 address) { - return myReadStream.Pop(address); + if (myReadStream.isYield()) return mySystem->getDataBusState(); + + myLastPeekResult[address & 0xfff] = myReadStream.pop(address); + return myLastPeekResult[address & 0xfff]; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt8 CartridgeELF::peekOob(uInt16 address) +{ + return myLastPeekResult[address & 0xfff]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -92,30 +146,62 @@ const ByteBuffer& CartridgeELF::getImage(size_t& size) const return myImage; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeELF::vcsWrite5(uInt8 zpAddress, uInt8 value) +{ + myReadStream.push(0xa9); + myReadStream.push(value); + myReadStream.push(0x85); + myReadStream.push(zpAddress); + myReadStream.yield(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeELF::vcsCopyOverblankToRiotRam() +{ + for (size_t i = 0; i < sizeof(OVERBLANK_PROGRAM); i++) + vcsWrite5(0x80 + i, OVERBLANK_PROGRAM[i]); +} + +void CartridgeELF::vcsStartOverblank() +{ + myReadStream.push(0x4c); + myReadStream.push(0x80); + myReadStream.push(0x00); + myReadStream.yield(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeELF::ReadStream::ReadStream() { myStream = make_unique(READ_STREAM_CAPACITY); - Reset(); + reset(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeELF::ReadStream::Reset() +void CartridgeELF::ReadStream::reset() { - myStreamNext = myStreamSize = 0; + myStreamNext = myStreamSize = myNextPushAddress = 0; + myIsYield = true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeELF::ReadStream::Push(uInt8 value) +void CartridgeELF::ReadStream::setNextPushAddress(uInt16 address) { - if (myNextReadAddress == 0xfff) - throw FatalEmulationError("read stream has reached the end of address space"); - - Push(value, myNextReadAddress + 1); + myNextPushAddress = address; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeELF::ReadStream::Push(uInt8 value, uInt8 address) +void CartridgeELF::ReadStream::push(uInt8 value) +{ + if (myNextPushAddress > 0xfff) + throw FatalEmulationError("read stream pointer overflow"); + + push(value, myNextPushAddress); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeELF::ReadStream::push(uInt8 value, uInt16 address) { if (myStreamSize == READ_STREAM_CAPACITY) throw FatalEmulationError("read stream overflow"); @@ -123,37 +209,57 @@ void CartridgeELF::ReadStream::Push(uInt8 value, uInt8 address) address &= 0xfff; myStream[(myStreamNext + myStreamSize++) % READ_STREAM_CAPACITY] = - {.address = address, .value = value}; + {.address = address, .value = value, .yield = false}; + + myNextPushAddress = address + 1; + myIsYield = false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeELF::ReadStream::HasPendingRead() const +void CartridgeELF::ReadStream::yield() +{ + if (myStreamSize == 0) + throw new FatalEmulationError("yield called on empty stream"); + + myStream[(myStreamNext + myStreamSize - 1) % READ_STREAM_CAPACITY].yield = true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeELF::ReadStream::isYield() const +{ + return myIsYield; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeELF::ReadStream::hasPendingRead() const { return myStreamSize > 0; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeELF::ReadStream::GetNextReadAddress() const +uInt8 CartridgeELF::ReadStream::pop(uInt16 readAddress) { - return myNextReadAddress; -} + if (myStreamSize == 0) { + ostringstream s; + s << "read stream underflow at 0x" << std::hex << std::setw(4) << readAddress; + throw FatalEmulationError(s.str()); + } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeELF::ReadStream::Pop(uInt16 readAddress) -{ - if (myStreamSize == 0) - throw FatalEmulationError("read stream underflow"); - - if ((readAddress & 0xfff) != myNextReadAddress) + if ((readAddress & 0xfff) != myStream[myStreamNext].address) { ostringstream s; - s << "unexcpected cartridge read from 0x" << std::hex << std::setw(4) << readAddress; + s << + "unexcpected cartridge read from 0x" << std::hex << std::setw(4) << + std::setfill('0') << (readAddress & 0xfff) << " expected 0x" << myStream[myStreamNext].address; throw FatalEmulationError(s.str()); } + myIsYield = myStream[myStreamNext].yield && myStreamSize == 1; const uInt8 value = myStream[myStreamNext++].value; + myStreamNext %= READ_STREAM_CAPACITY; + myStreamSize--; return value; } diff --git a/src/emucore/CartELF.hxx b/src/emucore/CartELF.hxx index c13003b94..5b1d9ad7a 100644 --- a/src/emucore/CartELF.hxx +++ b/src/emucore/CartELF.hxx @@ -38,6 +38,7 @@ class CartridgeELF: public Cartridge { bool load(Serializer& in) override; uInt8 peek(uInt16 address) override; + uInt8 peekOob(uInt16 address) override; bool poke(uInt16 address, uInt8 value) override; @@ -51,31 +52,42 @@ class CartridgeELF: public Cartridge { string name() const override { return "CartridgeELF"; }; + private: + void vcsWrite5(uInt8 zpAddress, uInt8 value); + void vcsCopyOverblankToRiotRam(); + void vcsStartOverblank(); + private: struct ScheduledRead { uInt16 address; uInt8 value; + bool yield; }; class ReadStream { public: ReadStream(); - void Reset(); + void reset(); - void Push(uInt8 value); - void Push(uInt8 value, uInt8 address); + void setNextPushAddress(uInt16 address); + void push(uInt8 value); + void push(uInt8 value, uInt16 address); - bool HasPendingRead() const; - uInt16 GetNextReadAddress() const; - uInt8 Pop(uInt16 readAddress); + void yield(); + bool isYield() const; + + bool hasPendingRead() const; + uInt8 pop(uInt16 readAddress); private: unique_ptr myStream; size_t myStreamNext{0}; size_t myStreamSize{0}; - uInt16 myNextReadAddress{0}; + uInt16 myNextPushAddress{0}; + + bool myIsYield{true}; }; private: @@ -84,6 +96,7 @@ class CartridgeELF: public Cartridge { System* mySystem{nullptr}; + unique_ptr myLastPeekResult; ReadStream myReadStream; }; diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index ee5e98c6b..5c2e4e44c 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -374,7 +374,7 @@ bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) // However, the patch command is special in that ignores such // cart restrictions myRAM[address & myRamMask] = value; - mySystem->poke(address, value); // keep RIOT RAM in sync + mySystem->pokeOob(address, value); // keep RIOT RAM in sync } else myImage[romAddressSegmentOffset(address) + (address & myBankMask)] = value; diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 0d9a68a86..eab10ac92 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -789,7 +789,7 @@ void Console::initializeAudio() void Console::fry() const { for(int i = 0; i < 0x100; i += mySystem->randGenerator().next() % 4) - mySystem->poke(i, mySystem->peek(i) & mySystem->randGenerator().next()); + mySystem->pokeOob(i, mySystem->peekOob(i) & mySystem->randGenerator().next()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Device.hxx b/src/emucore/Device.hxx index ac04324a2..09461698c 100644 --- a/src/emucore/Device.hxx +++ b/src/emucore/Device.hxx @@ -119,6 +119,7 @@ class Device : public Serializable @return The byte at the specified address */ virtual uInt8 peek(uInt16 address) = 0; + virtual uInt8 peekOob(uInt16 address) { return peek(address); }; /** Change the byte at the specified address to the given value @@ -129,6 +130,7 @@ class Device : public Serializable @return True if the poke changed the device address space, else false */ virtual bool poke(uInt16 address, uInt8 value) { return false; } + virtual bool pokeOob(uInt16 address, uInt8 value) { return poke(address, value); } #ifdef DEBUGGER_SUPPORT /** diff --git a/src/emucore/System.cxx b/src/emucore/System.cxx index 216e4b313..6764ed414 100644 --- a/src/emucore/System.cxx +++ b/src/emucore/System.cxx @@ -97,7 +97,8 @@ void System::clearDirtyPages() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 System::peek(uInt16 addr, Device::AccessFlags flags) +template +uInt8 System::peekImpl(uInt16 addr, Device::AccessFlags flags) { const PageAccess& access = getPageAccess(addr); @@ -120,7 +121,7 @@ uInt8 System::peek(uInt16 addr, Device::AccessFlags flags) // See if this page uses direct accessing or not const uInt8 result = access.directPeekBase ? *(access.directPeekBase + (addr & PAGE_MASK)) - : access.device->peek(addr); + : (oob ? access.device->peekOob(addr) : access.device->peek(addr)); #ifdef DEBUGGER_SUPPORT if(!myDataBusLocked) @@ -130,8 +131,15 @@ uInt8 System::peek(uInt16 addr, Device::AccessFlags flags) return result; } +template +uInt8 System::peekImpl(uInt16 addr, Device::AccessFlags flags); + +template +uInt8 System::peekImpl(uInt16 addr, Device::AccessFlags flags); + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void System::poke(uInt16 addr, uInt8 value, Device::AccessFlags flags) +template +void System::pokeImpl(uInt16 addr, uInt8 value, Device::AccessFlags flags) { const uInt16 page = (addr & ADDRESS_MASK) >> PAGE_SHIFT; const PageAccess& access = myPageAccessTable[page]; @@ -162,7 +170,7 @@ void System::poke(uInt16 addr, uInt8 value, Device::AccessFlags flags) else { // The specific device informs us if the poke succeeded - myPageIsDirtyTable[page] = access.device->poke(addr, value); + myPageIsDirtyTable[page] = oob ? access.device->pokeOob(addr, value) : access.device->poke(addr, value); } #ifdef DEBUGGER_SUPPORT @@ -171,6 +179,12 @@ void System::poke(uInt16 addr, uInt8 value, Device::AccessFlags flags) myDataBusState = value; } +template +void System::pokeImpl(uInt16 addr, uInt8 value, Device::AccessFlags flags); + +template +void System::pokeImpl(uInt16 addr, uInt8 value, Device::AccessFlags flags); + #ifdef DEBUGGER_SUPPORT // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Device::AccessFlags System::getAccessFlags(uInt16 addr) const diff --git a/src/emucore/System.hxx b/src/emucore/System.hxx index 644ffee59..f58f2077c 100644 --- a/src/emucore/System.hxx +++ b/src/emucore/System.hxx @@ -169,32 +169,36 @@ class System : public Serializable uInt8 getDataBusState() const { return myDataBusState; } /** - Get the byte at the specified address. No masking of the - address occurs before it's sent to the device mapped at - the address. - - @param address The address from which the value should be loaded - @param flags Indicates that this address has the given flags - for type of access (CODE, DATA, GFX, etc) - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address, Device::AccessFlags flags = Device::NONE); + * See peekImpl below. + */ + inline uInt8 peek(uInt16 address, Device::AccessFlags flags = Device::NONE) + { + return peekImpl(address, flags); + } /** - Change the byte at the specified address to the given value. - No masking of the address occurs before it's sent to the device - mapped at the address. + * See peekImpl below. + */ + inline uInt8 peekOob(uInt16 address, Device::AccessFlags flags = Device::NONE) + { + return peekImpl(address, flags); + } - This method sets the 'page dirty' if the write succeeds. In the - case of direct-access pokes, the write always succeeds. Otherwise, - if the device is handling the poke, we depend on its return value - for this information. + /** + * See pokeImpl below. + */ + inline void poke(uInt16 address, uInt8 value, Device::AccessFlags flags = Device::NONE) + { + pokeImpl(address, value, flags); + } - @param address The address where the value should be stored - @param value The value to be stored at the address - */ - void poke(uInt16 address, uInt8 value, Device::AccessFlags flags = Device::NONE); + /** + * See pokeImpl below. + */ + inline void pokeOob(uInt16 address, uInt8 value, Device::AccessFlags flags = Device::NONE) + { + pokeImpl(address, value, flags); + } /** Lock/unlock the data bus. When the bus is locked, peek() and @@ -365,6 +369,41 @@ class System : public Serializable */ bool load(Serializer& in) override; + private: + /** + Get the byte at the specified address. No masking of the + address occurs before it's sent to the device mapped at + the address. + + @param oob Out-of-band peeks are not part of the activity of the + emulated system + @param address The address from which the value should be loaded + @param flags Indicates that this address has the given flags + for type of access (CODE, DATA, GFX, etc) + + @return The byte at the specified address + */ + template + uInt8 peekImpl(uInt16 address, Device::AccessFlags flags); + + /** + Change the byte at the specified address to the given value. + No masking of the address occurs before it's sent to the device + mapped at the address. + + This method sets the 'page dirty' if the write succeeds. In the + case of direct-access pokes, the write always succeeds. Otherwise, + if the device is handling the poke, we depend on its return value + for this information. + + @param oob Out-of-band peeks are not part of the activity of the + emulated system + @param address The address where the value should be stored + @param value The value to be stored at the address + */ + template + void pokeImpl(uInt16 address, uInt8 value, Device::AccessFlags flags); + private: // The system RNG Random& myRandom;