Improved cart auto-detection logic. There's still quite a bit to do,

and I'm not sure if some of the remaining types can even be autodetected.
I only wish I'd had time to include this in the 2.3 release.

Bumped version number to 2.3.01, and starting all over again.  Hopefully
more help will find its way to me this time :(


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1237 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2006-12-24 17:13:10 +00:00
parent 61ef87830e
commit deacea8437
6 changed files with 594 additions and 1003 deletions

View File

@ -13,13 +13,13 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Version.hxx,v 1.20 2006-12-20 12:42:54 stephena Exp $
// $Id: Version.hxx,v 1.21 2006-12-24 17:13:09 stephena Exp $
//============================================================================
#ifndef VERSION_HXX
#define VERSION_HXX
#define STELLA_BASE_VERSION "2.3"
#define STELLA_BASE_VERSION "2.3.01"
#ifdef NIGHTLY_BUILD
#define STELLA_VERSION STELLA_BASE_VERSION "pre-" NIGHTLY_BUILD

View File

@ -13,10 +13,11 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Cart.cxx,v 1.22 2006-12-08 16:49:19 stephena Exp $
// $Id: Cart.cxx,v 1.23 2006-12-24 17:13:10 stephena Exp $
//============================================================================
#include <assert.h>
#include <cassert>
#include <sstream>
#include "bspf.hxx"
#include "Cart.hxx"
@ -54,9 +55,19 @@ Cartridge* Cartridge::create(const uInt8* image, uInt32 size,
// Get the type of the cartridge we're creating
string type = properties.get(Cartridge_Type);
// Collect some info about the ROM
ostringstream buf;
buf << "Size of ROM: " << size << endl
<< "Specified type: " << type << endl;
// See if we should try to auto-detect the cartridge type
if(type == "AUTO-DETECT")
{
type = autodetectType(image, size);
buf << "Auto-detected type: " << type << endl;
}
// cerr << buf.str() << endl;
// We should know the cart's type by now so let's create it
if(type == "2K")
@ -128,71 +139,97 @@ string Cartridge::autodetectType(const uInt8* image, uInt32 size)
{
type = "AR";
}
else if((size == 2048) || (memcmp(image, image + 2048, 2048) == 0))
else if(size == 2048)
{
// TODO - autodetect CV
type = "2K";
}
else if((size == 4096) || (memcmp(image, image + 4096, 4096) == 0))
else if(size == 4096)
{
type = "4K";
// 2K image in consecutive banks
if(memcmp(image, image + 2048, 2048) == 0)
type = "2K";
else
type = "4K";
}
else if((size == 8192) || (memcmp(image, image + 8192, 8192) == 0))
else if(size == 8192) // 8K
{
type = isProbably3F(image, size) ? "3F" : "F8";
// TODO - autodetect E0, FE, UA
if(isProbablySC(image, size))
type = "F8SC";
else if(memcmp(image, image + 4096, 4096) == 0)
type = "4K";
else if(isProbably3E(image, size))
type = "3E";
else if(isProbably3F(image, size))
type = "3F";
else
type = "F8";
}
else if((size == 10495) || (size == 10240))
else if((size == 10495) || (size == 10496) || (size == 10240)) // 10K - Pitfall2
{
type = "DPC";
}
else if(size == 12288)
else if(size == 12288) // 12K
{
// TODO - this should really be in a method that checks the first
// 512 bytes of ROM and finds if either the lower 256 bytes or
// higher 256 bytes are all the same. For now, we assume that
// all carts of 12K are CBS RAM Plus/FASC.
type = "FASC";
}
else if(size == 32768)
else if(size == 16384) // 16K
{
// Assume this is a 32K super-cart then check to see if it is
type = "F4SC";
uInt8 first = image[0];
for(uInt32 i = 0; i < 256; ++i)
{
if(image[i] != first)
{
// It's not a super cart (probably)
type = isProbably3F(image, size) ? "3F" : "F4";
break;
}
}
// TODO - autodetect E7
if(isProbablySC(image, size))
type = "F6SC";
else if(isProbably3E(image, size))
type = "3E";
else if(isProbably3F(image, size))
type = "3F";
else
type = "F6";
}
else if(size == 65536)
else if(size == 32768) // 32K
{
type = isProbably3F(image, size) ? "3F" : "MB";
if(isProbablySC(image, size))
type = "F4SC";
else if(isProbably3E(image, size))
type = "3E";
else if(isProbably3F(image, size))
type = "3F";
else
type = "F4";
}
else if(size == 131072)
else if(size == 65536) // 64K
{
type = isProbably3F(image, size) ? "3F" : "MC";
// TODO - autodetect 4A50
if(isProbably3E(image, size))
type = "3E";
else if(isProbably3F(image, size))
type = "3F";
else
type = "MB";
}
else
else if(size == 131072) // 128K
{
// Assume this is a 16K super-cart then check to see if it is
type = "F6SC";
uInt8 first = image[0];
for(uInt32 i = 0; i < 256; ++i)
{
if(image[i] != first)
{
// It's not a super cart (probably)
type = isProbably3F(image, size) ? "3F" : "F6";
break;
}
}
// TODO - autodetect 4A50
if(isProbably3E(image, size))
type = "3E";
else if(isProbably3F(image, size))
type = "3F";
else
type = "MC";
}
else // what else can we do?
{
if(isProbably3E(image, size))
type = "3E";
else if(isProbably3F(image, size))
type = "3F";
else
type = "4K"; // Most common bankswitching type
}
/* The above logic was written long before 3E support existed. It will
detect a 3E cart as 3F. Let's remedy that situation: */
if(type == "3F" && isProbably3E(image, size))
type = "3E";
return type;
}
@ -212,6 +249,25 @@ int Cartridge::searchForBytes(const uInt8* image, uInt32 size, uInt8 byte1, uInt
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge::isProbablySC(const uInt8* image, uInt32 size)
{
// We assume a Superchip cart contains the same bytes for its entire
// RAM area; obviously this test will fail if it doesn't
// The RAM area will be the first 256 bytes of each 4K bank
uInt32 banks = size / 4096;
for(uInt32 i = 0; i < banks; ++i)
{
uInt8 first = image[i*4096];
for(uInt32 j = 0; j < 256; ++j)
{
if(image[i*4096+j] != first)
return false;
}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge::isProbably3F(const uInt8* image, uInt32 size)
{
@ -225,18 +281,6 @@ bool Cartridge::isProbably3E(const uInt8* image, uInt32 size)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge::Cartridge(const Cartridge&)
{
assert(false);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge& Cartridge::operator = (const Cartridge&)
{
assert(false);
return *this;
}
// default implementations of bankswitching-related methods.
// These are suitable to be inherited by a cart type that
// doesn't support bankswitching at all.
@ -289,3 +333,16 @@ uInt8* Cartridge::getImage(int& size)
size = 0;
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge::Cartridge(const Cartridge&)
{
assert(false);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge& Cartridge::operator = (const Cartridge&)
{
assert(false);
return *this;
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Cart.hxx,v 1.11 2006-12-08 16:49:19 stephena Exp $
// $Id: Cart.hxx,v 1.12 2006-12-24 17:13:10 stephena Exp $
//============================================================================
#ifndef CARTRIDGE_HXX
@ -33,7 +33,7 @@ class Settings;
game and handles any bankswitching performed by the cartridge.
@author Bradford W. Mott
@version $Id: Cart.hxx,v 1.11 2006-12-08 16:49:19 stephena Exp $
@version $Id: Cart.hxx,v 1.12 2006-12-24 17:13:10 stephena Exp $
*/
class Cartridge : public Device
{
@ -87,6 +87,16 @@ class Cartridge : public Device
*/
static string autodetectType(const uInt8* image, uInt32 size);
/**
Utility method used by isProbably3F and isProbably3E
*/
static int searchForBytes(const uInt8* image, uInt32 size, uInt8 byte1, uInt8 byte2);
/**
Returns true if the image contains a extra RAM (aka SuperChip)
*/
static bool isProbablySC(const uInt8* image, uInt32 size);
/**
Returns true if the image is probably a 3F bankswitching cartridge
*/
@ -97,11 +107,6 @@ class Cartridge : public Device
*/
static bool isProbably3E(const uInt8* image, uInt32 size);
/**
Utility method used by isProbably3F and isProbably3E
*/
static int searchForBytes(const uInt8* image, uInt32 size, uInt8 byte1, uInt8 byte2);
private:
// Copy constructor isn't supported by cartridges so make it private
Cartridge(const Cartridge&);

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: CartF8SC.cxx,v 1.10 2006-12-08 16:49:22 stephena Exp $
// $Id: CartF8SC.cxx,v 1.11 2006-12-24 17:13:10 stephena Exp $
//============================================================================
#include <assert.h>
@ -161,12 +161,14 @@ void CartridgeF8SC::poke(uInt16 address, uInt8)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int CartridgeF8SC::bank() {
int CartridgeF8SC::bank()
{
return myCurrentBank;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int CartridgeF8SC::bankCount() {
int CartridgeF8SC::bankCount()
{
return 2;
}
@ -265,7 +267,8 @@ bool CartridgeF8SC::load(Deserializer& in)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8* CartridgeF8SC::getImage(int& size) {
uInt8* CartridgeF8SC::getImage(int& size)
{
size = 8192;
return &myImage[0];
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff