mirror of https://github.com/stella-emu/stella.git
added mirrors to 3E hotspots
adapted derived 3E+ so that it does not use the mirrors
This commit is contained in:
parent
d4f3187ee0
commit
acaeed8322
|
@ -159,7 +159,7 @@ uInt8 RiotDebug::inpt(int x)
|
|||
static constexpr std::array<TIARegister, 6> _inpt = {
|
||||
INPT0, INPT1, INPT2, INPT3, INPT4, INPT5
|
||||
};
|
||||
return mySystem.peekOob(_inpt[x]);
|
||||
return mySystem.peekOob(_inpt[x] | 0x40); // fix for 3E/3F bankswitching
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
//============================================================================
|
||||
|
||||
#include "System.hxx"
|
||||
#include "TIA.hxx"
|
||||
#include "Cart3E.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -37,54 +36,31 @@ void Cartridge3E::install(System& system)
|
|||
{
|
||||
CartridgeEnhanced::install(system);
|
||||
|
||||
const System::PageAccess access(this, System::PageAccessType::WRITE);
|
||||
const System::PageAccess access(this, System::PageAccessType::READWRITE);
|
||||
|
||||
// The hotspots ($3E and $3F) are in TIA address space, so we claim it here
|
||||
for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE)
|
||||
// The hotspots ($3E and $3F) are in TIA address space (plus mirrors), so we claim them here
|
||||
for(uInt16 addr = 0x0000; addr < 0x0800; addr += 0x100)
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge3E::checkSwitchBank(uInt16 address, uInt8 value)
|
||||
{
|
||||
// Tigervision bankswitching checks only A12, A11, A7, A6 and A0
|
||||
address &= 0b1100011000001; // 0x18c1;
|
||||
|
||||
// Switch banks if necessary
|
||||
if(address == 0x003F) {
|
||||
// Switch ROM bank into segment 0
|
||||
if(address == 0x01) // $3F
|
||||
{
|
||||
// Switch ROM bank into segment <value>
|
||||
bank(value);
|
||||
return true;
|
||||
}
|
||||
else if(address == 0x003E)
|
||||
if(address == 0x00) // $3E
|
||||
{
|
||||
// Switch RAM bank into segment 0
|
||||
// Switch RAM bank into segment <value>
|
||||
bank(value + romBankCount());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 Cartridge3E::peek(uInt16 address)
|
||||
{
|
||||
const uInt16 peekAddress = address;
|
||||
address &= ROM_MASK;
|
||||
|
||||
if(address < 0x0040) // TIA access
|
||||
return mySystem->tia().peek(address);
|
||||
|
||||
return CartridgeEnhanced::peek(peekAddress);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge3E::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
const uInt16 pokeAddress = address;
|
||||
address &= ROM_MASK;
|
||||
|
||||
if(address < 0x0040) // TIA access
|
||||
{
|
||||
checkSwitchBank(address, value);
|
||||
return mySystem->tia().poke(address, value);
|
||||
}
|
||||
|
||||
return CartridgeEnhanced::poke(pokeAddress, value);
|
||||
}
|
||||
}
|
|
@ -45,7 +45,10 @@ class System;
|
|||
|
||||
To map ROM, the desired bank number of the first 2K segment is selected
|
||||
by storing its value into $3F. To map RAM in the first 2K segment
|
||||
instead, store the RAM bank number into $3E.
|
||||
instead, store the RAM bank number into $3E. (*)
|
||||
|
||||
(*) 1/2025: Updated to emulate the new 3E board. Now reads and writes and
|
||||
all mirror addresses are considered. This breaks previous Boulder Dash ROMs!
|
||||
|
||||
This implementation of 3E bankswitching numbers the RAM banks (up to 32)
|
||||
after the ROM banks (up to 256).
|
||||
|
@ -107,26 +110,11 @@ class Cartridge3E : public CartridgeEnhanced
|
|||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
/**
|
||||
Get the byte at the specified address
|
||||
|
||||
@return The byte at the specified address
|
||||
*/
|
||||
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:
|
||||
bool checkSwitchBank(uInt16 address, uInt8 value) override;
|
||||
|
||||
uInt16 hotspot() const override { return 0x013F; } // mirrors outside ZP area
|
||||
|
||||
protected:
|
||||
// log(ROM bank segment size) / log(2)
|
||||
static constexpr uInt16 BANK_SHIFT = 11; // = 2K = 0x0800
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
//============================================================================
|
||||
|
||||
#include "System.hxx"
|
||||
#include "TIA.hxx"
|
||||
#include "Cart3EPlus.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -30,6 +31,17 @@ Cartridge3EPlus::Cartridge3EPlus(const ByteBuffer& image, size_t size,
|
|||
myRamBankCount = RAM_BANKS;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Cartridge3EPlus::install(System& system)
|
||||
{
|
||||
CartridgeEnhanced::install(system);
|
||||
|
||||
const System::PageAccess access(this, System::PageAccessType::WRITE);
|
||||
|
||||
// The hotspots ($3E and $3F) are in TIA address space, so we claim them here
|
||||
for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE)
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Cartridge3EPlus::reset()
|
||||
{
|
||||
|
@ -50,7 +62,7 @@ bool Cartridge3EPlus::checkSwitchBank(uInt16 address, uInt8 value)
|
|||
bank(value & 0b111111, value >> 6);
|
||||
return true;
|
||||
}
|
||||
else if(address == 0x003E)
|
||||
if(address == 0x003E)
|
||||
{
|
||||
// Switch RAM bank into segment
|
||||
bank((value & 0b111111) + romBankCount(), value >> 6);
|
||||
|
@ -58,3 +70,30 @@ bool Cartridge3EPlus::checkSwitchBank(uInt16 address, uInt8 value)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 Cartridge3EPlus::peek(uInt16 address)
|
||||
{
|
||||
const uInt16 peekAddress = address;
|
||||
address &= ROM_MASK;
|
||||
|
||||
if(address < 0x0040) // TIA access
|
||||
return mySystem->tia().peek(address);
|
||||
|
||||
return CartridgeEnhanced::peek(peekAddress);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge3EPlus::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
const uInt16 pokeAddress = address;
|
||||
address &= ROM_MASK;
|
||||
|
||||
if(address < 0x0040) // TIA access
|
||||
{
|
||||
checkSwitchBank(address, value);
|
||||
return mySystem->tia().poke(address, value);
|
||||
}
|
||||
|
||||
return CartridgeEnhanced::poke(pokeAddress, value);
|
||||
}
|
||||
|
|
|
@ -102,6 +102,14 @@ class Cartridge3EPlus: public Cartridge3E
|
|||
~Cartridge3EPlus() override = default;
|
||||
|
||||
public:
|
||||
/**
|
||||
Install cartridge in the specified system. Invoked by the system
|
||||
when the cartridge is attached to it.
|
||||
|
||||
@param system The system the device should install itself in
|
||||
*/
|
||||
void install(System& system) override;
|
||||
|
||||
/** Reset device to its power-on state */
|
||||
void reset() override;
|
||||
|
||||
|
@ -124,6 +132,23 @@ class Cartridge3EPlus: public Cartridge3E
|
|||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
/**
|
||||
Get the byte at the specified address
|
||||
|
||||
@return The byte at the specified address
|
||||
*/
|
||||
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:
|
||||
/**
|
||||
Checks if startup bank randomization is enabled. For this scheme,
|
||||
|
@ -133,6 +158,8 @@ class Cartridge3EPlus: public Cartridge3E
|
|||
|
||||
bool checkSwitchBank(uInt16 address, uInt8 value) override;
|
||||
|
||||
uInt16 hotspot() const override { return 0x003F; }
|
||||
|
||||
/**
|
||||
Get the number of segments supported by the cartridge.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue