AxibugEmuOnline/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper163.cs
2024-07-03 18:22:22 +08:00

110 lines
2.4 KiB
C#

namespace MyNes.Core
{
[BoardInfo("Unknown", 163)]
internal class Mapper163 : Board
{
internal byte prg_reg;
internal byte security_reg;
internal bool security_trigger;
internal byte security_reg101;
internal bool do_chr_ram;
internal override void HardReset()
{
base.HardReset();
security_reg101 = 1;
security_trigger = false;
do_chr_ram = true;
Switch32KPRG(15, PRGArea.Area8000);
Toggle08KCHR_RAM(ram: true);
}
internal override void WriteEX(ref ushort address, ref byte data)
{
if (address == 20737)
{
if (security_reg101 != 0 && data == 0)
{
security_trigger = true;
}
security_reg101 = data;
}
else
{
if (address < 20480)
{
return;
}
switch (address & 0x7300)
{
case 20480:
prg_reg = (byte)((prg_reg & 0xF0u) | (data & 0xFu));
Switch32KPRG(prg_reg, PRGArea.Area8000);
do_chr_ram = (data & 0x80) != 0;
if (!do_chr_ram && NesEmu.ppu_clock_v < 128)
{
Switch08KCHR(0);
}
break;
case 20736:
if (data == 6)
{
Switch32KPRG(3, PRGArea.Area8000);
}
break;
case 20992:
prg_reg = (byte)((prg_reg & 0xFu) | (uint)((data & 0xF) << 4));
Switch32KPRG(prg_reg, PRGArea.Area8000);
break;
case 21248:
security_reg = data;
break;
}
}
}
internal override void ReadEX(ref ushort addr, out byte val)
{
val = 0;
if (addr < 20480)
{
return;
}
switch (addr & 0x1E14)
{
case 20736:
val = security_reg;
break;
case 21760:
if (security_trigger)
{
val = security_reg;
}
break;
}
}
internal override void OnPPUScanlineTick()
{
base.OnPPUScanlineTick();
if (do_chr_ram && NesEmu.IsRenderingOn())
{
if (NesEmu.ppu_clock_v == 127)
{
Switch04KCHR(1, CHRArea.Area0000);
Switch04KCHR(1, CHRArea.Area1000);
}
if (NesEmu.ppu_clock_v == 237)
{
Switch04KCHR(0, CHRArea.Area0000);
Switch04KCHR(0, CHRArea.Area1000);
}
}
}
}
}