From 7e2ccf6d99223910c1dd16bb13871a1671fbc0d8 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 4 Apr 2020 17:28:30 +0200 Subject: [PATCH] refactor Cart3F improve CartEnhanced for segmented types --- src/debugger/gui/Cart3FWidget.cxx | 2 +- src/emucore/Cart3F.cxx | 163 ++---------------------------- src/emucore/Cart3F.hxx | 88 ++-------------- src/emucore/CartE0.cxx | 37 ------- src/emucore/CartE0.hxx | 8 -- src/emucore/CartEnhanced.cxx | 15 +-- src/emucore/CartEnhanced.hxx | 6 +- 7 files changed, 28 insertions(+), 291 deletions(-) diff --git a/src/debugger/gui/Cart3FWidget.cxx b/src/debugger/gui/Cart3FWidget.cxx index 223e56cc0..ab5a48761 100644 --- a/src/debugger/gui/Cart3FWidget.cxx +++ b/src/debugger/gui/Cart3FWidget.cxx @@ -88,7 +88,7 @@ string Cartridge3FWidget::bankState() { ostringstream& buf = buffer(); - buf << "Bank = #" << std::dec << myCart.myCurrentBank << ", hotspot = $3F"; + buf << "Bank = #" << std::dec << (myCart.myCurrentSegOffset[0] >> myCart.myBankShift) << ", hotspot = $3F"; return buf.str(); } diff --git a/src/emucore/Cart3F.cxx b/src/emucore/Cart3F.cxx index 2989e88ff..7c3701c16 100644 --- a/src/emucore/Cart3F.cxx +++ b/src/emucore/Cart3F.cxx @@ -22,177 +22,32 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3F::Cartridge3F(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size) + : CartridgeEnhanced(image, size, md5, settings) { - // Allocate array for the ROM image - myImage = make_unique(mySize); - - // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); - createRomAccessArrays(mySize); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3F::reset() -{ - initializeStartBank(bankCount() - 1); - - bank(startBank()); + myBankShift = BANK_SHIFT; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge3F::install(System& system) { - mySystem = &system; + CartridgeEnhanced::install(system); System::PageAccess access(this, System::PageAccessType::READWRITE); // The hotspot ($3F) is in TIA address space, so we claim it here for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE) mySystem->setPageAccess(addr, access); - - // Setup the second segment to always point to the last ROM slice - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1800; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[(mySize - 2048) + (addr & 0x07FF)]; - access.romAccessBase = &myRomAccessBase[(mySize - 2048) + (addr & 0x07FF)]; - access.romPeekCounter = &myRomAccessCounter[(mySize - 2048) + (addr & 0x07FF)]; - access.romPokeCounter = &myRomAccessCounter[(mySize - 2048) + (addr & 0x07FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - bank(startBank()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 Cartridge3F::peek(uInt16 address) +bool Cartridge3F::checkSwitchBank(uInt16 address, uInt8 value) { - address &= 0x0FFF; - - if(address < 0x0800) - return myImage[(address & 0x07FF) + (myCurrentBank << 11)]; - else - return myImage[(address & 0x07FF) + mySize - 2048]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3F::poke(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - // Switch banks if necessary if(address <= 0x003F) - bank(value); - - // Handle TIA space that we claimed above - mySystem->tia().poke(address, value); - + { + // Make sure the bank they're asking for is reasonable + bank(value % bankCount(), 0); + return true; + } return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3F::bank(uInt16 bank) -{ - if(bankLocked()) - return false; - - // Make sure the bank they're asking for is reasonable - if((uInt32(bank) << 11) < mySize) - { - myCurrentBank = bank; - } - else - { - // Oops, the bank they're asking for isn't valid so let's wrap it - // around to a valid bank number - myCurrentBank = bank % (mySize >> 11); - } - - uInt32 offset = myCurrentBank << 11; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - // Map ROM image into the system - for(uInt16 addr = 0x1000; addr < 0x1800; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[offset + (addr & 0x07FF)]; - access.romAccessBase = &myRomAccessBase[offset + (addr & 0x07FF)]; - access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x07FF)]; - access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x07FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 Cartridge3F::getBank(uInt16 address) const -{ - if (address & 0x800) - return uInt16((mySize >> 11) - 1); // 2K slices, fixed bank - else - return myCurrentBank; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 Cartridge3F::bankCount() const -{ - return uInt16(mySize >> 11); // 2K slices -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3F::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0800) - myImage[(address & 0x07FF) + (myCurrentBank << 11)] = value; - else - myImage[(address & 0x07FF) + mySize - 2048] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* Cartridge3F::getImage(size_t& size) const -{ - size = mySize; - return myImage.get(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3F::save(Serializer& out) const -{ - try - { - out.putShort(myCurrentBank); - } - catch(...) - { - cerr << "ERROR: Cartridge3F::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3F::load(Serializer& in) -{ - try - { - myCurrentBank = in.getShort(); - } - catch(...) - { - cerr << "ERROR: Cartridge3F::load" << endl; - return false; - } - - // Now, go to the current bank - bank(myCurrentBank); - - return true; -} diff --git a/src/emucore/Cart3F.hxx b/src/emucore/Cart3F.hxx index cb75bcd88..53b71427a 100644 --- a/src/emucore/Cart3F.hxx +++ b/src/emucore/Cart3F.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "Cart3FWidget.hxx" #endif @@ -38,7 +38,7 @@ class System; @author Bradford W. Mott */ -class Cartridge3F : public Cartridge +class Cartridge3F : public CartridgeEnhanced { friend class Cartridge3FWidget; @@ -56,11 +56,6 @@ class Cartridge3F : public Cartridge virtual ~Cartridge3F() = 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. @@ -69,57 +64,6 @@ class Cartridge3F : public Cartridge */ 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). @@ -140,32 +84,12 @@ class Cartridge3F : public Cartridge } #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; private: - // Pointer to a dynamically allocated ROM image of the cartridge - ByteBuffer myImage; - - // Size of the ROM image - size_t mySize{0}; - - // Indicates which bank is currently active for the first segment - uInt16 myCurrentBank{0}; + // log(ROM bank segment size) / log(2) + static constexpr uInt16 BANK_SHIFT = 11; // = 2K = 0x0800 private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartE0.cxx b/src/emucore/CartE0.cxx index e35917993..97752e447 100644 --- a/src/emucore/CartE0.cxx +++ b/src/emucore/CartE0.cxx @@ -42,46 +42,9 @@ void CartridgeE0::reset() bank(5, 1); bank(6, 2); } - myCurrentSegOffset[3] = (bankCount() - 1) << myBankShift; // fixed - myBankChanged = true; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE0::install(System& system) -{ - //// Allocate array for the current bank segments slices - //myCurrentSegOffset = make_unique(myBankSegs); - - //// Setup page access - //mySystem = &system; - - CartridgeEnhanced::install(system); - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page acessing methods for the first part of the last segment - for(uInt16 addr = 0x1C00; addr < static_cast(0x1FE0U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[0x1C00 + (addr & 0x03FF)]; - access.romAccessBase = &myRomAccessBase[0x1C00 + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[0x1C00 + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[0x1C00 + (addr & 0x03FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing methods for the hot spots in the last segment - access.directPeekBase = nullptr; - access.romAccessBase = &myRomAccessBase[0x1FC0]; - access.romPeekCounter = &myRomAccessCounter[0x1FC0]; - access.romPokeCounter = &myRomAccessCounter[0x1FC0 + myAccessSize]; - access.type = System::PageAccessType::READ; - for(uInt16 addr = (0x1FE0 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - mySystem->setPageAccess(addr, access); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeE0::checkSwitchBank(uInt16 address, uInt8) { diff --git a/src/emucore/CartE0.hxx b/src/emucore/CartE0.hxx index 66dbbba6a..08fc82806 100644 --- a/src/emucore/CartE0.hxx +++ b/src/emucore/CartE0.hxx @@ -64,14 +64,6 @@ class CartridgeE0 : public CartridgeEnhanced */ 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; - /** Get a descriptor for the device name (used in error checking). diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 0f0472392..0ac9ffadd 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -79,8 +79,11 @@ void CartridgeEnhanced::install(System& system) mySystem->setPageAccess(addr, access); } - // Install pages for the startup bank - bank(startBank()); + // Install pages for the startup bank (TODO: currently only in first bank segment) + bank(startBank(), 0); + if(myBankSegs > 1) + // Setup the last bank segment to always point to the last ROM segment + bank(bankCount() - 1, myBankSegs - 1); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -99,13 +102,13 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) { uInt16 peekAddress = address; - checkSwitchBank(address & 0x0FFF); + if (romHotspot()) + checkSwitchBank(address & 0x0FFF); address &= myBankMask; if(address < myRamSize) // Write port is at 0xF000 - 0xF07F (128 bytes) return peekRAM(myRAM[address], peekAddress); else - //return myImage[myBankOffset + address]; return myImage[myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] + address]; } @@ -113,7 +116,7 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) { // Switch banks if necessary - if (checkSwitchBank(address & 0x0FFF)) + if (checkSwitchBank(address & 0x0FFF, value)) return false; if(myRamSize) @@ -149,7 +152,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) uInt16 toAddr = (segmentOffset + 0x1000 + myBankSize) & ~System::PAGE_MASK; if(romHotspot) - hotSpotAddr = segmentOffset + (romHotspot & ~System::PAGE_MASK); + hotSpotAddr = (romHotspot & ~System::PAGE_MASK); else hotSpotAddr = 0xFFFF; // none diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index b8511ac29..4bd45fadd 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -165,6 +165,9 @@ class CartridgeEnhanced : public Cartridge // Pointer to a dynamically allocated RAM area of the cartridge ByteBuffer myRAM{nullptr}; + // The size of the ROM image + size_t mySize{0}; + private: // Calculated as: log(ROM bank segment size) / log(2) static constexpr uInt16 BANK_SHIFT = 12; // default = 4K @@ -172,9 +175,6 @@ class CartridgeEnhanced : public Cartridge // The size of extra RAM in ROM address space static constexpr uInt16 RAM_SIZE = 0; // default = none - // The size of the ROM image - size_t mySize{0}; - protected: /** Check hotspots and switch bank if triggered.