BizHawk/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper222.cs

115 lines
2.6 KiB
C#

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);
}
}
}