From 72c62a613fea70d4ba024f0ef9c5a4d1272ddde9 Mon Sep 17 00:00:00 2001 From: Sergey Dvodnenko Date: Wed, 14 Oct 2020 17:08:44 +0300 Subject: [PATCH] snes: add BSX support * pcecd: read 256 sectors when length is 0 (Kabuki Itouryodan). * pcecd: send status immediately for commands with instant execution (Bomberman: Panic Bomber), some cleanup * snes: add BSX support --- support/snes/snes.cpp | 172 ++++++++++++++++++++++++------------------ support/snes/snes.h | 1 + user_io.cpp | 71 ++++++++++++++--- 3 files changed, 162 insertions(+), 82 deletions(-) diff --git a/support/snes/snes.cpp b/support/snes/snes.cpp index 97545e9..306734b 100644 --- a/support/snes/snes.cpp +++ b/support/snes/snes.cpp @@ -143,6 +143,11 @@ uint8_t* snes_get_header(fileTYPE *f) *(uint32_t*)(&hdr[8]) = size; + bool is_bsx_bios = false; + if (!memcmp(buf+0x7FC0, "Satellaview BS-X ", 21)) { + is_bsx_bios = true; + } + uint32_t addr = find_header(buf, size); if (addr) { @@ -164,86 +169,93 @@ uint8_t* snes_get_header(fileTYPE *f) //Rom type: 0-Low, 1-High, 2-ExHigh hdr[1] = (addr == 0x00ffc0) ? 1 : (addr == 0x40ffc0) ? 2 : 0; - //DSPn types 8..B - if (buf[addr + Mapper] == 0x20 && buf[addr + RomType] == 0x03) - { //DSP1 - hdr[1] |= 0x84; - } - else if (buf[addr + Mapper] == 0x21 && buf[addr + RomType] == 0x03) - { //DSP1B - hdr[1] |= 0x80; - } - else if (buf[addr + Mapper] == 0x30 && buf[addr + RomType] == 0x05 && buf[addr + Company] != 0xb2) - { //DSP1B - hdr[1] |= 0x80; - } - else if (buf[addr + Mapper] == 0x31 && (buf[addr + RomType] == 0x03 || buf[addr + RomType] == 0x05)) - { //DSP1B - 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; - } - else if (buf[addr + Mapper] == 0x30 && buf[addr + RomType] == 0xf6) - { //ST010 - hdr[1] |= 0x88; - ramsz = 1; - if(buf[addr + RomSize] < 10) hdr[1] |= 0x20; // ST011 - } - else if (buf[addr + Mapper] == 0x30 && buf[addr + RomType] == 0x25) - { //OBC1 - hdr[1] |= 0xC0; + //BSX 3 + if (is_bsx_bios) { + hdr[1] = 0x30; } + else { - if (buf[addr + Mapper] == 0x3a && (buf[addr + RomType] == 0xf5 || buf[addr + RomType] == 0xf9)) { - //SPC7110 - hdr[1] |= 0xD0; - if(buf[addr + RomType] == 0xf9) hdr[1] |= 0x08; // with RTC - } + //DSPn types 8..B + if (buf[addr + Mapper] == 0x20 && buf[addr + RomType] == 0x03) + { //DSP1 + hdr[1] |= 0x84; + } + else if (buf[addr + Mapper] == 0x21 && buf[addr + RomType] == 0x03) + { //DSP1B + hdr[1] |= 0x80; + } + else if (buf[addr + Mapper] == 0x30 && buf[addr + RomType] == 0x05 && buf[addr + Company] != 0xb2) + { //DSP1B + hdr[1] |= 0x80; + } + else if (buf[addr + Mapper] == 0x31 && (buf[addr + RomType] == 0x03 || buf[addr + RomType] == 0x05)) + { //DSP1B + 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; + } + else if (buf[addr + Mapper] == 0x30 && buf[addr + RomType] == 0xf6) + { //ST010 + hdr[1] |= 0x88; + ramsz = 1; + if (buf[addr + RomSize] < 10) hdr[1] |= 0x20; // ST011 + } + else if (buf[addr + Mapper] == 0x30 && buf[addr + RomType] == 0x25) + { //OBC1 + hdr[1] |= 0xC0; + } - if (buf[addr + Mapper] == 0x35 && buf[addr + RomType] == 0x55) - { - //S-RTC (+ExHigh) - hdr[1] |= 0x08; - } + if (buf[addr + Mapper] == 0x3a && (buf[addr + RomType] == 0xf5 || buf[addr + RomType] == 0xf9)) { + //SPC7110 + hdr[1] |= 0xD0; + if (buf[addr + RomType] == 0xf9) hdr[1] |= 0x08; // with RTC + } - //CX4 4 - if (buf[addr + Mapper] == 0x20 && buf[addr + RomType] == 0xf3) - { - hdr[1] |= 0x40; - } + if (buf[addr + Mapper] == 0x35 && buf[addr + RomType] == 0x55) + { + //S-RTC (+ExHigh) + hdr[1] |= 0x08; + } - //SDD1 5 - if (buf[addr + Mapper] == 0x32 && (buf[addr + RomType] == 0x43 || buf[addr + RomType] == 0x45)) - { - if (romsz < 14) hdr[1] |= 0x50; // except Star Ocean un-SDD1 - } + //CX4 4 + if (buf[addr + Mapper] == 0x20 && buf[addr + RomType] == 0xf3) + { + hdr[1] |= 0x40; + } - //SA1 6 - if (buf[addr + Mapper] == 0x23 && (buf[addr + RomType] == 0x32 || buf[addr + RomType] == 0x34 || buf[addr + RomType] == 0x35)) - { - hdr[1] |= 0x60; - } + //SDD1 5 + if (buf[addr + Mapper] == 0x32 && (buf[addr + RomType] == 0x43 || buf[addr + RomType] == 0x45)) + { + if (romsz < 14) hdr[1] |= 0x50; // except Star Ocean un-SDD1 + } - //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; - } + //SA1 6 + if (buf[addr + Mapper] == 0x23 && (buf[addr + RomType] == 0x32 || buf[addr + RomType] == 0x34 || buf[addr + RomType] == 0x35)) + { + hdr[1] |= 0x60; + } - //1..3,E..F - reserved for other mappers. + //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..2,E..F - reserved for other mappers. + } hdr[2] = 0; @@ -263,3 +275,19 @@ uint8_t* snes_get_header(fileTYPE *f) } return hdr; } + +void snes_patch_bs_header(fileTYPE *f, uint8_t *buf) +{ + if ((f->offset == 0x008000 && (buf[0xFD8] == 0x20 || buf[0xFD8] == 0x30)) || + (f->offset == 0x010000 && (buf[0xFD8] == 0x21 || buf[0xFD8] == 0x31))) { + if (buf[0xFD0] == 0xFF && buf[0xFD1] == 0xFF && buf[0xFD2] == 0xFF && buf[0xFD3] == 0xFF) { + buf[0xFD3] = 0x00; + buf[0xFD2] = 0x00; + buf[0xFD1] = 0x00; + buf[0xFD0] = f->size <= 256 * 1024 ? 0x03 : + f->size <= 512 * 1024 ? 0x0F : + 0xFF; + printf("SNES: Patch bad BS header: offset %06X, size %d\n", (int)f->offset, (int)f->size); + } + } +} \ No newline at end of file diff --git a/support/snes/snes.h b/support/snes/snes.h index 8651d4e..7f43d79 100644 --- a/support/snes/snes.h +++ b/support/snes/snes.h @@ -2,5 +2,6 @@ #define SNES_H uint8_t* snes_get_header(fileTYPE *f); +void snes_patch_bs_header(fileTYPE *f, uint8_t *buf); #endif diff --git a/user_io.cpp b/user_io.cpp index abed8e4..138a48d 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -1881,18 +1881,68 @@ int user_io_file_tx(const char* name, unsigned char index, char opensave, char m // prepare transmission of new file user_io_set_download(1); + int dosend = 1; + + int is_snes_bs = 0; if (is_snes() && bytes2send) { - printf("Load SNES ROM.\n"); - uint8_t* buf = snes_get_header(&f); - hexdump(buf, 16, 0); - user_io_file_tx_data(buf, 512); + const char *ext = strrchr(f.name, '.'); + if (ext && !strcasecmp(ext, ".BS")) { + is_snes_bs = 1; + } - //strip original SNES ROM header if present (not used) - if (bytes2send & 512) - { - bytes2send -= 512; - FileReadSec(&f, buf); + if (is_snes_bs) { + char *rom_path = (char*)buf; + strcpy(rom_path, name); + char *offs = strrchr(rom_path, '/'); + if (offs) *offs = 0; + else *rom_path = 0; + + fileTYPE fb = {}; + if (FileOpen(&fb, user_io_make_filepath(rom_path, "bsx_bios.rom")) || + FileOpen(&fb, user_io_make_filepath(HomeDir(), "bsx_bios.rom"))) + { + printf("Load BSX bios ROM.\n"); + uint8_t* buf = snes_get_header(&fb); + hexdump(buf, 16, 0); + user_io_file_tx_data(buf, 512); + + //strip original SNES ROM header if present (not used) + if (bytes2send & 512) + { + bytes2send -= 512; + FileReadSec(&f, buf); + } + + uint32_t sz = fb.size; + while (sz) + { + uint16_t chunk = (sz > sizeof(buf)) ? sizeof(buf) : sz; + FileReadAdv(&fb, buf, chunk); + user_io_file_tx_data(buf, chunk); + sz -= chunk; + } + FileClose(&fb); + } + else + { + dosend = 0; + Info("Cannot open bsx_bios.rom!"); + sleep(1); + } + } + else { + printf("Load SNES ROM.\n"); + uint8_t* buf = snes_get_header(&f); + hexdump(buf, 16, 0); + user_io_file_tx_data(buf, 512); + + //strip original SNES ROM header if present (not used) + if (bytes2send & 512) + { + bytes2send -= 512; + FileReadSec(&f, buf); + } } } @@ -1904,7 +1954,7 @@ int user_io_file_tx(const char* name, unsigned char index, char opensave, char m int progress = -1; if (use_progress) MenuHide(); - int dosend = 1; + if (is_gba()) { process_ss(name); @@ -1938,6 +1988,7 @@ int user_io_file_tx(const char* name, unsigned char index, char opensave, char m uint16_t chunk = (bytes2send > sizeof(buf)) ? sizeof(buf) : bytes2send; FileReadAdv(&f, buf, chunk); + if (is_snes() && is_snes_bs) snes_patch_bs_header(&f, buf); user_io_file_tx_data(buf, chunk); if (use_progress)