2013-10-27 22:07:40 +00:00
|
|
|
|
using BizHawk.Common;
|
2014-07-03 17:23:03 +00:00
|
|
|
|
using BizHawk.Common.NumberExtensions;
|
2013-10-27 22:07:40 +00:00
|
|
|
|
|
2013-11-14 13:15:41 +00:00
|
|
|
|
namespace BizHawk.Emulation.Cores.Nintendo.NES
|
2012-07-18 04:22:41 +00:00
|
|
|
|
{
|
2013-08-25 01:08:17 +00:00
|
|
|
|
public sealed class Mapper226 : NES.NESBoardBase
|
2012-07-18 04:22:41 +00:00
|
|
|
|
{
|
2016-02-05 18:43:22 +00:00
|
|
|
|
// http://wiki.nesdev.com/w/index.php/INES_Mapper_226
|
2012-07-19 18:20:32 +00:00
|
|
|
|
public int prg_page;
|
2012-07-18 04:22:41 +00:00
|
|
|
|
public bool prg_mode;
|
|
|
|
|
|
2015-08-18 23:15:49 +00:00
|
|
|
|
private int prg_mask_32k;
|
|
|
|
|
private int prg_mask_16k;
|
|
|
|
|
|
2016-02-05 18:43:22 +00:00
|
|
|
|
private bool resetFlag = false;
|
|
|
|
|
private bool resetSwitchMode = false;
|
|
|
|
|
|
2012-07-18 04:22:41 +00:00
|
|
|
|
public override bool Configure(NES.EDetectionOrigin origin)
|
|
|
|
|
{
|
|
|
|
|
switch (Cart.board_type)
|
|
|
|
|
{
|
|
|
|
|
case "MAPPER226":
|
2016-02-05 18:43:22 +00:00
|
|
|
|
break;
|
2015-08-18 23:15:49 +00:00
|
|
|
|
case "UNIF_BMC-42in1ResetSwitch":
|
2016-02-05 18:43:22 +00:00
|
|
|
|
resetSwitchMode = true;
|
2012-07-18 04:22:41 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2012-07-19 02:56:43 +00:00
|
|
|
|
prg_page = 0;
|
2012-07-18 04:22:41 +00:00
|
|
|
|
prg_mode = false;
|
2015-08-18 23:15:49 +00:00
|
|
|
|
|
2016-02-05 18:43:22 +00:00
|
|
|
|
prg_mask_32k = (Cart.prg_size / 2) / 32 - 1;
|
|
|
|
|
prg_mask_16k = (Cart.prg_size / 2) / 16 - 1;
|
2015-08-18 23:15:49 +00:00
|
|
|
|
|
2012-07-18 04:22:41 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-05 18:43:22 +00:00
|
|
|
|
public override void NESSoftReset()
|
|
|
|
|
{
|
|
|
|
|
resetFlag ^= true;
|
|
|
|
|
prg_page = 0;
|
|
|
|
|
prg_mode = false;
|
|
|
|
|
base.NESSoftReset();
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-18 04:22:41 +00:00
|
|
|
|
public override void SyncState(Serializer ser)
|
|
|
|
|
{
|
|
|
|
|
ser.Sync("prg_page", ref prg_page);
|
|
|
|
|
ser.Sync("prg_mode", ref prg_mode);
|
2016-02-05 18:43:22 +00:00
|
|
|
|
ser.Sync("resetFlag", ref resetFlag);
|
|
|
|
|
ser.Sync("resetSwitchMode", ref resetSwitchMode);
|
2012-07-18 04:22:41 +00:00
|
|
|
|
base.SyncState(ser);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void WritePRG(int addr, byte value)
|
|
|
|
|
{
|
2012-07-19 18:20:32 +00:00
|
|
|
|
addr &= 1;
|
2012-07-18 04:22:41 +00:00
|
|
|
|
if (addr == 0)
|
|
|
|
|
{
|
2012-07-19 18:20:32 +00:00
|
|
|
|
prg_page &= ~0x3F;
|
|
|
|
|
prg_page |= ((value & 0x1F) + ((value & 0x80) >> 2));
|
2012-07-18 04:22:41 +00:00
|
|
|
|
prg_mode = value.Bit(5);
|
|
|
|
|
|
|
|
|
|
if (value.Bit(6))
|
|
|
|
|
{
|
|
|
|
|
SetMirrorType(EMirrorType.Vertical);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SetMirrorType(EMirrorType.Horizontal);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-07-19 18:20:32 +00:00
|
|
|
|
else if (addr == 1)
|
2012-07-18 04:22:41 +00:00
|
|
|
|
{
|
2012-07-19 18:20:32 +00:00
|
|
|
|
prg_page &= ~0x40;
|
|
|
|
|
prg_page |= ((value & 0x1) << 6);
|
2012-07-18 04:22:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-07-19 02:56:43 +00:00
|
|
|
|
|
2012-07-18 04:22:41 +00:00
|
|
|
|
public override byte ReadPRG(int addr)
|
|
|
|
|
{
|
2016-02-05 18:43:22 +00:00
|
|
|
|
int baseAddr = resetSwitchMode && resetFlag ? 0x80000 : 0;
|
|
|
|
|
|
2012-07-18 04:22:41 +00:00
|
|
|
|
if (prg_mode == false)
|
2016-02-05 18:43:22 +00:00
|
|
|
|
{
|
|
|
|
|
return ROM[baseAddr + (( ((prg_page >> 1) & prg_mask_32k) << 15) + (addr & 0x7FFF))];
|
2012-07-18 04:22:41 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2016-02-05 18:43:22 +00:00
|
|
|
|
return ROM[baseAddr + (((prg_page & prg_mask_16k) << 14) + (addr & 0x3FFF))];
|
2012-07-18 04:22:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|