SNES: update parser with chip detection.
This commit is contained in:
@@ -126,35 +126,113 @@ static uint32_t find_header(const uint8_t *data, uint32_t size)
|
||||
uint8_t* snes_get_header(fileTYPE *f)
|
||||
{
|
||||
memset(hdr, 0, sizeof(hdr));
|
||||
uint8_t *buf = (uint8_t*)malloc(f->size);
|
||||
if (buf)
|
||||
uint32_t size = f->size;
|
||||
uint8_t *prebuf = (uint8_t*)malloc(size);
|
||||
if (prebuf)
|
||||
{
|
||||
FileSeekLBA(f, 0);
|
||||
if (FileReadAdv(f, buf, f->size))
|
||||
if (FileReadAdv(f, prebuf, size))
|
||||
{
|
||||
uint32_t addr = find_header(buf, f->size);
|
||||
uint8_t *buf = prebuf;
|
||||
|
||||
if (size & 512)
|
||||
{
|
||||
buf += 512;
|
||||
size -= 512;
|
||||
}
|
||||
|
||||
*(uint32_t*)(&hdr[8]) = size;
|
||||
|
||||
uint32_t addr = find_header(buf, size);
|
||||
if (addr)
|
||||
{
|
||||
uint8_t romsz = buf[addr + RomSize];
|
||||
uint8_t ramsz = buf[addr + RamSize];
|
||||
if (romsz >= 0x10) romsz = 0;
|
||||
if (ramsz >= 0x08) ramsz = 0;
|
||||
hdr[0] = (ramsz << 4) | romsz;
|
||||
|
||||
hdr[1] = (addr == 0x00ffc0) ? 1 : (addr == 0x40ffc0) ? 5 : 0; //LHRom type
|
||||
//Rom type: 0-Low, 1-High, 2-ExHigh
|
||||
hdr[1] = (addr == 0x00ffc0) ? 1 : (addr == 0x40ffc0) ? 2 : 0;
|
||||
|
||||
hdr[2] = buf[addr + RomType];
|
||||
//DSPn types 8..B
|
||||
if ((buf[addr + Mapper] == 0x20 || buf[addr + Mapper] == 0x21) && buf[addr + RomType] == 0x03)
|
||||
{ //DSP1
|
||||
hdr[1] |= 0x80;
|
||||
}
|
||||
else if (buf[addr + Mapper] == 0x30 && buf[addr + RomType] == 0x05 && buf[addr + Company] != 0xb2)
|
||||
{ //DSP1
|
||||
hdr[1] |= 0x80;
|
||||
}
|
||||
else if (buf[addr + Mapper] == 0x31 && (buf[addr + RomType] == 0x03 || buf[addr + RomType] == 0x05))
|
||||
{ //DSP1
|
||||
hdr[1] |= 0x80;
|
||||
}
|
||||
else if (buf[addr + Mapper] == 0x20 && buf[addr + RomType] == 0x05)
|
||||
{ //DSP2
|
||||
hdr[1] |= 0x90;
|
||||
}
|
||||
else if (buf[addr + Mapper] == 0x30 && buf[addr + RomType] == 0x05 && buf[addr + Company] == 0xb2)
|
||||
{ //DSP3
|
||||
hdr[1] |= 0xA0;
|
||||
}
|
||||
else if (buf[addr + Mapper] == 0x30 && buf[addr + RomType] == 0x03)
|
||||
{ //DSP4
|
||||
hdr[1] |= 0xB0;
|
||||
}
|
||||
|
||||
//CX4 4
|
||||
if (buf[addr + Mapper] == 0x20 && buf[addr + RomType] == 0xf3)
|
||||
{
|
||||
hdr[1] |= 0x40;
|
||||
}
|
||||
|
||||
//SDD1 5
|
||||
if (buf[addr + Mapper] == 0x32 && (buf[addr + RomType] == 0x43 || buf[addr + RomType] == 0x45))
|
||||
{
|
||||
hdr[1] |= 0x50;
|
||||
}
|
||||
|
||||
//SA1 6
|
||||
if (buf[addr + Mapper] == 0x23 && (buf[addr + RomType] == 0x32 || buf[addr + RomType] == 0x34 || buf[addr + RomType] == 0x35))
|
||||
{
|
||||
hdr[1] |= 0x60;
|
||||
}
|
||||
|
||||
//GSU 7
|
||||
if (buf[addr + Mapper] == 0x20 && (buf[addr + RomType] == 0x13 || buf[addr + RomType] == 0x14 || buf[addr + RomType] == 0x15 || buf[addr + RomType] == 0x1a))
|
||||
{
|
||||
ramsz = buf[addr - 3];
|
||||
if (ramsz == 0xFF) ramsz = 5; //StarFox
|
||||
if (ramsz > 6) ramsz = 6;
|
||||
hdr[1] |= 0x70;
|
||||
}
|
||||
|
||||
//1..3,C..F - reserved for other mappers.
|
||||
|
||||
hdr[2] = 0;
|
||||
|
||||
//PAL Regions
|
||||
if ((buf[addr + CartRegion] >= 0x02 && buf[addr + CartRegion] <= 0x0C) || buf[addr + CartRegion] == 0x11)
|
||||
{ //PAL Regions
|
||||
{
|
||||
hdr[3] |= 1;
|
||||
}
|
||||
|
||||
*(uint32_t*)(&hdr[4]) = addr;
|
||||
//re-calc rom size
|
||||
uint8_t romsz = 15;
|
||||
size--;
|
||||
if (!(size & 0xFF000000))
|
||||
{
|
||||
while (!(size & 0x1000000))
|
||||
{
|
||||
romsz--;
|
||||
size <<= 1;
|
||||
}
|
||||
}
|
||||
hdr[0] = (ramsz << 4) | romsz;
|
||||
printf("Size from header: 0x%X, calculated size: 0x%X\n", buf[addr + RomSize], romsz);
|
||||
}
|
||||
*(uint32_t*)(&hdr[4]) = addr;
|
||||
}
|
||||
FileSeekLBA(f, 0);
|
||||
free(buf);
|
||||
free(prebuf);
|
||||
}
|
||||
return hdr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user