More carts converted to new RWP code.

This commit is contained in:
Stephen Anthony 2018-12-17 21:25:08 -03:30
parent 9aaf8b22b5
commit dea62573f8
9 changed files with 89 additions and 144 deletions

View File

@ -85,16 +85,7 @@ uInt8 Cartridge3E::peek(uInt16 address)
else else
{ {
// Reading from the write port triggers an unwanted write // Reading from the write port triggers an unwanted write
uInt8 value = mySystem->getDataBusState(0xFF); return peekRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - 256) << 10)], peekAddress);
if(bankLocked())
return value;
else
{
myRAM[(address & 0x03FF) + ((myCurrentBank - 256) << 10)] = value;
triggerReadFromWritePort(peekAddress);
return value;
}
} }
} }
} }
@ -107,23 +98,24 @@ uInt8 Cartridge3E::peek(uInt16 address)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge3E::poke(uInt16 address, uInt8 value) bool Cartridge3E::poke(uInt16 address, uInt8 value)
{ {
uInt16 pokeAddress = address;
address &= 0x0FFF; address &= 0x0FFF;
// Switch banks if necessary. Armin (Kroko) says there are no mirrored // Switch banks if necessary. Armin (Kroko) says there are no mirrored
// hotspots. // hotspots.
if(address == 0x003F) if(address < 0x0040)
{ {
bank(value); if(address == 0x003F)
} bank(value);
else if(address == 0x003E) else if(address == 0x003E)
{ bank(value + 256);
bank(value + 256);
}
// Handle TIA space that we claimed above return mySystem->tia().poke(address, value);
mySystem->tia().poke(address, value); }
else
pokeRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - 256) << 10)], pokeAddress, value);
return false; return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -181,9 +173,10 @@ bool Cartridge3E::bank(uInt16 bank)
access.type = System::PA_WRITE; access.type = System::PA_WRITE;
// Map write-port RAM image into the system // 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) for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE)
{ {
access.directPokeBase = &myRAM[offset + (addr & 0x03FF)];
access.codeAccessBase = &myCodeAccessBase[mySize + offset + (addr & 0x03FF)]; access.codeAccessBase = &myCodeAccessBase[mySize + offset + (addr & 0x03FF)];
mySystem->setPageAccess(addr, access); mySystem->setPageAccess(addr, access);
} }

View File

