mirror of https://github.com/stella-emu/stella.git
Improvements to E0 autodetection; now Swordquest Waterworld isn't
misdetected any more. Optimizations in autodetect logic, thanks to suggestions from Thomas Jentzsch. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1322 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
c4fa58b38f
commit
317648f37d
|
@ -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.cxx,v 1.33 2007-06-09 23:20:16 stephena Exp $
|
||||
// $Id: Cart.cxx,v 1.34 2007-06-14 13:47:50 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <cassert>
|
||||
|
@ -201,10 +201,10 @@ string Cartridge::autodetectType(const uInt8* image, uInt32 size)
|
|||
type = "4K";
|
||||
else if(isProbablyE0(image, size))
|
||||
type = "E0";
|
||||
else if(isProbably3F(image, size))
|
||||
type = isProbably3E(image, size) ? "3E" : "3F";
|
||||
else if(isProbably3E(image, size))
|
||||
type = "3E";
|
||||
else if(isProbably3F(image, size))
|
||||
type = "3F";
|
||||
else if(isProbablyUA(image, size))
|
||||
type = "UA";
|
||||
else if(isProbablyFE(image, size))
|
||||
|
@ -230,10 +230,10 @@ string Cartridge::autodetectType(const uInt8* image, uInt32 size)
|
|||
type = "F6SC";
|
||||
else if(isProbablyE7(image, size))
|
||||
type = "E7";
|
||||
else if(isProbably3F(image, size))
|
||||
type = isProbably3E(image, size) ? "3E" : "3F";
|
||||
else if(isProbably3E(image, size))
|
||||
type = "3E";
|
||||
else if(isProbably3F(image, size))
|
||||
type = "3F";
|
||||
else
|
||||
type = "F6";
|
||||
}
|
||||
|
@ -241,39 +241,39 @@ string Cartridge::autodetectType(const uInt8* image, uInt32 size)
|
|||
{
|
||||
if(isProbablySC(image, size))
|
||||
type = "F4SC";
|
||||
else if(isProbably3F(image, size))
|
||||
type = isProbably3E(image, size) ? "3E" : "3F";
|
||||
else if(isProbably3E(image, size))
|
||||
type = "3E";
|
||||
else if(isProbably3F(image, size))
|
||||
type = "3F";
|
||||
else
|
||||
type = "F4";
|
||||
}
|
||||
else if(size == 65536) // 64K
|
||||
{
|
||||
// TODO - autodetect 4A50
|
||||
if(isProbably3F(image, size))
|
||||
type = isProbably3E(image, size) ? "3E" : "3F";
|
||||
else if(isProbably3E(image, size))
|
||||
if(isProbably3E(image, size))
|
||||
type = "3E";
|
||||
else if(isProbably3F(image, size))
|
||||
type = "3F";
|
||||
else
|
||||
type = "MB";
|
||||
}
|
||||
else if(size == 131072) // 128K
|
||||
{
|
||||
// TODO - autodetect 4A50
|
||||
if(isProbably3F(image, size))
|
||||
type = isProbably3E(image, size) ? "3E" : "3F";
|
||||
else if(isProbably3E(image, size))
|
||||
if(isProbably3E(image, size))
|
||||
type = "3E";
|
||||
else if(isProbably3F(image, size))
|
||||
type = "3F";
|
||||
else
|
||||
type = "MC";
|
||||
}
|
||||
else // what else can we do?
|
||||
{
|
||||
if(isProbably3F(image, size))
|
||||
type = isProbably3E(image, size) ? "3E" : "3F";
|
||||
else if(isProbably3E(image, size))
|
||||
if(isProbably3E(image, size))
|
||||
type = "3E";
|
||||
else if(isProbably3F(image, size))
|
||||
type = "3F";
|
||||
else
|
||||
type = "4K"; // Most common bankswitching type
|
||||
}
|
||||
|
@ -282,8 +282,9 @@ string Cartridge::autodetectType(const uInt8* image, uInt32 size)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int Cartridge::searchForBytes(const uInt8* image, uInt32 imagesize,
|
||||
const uInt8* signature, uInt32 sigsize)
|
||||
bool Cartridge::searchForBytes(const uInt8* image, uInt32 imagesize,
|
||||
const uInt8* signature, uInt32 sigsize,
|
||||
uInt32 minhits)
|
||||
{
|
||||
uInt32 count = 0;
|
||||
for(uInt32 i = 0; i < imagesize - sigsize; ++i)
|
||||
|
@ -297,10 +298,15 @@ int Cartridge::searchForBytes(const uInt8* image, uInt32 imagesize,
|
|||
break;
|
||||
}
|
||||
if(matches == sigsize)
|
||||
{
|
||||
++count;
|
||||
i += sigsize; // skip past this signature 'window' entirely
|
||||
}
|
||||
if(count >= minhits)
|
||||
break;
|
||||
}
|
||||
|
||||
return count;
|
||||
return (count >= minhits);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -330,7 +336,7 @@ bool Cartridge::isProbably3F(const uInt8* image, uInt32 size)
|
|||
// We expect it will be present at least 2 times, since there are
|
||||
// at least two banks
|
||||
uInt8 signature[] = { 0x85, 0x3F }; // STA $3F
|
||||
return searchForBytes(image, size, signature, 2) > 1;
|
||||
return searchForBytes(image, size, signature, 2, 2);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -340,30 +346,30 @@ bool Cartridge::isProbably3E(const uInt8* image, uInt32 size)
|
|||
// in address 3E using 'STA $3E', commonly followed by an
|
||||
// immediate mode LDA
|
||||
uInt8 signature[] = { 0x85, 0x3E, 0xA9, 0x00 }; // STA $3E; LDA #$00
|
||||
return searchForBytes(image, size, signature, 4) > 0;
|
||||
return searchForBytes(image, size, signature, 4, 1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge::isProbablyE0(const uInt8* image, uInt32 size)
|
||||
{
|
||||
// E0 cart bankswitching is triggered by accessing addresses
|
||||
// $FE0 to $FF7 using absolute non-indexed addressing
|
||||
// So we search for the pattern 'LDA Fxxx' or 'STA Fxxx' in hex
|
||||
// using the regex (AD|8D, E0-F7, xF)
|
||||
// This must be present at least three times, since there are
|
||||
// three segments to be initialized (and a few more so that more
|
||||
// of the ROM is used)
|
||||
// $FE0 to $FF9 using absolute non-indexed addressing
|
||||
// To eliminate false positives (and speed up processing), we
|
||||
// search for only certain known signatures
|
||||
// Thanks to "stella@casperkitty.com" for this advice
|
||||
uInt32 count = 0;
|
||||
for(uInt32 i = 0; i < size - 2; ++i)
|
||||
// These signatures are attributed to the MESS project
|
||||
uInt8 signature[6][3] = {
|
||||
{ 0x8D, 0xE0, 0x1F }, // STA $1FE0
|
||||
{ 0x8D, 0xE0, 0x5F }, // STA $5FE0
|
||||
{ 0x8D, 0xE9, 0xFF }, // STA $FFE9
|
||||
{ 0xAD, 0xE9, 0xFF }, // LDA $FFE9
|
||||
{ 0xAD, 0xED, 0xFF }, // LDA $FFED
|
||||
{ 0xAD, 0xF3, 0xBF } // LDA $BFF3
|
||||
};
|
||||
for(uInt32 i = 0; i < 6; ++i)
|
||||
{
|
||||
uInt8 b1 = image[i], b2 = image[i+1], b3 = image[i+2];
|
||||
if((b1 == 0xAD || b1 == 0x8D) &&
|
||||
(b2 >= 0xE0 && b2 <= 0xF7) &&
|
||||
(b3 & 0xF == 0xF))
|
||||
{
|
||||
if(++count > 4) return true;
|
||||
}
|
||||
if(searchForBytes(image, size, signature[i], 3, 1))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -409,7 +415,7 @@ bool Cartridge::isProbablyUA(const uInt8* image, uInt32 size)
|
|||
// UA cart bankswitching switches to bank 1 by accessing address 0x240
|
||||
// using 'STA $240'
|
||||
uInt8 signature[] = { 0x8D, 0x40, 0x02 }; // STA $240
|
||||
return searchForBytes(image, size, signature, 3) > 0;
|
||||
return searchForBytes(image, size, signature, 3, 1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -421,10 +427,10 @@ bool Cartridge::isProbablyCV(const uInt8* image, uInt32 size)
|
|||
{ 0x9D, 0xFF, 0xF3 }, // STA $F3FF
|
||||
{ 0x99, 0x00, 0xF4 } // STA $F400
|
||||
};
|
||||
if(searchForBytes(image, size, signature[0], 3) > 0)
|
||||
if(searchForBytes(image, size, signature[0], 3, 1))
|
||||
return true;
|
||||
else
|
||||
return searchForBytes(image, size, signature[1], 3) > 0;
|
||||
return searchForBytes(image, size, signature[1], 3, 1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -441,7 +447,7 @@ bool Cartridge::isProbablyFE(const uInt8* image, uInt32 size)
|
|||
};
|
||||
for(uInt32 i = 0; i < 4; ++i)
|
||||
{
|
||||
if(searchForBytes(image, size, signature[i], 5) > 0)
|
||||
if(searchForBytes(image, size, signature[i], 5, 1))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -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.18 2007-06-08 12:36:51 stephena Exp $
|
||||
// $Id: Cart.hxx,v 1.19 2007-06-14 13:47:50 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.18 2007-06-08 12:36:51 stephena Exp $
|
||||
@version $Id: Cart.hxx,v 1.19 2007-06-14 13:47:50 stephena Exp $
|
||||
*/
|
||||
class Cartridge : public Device
|
||||
{
|
||||
|
@ -140,11 +140,13 @@ class Cartridge : public Device
|
|||
@param imagesize The size of the ROM image
|
||||
@param signature The byte sequence to search for
|
||||
@param sigsize The number of bytes in the signature
|
||||
@param minhits The minimum number of times a signature is to be found
|
||||
|
||||
@return The number of times the signature was found
|
||||
@return True if the signature was found at least 'minhits' time, else false
|
||||
*/
|
||||
static int searchForBytes(const uInt8* image, uInt32 imagesize,
|
||||
const uInt8* signature, uInt32 sigsize);
|
||||
static bool searchForBytes(const uInt8* image, uInt32 imagesize,
|
||||
const uInt8* signature, uInt32 sigsize,
|
||||
uInt32 minhits);
|
||||
|
||||
/**
|
||||
Returns true if the image is probably a SuperChip (256 bytes RAM)
|
||||
|
|
|
@ -1962,7 +1962,7 @@ static const char* DefProps[2722][21] = {
|
|||
{ "bc3057a35319aae3a5cd87a203736abe", "CCE", "", "Time Warp (CCE) [!]", "", "", "", "", "", "", "", "", "", "", "", "", "30", "", "", "", "" },
|
||||
{ "bc4cf38a4bee45752dc466c98ed7ad09", "Atari", "CX26136", "Solaris (1986) (Atari) (PAL) [!]", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
|
||||
{ "bc526185ad324241782dc68ba5d0540b", "", "", "Dodge Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
|
||||
{ "bc5389839857612cfabeb810ba7effdc", "Atari", "CX2671", "SwordQuest - Waterworld (1983) (Atari)", "", "Unbelievably Rare", "", "F8", "", "", "", "", "", "", "", "", "", "", "", "", "" },
|
||||
{ "bc5389839857612cfabeb810ba7effdc", "Atari", "CX2671", "SwordQuest - Waterworld (1983) (Atari)", "", "Unbelievably Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
|
||||
{ "bc6432cbed32c695658514c4eb41d905", "Manuel Polik", "", "Star Fire (MP) (2002) (PD)", "Won't work with Stella < V1.2", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
|
||||
{ "bc703ea6afb20bc089f04d8c9d79a2bd", "", "", "Gunfight 2600 - Not mergeable with Colbert wizardry... (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
|
||||
{ "bc97d544f1d4834cc72bcc92a37b8c1b", "", "", "Sky Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
|
||||
|
|
|
@ -11487,7 +11487,6 @@
|
|||
"Cartridge.ModelNo" "CX2671"
|
||||
"Cartridge.Name" "SwordQuest - Waterworld (1983) (Atari)"
|
||||
"Cartridge.Rarity" "Unbelievably Rare"
|
||||
"Cartridge.Type" "F8"
|
||||
""
|
||||
|
||||
"Cartridge.MD5" "bc97d544f1d4834cc72bcc92a37b8c1b"
|
||||
|
|
Loading…
Reference in New Issue