diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index 844f12804..24fe8d0a7 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -131,6 +131,15 @@ namespace BSPF // Maximum size of a ROM that Stella can support inline constexpr size_t romMaxSize() { return 512_KB; } + // Get next power of two greater than or equal to the given value + inline size_t nextPowerOfTwo(size_t size) { + if(size < 2) return 1; + size_t power2 = 1; + while(power2 < size) + power2 <<= 1; + return power2; + } + // Make 2D-arrays using std::array less verbose template using array2D = std::array, ROW>; diff --git a/src/emucore/Cart0840.cxx b/src/emucore/Cart0840.cxx index e071f61a2..894b8eed7 100644 --- a/src/emucore/Cart0840.cxx +++ b/src/emucore/Cart0840.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge0840::Cartridge0840(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 8_KB, md5, settings) { } diff --git a/src/emucore/Cart2K.cxx b/src/emucore/Cart2K.cxx index f4d4ef7bd..c70cc373f 100644 --- a/src/emucore/Cart2K.cxx +++ b/src/emucore/Cart2K.cxx @@ -21,38 +21,6 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge2K::Cartridge2K(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 2_KB, md5, settings) { - // Size can be a maximum of 2K - if(size > 2_KB) - size = 2_KB; - - // Set image size to closest power-of-two for the given size - mySize = 1; myBankShift = 0; - while(mySize < size) - { - mySize <<= 1; - myBankShift++; - } - - // Initialize ROM with illegal 6502 opcode that causes a real 6502 to jam - size_t bufSize = std::max(mySize, System::PAGE_SIZE); - myImage = make_unique(bufSize); - std::fill_n(myImage.get(), bufSize, 0x02); - - // Handle cases where ROM is smaller than the page size - // It's much easier to do it this way rather than changing the page size - if(mySize >= System::PAGE_SIZE) - { - // Directly copy the ROM image into the buffer - std::copy_n(image.get(), mySize, myImage.get()); - } - else - { - // Manually 'mirror' the ROM image into the buffer - for(size_t i = 0; i < System::PAGE_SIZE; i += mySize) - std::copy_n(image.get(), mySize, myImage.get() + i); - mySize = System::PAGE_SIZE; - myBankShift = 6; - } } diff --git a/src/emucore/Cart3E.cxx b/src/emucore/Cart3E.cxx index be69d105d..263c8b2e9 100644 --- a/src/emucore/Cart3E.cxx +++ b/src/emucore/Cart3E.cxx @@ -22,7 +22,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) { myBankShift = BANK_SHIFT; myRamSize = RAM_SIZE; diff --git a/src/emucore/Cart3F.cxx b/src/emucore/Cart3F.cxx index 21b21b9c7..20d9cef1d 100644 --- a/src/emucore/Cart3F.cxx +++ b/src/emucore/Cart3F.cxx @@ -22,7 +22,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3F::Cartridge3F(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) { myBankShift = BANK_SHIFT; } diff --git a/src/emucore/Cart4K.cxx b/src/emucore/Cart4K.cxx index 9e684afad..0a3e27bdc 100644 --- a/src/emucore/Cart4K.cxx +++ b/src/emucore/Cart4K.cxx @@ -21,6 +21,6 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge4K::Cartridge4K(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 4_KB, md5, settings) { } diff --git a/src/emucore/CartBF.cxx b/src/emucore/CartBF.cxx index ce3c53198..065b657dc 100644 --- a/src/emucore/CartBF.cxx +++ b/src/emucore/CartBF.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeBF::CartridgeBF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 256_KB, md5, settings) { } diff --git a/src/emucore/CartCV.cxx b/src/emucore/CartCV.cxx index 8d7ac9d89..8e8e6504e 100644 --- a/src/emucore/CartCV.cxx +++ b/src/emucore/CartCV.cxx @@ -21,23 +21,19 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeCV::CartridgeCV(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 2_KB, md5, settings) { myBankShift = BANK_SHIFT; myRamSize = RAM_SIZE; myRamWpHigh = RAM_HIGH_WP; - if(mySize == 4_KB) + if(size == 4_KB) { // The game has something saved in the RAM // Useful for MagiCard program listings - // Allocate array for the ROM image - mySize = 2_KB; - myImage = make_unique(mySize); - // Copy the ROM image into my buffer - std::copy_n(image.get() + mySize, mySize, myImage.get()); + std::copy_n(image.get() + 2_KB, 2_KB, myImage.get()); myInitialRAM = make_unique(1_KB); // Copy the RAM image into a buffer for use in reset() diff --git a/src/emucore/CartDF.cxx b/src/emucore/CartDF.cxx index 0f4d9a1ca..f95ebcc93 100644 --- a/src/emucore/CartDF.cxx +++ b/src/emucore/CartDF.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeDF::CartridgeDF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 128_KB, md5, settings) { } diff --git a/src/emucore/CartE0.cxx b/src/emucore/CartE0.cxx index 07afae5a2..7a10c3e34 100644 --- a/src/emucore/CartE0.cxx +++ b/src/emucore/CartE0.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeE0::CartridgeE0(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 8_KB, md5, settings) { myBankShift = BANK_SHIFT; } diff --git a/src/emucore/CartEF.cxx b/src/emucore/CartEF.cxx index 039f4aa5c..175b42263 100644 --- a/src/emucore/CartEF.cxx +++ b/src/emucore/CartEF.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeEF::CartridgeEF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 64_KB, md5, settings) { } diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index c7378670a..363ffcd59 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -15,20 +15,84 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ +#include "Logger.hxx" #include "System.hxx" #include "CartEnhanced.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size) + size_t bsSize, const string& md5, + const Settings& settings) + : Cartridge(settings, md5) { - // Allocate array for the ROM image (at least 64 bytzes) - myImage = make_unique(std::max(uInt32(mySize), uInt32(System::PAGE_SIZE))); + // ROMs are not always at the 'legal' size for their associated + // bankswitching scheme; here we deal with the differing sizes + if(size != bsSize) + { + // Is the ROM too large? If so, we cap it + if(size > bsSize) + { + ostringstream buf; + buf << "ROM larger than expected (" << size << " > " << bsSize << "), truncating\n"; + Logger::info(buf.str()); - // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); + size = bsSize; + } + + // Set image size to closest power-of-two for the given size + // This only applies for sizes less than the standard bank size + if(size < 4_KB) + { + mySize = 1; myBankShift = 0; + while(mySize < size) + { + mySize <<= 1; + myBankShift++; + } + } + else + mySize = size; + + // Initialize ROM with all 0's, to fill areas that the ROM may not cover + size_t bufSize = std::max(mySize, System::PAGE_SIZE); + myImage = make_unique(bufSize); + std::fill_n(myImage.get(), bufSize, 0); + + // Handle cases where ROM is smaller than the page size + // It's much easier to do it this way rather than changing the page size + if(mySize >= System::PAGE_SIZE) + { + if(size < mySize) + { + ostringstream buf; + buf << "ROM smaller than expected (" << mySize << " > " << size + << "), appending " << (mySize - size) << " bytes\n"; + Logger::info(buf.str()); + } + + // TODO: should we mirror here too?? + // Directly copy the ROM image into the buffer + std::copy_n(image.get(), mySize, myImage.get()); + } + else + { + // Manually 'mirror' the ROM image into the buffer + for(size_t i = 0; i < System::PAGE_SIZE; i += mySize) + std::copy_n(image.get(), mySize, myImage.get() + i); + mySize = System::PAGE_SIZE; + myBankShift = 6; + } + } + else + { + mySize = size; + + // 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()); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 3c2e2c80d..be0ac95de 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -42,10 +42,11 @@ class CartridgeEnhanced : public Cartridge @param image Pointer to the ROM image @param size The size of the ROM image @param md5 The md5sum of the ROM image + @param bsSize The size specified by the bankswitching scheme @param settings A reference to the various settings (read-only) */ - CartridgeEnhanced(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + CartridgeEnhanced(const ByteBuffer& image, size_t size, size_t bsSize, + const string& md5, const Settings& settings); virtual ~CartridgeEnhanced() = default; public: diff --git a/src/emucore/CartF0.cxx b/src/emucore/CartF0.cxx index 8747c57f3..f21bba07e 100644 --- a/src/emucore/CartF0.cxx +++ b/src/emucore/CartF0.cxx @@ -20,7 +20,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF0::CartridgeF0(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 64_KB, md5, settings) { } diff --git a/src/emucore/CartF4.cxx b/src/emucore/CartF4.cxx index 6a8cd6e00..609fd0b03 100644 --- a/src/emucore/CartF4.cxx +++ b/src/emucore/CartF4.cxx @@ -20,7 +20,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF4::CartridgeF4(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 32_KB, md5, settings) { } diff --git a/src/emucore/CartF6.cxx b/src/emucore/CartF6.cxx index 50e993e26..572909952 100644 --- a/src/emucore/CartF6.cxx +++ b/src/emucore/CartF6.cxx @@ -20,7 +20,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF6::CartridgeF6(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 16_KB, md5, settings) { } diff --git a/src/emucore/CartF8.cxx b/src/emucore/CartF8.cxx index 5d898091c..7ea1216a5 100644 --- a/src/emucore/CartF8.cxx +++ b/src/emucore/CartF8.cxx @@ -20,7 +20,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF8::CartridgeF8(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 8_KB, md5, settings) { } diff --git a/src/emucore/CartFA.cxx b/src/emucore/CartFA.cxx index 082e403f7..bc82dec84 100644 --- a/src/emucore/CartFA.cxx +++ b/src/emucore/CartFA.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFA::CartridgeFA(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 12_KB, md5, settings) { myRamSize = RAM_SIZE; } diff --git a/src/emucore/CartFC.cxx b/src/emucore/CartFC.cxx index c415ba1af..9b945c666 100644 --- a/src/emucore/CartFC.cxx +++ b/src/emucore/CartFC.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFC::CartridgeFC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) { } diff --git a/src/emucore/CartFE.cxx b/src/emucore/CartFE.cxx index 7c3debda3..a9602e88a 100644 --- a/src/emucore/CartFE.cxx +++ b/src/emucore/CartFE.cxx @@ -22,7 +22,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFE::CartridgeFE(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 8_KB, md5, settings) { myDirectPeek = false; } diff --git a/src/emucore/CartMDM.cxx b/src/emucore/CartMDM.cxx index 2734b2793..022bc1bdb 100644 --- a/src/emucore/CartMDM.cxx +++ b/src/emucore/CartMDM.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeMDM::CartridgeMDM(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) { } diff --git a/src/emucore/CartSB.cxx b/src/emucore/CartSB.cxx index 5caa01be7..8ad55f28d 100644 --- a/src/emucore/CartSB.cxx +++ b/src/emucore/CartSB.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeSB::CartridgeSB(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) { } diff --git a/src/emucore/CartTVBoy.cxx b/src/emucore/CartTVBoy.cxx index b60c374c4..0626da0aa 100644 --- a/src/emucore/CartTVBoy.cxx +++ b/src/emucore/CartTVBoy.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeTVBoy::CartridgeTVBoy(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 512_KB, md5, settings) { } diff --git a/src/emucore/CartUA.cxx b/src/emucore/CartUA.cxx index 74ccc3773..23caa5091 100644 --- a/src/emucore/CartUA.cxx +++ b/src/emucore/CartUA.cxx @@ -22,7 +22,7 @@ CartridgeUA::CartridgeUA(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, bool swapHotspots) - : CartridgeEnhanced(image, size, md5, settings), + : CartridgeEnhanced(image, size, 8_KB, md5, settings), mySwappedHotspots(swapHotspots) { } diff --git a/src/emucore/CartWD.cxx b/src/emucore/CartWD.cxx index 11ebc653e..f9c7463f3 100644 --- a/src/emucore/CartWD.cxx +++ b/src/emucore/CartWD.cxx @@ -23,10 +23,10 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeWD::CartridgeWD(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 8_KB, md5, settings) { // Copy the ROM image into my buffer - if (mySize == 8_KB + 3) + if(size == 8_KB + 3) { // swap banks 2 & 3 of bad dump and correct size std::copy_n(image.get() + 1_KB * 3, 1_KB * 1, myImage.get() + 1_KB * 2); diff --git a/src/emucore/CartX07.cxx b/src/emucore/CartX07.cxx index ac40b6ac6..e28869920 100644 --- a/src/emucore/CartX07.cxx +++ b/src/emucore/CartX07.cxx @@ -23,7 +23,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeX07::CartridgeX07(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 64_KB, md5, settings) { }