forked from sin365/AxibugEmuOnline
201 lines
4.5 KiB
C#
201 lines
4.5 KiB
C#
using System.IO;
|
|
|
|
namespace MyNes.Core
|
|
{
|
|
[BoardInfo("NES-EVENT", 105)]
|
|
[HassIssues]
|
|
internal class Mapper105 : Board
|
|
{
|
|
private int DipSwitchNumber;
|
|
|
|
private byte[] reg = new byte[4];
|
|
|
|
private byte shift;
|
|
|
|
private byte buffer;
|
|
|
|
private bool flag_p;
|
|
|
|
private bool flag_s;
|
|
|
|
private bool flag_o;
|
|
|
|
private int reg_a;
|
|
|
|
private int reg_b;
|
|
|
|
private bool irq_control;
|
|
|
|
private bool initialized;
|
|
|
|
private int irq_counter;
|
|
|
|
private int dipswitches;
|
|
|
|
internal override string Issues => MNInterfaceLanguage.IssueMapper105;
|
|
|
|
internal override void HardReset()
|
|
{
|
|
base.HardReset();
|
|
TogglePRGRAMEnable(enable: true);
|
|
reg = new byte[4];
|
|
reg[0] = 12;
|
|
flag_s = (flag_p = true);
|
|
reg[1] = (reg[2] = (reg[3] = 0));
|
|
buffer = 0;
|
|
shift = 0;
|
|
initialized = false;
|
|
DipSwitchNumber = 0;
|
|
dipswitches = 0x20000000 | (DipSwitchNumber << 22);
|
|
}
|
|
|
|
internal override void SoftReset()
|
|
{
|
|
DipSwitchNumber = (DipSwitchNumber + 1) & 0xF;
|
|
dipswitches = 0x20000000 | (DipSwitchNumber << 22);
|
|
}
|
|
|
|
internal override void WritePRG(ref ushort address, ref byte value)
|
|
{
|
|
if ((value & 0x80) == 128)
|
|
{
|
|
reg[0] |= 12;
|
|
flag_s = (flag_p = true);
|
|
shift = (buffer = 0);
|
|
return;
|
|
}
|
|
if ((value & 1) == 1)
|
|
{
|
|
buffer |= (byte)(1 << (int)shift);
|
|
}
|
|
if (++shift < 5)
|
|
{
|
|
return;
|
|
}
|
|
address = (ushort)((address & 0x7FFF) >> 13);
|
|
reg[address] = buffer;
|
|
shift = (buffer = 0);
|
|
switch (address)
|
|
{
|
|
case 0:
|
|
flag_p = (reg[0] & 8) != 0;
|
|
flag_s = (reg[0] & 4) != 0;
|
|
UpdatePRG();
|
|
switch (reg[0] & 3)
|
|
{
|
|
case 0:
|
|
Switch01KNMTFromMirroring(Mirroring.OneScA);
|
|
break;
|
|
case 1:
|
|
Switch01KNMTFromMirroring(Mirroring.OneScB);
|
|
break;
|
|
case 2:
|
|
Switch01KNMTFromMirroring(Mirroring.Vert);
|
|
break;
|
|
case 3:
|
|
Switch01KNMTFromMirroring(Mirroring.Horz);
|
|
break;
|
|
}
|
|
break;
|
|
case 1:
|
|
irq_control = (reg[1] & 0x10) == 16;
|
|
if (irq_control)
|
|
{
|
|
initialized = true;
|
|
irq_counter = 0;
|
|
NesEmu.IRQFlags &= -9;
|
|
}
|
|
else
|
|
{
|
|
Switch32KPRG(0, PRGArea.Area8000);
|
|
}
|
|
flag_o = (reg[1] & 8) == 8;
|
|
reg_a = (reg[1] >> 1) & 3;
|
|
UpdatePRG();
|
|
break;
|
|
case 3:
|
|
TogglePRGRAMEnable((reg[3] & 0x10) == 0);
|
|
reg_b = reg[3] & 0xF;
|
|
UpdatePRG();
|
|
break;
|
|
case 2:
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void UpdatePRG()
|
|
{
|
|
if (initialized)
|
|
{
|
|
if (!flag_o)
|
|
{
|
|
Switch32KPRG(reg_a, PRGArea.Area8000);
|
|
}
|
|
else if (!flag_p)
|
|
{
|
|
Switch32KPRG((reg_b >> 1) + 4, PRGArea.Area8000);
|
|
}
|
|
else if (!flag_s)
|
|
{
|
|
Switch16KPRG(8, PRGArea.Area8000);
|
|
Switch16KPRG(reg_b + 8, PRGArea.AreaC000);
|
|
}
|
|
else
|
|
{
|
|
Switch16KPRG(reg_b + 8, PRGArea.Area8000);
|
|
Switch16KPRG(15, PRGArea.AreaC000);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal override void OnCPUClock()
|
|
{
|
|
if (!irq_control)
|
|
{
|
|
irq_counter++;
|
|
if (irq_counter == dipswitches)
|
|
{
|
|
irq_counter = 0;
|
|
NesEmu.IRQFlags |= 8;
|
|
}
|
|
}
|
|
}
|
|
|
|
internal override void WriteStateData(ref BinaryWriter stream)
|
|
{
|
|
base.WriteStateData(ref stream);
|
|
stream.Write(DipSwitchNumber);
|
|
stream.Write(reg);
|
|
stream.Write(shift);
|
|
stream.Write(buffer);
|
|
stream.Write(flag_p);
|
|
stream.Write(flag_s);
|
|
stream.Write(flag_o);
|
|
stream.Write(reg_a);
|
|
stream.Write(reg_b);
|
|
stream.Write(irq_control);
|
|
stream.Write(initialized);
|
|
stream.Write(irq_counter);
|
|
stream.Write(dipswitches);
|
|
}
|
|
|
|
internal override void ReadStateData(ref BinaryReader stream)
|
|
{
|
|
base.ReadStateData(ref stream);
|
|
DipSwitchNumber = stream.ReadInt32();
|
|
stream.Read(reg, 0, reg.Length);
|
|
shift = stream.ReadByte();
|
|
buffer = stream.ReadByte();
|
|
flag_p = stream.ReadBoolean();
|
|
flag_s = stream.ReadBoolean();
|
|
flag_o = stream.ReadBoolean();
|
|
reg_a = stream.ReadInt32();
|
|
reg_b = stream.ReadInt32();
|
|
irq_control = stream.ReadBoolean();
|
|
initialized = stream.ReadBoolean();
|
|
irq_counter = stream.ReadInt32();
|
|
dipswitches = stream.ReadInt32();
|
|
}
|
|
}
|
|
}
|