Updated DPC+ scheme to autodetect and use DPC+ carts in 32KB format.

These have ARM code appended to the beginning of the ROM, which is
(for now) ignored by Stella.

Improved memory usage for DPC and DPC+ schemes, so that an extra
copy of the ROM image is no longer required.  This also fixes a bug
in the getImage methods, which wouldn't have actually returned any
changes made by patching the ROM (it always returned the original,
non-modified copy).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2030 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2010-05-02 22:52:59 +00:00
parent 5de12952ec
commit f5dd4e6ce7
6 changed files with 72 additions and 45 deletions

View File

@ -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)
{

View File

@ -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

View File

@ -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;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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];

View File

@ -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;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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];