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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
71
user_io.cpp
71
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)
|
||||
|
||||
Reference in New Issue
Block a user