@ -42,7 +42,7 @@ CartridgeCTY::CartridgeCTY(const BytePtr& image, uInt32 size,
memset(myTuneData, 0, 28*1024); memset(myTuneData, 0, 28*1024);
// Extract tune data if it exists // Extract tune data if it exists
if (size > 32768u) if(size > 32768u)
memcpy(myTuneData, image.get() + 32768u, size - 32768u); memcpy(myTuneData, image.get() + 32768u, size - 32768u);
// Point to the first tune // Point to the first tune
@ -125,16 +125,7 @@ uInt8 CartridgeCTY::peek(uInt16 address)
if(address < 0x0040) // Write port is at $1000 - $103F (64 bytes) if(address < 0x0040) // Write port is at $1000 - $103F (64 bytes)
{ {
// Reading from the write port triggers an unwanted write // Reading from the write port triggers an unwanted write
uInt8 value = mySystem->getDataBusState(0xFF); return peekRAM(myRAM[address], peekAddress);
if(bankLocked())
return value;
else
{
myRAM[address] = value;
triggerReadFromWritePort(peekAddress);
return value;
}
} }
else if(address < 0x0080) // Read port is at $1040 - $107F (64 bytes) 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) bool CartridgeCTY::poke(uInt16 address, uInt8 value)
{ {
uInt16 pokeAddress = address;
address &= 0x0FFF; address &= 0x0FFF;
//cerr << "POKE: address=" << HEX4 << address << ", value=" << HEX2 << value << endl;
if(address < 0x0040) // Write port is at $1000 - $103F (64 bytes) if(address < 0x0040) // Write port is at $1000 - $103F (64 bytes)
{ {
switch(address) switch(address)
@ -212,7 +203,7 @@ bool CartridgeCTY::poke(uInt16 address, uInt8 value)
updateTune(); updateTune();
break; break;
default: default:
myRAM[address] = value; pokeRAM(myRAM[address], pokeAddress, value);
break; break;
} }
} }

View File

@ -74,14 +74,13 @@ void CartridgeCV::install(System& system)
} }
// Set the page accessing method for the RAM writing pages // 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.directPeekBase = nullptr;
access.codeAccessBase = nullptr; access.codeAccessBase = nullptr;
access.type = System::PA_WRITE; access.type = System::PA_WRITE;
for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE) for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE)
{
access.directPokeBase = &myRAM[addr & 0x03FF];
mySystem->setPageAccess(addr, access); mySystem->setPageAccess(addr, access);
}
// Set the page accessing method for the RAM reading pages // Set the page accessing method for the RAM reading pages
access.directPokeBase = nullptr; 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 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 // the write port (0xF400 - 0xF7FF, 1024 bytes), in which case an
// unwanted write is triggered // unwanted write is potentially triggered
uInt8 value = mySystem->getDataBusState(0xFF); return peekRAM(myRAM[address & 0x03FF], address);
}
if(bankLocked()) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
return value; bool CartridgeCV::poke(uInt16 address, uInt8 value)
else {
{ pokeRAM(myRAM[address & 0x03FF], address, value);
myRAM[address & 0x03FF] = value; return true;
triggerReadFromWritePort(address);
return value;
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -124,6 +124,15 @@ class CartridgeCV : public Cartridge
*/ */
uInt8 peek(uInt16 address) override; 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: private:
// Pointer to the initial RAM data from the cart // Pointer to the initial RAM data from the cart
// This doesn't always exist, so we don't pre-allocate it // This doesn't always exist, so we don't pre-allocate it

View File

@ -56,18 +56,18 @@ void CartridgeCVPlus::install(System& system)
mySystem->setPageAccess(addr, access); mySystem->setPageAccess(addr, access);
// Set the page accessing method for the RAM writing pages // 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.codeAccessBase = nullptr;
access.type = System::PA_WRITE; access.type = System::PA_WRITE;
for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE) for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE)
{ {
access.directPokeBase = &myRAM[addr & 0x03FF];
access.codeAccessBase = &myCodeAccessBase[mySize + (addr & 0x03FF)]; access.codeAccessBase = &myCodeAccessBase[mySize + (addr & 0x03FF)];
mySystem->setPageAccess(addr, access); mySystem->setPageAccess(addr, access);
} }
// Set the page accessing method for the RAM reading pages // Set the page accessing method for the RAM reading pages
access.directPokeBase = nullptr;
access.type = System::PA_READ; access.type = System::PA_READ;
for(uInt16 addr = 0x1000; addr < 0x1400; addr += System::PAGE_SIZE) for(uInt16 addr = 0x1000; addr < 0x1400; addr += System::PAGE_SIZE)
{ {
@ -84,19 +84,7 @@ void CartridgeCVPlus::install(System& system)
uInt8 CartridgeCVPlus::peek(uInt16 address) uInt8 CartridgeCVPlus::peek(uInt16 address)
{ {
if((address & 0x0FFF) < 0x0800) // Write port is at 0xF400 - 0xF7FF (1024 bytes) if((address & 0x0FFF) < 0x0800) // Write port is at 0xF400 - 0xF7FF (1024 bytes)
{ // Read port is handled in ::install() return peekRAM(myRAM[address & 0x03FF], address);
// 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;
}
}
else else
return myImage[(address & 0x07FF) + (myCurrentBank << 11)]; return myImage[(address & 0x07FF) + (myCurrentBank << 11)];
} }
@ -104,16 +92,22 @@ uInt8 CartridgeCVPlus::peek(uInt16 address)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeCVPlus::poke(uInt16 address, uInt8 value) bool CartridgeCVPlus::poke(uInt16 address, uInt8 value)
{ {
uInt16 pokeAddress = address;
address &= 0x0FFF; address &= 0x0FFF;
// Switch banks if necessary if(address < 0x0040)
if(address == 0x003D) {
bank(value); // Switch banks if necessary
if(address == 0x003D)
bank(value);
// Handle TIA space that we claimed above // 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;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -47,16 +47,16 @@ void CartridgeFA::install(System& system)
System::PageAccess access(this, System::PA_READ); System::PageAccess access(this, System::PA_READ);
// Set the page accessing method for the RAM writing pages // 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; access.type = System::PA_WRITE;
for(uInt16 addr = 0x1000; addr < 0x1100; addr += System::PAGE_SIZE) for(uInt16 addr = 0x1000; addr < 0x1100; addr += System::PAGE_SIZE)
{ {
access.directPokeBase = &myRAM[addr & 0x00FF];
access.codeAccessBase = &myCodeAccessBase[addr & 0x00FF]; access.codeAccessBase = &myCodeAccessBase[addr & 0x00FF];
mySystem->setPageAccess(addr, access); mySystem->setPageAccess(addr, access);
} }
// Set the page accessing method for the RAM reading pages // Set the page accessing method for the RAM reading pages
access.directPokeBase = nullptr;
access.type = System::PA_READ; access.type = System::PA_READ;
for(uInt16 addr = 0x1100; addr < 0x1200; addr += System::PAGE_SIZE) 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) if(address < 0x0100) // Write port is at 0xF000 - 0xF0FF (256 bytes)
{ return peekRAM(myRAM[address], peekAddress);
// 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;
}
}
else else
return myImage[myBankOffset + address]; return myImage[myBankOffset + address];
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeFA::poke(uInt16 address, uInt8) bool CartridgeFA::poke(uInt16 address, uInt8 value)
{ {
address &= 0x0FFF;
// Switch banks if necessary // Switch banks if necessary
switch(address) switch(address & 0x0FFF)
{ {
case 0x0FF8: case 0x0FF8:
// Set the current bank to the lower 4k bank // Set the current bank to the lower 4k bank
bank(0); bank(0);
break; return false;
case 0x0FF9: case 0x0FF9:
// Set the current bank to the middle 4k bank // Set the current bank to the middle 4k bank
bank(1); bank(1);
break; return false;
case 0x0FFA: case 0x0FFA:
// Set the current bank to the upper 4k bank // Set the current bank to the upper 4k bank
bank(2); bank(2);
break; return false;
default: default:
break; break;
} }
// NOTE: This does not handle accessing RAM, however, this function pokeRAM(myRAM[address & 0x00FF], address, value);
// should never be called for RAM because of the way page accessing return true;
// has been setup
return false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -59,10 +59,11 @@ void CartridgeFA2::install(System& system)
System::PageAccess access(this, System::PA_READ); System::PageAccess access(this, System::PA_READ);
// Set the page accessing method for the RAM writing pages // 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; access.type = System::PA_WRITE;
for(uInt16 addr = 0x1000; addr < 0x1100; addr += System::PAGE_SIZE) for(uInt16 addr = 0x1000; addr < 0x1100; addr += System::PAGE_SIZE)
{ {
access.directPokeBase = &myRAM[addr & 0x00FF];
access.codeAccessBase = &myCodeAccessBase[addr & 0x00FF]; access.codeAccessBase = &myCodeAccessBase[addr & 0x00FF];
mySystem->setPageAccess(addr, access); mySystem->setPageAccess(addr, access);
} }
@ -137,81 +138,65 @@ uInt8 CartridgeFA2::peek(uInt16 address)
} }
if(address < 0x0100) // Write port is at 0xF000 - 0xF0FF (256 bytes) if(address < 0x0100) // Write port is at 0xF000 - 0xF0FF (256 bytes)
{ return peekRAM(myRAM[address], peekAddress);
// 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;
}
}
else else
return myImage[myBankOffset + address]; return myImage[myBankOffset + address];
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeFA2::poke(uInt16 address, uInt8) bool CartridgeFA2::poke(uInt16 address, uInt8 value)
{ {
address &= 0x0FFF;
// Switch banks if necessary // Switch banks if necessary
switch(address) switch(address & 0x0FFF)
{ {
case 0x0FF4: case 0x0FF4:
// Load/save RAM to/from Harmony cart flash // Load/save RAM to/from Harmony cart flash
if(mySize == 28*1024 && !bankLocked()) if(mySize == 28*1024 && !bankLocked())
ramReadWrite(); ramReadWrite();
break; return false;
case 0x0FF5: case 0x0FF5:
// Set the current bank to the first 4k bank // Set the current bank to the first 4k bank
bank(0); bank(0);
break; return false;
case 0x0FF6: case 0x0FF6:
// Set the current bank to the second 4k bank // Set the current bank to the second 4k bank
bank(1); bank(1);
break; return false;
case 0x0FF7: case 0x0FF7:
// Set the current bank to the third 4k bank // Set the current bank to the third 4k bank
bank(2); bank(2);
break; return false;
case 0x0FF8: case 0x0FF8:
// Set the current bank to the fourth 4k bank // Set the current bank to the fourth 4k bank
bank(3); bank(3);
break; return false;
case 0x0FF9: case 0x0FF9:
// Set the current bank to the fifth 4k bank // Set the current bank to the fifth 4k bank
bank(4); bank(4);
break; return false;
case 0x0FFA: case 0x0FFA:
// Set the current bank to the sixth 4k bank // Set the current bank to the sixth 4k bank
bank(5); bank(5);
break; return false;
case 0x0FFB: case 0x0FFB:
// Set the current bank to the seventh 4k bank // Set the current bank to the seventh 4k bank
// This is only available on 28K ROMs // This is only available on 28K ROMs
if(mySize == 28*1024) bank(6); if(mySize == 28*1024) bank(6);
break; return false;
default: default:
break; break;
} }
// NOTE: This does not handle accessing RAM, however, this function pokeRAM(myRAM[address & 0x00FF], address, value);
// should never be called for RAM because of the way page accessing return true;
// has been setup
return false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -255,7 +255,8 @@ bool CartridgeMNetwork::save(Serializer& out) const
out.putShortArray(myCurrentSlice, NUM_SEGMENTS); out.putShortArray(myCurrentSlice, NUM_SEGMENTS);
out.putShort(myCurrentRAM); out.putShort(myCurrentRAM);
out.putByteArray(myRAM, RAM_SIZE); out.putByteArray(myRAM, RAM_SIZE);
} catch(...) }
catch(...)
{ {
cerr << "ERROR: " << name() << "::save" << endl; cerr << "ERROR: " << name() << "::save" << endl;
return false; return false;
@ -272,7 +273,8 @@ bool CartridgeMNetwork::load(Serializer& in)
in.getShortArray(myCurrentSlice, NUM_SEGMENTS); in.getShortArray(myCurrentSlice, NUM_SEGMENTS);
myCurrentRAM = in.getShort(); myCurrentRAM = in.getShort();
in.getByteArray(myRAM, RAM_SIZE); in.getByteArray(myRAM, RAM_SIZE);
} catch(...) }
catch(...)
{ {
cerr << "ERROR: " << name() << "::load" << endl; cerr << "ERROR: " << name() << "::load" << endl;
return false; return false;
@ -296,4 +298,3 @@ uInt32 CartridgeMNetwork::romSize() const
{ {
return bankCount() * BANK_SIZE; return bankCount() * BANK_SIZE;
} }

View File

@ -62,10 +62,11 @@ void CartridgeWD::install(System& system)
} }
// Set the page accessing method for the RAM writing pages // 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); System::PageAccess write(this, System::PA_WRITE);
for(uInt16 addr = 0x1040; addr < 0x1080; addr += System::PAGE_SIZE) for(uInt16 addr = 0x1040; addr < 0x1080; addr += System::PAGE_SIZE)
{ {
write.directPokeBase = &myRAM[addr & 0x003F];
write.codeAccessBase = &myCodeAccessBase[addr & 0x003F]; write.codeAccessBase = &myCodeAccessBase[addr & 0x003F];
mySystem->setPageAccess(addr, write); mySystem->setPageAccess(addr, write);
} }
@ -109,19 +110,8 @@ uInt8 CartridgeWD::peek(uInt16 address)
if(address < 0x0040) // RAM read port if(address < 0x0040) // RAM read port
return myRAM[address]; return myRAM[address];
else if(address < 0x0080) // RAM write port else if(address < 0x0080) // RAM write port
{
// Reading from the write port @ $1040 - $107F triggers an unwanted write // Reading from the write port @ $1040 - $107F triggers an unwanted write
uInt8 value = mySystem->getDataBusState(0xFF); return peekRAM(myRAM[address & 0x003F], peekAddress);
if(bankLocked())
return value;
else
{
myRAM[address & 0x003F] = value;
triggerReadFromWritePort(peekAddress);
return value;
}
}
else if(address < 0x0400) else if(address < 0x0400)
return myImage[myOffset[0] + (address & 0x03FF)]; return myImage[myOffset[0] + (address & 0x03FF)];
else if(address < 0x0800) else if(address < 0x0800)
@ -136,11 +126,12 @@ uInt8 CartridgeWD::peek(uInt16 address)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeWD::poke(uInt16 address, uInt8 value) bool CartridgeWD::poke(uInt16 address, uInt8 value)
{ {
// Only TIA writes will reach here if(!(address & 0x1000)) // TIA addresses
if(!(address & 0x1000))
return mySystem->tia().poke(address, value); return mySystem->tia().poke(address, value);
else else
return false; pokeRAM(myRAM[address & 0x003F], address, value);
return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -