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

154 lines
2.6 KiB
C#

using BizHawk.Common;
using BizHawk.Common.NumberExtensions;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public sealed class Mapper106 : NES.NESBoardBase
{
private ByteBuffer regs = new ByteBuffer(16);
private int prg_bank_mask_8k;
private int chr_bank_mask_1k;
private bool IRQa;
private int IRQCount;
public override bool Configure(NES.EDetectionOrigin origin)
{
switch (Cart.board_type)
{
case "MAPPER106":
break;
default:
return false;
}
regs[0x8] = 0xFF;
regs[0x9] = 0xFF;
regs[0xA] = 0xFF;
regs[0xB] = 0xFF;
prg_bank_mask_8k = Cart.prg_size / 8 - 1;
chr_bank_mask_1k = Cart.chr_size / 1 - 1;
return true;
}
public override void Dispose()
{
regs.Dispose();
base.Dispose();
}
public override void SyncState(Serializer ser)
{
ser.Sync("regs", ref regs);
ser.Sync("IRQa", ref IRQa);
ser.Sync("IRQCount", ref IRQCount);
base.SyncState(ser);
}
public override void WritePRG(int addr, byte value)
{
int a = addr & 0xF;
switch(a)
{
default:
regs[a] = value;
SetMirror();
break;
// TODO: IRQs
case 0xD:
IRQa = false;
IRQCount = 0;
IRQSignal = false;
break;
case 0xE:
IRQCount = (IRQCount & 0xFF00) | value;
break;
case 0XF:
IRQCount = (IRQCount & 0x00FF) | (value << 8);
IRQa = true;
break;
}
}
private void SetMirror()
{
SetMirrorType(regs[0xC].Bit(0) ? EMirrorType.Horizontal : EMirrorType.Vertical);
}
public override byte ReadPPU(int addr)
{
if (addr < 0x2000)
{
int bank = 0;
if (addr < 0x400)
{
bank = regs[0] & 0xFE;
}
else if (addr < 0x800)
{
bank = regs[1] | 1;
}
else if (addr < 0xC00)
{
bank = regs[2] & 0xFE;
}
else if (addr < 0x1000)
{
bank = regs[3] | 1;
}
else if (addr < 0x1400)
{
bank = regs[4];
}
else if (addr < 0x1800)
{
bank = regs[5];
}
else if (addr < 0x1C00)
{
bank = regs[6];
}
else
{
bank = regs[7];
}
bank &= chr_bank_mask_1k;
return VROM[(bank << 10) + (addr & 0x3FF)];
}
return base.ReadPPU(addr);
}
public override byte ReadPRG(int addr)
{
int index = ((addr >> 13) & 3) + 8;
int bank = regs[index] & prg_bank_mask_8k;
return ROM[(bank << 13) + (addr & 0x1FFF)];
}
public override void ClockCPU()
{
IrqHook(1);
}
private void IrqHook(int a)
{
if (IRQa)
{
IRQCount += a;
if (IRQCount > 0x10000)
{
IRQSignal = true;
IRQa = false;
}
}
}
}
}