diff --git a/src/emucore/Cart3E.cxx b/src/emucore/Cart3E.cxx index 3e7454bda..642ac6ce1 100644 --- a/src/emucore/Cart3E.cxx +++ b/src/emucore/Cart3E.cxx @@ -64,7 +64,7 @@ bool Cartridge3E::checkSwitchBank(uInt16 address, uInt8 value) uInt8 Cartridge3E::peek(uInt16 address) { uInt16 peekAddress = address; - address &= 0x0FFF; + address &= ROM_MASK; if(address < 0x0040) // TIA access return mySystem->tia().peek(address); diff --git a/src/emucore/Cart3EPlus.cxx b/src/emucore/Cart3EPlus.cxx index f6ac01679..274e1f9db 100644 --- a/src/emucore/Cart3EPlus.cxx +++ b/src/emucore/Cart3EPlus.cxx @@ -103,7 +103,7 @@ bool Cartridge3EPlus::checkSwitchBank(uInt16 address, uInt8 value) uInt8 Cartridge3EPlus::peek(uInt16 address) { uInt16 peekAddress = address; - address &= 0x0FFF; + address &= ROM_MASK; if(address < 0x0040) // TIA peek return mySystem->tia().peek(address); diff --git a/src/emucore/CartBF.cxx b/src/emucore/CartBF.cxx index 0d1921c17..ce3c53198 100644 --- a/src/emucore/CartBF.cxx +++ b/src/emucore/CartBF.cxx @@ -30,7 +30,7 @@ bool CartridgeBF::checkSwitchBank(uInt16 address, uInt8) { // Due to the way addressing is set up, we will only get here if the // address is in the hotspot range ($1F80 - $1FFF) - address &= 0x0FFF; + address &= ROM_MASK; // Switch banks if necessary if((address >= 0x0F80) && (address <= 0x0FBF)) diff --git a/src/emucore/CartDF.cxx b/src/emucore/CartDF.cxx index db9ab62d2..0f4d9a1ca 100644 --- a/src/emucore/CartDF.cxx +++ b/src/emucore/CartDF.cxx @@ -28,7 +28,7 @@ CartridgeDF::CartridgeDF(const ByteBuffer& image, size_t size, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeDF::checkSwitchBank(uInt16 address, uInt8) { - address &= 0x0FFF; + address &= ROM_MASK; // Switch banks if necessary if((address >= 0x0FC0) && (address <= 0x0FDF)) diff --git a/src/emucore/CartEF.cxx b/src/emucore/CartEF.cxx index 70cd8236b..039f4aa5c 100644 --- a/src/emucore/CartEF.cxx +++ b/src/emucore/CartEF.cxx @@ -28,7 +28,7 @@ CartridgeEF::CartridgeEF(const ByteBuffer& image, size_t size, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeEF::checkSwitchBank(uInt16 address, uInt8) { - address &= 0x0FFF; + address &= ROM_MASK; // Switch banks if necessary if((address >= 0x0FE0) && (address <= 0x0FEF)) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 01cf5cbcb..5816181f2 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -35,18 +35,18 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, void CartridgeEnhanced::install(System& system) { // limit banked RAM size to the size of one RAM bank - uInt16 ramSize = myRamBankCount ? 1 << (myBankShift - 1) : myRamSize; + uInt16 ramSize = myRamBankCount > 0 ? 1 << (myBankShift - 1) : myRamSize; // calculate bank switching and RAM sizes and masks - myBankSize = 1 << myBankShift; // e.g. = 2 ^ 12 = 4K = 0x1000 - myBankMask = myBankSize - 1; // e.g. = 0x0FFF - myBankSegs = 1 << (12 - myBankShift); // e.g. = 1 - myRomOffset = myRamBankCount ? 0 : myRamSize * 2; - myRamMask = ramSize - 1; // e.g. = 0xFFFF (doesn't matter for RAM size 0) - myWriteOffset = myRamWpHigh ? ramSize : 0; - myReadOffset = myRamWpHigh ? 0 : ramSize; + myBankSize = 1 << myBankShift; // e.g. = 2 ^ 12 = 4K = 0x1000 + myBankMask = myBankSize - 1; // e.g. = 0x0FFF + myBankSegs = 1 << (MAX_BANK_SHIFT - myBankShift); // e.g. = 1 + myRomOffset = myRamBankCount > 0 ? 0 : myRamSize * 2; + myRamMask = ramSize - 1; // e.g. = 0xFFFF (doesn't matter for RAM size 0) + myWriteOffset = myRamWpHigh ? ramSize : 0; // e.g. = 0x0000 + myReadOffset = myRamWpHigh ? 0 : ramSize; // e.g. = 0x0080 - createRomAccessArrays(mySize + (myRomOffset ? 0 : myRamSize)); + createRomAccessArrays(mySize + (myRomOffset > 0 ? 0 : myRamSize)); // Allocate array for the current bank segments slices myCurrentSegOffset = make_unique(myBankSegs); @@ -56,7 +56,7 @@ void CartridgeEnhanced::install(System& system) mySystem = &system; - if(myRomOffset) + if(myRomOffset > 0) { // Setup page access for extended RAM; banked RAM will be setup in bank() System::PageAccess access(this, System::PageAccessType::READ); @@ -65,7 +65,7 @@ void CartridgeEnhanced::install(System& system) // 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 + myWriteOffset; addr < 0x1000 + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) + for(uInt16 addr = ROM_OFFSET + myWriteOffset; addr < ROM_OFFSET + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) { uInt16 offset = addr & myRamMask; access.romAccessBase = &myRomAccessBase[myWriteOffset + offset]; @@ -76,7 +76,7 @@ void CartridgeEnhanced::install(System& system) // Set the page accessing method for the RAM reading pages access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1000 + myReadOffset; addr < 0x1000 + myReadOffset + myRamSize; addr += System::PAGE_SIZE) + for(uInt16 addr = ROM_OFFSET + myReadOffset; addr < ROM_OFFSET + myReadOffset + myRamSize; addr += System::PAGE_SIZE) { uInt16 offset = addr & myRamMask; access.directPeekBase = &myRAM[offset]; @@ -110,8 +110,8 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) { uInt16 peekAddress = address; - if (hotspot()) - checkSwitchBank(address & 0x0FFF); + if (hotspot() != 0) + checkSwitchBank(address & ROM_MASK); if(isRamBank(address)) { @@ -120,7 +120,7 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) // This is a read access to a write port! // Reading from the write port triggers an unwanted write // The RAM banks follow the ROM banks and are half the size of a ROM bank - return peekRAM(myRAM[((myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] - mySize) >> 1) + address], + return peekRAM(myRAM[((myCurrentSegOffset[(peekAddress & ROM_MASK) >> myBankShift] - mySize) >> 1) + address], peekAddress); } else @@ -133,7 +133,7 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) // Reading from the write port triggers an unwanted write return peekRAM(myRAM[address], peekAddress); else - return myImage[myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] + address]; + return myImage[myCurrentSegOffset[(peekAddress & ROM_MASK) >> myBankShift] + address]; } } @@ -144,10 +144,10 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) // Note: (TODO?) // The checkSwitchBank() call makes no difference between ROM and e.g TIA space // Writing to e.g. 0xf0xx might triger a bankswitch, is (and was!) this a bug??? - if (checkSwitchBank(address & 0x0FFF, value)) + if (checkSwitchBank(address & ROM_MASK, value)) return false; - if(myRamSize) + if(myRamSize > 0) { uInt16 pokeAddress = address; @@ -157,7 +157,7 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) { address &= myRamMask; // The RAM banks follow the ROM banks and are half the size of a ROM bank - pokeRAM(myRAM[((myCurrentSegOffset[(pokeAddress & 0xFFF) >> myBankShift] - mySize) >> 1) + address], + pokeRAM(myRAM[((myCurrentSegOffset[(pokeAddress & ROM_MASK) >> myBankShift] - mySize) >> 1) + address], pokeAddress, value); return true; } @@ -198,7 +198,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) uInt16 segmentOffset = segment << myBankShift; - if(!myRamBankCount || bank < romBankCount()) + if(myRamBankCount == 0 || bank < romBankCount()) { // Setup ROM bank uInt16 romBank = bank % romBankCount(); @@ -206,11 +206,11 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) uInt32 bankOffset = myCurrentSegOffset[segment] = romBank << myBankShift; uInt16 hotspot = this->hotspot(); uInt16 hotSpotAddr; - uInt16 fromAddr = (0x1000 + segmentOffset + myRomOffset) & ~System::PAGE_MASK; + uInt16 fromAddr = (ROM_OFFSET + segmentOffset + myRomOffset) & ~System::PAGE_MASK; // for ROMs < 4_KB, the whole address space will be mapped. - uInt16 toAddr = (0x1000 + segmentOffset + (mySize < 4_KB ? 0x1000 : myBankSize)) & ~System::PAGE_MASK; + uInt16 toAddr = (ROM_OFFSET + segmentOffset + (mySize < 4_KB ? 4_KB : myBankSize)) & ~System::PAGE_MASK; - if(hotspot) + if(hotspot != 0) hotSpotAddr = (hotspot & ~System::PAGE_MASK); else hotSpotAddr = 0xFFFF; // none @@ -242,8 +242,8 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) myCurrentSegOffset[segment] = bank << myBankShift; // Set the page accessing method for the RAM writing pages - uInt16 fromAddr = (0x1000 + segmentOffset + myWriteOffset) & ~System::PAGE_MASK; - uInt16 toAddr = (0x1000 + segmentOffset + myWriteOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; + uInt16 fromAddr = (ROM_OFFSET + segmentOffset + myWriteOffset) & ~System::PAGE_MASK; + uInt16 toAddr = (ROM_OFFSET + segmentOffset + myWriteOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; System::PageAccess access(this, System::PageAccessType::WRITE); for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) @@ -257,8 +257,8 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) } // Set the page accessing method for the RAM reading pages - fromAddr = (0x1000 + segmentOffset + myReadOffset) & ~System::PAGE_MASK; - toAddr = (0x1000 + segmentOffset + myReadOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; + fromAddr = (ROM_OFFSET + segmentOffset + myReadOffset) & ~System::PAGE_MASK; + toAddr = (ROM_OFFSET + segmentOffset + myReadOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; access.type = System::PageAccessType::READ; for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) @@ -270,7 +270,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) access.romPeekCounter = &myRomAccessCounter[offset]; access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; mySystem->setPageAccess(addr, access); - } + } } return myBankChanged = true; } @@ -278,7 +278,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 CartridgeEnhanced::getBank(uInt16 address) const { - return myCurrentSegOffset[(address & 0xFFF) >> myBankShift] >> myBankShift; + return myCurrentSegOffset[(address & ROM_MASK) >> myBankShift] >> myBankShift; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -302,7 +302,7 @@ uInt16 CartridgeEnhanced::ramBankCount() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeEnhanced::isRamBank(uInt16 address) const { - return myRamBankCount ? getBank(address) >= romBankCount() : false; + return myRamBankCount > 0 ? getBank(address) >= romBankCount() : false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -310,7 +310,7 @@ bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) { if(isRamBank(address)) { - myRAM[((myCurrentSegOffset[(address & 0xFFF) >> myBankShift] - mySize) >> 1) + (address & myRamMask)] = value; + myRAM[((myCurrentSegOffset[(address & ROM_MASK) >> myBankShift] - mySize) >> 1) + (address & myRamMask)] = value; } else { @@ -322,7 +322,7 @@ bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) myRAM[address & myRamMask] = value; } else - myImage[myCurrentSegOffset[(address & 0xFFF) >> myBankShift] + (address & myBankMask)] = value; + myImage[myCurrentSegOffset[(address & ROM_MASK) >> myBankShift] + (address & myBankMask)] = value; } return myBankChanged = true; @@ -341,7 +341,7 @@ bool CartridgeEnhanced::save(Serializer& out) const try { out.putIntArray(myCurrentSegOffset.get(), myBankSegs); - if(myRamSize) + if(myRamSize > 0) out.putByteArray(myRAM.get(), myRamSize); } catch(...) @@ -359,7 +359,7 @@ bool CartridgeEnhanced::load(Serializer& in) try { in.getIntArray(myCurrentSegOffset.get(), myBankSegs); - if(myRamSize) + if(myRamSize > 0) in.getByteArray(myRAM.get(), myRamSize); } catch(...) diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 3b68101cc..e66aeb9f5 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -218,6 +218,13 @@ class CartridgeEnhanced : public Cartridge // The size of the ROM image size_t mySize{0}; + protected: + // The offset into address space for accessing ROM + static constexpr uInt16 ROM_OFFSET = 0x1000; + + // The mask for ROM address space + static constexpr uInt16 ROM_MASK = 0x0FFF; + private: // Calculated as: log(ROM bank segment size) / log(2) static constexpr uInt16 BANK_SHIFT = 12; // default = 4K @@ -231,6 +238,9 @@ class CartridgeEnhanced : public Cartridge // Write port for extra RAM is at low address by default static constexpr bool RAM_HIGH_WP = false; + // The maximum shift (for a 4K bank size) + static constexpr uInt16 MAX_BANK_SHIFT = 12; ; // -> 4K + protected: /** Check hotspots and switch bank if triggered. diff --git a/src/emucore/CartFA2.cxx b/src/emucore/CartFA2.cxx index 1e4251988..6662e8171 100644 --- a/src/emucore/CartFA2.cxx +++ b/src/emucore/CartFA2.cxx @@ -35,7 +35,7 @@ CartridgeFA2::CartridgeFA2(const ByteBuffer& image, size_t size, myImage = make_unique(mySize); // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); + std::copy_n(img_ptr, mySize, myImage.get()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -53,7 +53,7 @@ bool CartridgeFA2::checkSwitchBank(uInt16 address, uInt8) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeFA2::peek(uInt16 address) { - if((address & 0x0FFF) == 0x0FF4) + if((address & ROM_MASK) == 0x0FF4) { // Load/save RAM to/from Harmony cart flash if(mySize == 28_KB && !bankLocked()) @@ -66,7 +66,7 @@ uInt8 CartridgeFA2::peek(uInt16 address) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeFA2::poke(uInt16 address, uInt8 value) { - if((address & 0x0FFF) == 0x0FF4) + if((address & ROM_MASK) == 0x0FF4) { // Load/save RAM to/from Harmony cart flash if(mySize == 28_KB && !bankLocked()) diff --git a/src/emucore/CartFE.cxx b/src/emucore/CartFE.cxx index 3a07730e0..7c3debda3 100644 --- a/src/emucore/CartFE.cxx +++ b/src/emucore/CartFE.cxx @@ -63,7 +63,7 @@ bool CartridgeFE::checkSwitchBank(uInt16 address, uInt8 value) uInt8 CartridgeFE::peek(uInt16 address) { uInt8 value = (address < 0x200) ? mySystem->m6532().peek(address) : - myImage[myCurrentSegOffset[(address & 0xFFF) >> myBankShift] + (address & myBankMask)]; + myImage[myCurrentSegOffset[(address & myBankMask) >> myBankShift] + (address & myBankMask)]; // Check if we hit hotspot checkSwitchBank(address, value); diff --git a/src/emucore/CartSB.cxx b/src/emucore/CartSB.cxx index 56973392c..5caa01be7 100644 --- a/src/emucore/CartSB.cxx +++ b/src/emucore/CartSB.cxx @@ -54,13 +54,12 @@ bool CartridgeSB::checkSwitchBank(uInt16 address, uInt8) // Switch banks if necessary if((address & 0x1800) == 0x0800) { - bank(address & startBank()); + bank(address & (romBankCount() - 1)); return true; } return false; } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeSB::peek(uInt16 address) {