mirror of https://github.com/stella-emu/stella.git
Fix some common errors causing crashes when ROM sizes aren't what we expect (fixes #654).
This commit is contained in:
parent
edcf1d3c9d
commit
5f2fbc8618
|
@ -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<typename T, size_t ROW, size_t COL>
|
||||
using array2D = std::array<std::array<T, COL>, ROW>;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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<size_t>(mySize, System::PAGE_SIZE);
|
||||
myImage = make_unique<uInt8[]>(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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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<uInt8[]>(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<uInt8[]>(1_KB);
|
||||
// Copy the RAM image into a buffer for use in reset()
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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<uInt8[]>(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<size_t>(mySize, System::PAGE_SIZE);
|
||||
myImage = make_unique<uInt8[]>(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<uInt8[]>(mySize);
|
||||
|
||||
// Copy the ROM image into my buffer
|
||||
std::copy_n(image.get(), mySize, myImage.get());
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue