ToP interleaved loading requirements reduced by 2MB, code cleanup.

This commit is contained in:
n-a-c-h
2003-07-10 19:06:36 +00:00
parent 91d11de3ed
commit 5dbb414d24

View File

@@ -1,318 +1,308 @@
/* /*
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 goodnes //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) void swapBlocks(char *blocks)
{ {
int i,j,k; int i,j,k;
for (i = 0; i < NumofBanks; i++) for (i = 0; i < NumofBanks; i++)
{ {
for (j = 0; j < NumofBanks; j++) for (j = 0; j < NumofBanks; j++)
{ {
if (blocks[j] == i) if (blocks[j] == i)
{ {
char b; char b;
unsigned int temp, unsigned int temp,
*loc1 = romdata + blocks[i]*0x2000, *loc1 = romdata + blocks[i]*0x2000,
*loc2 = romdata + blocks[j]*0x2000; *loc2 = romdata + blocks[j]*0x2000;
for (k = 0; k < 0x2000; k++) for (k = 0; k < 0x2000; k++)
{ {
temp = loc1[k]; temp = loc1[k];
loc1[k] = loc2[k]; loc1[k] = loc2[k];
loc2[k] = temp; loc2[k] = temp;
} }
b = blocks[j]; b = blocks[j];
blocks[j] = blocks[i]; blocks[j] = blocks[i];
blocks[i] = b; blocks[i] = b;
break; break;
} }
} }
} }
} }
void deintlv1() void deintlv1()
{ {
int i, numblocks = NumofBanks/2; char blocks[256];
char blocks[256]; int i, numblocks = NumofBanks/2;
for (i = 0; i < numblocks; i++) for (i = 0; i < numblocks; i++)
{ {
blocks[i * 2] = i + numblocks; blocks[i * 2] = i + numblocks;
blocks[i * 2 + 1] = i; blocks[i * 2 + 1] = i;
} }
swapBlocks(blocks); swapBlocks(blocks);
} }
void CheckIntl1(unsigned char *ROM) void CheckIntl1(unsigned char *ROM)
{ {
unsigned int ROMmidPoint = NumofBytes / 2; unsigned int ROMmidPoint = NumofBytes / 2;
if (validChecksum(ROM, ROMmidPoint + Lo) && if (validChecksum(ROM, ROMmidPoint + Lo) &&
!validChecksum(ROM, Lo) && !validChecksum(ROM, Lo) &&
ROM[ROMmidPoint+Lo+25] < 14) //Country Code ROM[ROMmidPoint+Lo+25] < 14) //Country Code
{ {
deintlv1(); deintlv1();
Interleaved = true; Interleaved = true;
} }
else if (validChecksum(ROM, Lo) && !validChecksum(ROM, Hi) && else if (validChecksum(ROM, Lo) && !validChecksum(ROM, Hi) &&
ROM[Lo+25] < 14 && //Country code ROM[Lo+25] < 14 && //Country code
//Rom make up //Rom make up
(ROM[Lo+21] == 33 || ROM[Lo+21] == 49 || ROM[Lo+21] == 53)) (ROM[Lo+21] == 33 || ROM[Lo+21] == 49 || ROM[Lo+21] == 53))
{ {
if (ROM[Lo+20] == 32 ||//Check that Header name did not overflow if (ROM[Lo+20] == 32 ||//Check that Header name did not overflow
!(ROM[Lo+21] == ROM[Lo+20] || ROM[Lo+21] == ROM[Lo+19] || !(ROM[Lo+21] == ROM[Lo+20] || ROM[Lo+21] == ROM[Lo+19] ||
ROM[Lo+21] == ROM[Lo+18] || ROM[Lo+21] == ROM[Lo+17])) ROM[Lo+21] == ROM[Lo+18] || ROM[Lo+21] == ROM[Lo+17]))
{ {
deintlv1(); deintlv1();
Interleaved = true; Interleaved = true;
} }
} }
} }
//It would be nice to find a way to eliminate the 2MB here void deintToP()
//Then we can also drop the includes of these two {
#include <string.h> //Swap 2MB and 4MB ROMs
#include <malloc.h> unsigned int temp, i, *loc1 = romdata, *loc2 = romdata + 0x80000;
void deintToP() for (i = 0; i < 0x100000; i++)
{ {
int i; temp = loc1[i];
char blocks[256]; loc1[i] = loc2[i];
char *ROM = (char *)romdata; loc2[i] = temp;
char *ROMSwap = (char *)malloc(0x200000); }
if (ROMSwap)
{ //Deinterleave the 4MB ROM first
memmove(ROMSwap, ROM, 0x200000); //Copy Small ROM to RAM NumofBanks = 128;
memmove(ROM, &ROM[0x200000], 0x400000); //Move Large ROM to front deintlv1();
memmove(&ROM[0x400000], ROMSwap, 0x200000); //Place Small ROM after
free(ROMSwap); //Now the 2MB one
} NumofBanks = 64;
romdata += 0x100000; //Ofset pointer
//Deinterleave the 4MB ROM first deintlv1();
NumofBanks = 128;
deintlv1(); //Now fix the data and we're done
NumofBanks = 192;
//Now the 2MB one romdata -= 0x100000;
NumofBanks = 64; }
romdata += 0x100000; //Ofset pointer
deintlv1();
//ROM loading functions, which some strangly enough were in guiload.inc
//Now fix the data and we're done bool AllASCII(char *b, int size)
NumofBanks = 192; {
romdata -= 0x100000; int i;
} for (i = 0; i < size; i++)
{
if (b[i] < 32 || b[i] > 126)
//ROM loading functions, which some strangly enough were in guiload.inc {
bool AllASCII(char *b, int size) return(false);
{ }
int i; }
for (i = 0; i < size; i++) return(true);
{ }
if (b[i] < 32 || b[i] > 126)
{ int InfoScore(char *Buffer)
return(false); {
} int score = 0;
} if (Buffer[26] == 0x33) { score += 2; }
return(true); if ((Buffer[21] & 0xf) < 4) { score += 2; }
} if (!(Buffer[61] & 0x80)) { score -= 4; }
if ((1 << (Buffer[23] - 7)) > 48) { score -= 1; }
int InfoScore(char *Buffer) if (Buffer[25] < 14) { score += 1; }
{ if (!AllASCII(Buffer, 20)) { score -= 1; }
int score = 0; return(score);
if (Buffer[26] == 0x33) { score += 2; } }
if ((Buffer[21] & 0xf) < 4) { score += 2; }
if (!(Buffer[61] & 0x80)) { score -= 4; } extern unsigned char ForceHiLoROM;
if ((1 << (Buffer[23] - 7)) > 48) { score -= 1; } extern unsigned char forceromtype;
if (Buffer[25] < 14) { score += 1; }
if (!AllASCII(Buffer, 20)) { score -= 1; } void BankCheck()
return(score); {
} unsigned char *ROM = (unsigned char *)romdata;
infoloc = 0;
extern unsigned char ForceHiLoROM; Interleaved = false;
extern unsigned char forceromtype;
if (NumofBytes >= 0x500000)
void BankCheck() {
{ if (validChecksum(ROM, 0x207FC0))
unsigned char *ROM = (unsigned char *)romdata; {
infoloc = 0; deintToP();
Interleaved = false; Interleaved = true;
}
if (NumofBytes >= 0x500000) if (validChecksum(ROM, EHi))
{ {
if (validChecksum(ROM, 0x207FC0)) romtype = 2;
{ infoloc = EHi;
deintToP(); }
Interleaved = true; }
}
if (validChecksum(ROM, EHi)) if (!infoloc)
{ {
romtype = 2; int loscore, hiscore;
infoloc = EHi;
} //Deinterleave if neccesary
} CheckIntl1(ROM);
if (!infoloc) loscore = InfoScore(ROM+Lo);
{ if (validChecksum(ROM, Lo)) { loscore += 3; }
int loscore, hiscore;
hiscore = InfoScore(ROM+Hi);
//Deinterleave if neccesary if (validChecksum(ROM, Hi)) { hiscore += 3; }
CheckIntl1(ROM);
switch(ROM[Lo + 21])
loscore = InfoScore(ROM+Lo); {
if (validChecksum(ROM, Lo)) { loscore += 3; } case 32: case 35: case 48: case 50:
case 128: case 156: case 176: case 188: case 252: //BS
hiscore = InfoScore(ROM+Hi); loscore += 1;
if (validChecksum(ROM, Hi)) { hiscore += 3; } break;
}
switch(ROM[Lo + 21]) switch(ROM[Hi + 21])
{ {
case 32: case 35: case 48: case 50: case 33: case 49: case 53:
case 128: case 156: case 176: case 188: case 252: //BS case 128: case 156: case 176: case 188: case 252: //BS
loscore += 1; hiscore += 1;
break; break;
} }
switch(ROM[Hi + 21])
{ if(ForceHiLoROM)
case 33: case 49: case 53: {
case 128: case 156: case 176: case 188: case 252: //BS //asm volatile("int $3");
hiscore += 1; if (forceromtype == 1) { loscore += 50; }
break; else if (forceromtype == 2) { hiscore += 50; }
} }
if(ForceHiLoROM) if (hiscore > loscore)
{ {
//asm volatile("int $3"); romtype = 2;
if (forceromtype == 1) { loscore += 50; } infoloc = Hi;
else if (forceromtype == 2) { hiscore += 50; } }
} else
{
if (hiscore > loscore) romtype = 1;
{ infoloc = Lo;
romtype = 2; }
infoloc = Hi; }
} }
else
{
romtype = 1; //Checksum functions
infoloc = Lo; unsigned short sum(unsigned char *array, unsigned int size)
} {
} unsigned short theSum = 0;
unsigned int i;
} for (i = 0; i < size; i++)
{
theSum += array[i];
//Checksum functions }
unsigned short sum(unsigned char *array, unsigned int size) return(theSum);
{ }
unsigned short theSum = 0;
unsigned int i; //Not entirely accurate pow, but good for our needs and very fast
for (i = 0; i < size; i++) unsigned int npow(register unsigned int base, register unsigned int exponent)
{ {
theSum += array[i]; register unsigned int total = base;
} register unsigned int i;
return(theSum); for (i = 1; i < exponent; i++)
} {
total *= base;
//Not entirely accurate pow, but good for our needs and very fast }
unsigned int npow(register unsigned int base, register unsigned int exponent) return(total);
{ }
register unsigned int total = base;
register unsigned int i; extern unsigned char SPC7110Enable;
for (i = 1; i < exponent; i++) extern unsigned char BSEnable;
{ extern unsigned short Checksumvalue;
total *= base; void CalcChecksum()
} {
return(total); unsigned char *ROM = (unsigned char *)romdata;
} unsigned short Mbit = NumofBanks >> 2, Checksum;
unsigned int ROMSize = NumofBytes, Bank = infoloc;
extern unsigned char SPC7110Enable;
extern unsigned char BSEnable; if ((Mbit == 10 || Mbit == 20 || Mbit == 40) && !SPC7110Enable)
extern unsigned short Checksumvalue; {
void CalcChecksum() unsigned int P1Size = npow(2, ROM[Bank + 23] - 7) * 65536;
{ unsigned short part1 = sum(ROM, P1Size),
unsigned char *ROM = (unsigned char *)romdata; part2 = sum(ROM+P1Size, ROMSize-P1Size);
unsigned short Mbit = NumofBanks >> 2, Checksum; Checksumvalue = part1 + part2*4;
unsigned int ROMSize = NumofBytes; }
unsigned int Bank = infoloc; else if ((Mbit == 12 || Mbit == 24 || Mbit == 48) && !SPC7110Enable)
{
unsigned int P1Size = npow(2, ROM[Bank + 23] - 7) * 65536;
if ((Mbit == 10 || Mbit == 20 || Mbit == 40) && !SPC7110Enable) unsigned short part1 = sum(ROM, P1Size),
{ part2 = sum(ROM+P1Size, ROMSize-P1Size);
unsigned int P1Size = npow(2, ROM[Bank + 23] - 7) * 65536; Checksumvalue = part1 + part2 + part2;
unsigned short part1 = sum(ROM, P1Size), }
part2 = sum(ROM+P1Size, ROMSize-P1Size); else
Checksumvalue = part1 + part2*4; {
} Checksumvalue = sum(ROM, ROMSize);
else if ((Mbit == 12 || Mbit == 24 || Mbit == 48) && !SPC7110Enable) if (BSEnable)
{ {
unsigned int P1Size = npow(2, ROM[Bank + 23] - 7) * 65536; Checksumvalue -= sum(&ROM[Bank - 16], 48); //Fix for BS Dumps
unsigned short part1 = sum(ROM, P1Size), }
part2 = sum(ROM+P1Size, ROMSize-P1Size); else if (Mbit == 24)
Checksumvalue = part1 + part2 + part2; {
} Checksumvalue += Checksumvalue; //Fix for 24Mb SPC7110 ROMs
else }
{ }
Checksumvalue = sum(ROM, ROMSize); }
if (BSEnable)
{
Checksumvalue -= sum(&ROM[Bank - 16], 48); //Fix for BS Dumps
}
else if (Mbit == 24)
{
Checksumvalue += Checksumvalue; //Fix for 24Mb SPC7110 ROMs
}
}
}