From 7ce4fd206ed70fa81e334020d2b573168e3d0a43 Mon Sep 17 00:00:00 2001 From: goyuken Date: Thu, 8 Jan 2015 01:00:48 +0000 Subject: [PATCH] nes: support cool boy 400 in 1 --- .../BizHawk.Emulation.Cores.csproj | 1 + .../Consoles/Nintendo/NES/Boards/CoolBoy.cs | 117 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/CoolBoy.cs diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 8c38a41d73..16404afba4 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -340,6 +340,7 @@ + diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/CoolBoy.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/CoolBoy.cs new file mode 100644 index 0000000000..b3cb891892 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/CoolBoy.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using BizHawk.Common; +using BizHawk.Common.NumberExtensions; + +namespace BizHawk.Emulation.Cores.Nintendo.NES +{ + public sealed class CoolBoy : MMC3Board_Base + { + // eldritch horror pirate multicart + // 32MB prg rom, no prg ram, no chr rom, 128KB chr ram + + // behavior directly from fceu-mm + + // this could be broken down into more sensibly named variables + byte[] exp = new byte[4]; + + public override bool Configure(NES.EDetectionOrigin origin) + { + switch (Cart.board_type) + { + case "UNIF_COOLBOY": + AssertChr(0); + break; + default: + return false; + } + + Cart.vram_size = 128; + Cart.wram_size = 0; + + BaseSetup(); + + // normally base mmc3 sets this right, but it has a hardcoded assumption + // that no chr rom => 8K of chr ram, not 128K. i'd change the base class, + // but not sure if that would break something else + chr_mask = 127; + + return true; + } + + public override void WriteWRAM(int addr, byte value) + { + if (addr < 0x1000) + { + if (!exp[3].Bit(7)) + { + exp[addr & 3] = value; + } + } + } + + protected override int Get_PRGBank_8K(int addr) + { + int mask = 0, shift = 0; + int baseaddr = exp[0] & 0x07 | (exp[1] & 0x10) >> 1 | (exp[1] & 0x0c) << 2 | (exp[0] & 0x30) << 2; + + switch (exp[0] & 0xc0) + { + case 0x00: + baseaddr >>= 2; + mask = 0x3f; + shift = 6; + break; + case 0x80: + baseaddr >>= 1; + mask = 0x1f; + shift = 5; + break; + case 0xc0: + shift = 4; + if (exp[3].Bit(4)) + { + mask = 1 | exp[1] & 2; + } + else + { + mask = 0xf; + } + break; + case 0x40: + // ?? + throw new InvalidOperationException(); + } + + int v = base.Get_PRGBank_8K(addr); + + int ret = baseaddr << shift | v & mask; + if (exp[3].Bit(0)) + { + ret |= exp[3] & (0x0e ^ exp[1] & 2); + } + return ret; + } + + protected override int Get_CHRBank_1K(int addr) + { + if (exp[3].Bit(4)) + { + return (exp[2] & 15) << 3 | addr >> 10 & 7; + } + else + { + return base.Get_CHRBank_1K(addr); + } + } + + public override void SyncState(Serializer ser) + { + base.SyncState(ser); + ser.Sync("exp", ref exp, false); + } + } +}