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
This commit is contained in:
Sergey Dvodnenko
2020-10-14 17:08:44 +03:00
committed by GitHub
parent 78e281f4df
commit 72c62a613f
3 changed files with 162 additions and 82 deletions

View File

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

View File

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

View File

@@ -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)