From 5d29bc0e2d2a35e38ad9b0601c5265b07add6654 Mon Sep 17 00:00:00 2001 From: stephena Date: Fri, 12 Jun 2009 14:04:18 +0000 Subject: [PATCH] ROMs smaller than 2K in the Cart2K class are now mirrored correctly, not by actually copying pieces of ROM, but by addressing different parts of the ROM with an appropriate mask. This fixes a patching bug I just found, whereby patching one part of the ROM wasn't propagating it to the rest of the image. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1769 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- src/emucore/Cart2K.cxx | 39 ++++++++++++++++++++------------------- src/emucore/Cart2K.hxx | 10 ++++++++-- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/emucore/Cart2K.cxx b/src/emucore/Cart2K.cxx index 4353d6b6f..2d9f66b9e 100644 --- a/src/emucore/Cart2K.cxx +++ b/src/emucore/Cart2K.cxx @@ -28,25 +28,27 @@ Cartridge2K::Cartridge2K(const uInt8* image, uInt32 size) // Size can be a maximum of 2K if(size > 2048) size = 2048; + // Set image size to closest power-of-two for the given size + mySize = 1; + while(mySize < size) + mySize <<= 1; + // Initialize ROM with illegal 6502 opcode that causes a real 6502 to jam - memset(myImage, 0x02, 2048); + myImage = new uInt8[mySize]; + memset(myImage, 0x02, mySize); - // Mirror each power-of-two slice in the 2K address space - uInt32 slice = 1, numslices = 2048; - while(slice < size) - { - slice <<= 1; - numslices >>= 1; - } + // Copy the ROM image into my buffer + memcpy(myImage, image, size); - // Copy the ROM image slices into my buffer - for(uInt32 i = 0; i < numslices; ++i) - memcpy(myImage + i*slice, image, slice); + // Set mask for accessing the image buffer + // This is guaranteed to work, as mySize is a power of two + myMask = mySize - 1; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge2K::~Cartridge2K() { + delete[] myImage; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -64,14 +66,13 @@ void Cartridge2K::install(System& system) // Make sure the system we're being installed in has a page size that'll work assert((0x1000 & mask) == 0); - System::PageAccess access; - access.directPokeBase = 0; - access.device = this; - // Map ROM image into the system + System::PageAccess access; for(uInt32 address = 0x1000; address < 0x2000; address += (1 << shift)) { - access.directPeekBase = &myImage[address & 0x07FF]; + access.device = this; + access.directPeekBase = &myImage[address & myMask]; + access.directPokeBase = 0; mySystem->setPageAccess(address >> shift, access); } } @@ -79,7 +80,7 @@ void Cartridge2K::install(System& system) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 Cartridge2K::peek(uInt16 address) { - return myImage[address & 0x07FF]; + return myImage[address & myMask]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -110,14 +111,14 @@ int Cartridge2K::bankCount() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Cartridge2K::patch(uInt16 address, uInt8 value) { - myImage[address & 0x07FF] = value; + myImage[address & myMask] = value; return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8* Cartridge2K::getImage(int& size) { - size = 2048; + size = mySize; return &myImage[0]; } diff --git a/src/emucore/Cart2K.hxx b/src/emucore/Cart2K.hxx index f38d631e3..df37f48bc 100644 --- a/src/emucore/Cart2K.hxx +++ b/src/emucore/Cart2K.hxx @@ -140,8 +140,14 @@ class Cartridge2K : public Cartridge virtual void poke(uInt16 address, uInt8 value); private: - // The 2k ROM image for the cartridge - uInt8 myImage[2048]; + // Pointer to a dynamically allocated ROM image of the cartridge + uInt8* myImage; + + // Size of the ROM image + uInt32 mySize; + + // Mask to use for mirroring + uInt32 myMask; }; #endif