Expanded ToP interleave detection to DKJM2, minor fix

This commit is contained in:
n-a-c-h
2003-07-20 13:08:09 +00:00
parent 0fa8db07c4
commit fe35d7d395

View File

@@ -1,302 +1,315 @@
/* /*
Copyright (C) 2003 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com ) Copyright (C) 2003 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com )
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version 2 of the License, or (at your option) any later
version. version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
//C++ style code in C //C++ style code in C
#define bool unsigned char #define bool unsigned char
#define true 1 #define true 1
#define false 0 #define false 0
#define Lo 0x7FC0 #define Lo 0x7FC0
#define Hi 0xFFC0 #define Hi 0xFFC0
#define EHi 0x40FFC0 #define EHi 0x40FFC0
//I want to port over the more complicated //I want to port over the more complicated
//functions from init.asm, or replace with //functions from init.asm, or replace with
//better versions from NSRT. -Nach //better versions from NSRT. -Nach
//init.asm goodness //init.asm goodness
extern unsigned int NumofBanks; extern unsigned int NumofBanks;
extern unsigned int NumofBytes; extern unsigned int NumofBytes;
extern unsigned int *romdata; extern unsigned int *romdata;
extern unsigned char romtype; extern unsigned char romtype;
extern unsigned char Interleaved; extern unsigned char Interleaved;
unsigned int infoloc; unsigned int infoloc;
//Deinterleave functions //Deinterleave functions
bool validChecksum(unsigned char *ROM, int BankLoc) bool validChecksum(unsigned char *ROM, int BankLoc)
{ {
if (ROM[BankLoc + 28] + (ROM[BankLoc + 29] << 8) + if (ROM[BankLoc + 28] + (ROM[BankLoc + 29] << 8) +
ROM[BankLoc + 30] + (ROM[BankLoc + 31] << 8) == 0xFFFF) ROM[BankLoc + 30] + (ROM[BankLoc + 31] << 8) == 0xFFFF)
{ {
return(true); return(true);
} }
return(false); return(false);
} }
void swapBlocks(char *blocks) bool EHiHeader(unsigned char *ROM, int BankLoc)
{ {
int i,j,k; if (validChecksum(ROM, BankLoc) && ROM[BankLoc+21] == 53)
for (i = 0; i < NumofBanks; i++) {
{ return(true);
for (j = 0; j < NumofBanks; j++) }
{ return(false);
if (blocks[j] == i) }
{
char b; void swapBlocks(char *blocks)
unsigned int temp, {
*loc1 = romdata + blocks[i]*0x2000, int i,j,k;
*loc2 = romdata + blocks[j]*0x2000; for (i = 0; i < NumofBanks; i++)
for (k = 0; k < 0x2000; k++) {
{ for (j = 0; j < NumofBanks; j++)
temp = loc1[k]; {
loc1[k] = loc2[k]; if (blocks[j] == i)
loc2[k] = temp; {
} char b;
b = blocks[j]; unsigned int temp,
blocks[j] = blocks[i]; *loc1 = romdata + blocks[i]*0x2000,
blocks[i] = b; *loc2 = romdata + blocks[j]*0x2000;
break; for (k = 0; k < 0x2000; k++)
} {
} temp = loc1[k];
} loc1[k] = loc2[k];
} loc2[k] = temp;
}
void deintlv1() b = blocks[j];
{ blocks[j] = blocks[i];
char blocks[256]; blocks[i] = b;
int i, numblocks = NumofBanks/2; break;
for (i = 0; i < numblocks; i++) }
{ }
blocks[i * 2] = i + numblocks; }
blocks[i * 2 + 1] = i; }
}
swapBlocks(blocks); void deintlv1()
} {
char blocks[256];
void CheckIntl1(unsigned char *ROM) int i, numblocks = NumofBanks/2;
{ for (i = 0; i < numblocks; i++)
unsigned int ROMmidPoint = NumofBytes / 2; {
if (validChecksum(ROM, ROMmidPoint + Lo) && blocks[i * 2] = i + numblocks;
!validChecksum(ROM, Lo) && blocks[i * 2 + 1] = i;
ROM[ROMmidPoint+Lo+25] < 14) //Country Code }
{ swapBlocks(blocks);
deintlv1(); }
Interleaved = true;
} void CheckIntl1(unsigned char *ROM)
else if (validChecksum(ROM, Lo) && !validChecksum(ROM, Hi) && {
ROM[Lo+25] < 14 && //Country code unsigned int ROMmidPoint = NumofBytes / 2;
//Rom make up if (validChecksum(ROM, ROMmidPoint + Lo) &&
(ROM[Lo+21] == 33 || ROM[Lo+21] == 49 || ROM[Lo+21] == 53)) !validChecksum(ROM, Lo) &&
{ ROM[ROMmidPoint+Lo+25] < 14) //Country Code
if (ROM[Lo+20] == 32 ||//Check that Header name did not overflow {
!(ROM[Lo+21] == ROM[Lo+20] || ROM[Lo+21] == ROM[Lo+19] || deintlv1();
ROM[Lo+21] == ROM[Lo+18] || ROM[Lo+21] == ROM[Lo+17])) Interleaved = true;
{ }
deintlv1(); else if (validChecksum(ROM, Lo) && !validChecksum(ROM, Hi) &&
Interleaved = true; ROM[Lo+25] < 14 && //Country code
} //Rom make up
} (ROM[Lo+21] == 33 || ROM[Lo+21] == 49 ||
} ROM[Lo+21] == 53 || ROM[Lo+21] == 58))
{
void deintToP() if (ROM[Lo+20] == 32 ||//Check that Header name did not overflow
{ !(ROM[Lo+21] == ROM[Lo+20] || ROM[Lo+21] == ROM[Lo+19] ||
//Swap 2MB and 4MB ROMs ROM[Lo+21] == ROM[Lo+18] || ROM[Lo+21] == ROM[Lo+17]))
unsigned int temp, i, *loc1 = romdata, *loc2 = romdata + 0x80000; {
for (i = 0; i < 0x100000; i++) deintlv1();
{ Interleaved = true;
temp = loc1[i]; }
loc1[i] = loc2[i]; }
loc2[i] = temp; }
}
void CheckIntlEHi(unsigned char *ROM)
//Deinterleave the 4MB ROM first {
NumofBanks = 128; if (EHiHeader(ROM, Lo))
deintlv1(); {
unsigned int temp, i, oldNumBanks = NumofBanks,
//Now the 2MB one *loc1 = romdata,
NumofBanks = 64; *loc2 = romdata + ((NumofBytes - 0x400000)/4);
romdata += 0x100000; //Ofset pointer
deintlv1(); //Swap 4MB ROM with the other one
for (i = 0; i < 0x100000; i++)
//Now fix the data and we're done {
NumofBanks = 192; temp = loc1[i];
romdata -= 0x100000; loc1[i] = loc2[i];
} loc2[i] = temp;
}
//ROM loading functions, which some strangly enough were in guiload.inc //Deinterleave the 4MB ROM first
bool AllASCII(char *b, int size) NumofBanks = 128;
{ deintlv1();
int i;
for (i = 0; i < size; i++) //Now the other one
{ NumofBanks = oldNumBanks - 128;
if (b[i] < 32 || b[i] > 126) romdata += 0x100000; //Ofset pointer
{ deintlv1();
return(false);
} //Now fix the data and we're done
} NumofBanks = oldNumBanks;
return(true); romdata -= 0x100000;
}
Interleaved = true;
int InfoScore(char *Buffer) }
{ }
int score = 0;
if (Buffer[26] == 0x33) { score += 2; } //ROM loading functions, which some strangly enough were in guiload.inc
if ((Buffer[21] & 0xf) < 4) { score += 2; } bool AllASCII(char *b, int size)
if (!(Buffer[61] & 0x80)) { score -= 4; } {
if ((1 << (Buffer[23] - 7)) > 48) { score -= 1; } int i;
if (Buffer[25] < 14) { score += 1; } for (i = 0; i < size; i++)
if (!AllASCII(Buffer, 20)) { score -= 1; } {
return(score); if (b[i] < 32 || b[i] > 126)
} {
return(false);
extern unsigned char ForceHiLoROM; }
extern unsigned char forceromtype; }
return(true);
void BankCheck() }
{
unsigned char *ROM = (unsigned char *)romdata; int InfoScore(char *Buffer)
infoloc = 0; {
Interleaved = false; int score = 0;
if (validChecksum(Buffer, 0)) { score += 3; }
if (NumofBytes >= 0x500000) if (Buffer[26] == 0x33) { score += 2; }
{ if ((Buffer[21] & 0xf) < 4) { score += 2; }
if (validChecksum(ROM, 0x207FC0)) if (!(Buffer[61] & 0x80)) { score -= 4; }
{ if ((1 << (Buffer[23] - 7)) > 48) { score -= 1; }
deintToP(); if (Buffer[25] < 14) { score += 1; }
Interleaved = true; if (!AllASCII(Buffer, 20)) { score -= 1; }
} return(score);
if (validChecksum(ROM, EHi)) }
{
romtype = 2; extern unsigned char ForceHiLoROM;
infoloc = EHi; extern unsigned char forceromtype;
}
} void BankCheck()
{
if (!infoloc) unsigned char *ROM = (unsigned char *)romdata;
{ infoloc = 0;
int loscore, hiscore; Interleaved = false;
//Deinterleave if neccesary if (NumofBytes >= 0x500000)
CheckIntl1(ROM); {
//Deinterleave if neccesary
loscore = InfoScore(ROM+Lo); CheckIntlEHi(ROM);
if (validChecksum(ROM, Lo)) { loscore += 3; }
if (EHiHeader(ROM, EHi))
hiscore = InfoScore(ROM+Hi); {
if (validChecksum(ROM, Hi)) { hiscore += 3; } romtype = 2;
infoloc = EHi;
switch(ROM[Lo + 21]) }
{ }
case 32: case 35: case 48: case 50:
case 128: case 156: case 176: case 188: case 252: //BS if (!infoloc)
loscore += 1; {
break; int loscore, hiscore;
}
switch(ROM[Hi + 21]) //Deinterleave if neccesary
{ CheckIntl1(ROM);
case 33: case 49: case 53:
case 128: case 156: case 176: case 188: case 252: //BS loscore = InfoScore(ROM+Lo);
hiscore += 1; hiscore = InfoScore(ROM+Hi);
break;
} switch(ROM[Lo + 21])
{
if(ForceHiLoROM) case 32: case 35: case 48: case 50:
{ case 128: case 156: case 176: case 188: case 252: //BS
//asm volatile("int $3"); loscore += 1;
if (forceromtype == 1) { loscore += 50; } break;
else if (forceromtype == 2) { hiscore += 50; } }
} switch(ROM[Hi + 21])
{
if (hiscore > loscore) case 33: case 49: case 53:
{ case 128: case 156: case 176: case 188: case 252: //BS
romtype = 2; hiscore += 1;
infoloc = Hi; break;
} }
else
{ if(ForceHiLoROM)
romtype = 1; {
infoloc = Lo; //asm volatile("int $3");
} if (forceromtype == 1) { loscore += 50; }
} else if (forceromtype == 2) { hiscore += 50; }
} }
if (hiscore > loscore)
//Checksum functions {
unsigned short sum(unsigned char *array, unsigned int size) romtype = 2;
{ infoloc = Hi;
unsigned short theSum = 0; }
unsigned int i; else
{
//Prevent crashing by reading too far (needed for messed up ROMs) romtype = 1;
if (array + size > (unsigned char *)romdata + NumofBytes) infoloc = Lo;
{ }
return(0xFFFF); }
} }
for (i = 0; i < size; i++)
{ //Checksum functions
theSum += array[i]; unsigned short sum(unsigned char *array, unsigned int size)
} {
return(theSum); unsigned short theSum = 0;
} unsigned int i;
extern unsigned char SPC7110Enable; //Prevent crashing by reading too far (needed for messed up ROMs)
extern unsigned char BSEnable; if (array + size > (unsigned char *)romdata + NumofBytes)
extern unsigned short Checksumvalue; {
void CalcChecksum() return(0xFFFF);
{ }
unsigned char *ROM = (unsigned char *)romdata;
unsigned short Mbit = NumofBanks >> 2; for (i = 0; i < size; i++)
{
if ((Mbit == 10 || Mbit == 20 || Mbit == 40) && !SPC7110Enable) theSum += array[i];
{ }
unsigned int P1Size = 512 << ROM[infoloc + 23]; return(theSum);
unsigned short part1 = sum(ROM, P1Size), }
part2 = sum(ROM+P1Size, NumofBytes-P1Size);
Checksumvalue = part1 + part2*4; extern unsigned char SPC7110Enable;
} extern unsigned char BSEnable;
else if ((Mbit == 12 || Mbit == 24 || Mbit == 48) && !SPC7110Enable) extern unsigned short Checksumvalue;
{ void CalcChecksum()
unsigned int P1Size = 512 << ROM[infoloc + 23]; {
unsigned short part1 = sum(ROM, P1Size), unsigned char *ROM = (unsigned char *)romdata;
part2 = sum(ROM+P1Size, NumofBytes-P1Size); unsigned short Mbit = NumofBanks >> 2;
Checksumvalue = part1 + part2 + part2;
} if ((Mbit == 10 || Mbit == 20 || Mbit == 40) && !SPC7110Enable)
else {
{ unsigned int P1Size = 512 << ROM[infoloc + 23];
Checksumvalue = sum(ROM, NumofBytes); unsigned short part1 = sum(ROM, P1Size),
if (BSEnable) part2 = sum(ROM+P1Size, NumofBytes-P1Size);
{ Checksumvalue = part1 + part2*4;
Checksumvalue -= sum(&ROM[infoloc - 16], 48); //Fix for BS Dumps }
} else if ((Mbit == 12 || Mbit == 24 || Mbit == 48) && !SPC7110Enable)
else if (Mbit == 24) {
{ unsigned int P1Size = 512 << ROM[infoloc + 23];
Checksumvalue += Checksumvalue; //Fix for 24Mb SPC7110 ROMs unsigned short part1 = sum(ROM, P1Size),
} part2 = sum(ROM+P1Size, NumofBytes-P1Size);
} Checksumvalue = part1 + part2 + part2;
} }
else
{
Checksumvalue = sum(ROM, NumofBytes);
if (BSEnable)
{
Checksumvalue -= sum(&ROM[infoloc - 16], 48); //Fix for BS Dumps
}
else if (Mbit == 24)
{
Checksumvalue += Checksumvalue; //Fix for 24Mb SPC7110 ROMs
}
}
}