diff --git a/src/emucore/Cart.cxx b/src/emucore/Cart.cxx index 684d60adc..e2a8f1ffb 100644 --- a/src/emucore/Cart.cxx +++ b/src/emucore/Cart.cxx @@ -390,6 +390,8 @@ string Cartridge::autodetectType(const uInt8* image, uInt32 size) type = "3E"; else if(isProbably3F(image, size)) type = "3F"; + else if(isProbablyDPCplus(image, size)) + type = "DPC+"; else type = "F4"; } @@ -515,6 +517,14 @@ bool Cartridge::isProbably3E(const uInt8* image, uInt32 size) return searchForBytes(image, size, signature, 4, 1); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool Cartridge::isProbablyDPCplus(const uInt8* image, uInt32 size) +{ + // DPC+ ARM code has 2 occurrences of the string DPC+ + uInt8 signature[] = { 0x44, 0x50, 0x43, 0x2B }; // DPC+ + return searchForBytes(image, size, signature, 4, 2); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Cartridge::isProbablyE0(const uInt8* image, uInt32 size) { diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx index 8440b191b..ae1551cbe 100644 --- a/src/emucore/Cart.hxx +++ b/src/emucore/Cart.hxx @@ -259,6 +259,11 @@ class Cartridge : public Device Returns true if the image is probably a 3E bankswitching cartridge */ static bool isProbably3E(const uInt8* image, uInt32 size); + + /** + Returns true if the image is probably a DPC+ bankswitching cartridge + */ + static bool isProbablyDPCplus(const uInt8* image, uInt32 size); /** Returns true if the image is probably a E0 bankswitching cartridge diff --git a/src/emucore/CartDPC.cxx b/src/emucore/CartDPC.cxx index e02d00ab7..4ad9d6990 100644 --- a/src/emucore/CartDPC.cxx +++ b/src/emucore/CartDPC.cxx @@ -28,15 +28,14 @@ CartridgeDPC::CartridgeDPC(const uInt8* image, uInt32 size) : mySystemCycles(0), myFractionalClocks(0.0) { - // Make a copy of the entire image as-is, for use by getImage() - // (this wastes 12K of RAM, should be controlled by a #ifdef) - memcpy(myImageCopy, image, BSPF_min(size, 8192u + 2048u + 255u)); + // Make a copy of the entire image + memcpy(myImage, image, BSPF_min(size, 8192u + 2048u + 255u)); - // Copy the program ROM image into my buffer - memcpy(myProgramImage, image, 8192); + // Pointer to the program ROM (8K @ 0 byte offset) + myProgramImage = myImage; - // Copy the display ROM image into my buffer - memcpy(myDisplayImage, image + 8192, 2048); + // Pointer to the display ROM (2K @ 8K offset) + myDisplayImage = myProgramImage + 8192; // Initialize the DPC data fetcher registers for(uInt16 i = 0; i < 8; ++i) @@ -474,7 +473,7 @@ bool CartridgeDPC::patch(uInt16 address, uInt8 value) const uInt8* CartridgeDPC::getImage(int& size) const { size = 8192 + 2048 + 255; - return myImageCopy; + return myImage; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartDPC.hxx b/src/emucore/CartDPC.hxx index 94a07512b..64309ad94 100644 --- a/src/emucore/CartDPC.hxx +++ b/src/emucore/CartDPC.hxx @@ -156,18 +156,18 @@ class CartridgeDPC : public Cartridge void updateMusicModeDataFetchers(); private: + // The ROM image + uInt8 myImage[8192 + 2048 + 255]; + + // Pointer to the 8K program ROM image of the cartridge + uInt8* myProgramImage; + + // Pointer to the 2K display ROM image of the cartridge + uInt8* myDisplayImage; + // Indicates which bank is currently active uInt16 myCurrentBank; - // The 8K program ROM image of the cartridge - uInt8 myProgramImage[8192]; - - // The 2K display ROM image of the cartridge - uInt8 myDisplayImage[2048]; - - // Copy of the raw image, for use by getImage() - uInt8 myImageCopy[8192 + 2048 + 255]; - // The top registers for the data fetchers uInt8 myTops[8]; diff --git a/src/emucore/CartDPCPlus.cxx b/src/emucore/CartDPCPlus.cxx index 034cc0944..09cc5bc57 100644 --- a/src/emucore/CartDPCPlus.cxx +++ b/src/emucore/CartDPCPlus.cxx @@ -31,18 +31,30 @@ CartridgeDPCPlus::CartridgeDPCPlus(const uInt8* image, uInt32 size) mySystemCycles(0), myFractionalClocks(0.0) { - // Make a copy of the entire image as-is, for use by getImage() - // (this wastes 29K of RAM, should be controlled by a #ifdef) - memcpy(myImageCopy, image, size); + // Store image, making sure it's at least 29KB + uInt32 minsize = 4096 * 6 + 4096 + 1024 + 255; + mySize = BSPF_max(minsize, size); + myImage = new uInt8[mySize]; + memcpy(myImage, image, size); - // Copy the program ROM image into my buffer - memcpy(myProgramImage, image, 4096 * 6); + // Pointer to the program ROM (24K @ 0 byte offset) + myProgramImage = myImage; - // Copy the display ROM image into my buffer - memcpy(myDisplayImage, image + 4096 * 6, 4096); + // Pointer to the display ROM (4K @ 24K offset) + myDisplayImage = myProgramImage + 4096 * 6; - // Copy the Frequency ROM image into my buffer - memcpy(myFrequencyImage, image + 4096 * 6 + 4096, 1024); + // Pointer to the Frequency ROM (1K @ 28K offset) + myFrequencyImage = myDisplayImage + 4096; + + // If the image is larger than 29K, we assume any excess at the + // beginning is ARM code, and skip over it + if(size > 29 * 1024) + { + int offset = size - 29 * 1024; + myProgramImage += offset; + myDisplayImage += offset; + myFrequencyImage += offset; + } // Initialize the DPC data fetcher registers for(uInt16 i = 0; i < 8; ++i) @@ -61,6 +73,7 @@ CartridgeDPCPlus::CartridgeDPCPlus(const uInt8* image, uInt32 size) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeDPCPlus::~CartridgeDPCPlus() { + delete[] myImage; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -159,7 +172,6 @@ inline void CartridgeDPCPlus::callFunction(uInt8 value) break; // reserved } - } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -234,11 +246,11 @@ uInt8 CartridgeDPCPlus::peek(uInt16 address) // Update the music data fetchers (counter & flag) updateMusicModeDataFetchers(); - // using myImageCopy[] instead of myDisplayImage[] because waveforms + // using myProgramImage[] instead of myDisplayImage[] because waveforms // could also be in the 1K Frequency table. - uInt32 i = myImageCopy[6*4096 + (myMusicWaveforms[0] << 5) + (myMusicCounters[0] >> 27)] + - myImageCopy[6*4096 + (myMusicWaveforms[1] << 5) + (myMusicCounters[1] >> 27)] + - myImageCopy[6*4096 + (myMusicWaveforms[2] << 5) + (myMusicCounters[2] >> 27)]; + uInt32 i = myProgramImage[6*4096 + (myMusicWaveforms[0] << 5) + (myMusicCounters[0] >> 27)] + + myProgramImage[6*4096 + (myMusicWaveforms[1] << 5) + (myMusicCounters[1] >> 27)] + + myProgramImage[6*4096 + (myMusicWaveforms[2] << 5) + (myMusicCounters[2] >> 27)]; result = (uInt8)i; break; @@ -580,8 +592,8 @@ bool CartridgeDPCPlus::patch(uInt16 address, uInt8 value) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const uInt8* CartridgeDPCPlus::getImage(int& size) const { - size = 4096 * 6 + 4096 + 1024 + 255; - return myImageCopy; + size = mySize; + return myImage; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartDPCPlus.hxx b/src/emucore/CartDPCPlus.hxx index 668480756..db06829f1 100644 --- a/src/emucore/CartDPCPlus.hxx +++ b/src/emucore/CartDPCPlus.hxx @@ -166,21 +166,22 @@ class CartridgeDPCPlus : public Cartridge inline void callFunction(uInt8 value); private: + // The ROM image and size + uInt8* myImage; + uInt32 mySize; + + // Pointer to the 24K program ROM image of the cartridge + uInt8* myProgramImage; + + // Pointer to the 4K display ROM image of the cartridge + uInt8* myDisplayImage; + + // Pointer to the 1K frequency table + uInt8* myFrequencyImage; + // Indicates which bank is currently active uInt16 myCurrentBank; - - // The 24K program ROM image of the cartridge - uInt8 myProgramImage[4096 * 6]; - - // The 4K display ROM image of the cartridge - uInt8 myDisplayImage[4096]; - - // The 1K frequency table - uInt8 myFrequencyImage[1024]; - // Copy of the raw image, for use by getImage() - uInt8 myImageCopy[4096 * 6 + 4096 + 1024 + 255]; - // The top registers for the data fetchers uInt8 myTops[8];