mirror of https://github.com/stella-emu/stella.git
More carts converted to new RWP code.
This commit is contained in:
parent
9aaf8b22b5
commit
dea62573f8
|
@ -85,16 +85,7 @@ uInt8 Cartridge3E::peek(uInt16 address)
|
|||
else
|
||||
{
|
||||
// Reading from the write port triggers an unwanted write
|
||||
uInt8 value = mySystem->getDataBusState(0xFF);
|
||||
|
||||
if(bankLocked())
|
||||
return value;
|
||||
else
|
||||
{
|
||||
myRAM[(address & 0x03FF) + ((myCurrentBank - 256) << 10)] = value;
|
||||
triggerReadFromWritePort(peekAddress);
|
||||
return value;
|
||||
}
|
||||
return peekRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - 256) << 10)], peekAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,23 +98,24 @@ uInt8 Cartridge3E::peek(uInt16 address)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge3E::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
uInt16 pokeAddress = address;
|
||||
address &= 0x0FFF;
|
||||
|
||||
// Switch banks if necessary. Armin (Kroko) says there are no mirrored
|
||||
// hotspots.
|
||||
if(address < 0x0040)
|
||||
{
|
||||
if(address == 0x003F)
|
||||
{
|
||||
bank(value);
|
||||
}
|
||||
else if(address == 0x003E)
|
||||
{
|
||||
bank(value + 256);
|
||||
|
||||
return mySystem->tia().poke(address, value);
|
||||
}
|
||||
else
|
||||
pokeRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - 256) << 10)], pokeAddress, value);
|
||||
|
||||
// Handle TIA space that we claimed above
|
||||
mySystem->tia().poke(address, value);
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -181,9 +173,10 @@ bool Cartridge3E::bank(uInt16 bank)
|
|||
access.type = System::PA_WRITE;
|
||||
|
||||
// Map write-port RAM image into the system
|
||||
// Map access to this class, since we need to inspect all accesses to
|
||||
// check if RWP happens
|
||||
for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPokeBase = &myRAM[offset + (addr & 0x03FF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[mySize + offset + (addr & 0x03FF)];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
|
|
@ -125,16 +125,7 @@ uInt8 CartridgeCTY::peek(uInt16 address)
|
|||
if(address < 0x0040) // Write port is at $1000 - $103F (64 bytes)
|
||||
{
|
||||
// Reading from the write port triggers an unwanted write
|
||||
uInt8 value = mySystem->getDataBusState(0xFF);
|
||||
|
||||
if(bankLocked())
|
||||
return value;
|
||||
else
|
||||
{
|
||||
myRAM[address] = value;
|
||||
triggerReadFromWritePort(peekAddress);
|
||||
return value;
|
||||
}
|
||||
return peekRAM(myRAM[address], peekAddress);
|
||||
}
|
||||
else if(address < 0x0080) // Read port is at $1040 - $107F (64 bytes)
|
||||
{
|
||||
|
@ -186,9 +177,9 @@ uInt8 CartridgeCTY::peek(uInt16 address)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeCTY::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
uInt16 pokeAddress = address;
|
||||
address &= 0x0FFF;
|
||||
|
||||
//cerr << "POKE: address=" << HEX4 << address << ", value=" << HEX2 << value << endl;
|
||||
if(address < 0x0040) // Write port is at $1000 - $103F (64 bytes)
|
||||
{
|
||||
switch(address)
|
||||
|
@ -212,7 +203,7 @@ bool CartridgeCTY::poke(uInt16 address, uInt8 value)
|
|||
updateTune();
|
||||
break;
|
||||
default:
|
||||
myRAM[address] = value;
|
||||
pokeRAM(myRAM[address], pokeAddress, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,14 +74,13 @@ void CartridgeCV::install(System& system)
|
|||
}
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
// Map access to this class, since we need to inspect all accesses to
|
||||
// check if RWP happens
|
||||
access.directPeekBase = nullptr;
|
||||
access.codeAccessBase = nullptr;
|
||||
access.type = System::PA_WRITE;
|
||||
for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPokeBase = &myRAM[addr & 0x03FF];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
access.directPokeBase = nullptr;
|
||||
|
@ -99,17 +98,15 @@ uInt8 CartridgeCV::peek(uInt16 address)
|
|||
{
|
||||
// The only way we can get to this method is if we attempt to read from
|
||||
// the write port (0xF400 - 0xF7FF, 1024 bytes), in which case an
|
||||
// unwanted write is triggered
|
||||
uInt8 value = mySystem->getDataBusState(0xFF);
|
||||
|
||||
if(bankLocked())
|
||||
return value;
|
||||
else
|
||||
{
|
||||
myRAM[address & 0x03FF] = value;
|
||||
triggerReadFromWritePort(address);
|
||||
return value;
|
||||
// unwanted write is potentially triggered
|
||||
return peekRAM(myRAM[address & 0x03FF], address);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeCV::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
pokeRAM(myRAM[address & 0x03FF], address, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -124,6 +124,15 @@ class CartridgeCV : public Cartridge
|
|||
*/
|
||||
uInt8 peek(uInt16 address) override;
|
||||
|
||||
/**
|
||||
Change the byte at the specified address to the given value
|
||||
|
||||
@param address The address where the value should be stored
|
||||
@param value The value to be stored at the address
|
||||
@return True if the poke changed the device address space, else false
|
||||
*/
|
||||
bool poke(uInt16 address, uInt8 value) override;
|
||||
|
||||
private:
|
||||
// Pointer to the initial RAM data from the cart
|
||||
// This doesn't always exist, so we don't pre-allocate it
|
||||
|
|
|
@ -56,18 +56,18 @@ void CartridgeCVPlus::install(System& system)
|
|||
mySystem->setPageAccess(addr, access);
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
access.directPeekBase = nullptr;
|
||||
// Map access to this class, since we need to inspect all accesses to
|
||||
// check if RWP happens
|
||||
access.directPeekBase = access.directPokeBase = nullptr;
|
||||
access.codeAccessBase = nullptr;
|
||||
access.type = System::PA_WRITE;
|
||||
for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPokeBase = &myRAM[addr & 0x03FF];
|
||||
access.codeAccessBase = &myCodeAccessBase[mySize + (addr & 0x03FF)];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
access.directPokeBase = nullptr;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt16 addr = 0x1000; addr < 0x1400; addr += System::PAGE_SIZE)
|
||||
{
|
||||
|
@ -84,19 +84,7 @@ void CartridgeCVPlus::install(System& system)
|
|||
uInt8 CartridgeCVPlus::peek(uInt16 address)
|
||||
{
|
||||
if((address & 0x0FFF) < 0x0800) // Write port is at 0xF400 - 0xF7FF (1024 bytes)
|
||||
{ // Read port is handled in ::install()
|
||||
// Reading from the write port triggers an unwanted write
|
||||
uInt8 value = mySystem->getDataBusState(0xFF);
|
||||
|
||||
if(bankLocked())
|
||||
return value;
|
||||
else
|
||||
{
|
||||
myRAM[address & 0x03FF] = value;
|
||||
triggerReadFromWritePort(address);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return peekRAM(myRAM[address & 0x03FF], address);
|
||||
else
|
||||
return myImage[(address & 0x07FF) + (myCurrentBank << 11)];
|
||||
}
|
||||
|
@ -104,16 +92,22 @@ uInt8 CartridgeCVPlus::peek(uInt16 address)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeCVPlus::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
uInt16 pokeAddress = address;
|
||||
address &= 0x0FFF;
|
||||
|
||||
if(address < 0x0040)
|
||||
{
|
||||
// Switch banks if necessary
|
||||
if(address == 0x003D)
|
||||
bank(value);
|
||||
|
||||
// Handle TIA space that we claimed above
|
||||
mySystem->tia().poke(address, value);
|
||||
return mySystem->tia().poke(address, value);
|
||||
}
|
||||
else
|
||||
pokeRAM(myRAM[address & 0x03FF], pokeAddress, value);
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -47,16 +47,16 @@ void CartridgeFA::install(System& system)
|
|||
System::PageAccess access(this, System::PA_READ);
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
// Map access to this class, since we need to inspect all accesses to
|
||||
// check if RWP happens
|
||||
access.type = System::PA_WRITE;
|
||||
for(uInt16 addr = 0x1000; addr < 0x1100; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPokeBase = &myRAM[addr & 0x00FF];
|
||||
access.codeAccessBase = &myCodeAccessBase[addr & 0x00FF];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
access.directPokeBase = nullptr;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt16 addr = 0x1100; addr < 0x1200; addr += System::PAGE_SIZE)
|
||||
{
|
||||
|
@ -98,54 +98,38 @@ uInt8 CartridgeFA::peek(uInt16 address)
|
|||
}
|
||||
|
||||
if(address < 0x0100) // Write port is at 0xF000 - 0xF0FF (256 bytes)
|
||||
{
|
||||
// Reading from the write port triggers an unwanted write
|
||||
uInt8 value = mySystem->getDataBusState(0xFF);
|
||||
|
||||
if(bankLocked())
|
||||
return value;
|
||||
else
|
||||
{
|
||||
myRAM[address] = value;
|
||||
triggerReadFromWritePort(peekAddress);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return peekRAM(myRAM[address], peekAddress);
|
||||
else
|
||||
return myImage[myBankOffset + address];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeFA::poke(uInt16 address, uInt8)
|
||||
bool CartridgeFA::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
address &= 0x0FFF;
|
||||
|
||||
// Switch banks if necessary
|
||||
switch(address)
|
||||
switch(address & 0x0FFF)
|
||||
{
|
||||
case 0x0FF8:
|
||||
// Set the current bank to the lower 4k bank
|
||||
bank(0);
|
||||
break;
|
||||
return false;
|
||||
|
||||
case 0x0FF9:
|
||||
// Set the current bank to the middle 4k bank
|
||||
bank(1);
|
||||
break;
|
||||
return false;
|
||||
|
||||
case 0x0FFA:
|
||||
// Set the current bank to the upper 4k bank
|
||||
bank(2);
|
||||
break;
|
||||
return false;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// NOTE: This does not handle accessing RAM, however, this function
|
||||
// should never be called for RAM because of the way page accessing
|
||||
// has been setup
|
||||
return false;
|
||||
pokeRAM(myRAM[address & 0x00FF], address, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -59,10 +59,11 @@ void CartridgeFA2::install(System& system)
|
|||
System::PageAccess access(this, System::PA_READ);
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
// Map access to this class, since we need to inspect all accesses to
|
||||
// check if RWP happens
|
||||
access.type = System::PA_WRITE;
|
||||
for(uInt16 addr = 0x1000; addr < 0x1100; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPokeBase = &myRAM[addr & 0x00FF];
|
||||
access.codeAccessBase = &myCodeAccessBase[addr & 0x00FF];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
@ -137,81 +138,65 @@ uInt8 CartridgeFA2::peek(uInt16 address)
|
|||
}
|
||||
|
||||
if(address < 0x0100) // Write port is at 0xF000 - 0xF0FF (256 bytes)
|
||||
{
|
||||
// Reading from the write port triggers an unwanted write
|
||||
uInt8 value = mySystem->getDataBusState(0xFF);
|
||||
|
||||
if(bankLocked())
|
||||
return value;
|
||||
else
|
||||
{
|
||||
myRAM[address] = value;
|
||||
triggerReadFromWritePort(peekAddress);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return peekRAM(myRAM[address], peekAddress);
|
||||
else
|
||||
return myImage[myBankOffset + address];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeFA2::poke(uInt16 address, uInt8)
|
||||
bool CartridgeFA2::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
address &= 0x0FFF;
|
||||
|
||||
// Switch banks if necessary
|
||||
switch(address)
|
||||
switch(address & 0x0FFF)
|
||||
{
|
||||
case 0x0FF4:
|
||||
// Load/save RAM to/from Harmony cart flash
|
||||
if(mySize == 28*1024 && !bankLocked())
|
||||
ramReadWrite();
|
||||
break;
|
||||
return false;
|
||||
|
||||
case 0x0FF5:
|
||||
// Set the current bank to the first 4k bank
|
||||
bank(0);
|
||||
break;
|
||||
return false;
|
||||
|
||||
case 0x0FF6:
|
||||
// Set the current bank to the second 4k bank
|
||||
bank(1);
|
||||
break;
|
||||
return false;
|
||||
|
||||
case 0x0FF7:
|
||||
// Set the current bank to the third 4k bank
|
||||
bank(2);
|
||||
break;
|
||||
return false;
|
||||
|
||||
case 0x0FF8:
|
||||
// Set the current bank to the fourth 4k bank
|
||||
bank(3);
|
||||
break;
|
||||
return false;
|
||||
|
||||
case 0x0FF9:
|
||||
// Set the current bank to the fifth 4k bank
|
||||
bank(4);
|
||||
break;
|
||||
return false;
|
||||
|
||||
case 0x0FFA:
|
||||
// Set the current bank to the sixth 4k bank
|
||||
bank(5);
|
||||
break;
|
||||
return false;
|
||||
|
||||
case 0x0FFB:
|
||||
// Set the current bank to the seventh 4k bank
|
||||
// This is only available on 28K ROMs
|
||||
if(mySize == 28*1024) bank(6);
|
||||
break;
|
||||
return false;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// NOTE: This does not handle accessing RAM, however, this function
|
||||
// should never be called for RAM because of the way page accessing
|
||||
// has been setup
|
||||
return false;
|
||||
pokeRAM(myRAM[address & 0x00FF], address, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -255,7 +255,8 @@ bool CartridgeMNetwork::save(Serializer& out) const
|
|||
out.putShortArray(myCurrentSlice, NUM_SEGMENTS);
|
||||
out.putShort(myCurrentRAM);
|
||||
out.putByteArray(myRAM, RAM_SIZE);
|
||||
} catch(...)
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "ERROR: " << name() << "::save" << endl;
|
||||
return false;
|
||||
|
@ -272,7 +273,8 @@ bool CartridgeMNetwork::load(Serializer& in)
|
|||
in.getShortArray(myCurrentSlice, NUM_SEGMENTS);
|
||||
myCurrentRAM = in.getShort();
|
||||
in.getByteArray(myRAM, RAM_SIZE);
|
||||
} catch(...)
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "ERROR: " << name() << "::load" << endl;
|
||||
return false;
|
||||
|
@ -296,4 +298,3 @@ uInt32 CartridgeMNetwork::romSize() const
|
|||
{
|
||||
return bankCount() * BANK_SIZE;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,10 +62,11 @@ void CartridgeWD::install(System& system)
|
|||
}
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
// Map access to this class, since we need to inspect all accesses to
|
||||
// check if RWP happens
|
||||
System::PageAccess write(this, System::PA_WRITE);
|
||||
for(uInt16 addr = 0x1040; addr < 0x1080; addr += System::PAGE_SIZE)
|
||||
{
|
||||
write.directPokeBase = &myRAM[addr & 0x003F];
|
||||
write.codeAccessBase = &myCodeAccessBase[addr & 0x003F];
|
||||
mySystem->setPageAccess(addr, write);
|
||||
}
|
||||
|
@ -109,19 +110,8 @@ uInt8 CartridgeWD::peek(uInt16 address)
|
|||
if(address < 0x0040) // RAM read port
|
||||
return myRAM[address];
|
||||
else if(address < 0x0080) // RAM write port
|
||||
{
|
||||
// Reading from the write port @ $1040 - $107F triggers an unwanted write
|
||||
uInt8 value = mySystem->getDataBusState(0xFF);
|
||||
|
||||
if(bankLocked())
|
||||
return value;
|
||||
else
|
||||
{
|
||||
myRAM[address & 0x003F] = value;
|
||||
triggerReadFromWritePort(peekAddress);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return peekRAM(myRAM[address & 0x003F], peekAddress);
|
||||
else if(address < 0x0400)
|
||||
return myImage[myOffset[0] + (address & 0x03FF)];
|
||||
else if(address < 0x0800)
|
||||
|
@ -136,11 +126,12 @@ uInt8 CartridgeWD::peek(uInt16 address)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeWD::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
// Only TIA writes will reach here
|
||||
if(!(address & 0x1000))
|
||||
if(!(address & 0x1000)) // TIA addresses
|
||||
return mySystem->tia().poke(address, value);
|
||||
else
|
||||
return false;
|
||||
pokeRAM(myRAM[address & 0x003F], address, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
Loading…
Reference in New Issue