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

98 lines
2.1 KiB
C#

using BizHawk.Common;
using BizHawk.Common.NumberExtensions;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public sealed class Mapper226 : NES.NESBoardBase
{
// http://wiki.nesdev.com/w/index.php/INES_Mapper_226
public int prg_page;
public bool prg_mode;
private int prg_mask_32k;
private int prg_mask_16k;
private bool resetFlag = false;
private bool resetSwitchMode = false;
public override bool Configure(NES.EDetectionOrigin origin)
{
int prg_mask_hack = 1;
switch (Cart.board_type)
{
case "MAPPER226":
break;
case "UNIF_BMC-42in1ResetSwitch":
resetSwitchMode = true;
prg_mask_hack = 2;
break;
default:
return false;
}
prg_page = 0;
prg_mode = false;
prg_mask_32k = (Cart.prg_size / prg_mask_hack) / 32 - 1;
prg_mask_16k = (Cart.prg_size / prg_mask_hack) / 16 - 1;
return true;
}
public override void NESSoftReset()
{
resetFlag ^= true;
prg_page = 0;
prg_mode = false;
base.NESSoftReset();
}
public override void SyncState(Serializer ser)
{
ser.Sync("prg_page", ref prg_page);
ser.Sync("prg_mode", ref prg_mode);
ser.Sync("resetFlag", ref resetFlag);
ser.Sync("resetSwitchMode", ref resetSwitchMode);
base.SyncState(ser);
}
public override void WritePRG(int addr, byte value)
{
addr &= 1;
if (addr == 0)
{
prg_page &= ~0x3F;
prg_page |= ((value & 0x1F) + ((value & 0x80) >> 2));
prg_mode = value.Bit(5);
if (value.Bit(6))
{
SetMirrorType(EMirrorType.Vertical);
}
else
{
SetMirrorType(EMirrorType.Horizontal);
}
}
else if (addr == 1)
{
prg_page &= ~0x40;
prg_page |= ((value & 0x1) << 6);
}
}
public override byte ReadPRG(int addr)
{
int baseAddr = resetSwitchMode && resetFlag ? 0x80000 : 0;
if (prg_mode == false)
{
return ROM[baseAddr + (( ((prg_page >> 1) & prg_mask_32k) << 15) + (addr & 0x7FFF))];
}
else
{
return ROM[baseAddr + (((prg_page & prg_mask_16k) << 14) + (addr & 0x3FFF))];
}
}
}
}