diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 05d42bfce8..0e2aa8931f 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -330,6 +330,7 @@ + diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper196.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper196.cs new file mode 100644 index 0000000000..1a1599ac83 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper196.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using BizHawk.Common; + +namespace BizHawk.Emulation.Cores.Nintendo.NES +{ + public class Mapper196 : MMC3Board_Base + { + // pirate crap + // behavior from fceumm + // standard MMC3, plus scrambled address lines to access the MMC3, and a bit of extra hardware + // adding a 32K prg banking mode + + // config + int prg_bank_mask_32k; + + // state + bool prgmode; + int prgreg; + + public override bool Configure(NES.EDetectionOrigin origin) + { + switch (Cart.board_type) + { + case "MAPPER196": + break; + default: + return false; + } + + Cart.wram_size = 0; + prg_bank_mask_32k = Cart.prg_size / 32 - 1; + BaseSetup(); + return true; + } + + public override void SyncState(Serializer ser) + { + base.SyncState(ser); + ser.BeginSection("Mapper196"); + ser.Sync("prgmode", ref prgmode); + ser.Sync("prgreg", ref prgreg); + ser.EndSection(); + } + + public override void WriteWRAM(int addr, byte value) + { + if (addr < 0x1000) + { + if (!prgmode) + Console.WriteLine("M196: 32K prg activated"); + prgmode = true; // no way to turn this off once activated? + prgreg = value & 15 | value >> 4; + prgreg &= prg_bank_mask_32k; + } + } + + public override void WritePRG(int addr, byte value) + { + // addresses are scrambled + if (addr >= 0x4000) + { + addr = (addr & 0xFFFE) | ((addr >> 2) & 1) | ((addr >> 3) & 1); + } + else + { + addr = (addr & 0xFFFE) | ((addr >> 2) & 1) | ((addr >> 3) & 1) | ((addr >> 1) & 1); + } + base.WritePRG(addr, value); + } + + public override byte ReadPRG(int addr) + { + if (prgmode) + { + return ROM[addr | prgreg << 15]; + } + else + { + return base.ReadPRG(addr); + } + } + + } +}