using BizHawk.Common; using BizHawk.Common.NumberExtensions; namespace BizHawk.Emulation.Cores.Nintendo.NES { internal sealed class Mapper175 : NesBoardBase { private bool delay; private int reg; private bool mirr; private int chrReg; private int prgReg8; private int prgRegC; private int prgRegE; public override bool Configure(EDetectionOrigin origin) { switch (Cart.BoardType) { case "MAPPER175": break; default: return false; } Sync(); return true; } public override void SyncState(Serializer ser) { ser.Sync(nameof(delay), ref delay); ser.Sync(nameof(reg), ref reg); ser.Sync(nameof(mirr), ref mirr); ser.Sync(nameof(chrReg), ref chrReg); ser.Sync(nameof(prgReg8), ref prgReg8); ser.Sync(nameof(prgRegC), ref prgRegC); ser.Sync(nameof(prgRegE), ref prgRegE); base.SyncState(ser); } public override void WritePrg(int addr, byte value) { if (addr == 0) { mirr = value.Bit(2); delay = true; Sync(); } else if (addr == 0x2000) { reg = value & 0x0F; delay = true; Sync(); } } private void Sync() { SetMirrorType(mirr ? EMirrorType.Horizontal : EMirrorType.Vertical); chrReg = reg; prgRegE = (reg << 1) + 1; if (!delay) { prgReg8 = reg; prgRegC = reg << 1; } } public override byte ReadPpu(int addr) { if (addr < 0x2000) { return Vrom[(chrReg << 13) + addr]; } return base.ReadPpu(addr); } public override byte ReadPrg(int addr) { if (addr == 0x7FFC) { delay = false; Sync(); } if (addr < 0x4000) { return Rom[(prgReg8 << 14) + (addr & 0x3FFF)]; } else if (addr < 0x6000) { return Rom[(prgRegC << 13) + (addr & 0x1FFF)]; } else { return Rom[(prgRegE << 13) + (addr & 0x1FFF)]; } } } }