diff --git a/src/debugger/RiotDebug.cxx b/src/debugger/RiotDebug.cxx index e4a003426..7a47e61fd 100644 --- a/src/debugger/RiotDebug.cxx +++ b/src/debugger/RiotDebug.cxx @@ -159,7 +159,7 @@ uInt8 RiotDebug::inpt(int x) static constexpr std::array _inpt = { INPT0, INPT1, INPT2, INPT3, INPT4, INPT5 }; - return mySystem.peekOob(_inpt[x]); + return mySystem.peekOob(_inpt[x] | 0x40); // fix for 3E/3F bankswitching } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Cart3E.cxx b/src/emucore/Cart3E.cxx index 0b1da8eb9..2e80c9a7f 100644 --- a/src/emucore/Cart3E.cxx +++ b/src/emucore/Cart3E.cxx @@ -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 bank(value); return true; } - else if(address == 0x003E) + if(address == 0x00) // $3E { - // Switch RAM bank into segment 0 + // Switch RAM bank into segment 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); -} +} \ No newline at end of file diff --git a/src/emucore/Cart3E.hxx b/src/emucore/Cart3E.hxx index 70d6d5316..a1f206780 100644 --- a/src/emucore/Cart3E.hxx +++ b/src/emucore/Cart3E.hxx @@ -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 diff --git a/src/emucore/Cart3EPlus.cxx b/src/emucore/Cart3EPlus.cxx index 4da27e628..ec601549d 100644 --- a/src/emucore/Cart3EPlus.cxx +++ b/src/emucore/Cart3EPlus.cxx @@ -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); +} diff --git a/src/emucore/Cart3EPlus.hxx b/src/emucore/Cart3EPlus.hxx index 57df01b4a..d2bf4d341 100644 --- a/src/emucore/Cart3EPlus.hxx +++ b/src/emucore/Cart3EPlus.hxx @@ -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. */