SNES: update parser with chip detection.

This commit is contained in:
sorgelig
2018-12-13 20:02:01 +08:00
parent 88e2176a4d
commit 57bcf43b1d

View File

@@ -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;
}