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; /* if (exp[3].Bit(7)) { Console.WriteLine("EXP Write Protect Activated"); } if (exp[3].Bit(4)) { Console.WriteLine("Funky Mode Active"); } */ } } } 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(4)) { 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); } public override void NESSoftReset() { Array.Clear(exp, 0, 4); } } }