forked from sin365/AxibugEmuOnline
74 lines
2.5 KiB
C#
74 lines
2.5 KiB
C#
using static AxibugEmuOnline.Client.UNES.Cartridge.VRAMMirroringMode;
|
|
|
|
namespace AxibugEmuOnline.Client.UNES.Mapper
|
|
{
|
|
[MapperDef(10)]
|
|
public class MMC4 : BaseMapper
|
|
{
|
|
protected readonly Cartridge.VRAMMirroringMode[] _mirroringModes = { Vertical, Horizontal };
|
|
|
|
protected int _prgBankOffset;
|
|
protected int[,] _chrBankOffsets = new int[2, 2];
|
|
protected bool[] _latches = new bool[2];
|
|
|
|
public MMC4(Emulator emulator) : base(emulator)
|
|
{
|
|
}
|
|
|
|
public override void InitializeMemoryMap(CPU cpu)
|
|
{
|
|
cpu.MapReadHandler(0x6000, 0x7FFF, address => _prgRAM[address - 0x6000]);
|
|
cpu.MapReadHandler(0x8000, 0xBFFF, address => _prgROM[_prgBankOffset + (address - 0x8000)]);
|
|
cpu.MapReadHandler(0xC000, 0xFFFF, address => _prgROM[_prgROM.Length - 0x4000 + (address - 0xC000)]);
|
|
|
|
cpu.MapWriteHandler(0x6000, 0x7FFF, (address, val) => _prgRAM[address - 0x6000] = val);
|
|
cpu.MapWriteHandler(0xA000, 0xAFFF, (address, val) => _prgBankOffset = (val & 0xF) * 0x4000);
|
|
cpu.MapWriteHandler(0xB000, 0xEFFF, (address, val) =>
|
|
{
|
|
var bank = (address - 0xB000) / 0x2000;
|
|
var latch = ((address & 0x1FFF) == 0).AsByte();
|
|
_chrBankOffsets[bank, latch] = (val & 0x1F) * 0x1000;
|
|
});
|
|
|
|
cpu.MapWriteHandler(0xF000, 0xFFFF, (address, val) => _emulator.Cartridge.MirroringMode = _mirroringModes[val & 0x1]);
|
|
}
|
|
|
|
public override void InitializeMemoryMap(PPU ppu)
|
|
{
|
|
ppu.MapReadHandler(0x0000, 0x1FFF, address =>
|
|
{
|
|
var bank = address / 0x1000;
|
|
var ret = _chrROM[_chrBankOffsets[bank, _latches[bank].AsByte()] + address % 0x1000];
|
|
if ((address & 0x08) > 0)
|
|
{
|
|
GetLatch(address, out uint latch, out bool? on);
|
|
|
|
if (on != null)
|
|
{
|
|
_latches[latch] = (bool)on;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
});
|
|
}
|
|
|
|
protected virtual void GetLatch(uint address, out uint latch, out bool? on)
|
|
{
|
|
latch = (address >> 12) & 0x1;
|
|
on = null;
|
|
|
|
address = (address >> 4) & 0xFF;
|
|
|
|
if (address == 0xFE)
|
|
{
|
|
on = true;
|
|
}
|
|
else if (address == 0xFD)
|
|
{
|
|
on = false;
|
|
}
|
|
}
|
|
}
|
|
}
|