From adcf2dc37520a40744ae9c32425da0cc98cac060 Mon Sep 17 00:00:00 2001 From: adelikat Date: Fri, 16 Sep 2016 17:47:52 -0400 Subject: [PATCH] support unif boards 70in1 and 70in1B --- .../BizHawk.Emulation.Cores.csproj | 1 + .../Consoles/Nintendo/NES/Boards/Mapper236.cs | 116 ++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper236.cs diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 1223bcc205..72bbd8db22 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -649,6 +649,7 @@ + diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper236.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper236.cs new file mode 100644 index 0000000000..75aba05481 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper236.cs @@ -0,0 +1,116 @@ +using System; +using BizHawk.Common; + +namespace BizHawk.Emulation.Cores.Nintendo.NES +{ + public sealed class Mapper236 : NES.NESBoardBase + { + [MapperProp] + public byte CartSwitch_70in1 = 0xd; + + [MapperProp] + public byte CartSwitch_800in1 = 06; + + private bool isLargeBanks = false; + private byte large_bank; + private byte prg_bank; + private byte chr_bank; + private byte bank_mode; + + public override bool Configure(NES.EDetectionOrigin origin) + { + switch (Cart.board_type) + { + //case "MAPPER236": // Nestopia classifies both boards as MAPPER236, but I have yet to a see a ROM iwth this iNES header, and how would we determine which one it was? + case "UNIF_BMC-70in1": + isLargeBanks = false; + break; + case "UNIF_BMC-70in1B": + isLargeBanks = true; + break; + default: + return false; + } + + AutoMapperProps.Apply(this); + + return true; + } + + public override void SyncState(Serializer ser) + { + base.SyncState(ser); + ser.Sync("isLargeBanks", ref isLargeBanks); + ser.Sync("large_bank", ref large_bank); + ser.Sync("prg_bank", ref prg_bank); + ser.Sync("chr_bank", ref chr_bank); + ser.Sync("bank_mode", ref bank_mode); + ser.Sync("Cart_Switch", ref CartSwitch_70in1); + ser.Sync("Cart_Switch", ref CartSwitch_800in1); + } + + public override void WritePRG(int addr, byte value) + { + addr += 0x8000; + if ((addr & 0x4000) > 0) + { + bank_mode = (byte)(addr & 0x30); + prg_bank = (byte)(addr & 7); + } + else + { + var mirroring = ((addr & 0x20) >> 5) ^ 1; + SetMirrorType(mirroring > 0 ? EMirrorType.Vertical : EMirrorType.Horizontal); + + if (isLargeBanks) + { + large_bank = (byte)((addr & 3) << 3); + } + else + { + chr_bank = (byte)(addr & 7); + } + } + } + + public override byte ReadPRG(int addr) + { + switch (bank_mode) + { + default: + throw new InvalidOperationException("Unexpected bank_mode value"); + case 0x00: + case 0x10: + int bank; + if (addr < 0x4000) + { + bank = (large_bank | prg_bank); + } + else + { + bank = (large_bank | 7); + } + + if (bank_mode == 0x10) + { + addr = (addr & 0x7FF0) | ((isLargeBanks ? CartSwitch_800in1 : CartSwitch_70in1) & 0xf); + } + return ROM[(bank << 14) + (addr & 0x3FFF)]; + case 0x20: + return ROM[(((large_bank | prg_bank) >> 1) << 15) + addr]; + case 0x30: + return ROM[((large_bank | prg_bank) << 14) + (addr & 0x3FFF)]; + } + } + + public override byte ReadPPU(int addr) + { + if (addr < 0x2000 && VROM != null) + { + return VROM[(chr_bank << 13) + (addr & 0x1FFF)]; + } + + return base.ReadPPU(addr); + } + } +}