From 57bcf43b1dd7d10aa1389be288a7193efb16f56c Mon Sep 17 00:00:00 2001 From: sorgelig Date: Thu, 13 Dec 2018 20:02:01 +0800 Subject: [PATCH] SNES: update parser with chip detection. --- support/snes/snes.cpp | 102 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 12 deletions(-) diff --git a/support/snes/snes.cpp b/support/snes/snes.cpp index 0f897e8..85616f1 100644 --- a/support/snes/snes.cpp +++ b/support/snes/snes.cpp @@ -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; }