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

134 lines
2.6 KiB
C#

using BizHawk.Common;
using BizHawk.Common.NumberExtensions;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public sealed class Mapper035 : NES.NESBoardBase
{
private ByteBuffer reg = new ByteBuffer(8);
private ByteBuffer chr = new ByteBuffer(8);
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 "MAPPER035":
break;
default:
return false;
}
prg_bank_mask_8k = Cart.prg_size / 8 - 1;
chr_bank_mask_1k = Cart.chr_size / 1 - 1;
SetMirrorType(Cart.pad_h, Cart.pad_v);
return true;
}
public override void Dispose()
{
reg.Dispose();
chr.Dispose();
base.Dispose();
}
public override void SyncState(Serializer ser)
{
ser.Sync("reg", ref reg);
ser.Sync("chr", ref chr);
ser.Sync("IRQa", ref IRQa);
ser.Sync("IRQCount", ref IRQCount);
base.SyncState(ser);
}
public override byte ReadEXP(int addr)
{
if (addr == 0x800)
{
return 0x20;
}
return base.ReadEXP(addr);
}
private void SetMirror()
{
SetMirrorType(reg[3].Bit(0) ? EMirrorType.Horizontal : EMirrorType.Vertical);
}
public override void WritePRG(int addr, byte value)
{
addr += 0x8000;
switch (addr)
{
case 0x8000: reg[0] = value; break;
case 0x8001: reg[1] = value; break;
case 0x8002: reg[2] = value; break;
case 0x9000: chr[0] = value; break;
case 0x9001: chr[1] = value; break;
case 0x9002: chr[2] = value; break;
case 0x9003: chr[3] = value; break;
case 0x9004: chr[4] = value; break;
case 0x9005: chr[5] = value; break;
case 0x9006: chr[6] = value; break;
case 0x9007: chr[7] = value; break;
case 0xC002: IRQa = false; IRQSignal = false; break;
case 0xC005: IRQCount = value; break;
case 0xC003: IRQa = true; break;
case 0xD001: reg[3] = value;
SetMirror(); break;
}
}
public override byte ReadPRG(int addr)
{
int index = addr >> 13;
int bank = reg[index];
if (index == 3) { bank = 0xFF; }
bank &= prg_bank_mask_8k;
return ROM[(bank << 13) + (addr & 0x1FFF)];
}
public override byte ReadPPU(int addr)
{
if (addr < 0x2000)
{
int index = addr >> 10;
int bank = chr[index];
bank &= chr_bank_mask_1k;
return VROM[(bank << 10) + (addr & 0x3FF)];
}
return base.ReadPPU(addr);
}
public override void ClockCPU()
{
IrqHook(1);
}
private void IrqHook(int a)
{
if (IRQa)
{
IRQCount += a;
if (IRQCount > 0x10000)
{
IRQSignal = true;
IRQa = false;
}
}
}
}
}