diff --git a/Assets/dll/bsnes.wbx.zst b/Assets/dll/bsnes.wbx.zst index 7bdaba4495..140cfc3578 100644 Binary files a/Assets/dll/bsnes.wbx.zst and b/Assets/dll/bsnes.wbx.zst differ diff --git a/src/BizHawk.Client.Common/RomLoader.cs b/src/BizHawk.Client.Common/RomLoader.cs index e37e404bee..3e78794e31 100644 --- a/src/BizHawk.Client.Common/RomLoader.cs +++ b/src/BizHawk.Client.Common/RomLoader.cs @@ -842,7 +842,7 @@ namespace BizHawk.Client.Common public static readonly IReadOnlyCollection SMS = new[] { "sms", "gg", "sg" }; - public static readonly IReadOnlyCollection SNES = new[] { "smc", "sfc", "xml" }; + public static readonly IReadOnlyCollection SNES = new[] { "smc", "sfc", "xml", "bs" }; public static readonly IReadOnlyCollection TI83 = new[] { "83g", "83l", "83p" }; diff --git a/src/BizHawk.Emulation.Common/Database/Database.cs b/src/BizHawk.Emulation.Common/Database/Database.cs index 599a3172f7..8ad2870973 100644 --- a/src/BizHawk.Emulation.Common/Database/Database.cs +++ b/src/BizHawk.Emulation.Common/Database/Database.cs @@ -250,6 +250,9 @@ namespace BizHawk.Emulation.Common case ".SMC": game.System = VSystemID.Raw.SNES; break; + case ".BS": + game.System = VSystemID.Raw.BSX; + break; case ".GB": game.System = VSystemID.Raw.GB; diff --git a/src/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs b/src/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs index 6c882f2e11..4e28e21462 100644 --- a/src/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs +++ b/src/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs @@ -89,6 +89,7 @@ namespace BizHawk.Emulation.Common Option("SNES", "Rom_SGB", in sgbA_Beta); Option("SNES", "Rom_SGB", in sgbB, FirmwareOptionStatus.Ideal); Option("SNES", "Rom_SGB2", in sgb2, FirmwareOptionStatus.Ideal); + FirmwareAndOption("604556B2E62860AF18DB5A77F2956EBC75450020", 1048576, "SNES", "Rom_BSX", "SNES_BS-X.sfc", "BS-X Rom (BS-X Sore wa Namae o Nusumareta Machi no Monogatari)"); FirmwareAndOption("A002F4EFBA42775A31185D443F3ED1790B0E949A", 3072, "SNES", "CX4", "SNES_cx4.rom", "CX4 Rom"); FirmwareAndOption("188D471FEFEA71EB53F0EE7064697FF0971B1014", 8192, "SNES", "DSP1", "SNES_dsp1.rom", "DSP1 Rom"); FirmwareAndOption("78B724811F5F18D8C67669D9390397EB1A47A5E2", 8192, "SNES", "DSP1b", "SNES_dsp1b.rom", "DSP1b Rom"); diff --git a/src/BizHawk.Emulation.Common/VSystemID.cs b/src/BizHawk.Emulation.Common/VSystemID.cs index 0a66728693..c5bf162dcc 100644 --- a/src/BizHawk.Emulation.Common/VSystemID.cs +++ b/src/BizHawk.Emulation.Common/VSystemID.cs @@ -20,6 +20,7 @@ namespace BizHawk.Emulation.Common public const string AmstradCPC = "AmstradCPC"; public const string AppleII = "AppleII"; public const string Arcade = "Arcade"; + public const string BSX = "BSX"; public const string C64 = "C64"; public const string ChannelF = "ChannelF"; public const string Coleco = "Coleco"; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesApi.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesApi.cs index 7915d775f0..353cd8aad3 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesApi.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesApi.cs @@ -80,6 +80,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES public abstract void snes_load_cartridge_normal(byte[] romData, int romSize); [BizImport(CallingConvention.Cdecl)] public abstract void snes_load_cartridge_super_gameboy(byte[] romData, byte[] sgbRomData, int romSize, int sgbRomSize); + [BizImport(CallingConvention.Cdecl)] + public abstract void snes_load_cartridge_bsx(byte[] romData, byte[] bsxRomData, int romSize, int bsxRomSize); [BizImport(CallingConvention.Cdecl)] public abstract void snes_get_cpu_registers(ref BsnesApi.CpuRegisters registers); @@ -159,7 +161,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES SbrkHeapSizeKB = 12 * 1024, InvisibleHeapSizeKB = 140 * 1024, // TODO: Roms get saved here and in mmap, consider consolidating? MmapHeapSizeKB = 33 * 1024, // TODO: check whether this needs to be larger; it depends on the rom size - PlainHeapSizeKB = 1 * 1024, + PlainHeapSizeKB = 4 * 1024, SealedHeapSizeKB = 0, SkipCoreConsistencyCheck = comm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxCoreConsistencyCheck), SkipMemoryConsistencyCheck = comm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxMemoryConsistencyCheck), diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.cs index e001bc7fe1..da99ed5a6e 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.cs @@ -17,6 +17,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES { [CoreConstructor(VSystemID.Raw.SGB)] [CoreConstructor(VSystemID.Raw.SNES)] + [CoreConstructor(VSystemID.Raw.BSX)] public BsnesCore(CoreLoadParameters loadParameters) : this(loadParameters, false) { } public BsnesCore(CoreLoadParameters loadParameters, bool subframe = false) { @@ -28,8 +29,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES _syncSettings = loadParameters.SyncSettings ?? new SnesSyncSettings(); SystemId = loadParameters.Game.System; _isSGB = SystemId == VSystemID.Raw.SGB; + bool IsBSX = loadParameters.Game.System == VSystemID.Raw.BSX; byte[] sgbRomData = null; + byte[] bsxRomData = null; if (_isSGB) { if ((loadParameters.Roms[0].RomData[0x143] & 0xc0) == 0xc0) @@ -43,6 +46,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES loadParameters.Game.FirmwareHash = SHA1Checksum.ComputeDigestHex(sgbRomData); } + else if (IsBSX) + { + bsxRomData = CoreComm.CoreFileProvider.GetFirmwareOrThrow(new FirmwareID("SNES", "Rom_BSX"), "BS-X rom is required for BS-X emulation"); + } BsnesApi.SnesCallbacks callbacks = new() { @@ -90,6 +97,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES Api.core.snes_load_cartridge_super_gameboy(sgbRomData, loadParameters.Roms[0].RomData, sgbRomData!.Length, loadParameters.Roms[0].RomData.Length); } + else if (IsBSX) + { + Api.core.snes_load_cartridge_bsx(bsxRomData, loadParameters.Roms[0].RomData, + bsxRomData!.Length, loadParameters.Roms[0].RomData.Length); + } else { Api.core.snes_load_cartridge_normal(loadParameters.Roms[0].RomData, loadParameters.Roms[0].RomData.Length); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/SubBsnesCore.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/SubBsnesCore.cs index 896af5d9c5..c971154787 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/SubBsnesCore.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/SubBsnesCore.cs @@ -10,6 +10,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES { [CoreConstructor(VSystemID.Raw.SGB)] [CoreConstructor(VSystemID.Raw.SNES)] + [CoreConstructor(VSystemID.Raw.BSX)] public SubBsnesCore(CoreLoadParameters loadParameters) { _bsnesCore = new BsnesCore(loadParameters, true); diff --git a/waterbox/bsnescore/bsnes/target-bsnescore/bsnescore.cpp b/waterbox/bsnescore/bsnes/target-bsnescore/bsnescore.cpp index 364d70d130..17acf1cfee 100644 --- a/waterbox/bsnescore/bsnes/target-bsnescore/bsnescore.cpp +++ b/waterbox/bsnescore/bsnes/target-bsnescore/bsnescore.cpp @@ -219,7 +219,21 @@ EXPORT void snes_load_cartridge_super_gameboy( program->load(); } -// Note that bsmemory and sufamiturbo (a and b) are never loaded + +EXPORT void snes_load_cartridge_bsx( + const uint8_t* rom_data, const uint8_t* bsx_rom_data, int rom_size, int bsx_rom_size +) { + emulator->connect(ID::Port::Expansion, ID::Device::Satellaview); + + program->superFamicom.raw_data.resize(rom_size); + memcpy(program->superFamicom.raw_data.data(), rom_data, rom_size); + + program->bsMemory.program.resize(bsx_rom_size); + memcpy(program->bsMemory.program.data(), bsx_rom_data, bsx_rom_size); + + program->load(); +} +// Note that sufamiturbo (a and b) are never loaded // I have no idea what that is but it probably should be supported frontend @@ -336,7 +350,6 @@ EXPORT void* snes_get_memory_region(int id, int* size, int* word_size) *word_size = 1; return program->superFamicom.program.data(); - // unused case SNES_MEMORY::BSX_RAM: if (!cartridge.has.BSMemorySlot) break; *size = mcc.rom.size(); @@ -347,6 +360,8 @@ EXPORT void* snes_get_memory_region(int id, int* size, int* word_size) *size = mcc.psram.size(); *word_size = 1; return mcc.psram.data(); + + // unused case SNES_MEMORY::SUFAMI_TURBO_A_RAM: if (!cartridge.has.SufamiTurboSlotA) break; *size = sufamiturboA.ram.size(); diff --git a/waterbox/bsnescore/bsnes/target-bsnescore/bsnescore.hpp b/waterbox/bsnescore/bsnes/target-bsnescore/bsnescore.hpp index 6d286544fd..a16be323ea 100644 --- a/waterbox/bsnescore/bsnes/target-bsnescore/bsnescore.hpp +++ b/waterbox/bsnescore/bsnes/target-bsnescore/bsnescore.hpp @@ -10,7 +10,7 @@ enum SNES_MEMORY { CARTRIDGE_RAM, CARTRIDGE_ROM, - // bsx and sufamiturbo unused cause unsupported by frontend + // sufamiturbo unused cause unsupported by frontend BSX_RAM, BSX_PRAM, SUFAMI_TURBO_A_RAM,