From 8980c6fc32e19a40059d5a0c3bd28ca5c4eca6a6 Mon Sep 17 00:00:00 2001 From: Yoshimaster96 Date: Sat, 31 Jul 2021 17:33:31 -0500 Subject: [PATCH] Add proper support for SuperFX 8MB ROM emulation This code adds support for SuperFX ROMS which use the extended 6MB CPU ROM region specified by the official SNES documentation. It's not super well-tested though. --- fxemu.cpp | 2 +- memmap.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++---------- memmap.h | 2 +- 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/fxemu.cpp b/fxemu.cpp index 2e0bdb30..bd1b0abf 100644 --- a/fxemu.cpp +++ b/fxemu.cpp @@ -196,7 +196,7 @@ static void FxReset (struct FxInfo_s *psFxInfo) else { b %= GSU.nRomBanks * 2; - GSU.apvRomBank[i] = &GSU.pvRom[(b << 16) + 0x200000]; + GSU.apvRomBank[i] = &GSU.pvRom[(b << 16) + 0x800000]; } } diff --git a/memmap.cpp b/memmap.cpp index 2e78de72..a99a7b06 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -1449,6 +1449,10 @@ bool8 CMemory::LoadROMInt (int32 ROMfillSize) CalculatedSize = ((ROMfillSize + 0x1fff) / 0x2000) * 0x2000; if (CalculatedSize > 0x400000 && + (ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x1320 && // exclude SuperFX + (ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x1420 && + (ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x1520 && + (ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x1A20 && (ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x3423 && // exclude SA-1 (ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x3523 && (ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x4332 && // exclude S-DD1 @@ -3066,24 +3070,58 @@ void CMemory::Map_SuperFXLoROMMap (void) printf("Map_SuperFXLoROMMap\n"); map_System(); - // Replicate the first 2Mb of the ROM at ROM + 2MB such that each 32K + // Replicate the first 2Mb of the ROM at ROM + 8MB such that each 32K // block is repeated twice in each 64K block. for (int c = 0; c < 64; c++) { - memmove(&ROM[0x200000 + c * 0x10000], &ROM[c * 0x8000], 0x8000); - memmove(&ROM[0x208000 + c * 0x10000], &ROM[c * 0x8000], 0x8000); + memmove(&ROM[0x800000 + c * 0x10000], &ROM[c * 0x8000], 0x8000); + memmove(&ROM[0x808000 + c * 0x10000], &ROM[c * 0x8000], 0x8000); } - map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize); - map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize); + // Check GSU revision (not 100% accurate but it works) + // GSU2 + if (CalculatedSize > 0x400000) + { + map_lorom(0x00, 0x3f, 0x8000, 0xffff, 0x200000); + map_lorom_offset(0x80, 0xbf, 0x8000, 0xffff, 0x200000, 0x200000); - map_hirom_offset(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize, 0); - map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize, 0); + map_hirom_offset(0x40, 0x5f, 0x0000, 0xffff, 0x200000, 0); + map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize - 0x400000, 0x400000); - map_space(0x00, 0x3f, 0x6000, 0x7fff, SRAM - 0x6000); - map_space(0x80, 0xbf, 0x6000, 0x7fff, SRAM - 0x6000); - map_space(0x70, 0x70, 0x0000, 0xffff, SRAM); - map_space(0x71, 0x71, 0x0000, 0xffff, SRAM + 0x10000); + map_space(0x00, 0x3f, 0x6000, 0x7fff, SRAM - 0x6000); + map_space(0x80, 0xbf, 0x6000, 0x7fff, SRAM - 0x6000); + map_space(0x70, 0x70, 0x0000, 0xffff, SRAM); + map_space(0x71, 0x71, 0x0000, 0xffff, SRAM + 0x10000); + } + else if (CalculatedSize > 0x200000) + { + map_lorom(0x00, 0x3f, 0x8000, 0xffff, 0x200000); + map_lorom_offset(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize - 0x200000, 0x200000); + + map_hirom_offset(0x40, 0x5f, 0x0000, 0xffff, 0x200000, 0); + map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize - 0x200000, 0x200000); + + map_space(0x00, 0x3f, 0x6000, 0x7fff, SRAM - 0x6000); + map_space(0x80, 0xbf, 0x6000, 0x7fff, SRAM - 0x6000); + map_space(0x70, 0x70, 0x0000, 0xffff, SRAM); + map_space(0x71, 0x71, 0x0000, 0xffff, SRAM + 0x10000); + } + // GSU1 + else + { + map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize); + map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize); + + map_hirom_offset(0x40, 0x5f, 0x0000, 0xffff, CalculatedSize, 0); + map_hirom_offset(0xc0, 0xdf, 0x0000, 0xffff, CalculatedSize, 0); + + map_space(0x00, 0x3f, 0x6000, 0x7fff, SRAM - 0x6000); + map_space(0x80, 0xbf, 0x6000, 0x7fff, SRAM - 0x6000); + map_space(0x70, 0x70, 0x0000, 0xffff, SRAM); + map_space(0x71, 0x71, 0x0000, 0xffff, SRAM + 0x10000); + map_space(0xf0, 0xf0, 0x0000, 0xffff, SRAM); + map_space(0xf1, 0xf1, 0x0000, 0xffff, SRAM + 0x10000); + } map_WRAM(); diff --git a/memmap.h b/memmap.h index aaa46dec..c2107ac0 100644 --- a/memmap.h +++ b/memmap.h @@ -15,7 +15,7 @@ struct CMemory { enum - { MAX_ROM_SIZE = 0x800000 }; + { MAX_ROM_SIZE = 0xC00000 }; enum file_formats { FILE_ZIP, FILE_JMA, FILE_DEFAULT };