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

98 lines
2.0 KiB
C#

using BizHawk.Common;
using BizHawk.Common.NumberExtensions;
// http://wiki.nesdev.com/w/index.php/INES_Mapper_230
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
internal sealed class Mapper230 : NesBoardBase
{
//TODO: soft reset back to contra = fails
public int prg_page;
public bool prg_mode;
public bool contra_mode;
public int chip0_prg_bank_mask_16k = 0x07;
public int chip1_prg_bank_mask_16k = 0x1F;
public int chip1_offset = 0x20000;
public override bool Configure(EDetectionOrigin origin)
{
switch (Cart.BoardType)
{
case "MAPPER230":
break;
default:
return false;
}
contra_mode = true;
SetMirrorType(EMirrorType.Vertical);
return true;
}
public override void SyncState(Serializer ser)
{
ser.Sync(nameof(contra_mode), ref contra_mode);
ser.Sync(nameof(prg_page), ref prg_page);
ser.Sync(nameof(prg_mode), ref prg_mode);
base.SyncState(ser);
}
public override void WritePrg(int addr, byte value)
{
if (contra_mode)
{
prg_page = value & 0x07;
}
else
{
prg_page = value & 0x1F;
prg_mode = value.Bit(5);
if (value.Bit(6))
{
SetMirrorType(EMirrorType.Vertical);
}
else
{
SetMirrorType(EMirrorType.Horizontal);
}
}
}
public override byte ReadPrg(int addr)
{
if (contra_mode)
{
if (addr < 0x4000)
{
return Rom[((prg_page & chip0_prg_bank_mask_16k) * 0x4000) + addr];
}
else
{
return Rom[(7 * 0x4000) + (addr & 0x3FFF)];
}
}
else
{
if (prg_mode == false)
{
return Rom[((prg_page >> 1) * 0x8000) + addr + chip1_offset];
}
else
{
int page = prg_page + 8;
return Rom[(page * 0x4000) + (addr & 0x03FFF)];
}
}
}
public override void NesSoftReset()
{
contra_mode ^= true;
prg_page = 0;
prg_mode = false;
SetMirrorType(EMirrorType.Vertical);
}
}
}