mirror of https://github.com/stella-emu/stella.git
Boot into overblank.
This commit is contained in:
parent
41c8bff0c6
commit
fe6e67de32
|
@ -55,5 +55,5 @@ bool RamCheat::disable()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RamCheat::evaluate()
|
||||
{
|
||||
myOSystem.console().system().poke(address, value);
|
||||
myOSystem.console().system().pokeOob(address, value);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<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.
|
||||
* See peekImpl below.
|
||||
*/
|
||||
inline uInt8 peekOob(uInt16 address, Device::AccessFlags flags = Device::NONE)
|
||||
{
|
||||
return peekImpl<true>(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<false>(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<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;
|
||||
|
|
Loading…
Reference in New Issue