Boot into overblank.

This commit is contained in:
Christian Speckner 2024-06-30 17:16:32 +02:00
parent 41c8bff0c6
commit fe6e67de32
14 changed files with 317 additions and 143 deletions

View File

@ -55,5 +55,5 @@ bool RamCheat::disable()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RamCheat::evaluate()
{
myOSystem.console().system().poke(address, value);
myOSystem.console().system().pokeOob(address, value);
}

View File

@ -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);
}

View File

@ -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<uInt16>(mySystem.peek(addr, flags) |
(mySystem.peek(addr+1, flags) << 8));
return static_cast<uInt16>(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<uInt16>(addr), flags);
return mySystem.peekOob(static_cast<uInt16>(addr), flags);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Debugger::dpeekAsInt(int addr, Device::AccessFlags flags)
{
return mySystem.peek(static_cast<uInt16>(addr), flags) |
(mySystem.peek(static_cast<uInt16>(addr+1), flags) << 8);
return mySystem.peekOob(static_cast<uInt16>(addr), flags) |
(mySystem.peekOob(static_cast<uInt16>(addr+1), flags) << 8);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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<TIARegister, 6> _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();
}

View File

@ -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<bool>(newVal));
mySystem.pokeOob(VDELP0, static_cast<bool>(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<bool>(newVal));
mySystem.pokeOob(VDELP1, static_cast<bool>(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<bool>(newVal));
mySystem.pokeOob(VDELBL, static_cast<bool>(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<bool>(newVal) << 1);
mySystem.pokeOob(ENAM0, static_cast<bool>(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<bool>(newVal) << 1);
mySystem.pokeOob(ENAM1, static_cast<bool>(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<bool>(newVal) << 1);
mySystem.pokeOob(ENABL, static_cast<bool>(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<bool>(newVal) << 1);
mySystem.pokeOob(RESMP0, static_cast<bool>(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<bool>(newVal) << 1);
mySystem.pokeOob(RESMP1, static_cast<bool>(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<bool>(newVal) << 3);
mySystem.pokeOob(REFP0, static_cast<bool>(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<bool>(newVal) << 3);
mySystem.pokeOob(REFP1, static_cast<bool>(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;
}

View File

@ -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; }

View File

@ -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)

View File

@ -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<uInt8[]>(size);
std::memcpy(myImage.get(), image.get(), size);
myLastPeekResult = make_unique<uInt8[]>(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<ScheduledRead[]>(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;
}

View File

@ -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<ScheduledRead[]> 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<uint8_t[]> myLastPeekResult;
ReadStream myReadStream;
};

View File

@ -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;

View File

@ -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());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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
/**

View File

@ -97,7 +97,8 @@ void System::clearDirtyPages()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 System::peek(uInt16 addr, Device::AccessFlags flags)
template<bool oob>
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<true>(uInt16 addr, Device::AccessFlags flags);
template
uInt8 System::peekImpl<false>(uInt16 addr, Device::AccessFlags flags);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void System::poke(uInt16 addr, uInt8 value, Device::AccessFlags flags)
template<bool oob>
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<true>(uInt16 addr, uInt8 value, Device::AccessFlags flags);
template
void System::pokeImpl<false>(uInt16 addr, uInt8 value, Device::AccessFlags flags);
#ifdef DEBUGGER_SUPPORT
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Device::AccessFlags System::getAccessFlags(uInt16 addr) const

View File

@ -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
* See peekImpl below.
*/
uInt8 peek(uInt16 address, Device::AccessFlags flags = Device::NONE);
inline uInt8 peek(uInt16 address, Device::AccessFlags flags = Device::NONE)
{
return peekImpl<false>(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.
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 address The address where the value should be stored
@param value The value to be stored at the address
* See peekImpl below.
*/
void poke(uInt16 address, uInt8 value, Device::AccessFlags flags = Device::NONE);
inline uInt8 peekOob(uInt16 address, Device::AccessFlags flags = Device::NONE)
{
return peekImpl<true>(address, flags);
}
/**
* See pokeImpl below.
*/
inline void poke(uInt16 address, uInt8 value, Device::AccessFlags flags = Device::NONE)
{
pokeImpl<false>(address, value, flags);
}
/**
* See pokeImpl below.
*/
inline void pokeOob(uInt16 address, uInt8 value, Device::AccessFlags flags = Device::NONE)
{
pokeImpl<true>(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<bool oob = false>
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<bool oob = false>
void pokeImpl(uInt16 address, uInt8 value, Device::AccessFlags flags);
private:
// The system RNG
Random& myRandom;