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 = {
|
static constexpr std::array<TIARegister, 6> _inpt = {
|
||||||
INPT0, INPT1, INPT2, INPT3, INPT4, INPT5
|
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 "System.hxx"
|
||||||
#include "TIA.hxx"
|
|
||||||
#include "Cart3E.hxx"
|
#include "Cart3E.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -37,54 +36,31 @@ void Cartridge3E::install(System& system)
|
||||||
{
|
{
|
||||||
CartridgeEnhanced::install(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
|
// The hotspots ($3E and $3F) are in TIA address space (plus mirrors), so we claim them here
|
||||||
for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE)
|
for(uInt16 addr = 0x0000; addr < 0x0800; addr += 0x100)
|
||||||
mySystem->setPageAccess(addr, access);
|
mySystem->setPageAccess(addr, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool Cartridge3E::checkSwitchBank(uInt16 address, uInt8 value)
|
bool Cartridge3E::checkSwitchBank(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
|
// Tigervision bankswitching checks only A12, A11, A7, A6 and A0
|
||||||
|
address &= 0b1100011000001; // 0x18c1;
|
||||||
|
|
||||||
// Switch banks if necessary
|
// Switch banks if necessary
|
||||||
if(address == 0x003F) {
|
if(address == 0x01) // $3F
|
||||||
// Switch ROM bank into segment 0
|
{
|
||||||
|
// Switch ROM bank into segment <value>
|
||||||
bank(value);
|
bank(value);
|
||||||
return true;
|
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());
|
bank(value + romBankCount());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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
|
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
|
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)
|
This implementation of 3E bankswitching numbers the RAM banks (up to 32)
|
||||||
after the ROM banks (up to 256).
|
after the ROM banks (up to 256).
|
||||||
|
@ -107,26 +110,11 @@ class Cartridge3E : public CartridgeEnhanced
|
||||||
}
|
}
|
||||||
#endif
|
#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:
|
private:
|
||||||
bool checkSwitchBank(uInt16 address, uInt8 value) override;
|
bool checkSwitchBank(uInt16 address, uInt8 value) override;
|
||||||
|
|
||||||
|
uInt16 hotspot() const override { return 0x013F; } // mirrors outside ZP area
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// log(ROM bank segment size) / log(2)
|
// log(ROM bank segment size) / log(2)
|
||||||
static constexpr uInt16 BANK_SHIFT = 11; // = 2K = 0x0800
|
static constexpr uInt16 BANK_SHIFT = 11; // = 2K = 0x0800
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
|
#include "TIA.hxx"
|
||||||
#include "Cart3EPlus.hxx"
|
#include "Cart3EPlus.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -30,6 +31,17 @@ Cartridge3EPlus::Cartridge3EPlus(const ByteBuffer& image, size_t size,
|
||||||
myRamBankCount = RAM_BANKS;
|
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()
|
void Cartridge3EPlus::reset()
|
||||||
{
|
{
|
||||||
|
@ -50,7 +62,7 @@ bool Cartridge3EPlus::checkSwitchBank(uInt16 address, uInt8 value)
|
||||||
bank(value & 0b111111, value >> 6);
|
bank(value & 0b111111, value >> 6);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if(address == 0x003E)
|
if(address == 0x003E)
|
||||||
{
|
{
|
||||||
// Switch RAM bank into segment
|
// Switch RAM bank into segment
|
||||||
bank((value & 0b111111) + romBankCount(), value >> 6);
|
bank((value & 0b111111) + romBankCount(), value >> 6);
|
||||||
|
@ -58,3 +70,30 @@ bool Cartridge3EPlus::checkSwitchBank(uInt16 address, uInt8 value)
|
||||||
}
|
}
|
||||||
return false;
|
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;
|
~Cartridge3EPlus() override = default;
|
||||||
|
|
||||||
public:
|
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 */
|
/** Reset device to its power-on state */
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
||||||
|
@ -124,6 +132,23 @@ class Cartridge3EPlus: public Cartridge3E
|
||||||
}
|
}
|
||||||
#endif
|
#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:
|
private:
|
||||||
/**
|
/**
|
||||||
Checks if startup bank randomization is enabled. For this scheme,
|
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;
|
bool checkSwitchBank(uInt16 address, uInt8 value) override;
|
||||||
|
|
||||||
|
uInt16 hotspot() const override { return 0x003F; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the number of segments supported by the cartridge.
|
Get the number of segments supported by the cartridge.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue