diff --git a/src/emucore/CartFA.cxx b/src/emucore/CartFA.cxx index 5a4ecb6bd..3f1062f41 100644 --- a/src/emucore/CartFA.cxx +++ b/src/emucore/CartFA.cxx @@ -21,235 +21,19 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFA::CartridgeFA(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); + myRamSize = RAM_SIZE; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFA::reset() -{ - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(2); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFA::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::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::PageAccessType::WRITE; - for(uInt16 addr = 0x1000; addr < 0x1100; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[addr & 0x00FF]; - access.romPeekCounter = &myRomAccessCounter[addr & 0x00FF]; - access.romPokeCounter = &myRomAccessCounter[(addr & 0x00FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the RAM reading pages - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1100; addr < 0x1200; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x00FF]; - access.romAccessBase = &myRomAccessBase[0x100 + (addr & 0x00FF)]; - access.romPeekCounter = &myRomAccessCounter[0x100 + (addr & 0x00FF)]; - access.romPokeCounter = &myRomAccessCounter[0x100 + (addr & 0x00FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeFA::peek(uInt16 address) -{ - uInt16 peekAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary - switch(address) - { - case 0x0FF8: - // Set the current bank to the lower 4k bank - bank(0); - break; - - case 0x0FF9: - // Set the current bank to the middle 4k bank - bank(1); - break; - - case 0x0FFA: - // Set the current bank to the upper 4k bank - bank(2); - break; - - default: - break; - } - - if(address < 0x0100) // Write port is at 0xF000 - 0xF0FF (256 bytes) - return peekRAM(myRAM[address], peekAddress); - else - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA::poke(uInt16 address, uInt8 value) +bool CartridgeFA::checkSwitchBank(uInt16 address, uInt8) { // Switch banks if necessary - switch(address & 0x0FFF) + if((address >= 0x0FF8) && (address <= 0x0FFA)) { - case 0x0FF8: - // Set the current bank to the lower 4k bank - bank(0); - return false; - - case 0x0FF9: - // Set the current bank to the middle 4k bank - bank(1); - return false; - - case 0x0FFA: - // Set the current bank to the upper 4k bank - bank(2); - return false; - - default: - break; - } - - if (!(address & 0x100)) - { - pokeRAM(myRAM[address & 0x00FF], address, value); + bank(address - 0x0FF8); return true; } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, address, value); - myRamWriteAccess = address; - return false; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FF8 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1200; addr < static_cast(0x1FF8U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeFA::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeFA::bankCount() const -{ - return 3; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0200) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & 0x00FF] = value; - } - else - myImage[myBankOffset + address] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeFA::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeFA::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeFA::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; + return false; } diff --git a/src/emucore/CartFA.hxx b/src/emucore/CartFA.hxx index 9729a366f..920f2bdec 100644 --- a/src/emucore/CartFA.hxx +++ b/src/emucore/CartFA.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartFAWidget.hxx" #endif @@ -31,9 +31,9 @@ class System; banks, accessible by read/write at $1FF8 - $1FFA, and 256 bytes of RAM. RAM read port is $1100 - $11FF, write port is $1000 - $10FF. - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class CartridgeFA : public Cartridge +class CartridgeFA : public CartridgeEnhanced { friend class CartridgeFAWidget; @@ -51,71 +51,6 @@ class CartridgeFA : public Cartridge virtual ~CartridgeFA() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - 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; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -135,32 +70,16 @@ class CartridgeFA : public Cartridge } #endif - public: - /** - Get the byte at the specified address. + private: + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; + uInt16 hotspot() const override { return 0x1FF8; } - /** - 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; + uInt16 getStartBank() const override { return 2; } private: - // The 12K ROM image of the cartridge - std::array myImage; - - // The 256 bytes of RAM on the cartridge - std::array myRAM; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; + // RAM size + static constexpr uInt16 RAM_SIZE = 0x100; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartFA2.cxx b/src/emucore/CartFA2.cxx index 1630f216e..0d892c9b3 100644 --- a/src/emucore/CartFA2.cxx +++ b/src/emucore/CartFA2.cxx @@ -15,308 +15,67 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "OSystem.hxx" -#include "Serializer.hxx" -#include "System.hxx" #include "TimerManager.hxx" #include "CartFA2.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFA2::CartridgeFA2(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeFA(image, size, md5, settings) { // 29/32K version of FA2 has valid data @ 1K - 29K const uInt8* img_ptr = image.get(); if(size >= 29_KB) + { img_ptr += 1_KB; - else if(size < mySize) - mySize = size; + mySize = 28_KB; + } + + // Allocate array for the ROM image + myImage = make_unique(mySize); // Copy the ROM image into my buffer - std::copy_n(img_ptr, mySize, myImage.begin()); - createRomAccessArrays(mySize); + std::copy_n(image.get(), mySize, myImage.get()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFA2::reset() +bool CartridgeFA2::checkSwitchBank(uInt16 address, uInt8) { - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(0); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFA2::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::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::PageAccessType::WRITE; - for(uInt16 addr = 0x1000; addr < 0x1100; addr += System::PAGE_SIZE) + // Switch banks if necessary + if((address >= 0x0FF5) && (address <= 0x0FFB)) { - access.romAccessBase = &myRomAccessBase[addr & 0x00FF]; - access.romPeekCounter = &myRomAccessCounter[addr & 0x00FF]; - access.romPokeCounter = &myRomAccessCounter[(addr & 0x00FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); + bank(address - 0x0FF5); + return true; } - - // Set the page accessing method for the RAM reading pages - access.directPokeBase = nullptr; - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1100; addr < 0x1200; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x00FF]; - access.romAccessBase = &myRomAccessBase[0x100 + (addr & 0x00FF)]; - access.romPeekCounter = &myRomAccessCounter[0x100 + (addr & 0x00FF)]; - access.romPokeCounter = &myRomAccessCounter[0x100 + (addr & 0x00FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Install pages for the startup bank - bank(startBank()); + return false; } - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeFA2::peek(uInt16 address) { - uInt16 peekAddress = address; - address &= 0x0FFF; - // Switch banks if necessary - switch(address) + if((address & 0x0FFF) == 0x0FF4) { - case 0x0FF4: - // Load/save RAM to/from Harmony cart flash - if(mySize == 28_KB && !bankLocked()) - return ramReadWrite(); - break; - - case 0x0FF5: - // Set the current bank to the first 4k bank - bank(0); - break; - - case 0x0FF6: - // Set the current bank to the second 4k bank - bank(1); - break; - - case 0x0FF7: - // Set the current bank to the third 4k bank - bank(2); - break; - - case 0x0FF8: - // Set the current bank to the fourth 4k bank - bank(3); - break; - - case 0x0FF9: - // Set the current bank to the fifth 4k bank - bank(4); - break; - - case 0x0FFA: - // Set the current bank to the sixth 4k bank - bank(5); - break; - - case 0x0FFB: - // Set the current bank to the seventh 4k bank - // This is only available on 28K ROMs - if(mySize == 28_KB) bank(6); - break; - - default: - break; + // Load/save RAM to/from Harmony cart flash + if(mySize == 28_KB && !bankLocked()) + return ramReadWrite(); } - if(address < 0x0100) // Write port is at 0xF000 - 0xF0FF (256 bytes) - return peekRAM(myRAM[address], peekAddress); - else - return myImage[myBankOffset + address]; + return CartridgeEnhanced::peek(address); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeFA2::poke(uInt16 address, uInt8 value) { - // Switch banks if necessary - switch(address & 0x0FFF) + if((address & 0x0FFF) == 0x0FF4) { - case 0x0FF4: - // Load/save RAM to/from Harmony cart flash - if(mySize == 28_KB && !bankLocked()) - ramReadWrite(); - return false; - - case 0x0FF5: - // Set the current bank to the first 4k bank - bank(0); - return false; - - case 0x0FF6: - // Set the current bank to the second 4k bank - bank(1); - return false; - - case 0x0FF7: - // Set the current bank to the third 4k bank - bank(2); - return false; - - case 0x0FF8: - // Set the current bank to the fourth 4k bank - bank(3); - return false; - - case 0x0FF9: - // Set the current bank to the fifth 4k bank - bank(4); - return false; - - case 0x0FFA: - // Set the current bank to the sixth 4k bank - bank(5); - return false; - - case 0x0FFB: - // Set the current bank to the seventh 4k bank - // This is only available on 28K ROMs - if(mySize == 28_KB) bank(6); - return false; - - default: - break; - } - - if(!(address & 0x100)) - { - pokeRAM(myRAM[address & 0x00FF], address, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, address, value); - myRamWriteAccess = address; - return false; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA2::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FF4 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1200; addr < static_cast(0x1FF4U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeFA2::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeFA2::bankCount() const -{ - return uInt16(mySize / 4_KB); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA2::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0200) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & 0x00FF] = value; - } - else - myImage[myBankOffset + address] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeFA2::getImage(size_t& size) const -{ - size = mySize; - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA2::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeFA2::save" << endl; + // Load/save RAM to/from Harmony cart flash + if(mySize == 28_KB && !bankLocked()) + ramReadWrite(); return false; } - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA2::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeFA2::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; + return CartridgeEnhanced::poke(address, value); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -361,11 +120,11 @@ uInt8 CartridgeFA2::ramReadWrite() { try { - serializer.getByteArray(myRAM.data(), myRAM.size()); + serializer.getByteArray(myRAM.get(), myRamSize); } catch(...) { - myRAM.fill(0); + std::fill_n(myRAM.get(), myRamSize, 0); } myRamAccessTimeout += 500; // Add 0.5 ms delay for read } @@ -373,7 +132,7 @@ uInt8 CartridgeFA2::ramReadWrite() { try { - serializer.putByteArray(myRAM.data(), myRAM.size()); + serializer.putByteArray(myRAM.get(), myRamSize); } catch(...) { @@ -384,7 +143,7 @@ uInt8 CartridgeFA2::ramReadWrite() } } // Bit 6 is 1, busy - return myImage[myBankOffset + 0xFF4] | 0x40; + return myImage[myCurrentSegOffset[0] + 0xFF4] | 0x40; } else { @@ -395,11 +154,11 @@ uInt8 CartridgeFA2::ramReadWrite() myRAM[255] = 0; // Successful operation // Bit 6 is 0, ready/success - return myImage[myBankOffset + 0xFF4] & ~0x40; + return myImage[myCurrentSegOffset[0] + 0xFF4] & ~0x40; } else // Bit 6 is 1, busy - return myImage[myBankOffset + 0xFF4] | 0x40; + return myImage[myCurrentSegOffset[0] + 0xFF4] | 0x40; } } @@ -424,18 +183,18 @@ void CartridgeFA2::flash(uInt8 operation) { try { - serializer.getByteArray(myRAM.data(), myRAM.size()); + serializer.getByteArray(myRAM.get(), myRamSize); } catch(...) { - myRAM.fill(0); + std::fill_n(myRAM.get(), myRamSize, 0); } } else if(operation == 2) // write { try { - serializer.putByteArray(myRAM.data(), myRAM.size()); + serializer.putByteArray(myRAM.get(), myRamSize); } catch(...) { diff --git a/src/emucore/CartFA2.hxx b/src/emucore/CartFA2.hxx index ea19b0d43..8175f4cdc 100644 --- a/src/emucore/CartFA2.hxx +++ b/src/emucore/CartFA2.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartFA.hxx" #ifdef DEBUGGER_SUPPORT #include "CartFA2Widget.hxx" #endif @@ -43,9 +43,9 @@ class System; by the emulator. Also supported is a 32K variant. In any event, only data at 1K - 29K of the ROM is used. - @author Chris D. Walton + @author Chris D. Walton, Thomas Jentzsch */ -class CartridgeFA2 : public Cartridge +class CartridgeFA2 : public CartridgeFA { friend class CartridgeFA2Widget; @@ -63,71 +63,6 @@ class CartridgeFA2 : public Cartridge virtual ~CartridgeFA2() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - 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; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -173,6 +108,12 @@ class CartridgeFA2 : public Cartridge bool poke(uInt16 address, uInt8 value) override; private: + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; + + uInt16 hotspot() const override { return 0x1FF4; } + + uInt16 getStartBank() const override { return 0; } + /** Either load or save internal RAM to Harmony flash (represented by a file in emulation). @@ -192,15 +133,6 @@ class CartridgeFA2 : public Cartridge void flash(uInt8 operation); private: - // The 24K/28K ROM image of the cartridge - std::array myImage; - - // Actual usable size of the ROM image - size_t mySize{28_KB}; - - // The 256 bytes of RAM on the cartridge - std::array myRAM; - // The time after which the first request of a load/save operation // will actually be completed // Due to flash RAM constraints, a read/write isn't instantaneous, @@ -211,9 +143,6 @@ class CartridgeFA2 : public Cartridge // of internal RAM to Harmony cart flash string myFlashFile; - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; - private: // Following constructors and assignment operators not supported CartridgeFA2() = delete;