using System; using System.Collections.Generic; using System.Linq; using System.Text; using BizHawk.Common; namespace BizHawk.Emulation.Cores.Nintendo.NES { // Bad Dudes.7z|Dragon Ninja (J) [p1][!].nes // irq doesn't work right; easily seen in any level but level 1 public sealed class Mapper222 : NES.NESBoardBase { int prg_bank_mask_8k; int chr_bank_mask_1k; int[] prg = new int[4]; int[] chr = new int[8]; int irq_time = 0; bool irq_counting = false; public override bool Configure(NES.EDetectionOrigin origin) { switch (Cart.board_type) { case "MAPPER222": break; default: return false; } SetMirrorType(EMirrorType.Vertical); prg_bank_mask_8k = Cart.prg_size / 8 - 1; chr_bank_mask_1k = Cart.chr_size - 1; prg[3] = prg_bank_mask_8k; prg[2] = prg[3] - 1; return true; } public override void WritePRG(int addr, byte value) { addr &= 0x7003; switch (addr) { case 0x0000: prg[0] = value & prg_bank_mask_8k; break; case 0x2000: prg[1] = value & prg_bank_mask_8k; break; case 0x7000: case 0x7001: // this is of course sort of VRC like... except it doesn't work right irq_time = (256 - value) * 113; IRQSignal = false; irq_counting = false; Console.WriteLine("IRQ Set\\Ack: SL {0} val {1}", NES.ppu.ppur.status.sl, value); break; case 0x7002: irq_counting = true; Console.WriteLine("IRQ GO: SL {0} val {1}", NES.ppu.ppur.status.sl, value); break; } if (addr >= 0x3000 && addr < 0x7000) { int b = (addr >> 11) - 6; b |= addr >> 1 & 1; if ((addr & 1) != 0) chr[b] = (chr[b] & 0x0f | value << 4) & chr_bank_mask_1k; else chr[b] = (chr[b] & 0xf0 | value & 0x0f) & chr_bank_mask_1k; } } public override byte ReadPRG(int addr) { return ROM[addr & 0x1fff | prg[addr >> 13] << 13]; } public override byte ReadPPU(int addr) { if (addr < 0x2000) return VROM[addr & 0x3ff | chr[addr >> 10] << 10]; else return base.ReadPPU(addr); } public override void ClockCPU() { if (irq_counting) { irq_time--; if (irq_time == 0) { irq_counting = false; IRQSignal = true; Console.WriteLine("IRQ TRIG: SL {0}", NES.ppu.ppur.status.sl); } } } public override void SyncState(Serializer ser) { ser.Sync("prg", ref prg, false); ser.Sync("chr", ref chr, false); ser.Sync("irq_time", ref irq_time); ser.Sync("irq_counting", ref irq_counting); base.SyncState(ser); } } }