134 lines
2.6 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|