using BizHawk.Common; namespace BizHawk.Emulation.Cores.Nintendo.NES { public sealed class Mapper142 : NES.NESBoardBase { private ByteBuffer reg = new ByteBuffer(8); private byte cmd; private int lastBank; private bool isirqused = false; private byte IRQa = 0; private int IRQCount = 0; public override bool Configure(NES.EDetectionOrigin origin) { switch (Cart.board_type) { case "MAPPER142": case "UNIF_UNL-KS7032": break; default: return false; } SetMirrorType(EMirrorType.Horizontal); lastBank = Cart.prg_size / 8 - 1; return true; } public override void Dispose() { reg.Dispose(); base.Dispose(); } public override byte ReadWRAM(int addr) { return ROM[(reg[4] << 13) + (addr & 0x1FFF)]; } public override byte ReadPRG(int addr) { if (addr < 0x2000) { return ROM[(reg[1] << 13) + (addr & 0x1FFF)]; } if (addr < 0x4000) { return ROM[(reg[2] << 13) + (addr & 0x1FFF)]; } if (addr < 0x6000) { return ROM[(reg[3] << 13) + (addr & 0x1FFF)]; } return ROM[(lastBank << 13) + (addr & 0x1FFF)]; } public override void WriteEXP(int addr, byte value) { Write(addr + 0x4000, value); } public override void WriteWRAM(int addr, byte value) { Write(addr + 0x6000, value); } public override void WritePRG(int addr, byte value) { Write(addr + 0x8000, value); } private void IRQHook(int a) { if (IRQa > 0) { IRQCount += a; if (IRQCount >= 0xFFFF) { IRQa = 0; IRQCount = 0; IRQSignal = true; } } } public override void ClockPPU() { IRQHook(1); } private void Write(int addr, byte value) { switch (addr & 0xF000) { case 0x8000: IRQSignal = false; IRQCount = (IRQCount & 0x000F) | (value & 0x0F); isirqused = true; break; case 0x9000: IRQSignal = false; IRQCount = (IRQCount & 0x00F0) | ((value & 0x0F) << 4); isirqused = true; break; case 0xA000: IRQSignal = false; IRQCount = (IRQCount & 0x0F00) | ((value & 0x0F) << 8); isirqused = true; break; case 0xB000: IRQSignal = false; IRQCount = (IRQCount & 0xF000) | (value << 12); isirqused = true; break; case 0xC000: if (isirqused) { IRQSignal = false; IRQa = 1; } break; case 0xE000: cmd = (byte)(value & 7); break; case 0xF000: reg[cmd] = value; break; } } } }