Expanded ToP interleave detection to DKJM2, minor fix
This commit is contained in:
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user