BizHawk/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0001.cs

150 lines
3.1 KiB
C#

using System;
using System.Collections.Generic;
namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge
{
internal sealed class Mapper0001 : CartridgeDevice
{
[SaveState.SaveWithName("RAM")] private readonly int[] _ram = new int[0x2000];
[SaveState.SaveWithName("RAMEnabled")] private bool _ramEnabled;
[SaveState.DoNotSave] private readonly int[] _rom = new int[0x8000];
[SaveState.SaveWithName("ROMOffset")] private int _romOffset;
[SaveState.SaveWithName("CartEnabled")] private bool _cartEnabled;
public Mapper0001(IList<int> newAddresses, IList<int> newBanks, IList<int[]> newData)
{
pinExRom = false;
pinGame = false;
for (var i = 0; i < newData.Count; i++)
{
if (newAddresses[i] == 0x8000)
Array.Copy(newData[i], 0, _rom, 0x2000 * newBanks[i], 0x2000);
}
_romOffset = 0;
_cartEnabled = true;
}
public override void HardReset()
{
base.HardReset();
pinExRom = false;
pinGame = false;
for (var i = 0; i < 0x2000; i++)
_ram[i] = 0x00;
_romOffset = 0;
_cartEnabled = true;
}
public override int Peek8000(int addr)
{
return GetLoRom(addr);
}
public override int PeekA000(int addr)
{
return Peek8000(addr);
}
public override int PeekDF00(int addr)
{
return GetIo2(addr);
}
public override void Poke8000(int addr, int val)
{
SetLoRom(addr, val);
}
public override void PokeA000(int addr, int val)
{
Poke8000(addr, val);
}
public override void PokeDE00(int addr, int val)
{
SetState(val);
}
public override void PokeDF00(int addr, int val)
{
SetIo2(addr, val);
}
public override int Read8000(int addr)
{
return GetLoRom(addr);
}
public override int ReadA000(int addr)
{
return GetHiRom(addr);
}
public override int ReadDF00(int addr)
{
return GetIo2(addr);
}
public override void Write8000(int addr, int val)
{
SetLoRom(addr, val);
}
public override void WriteA000(int addr, int val)
{
SetLoRom(addr, val);
}
public override void WriteDE00(int addr, int val)
{
SetState(val);
}
public override void WriteDF00(int addr, int val)
{
SetIo2(addr, val);
}
private void SetState(int val)
{
pinGame = (val & 0x01) == 0;
pinExRom = (val & 0x02) != 0;
_cartEnabled = (val & 0x04) == 0;
_romOffset = (val & 0x18) << 10;
_ramEnabled = (val & 0x20) == 0;
}
private int GetLoRom(int addr)
{
return _ramEnabled
? _ram[addr & 0x1FFF]
: _rom[(addr & 0x1FFF) | _romOffset];
}
private int GetHiRom(int addr)
{
return _rom[(addr & 0x1FFF) | _romOffset];
}
private void SetLoRom(int addr, int val)
{
_ram[addr & 0x1FFF] = val;
}
private int GetIo2(int addr)
{
if (!_cartEnabled)
return ReadOpenBus();
return _ramEnabled
? _ram[(addr & 0xFF) | 0x1F00]
: _rom[(addr & 0xFF) | _romOffset | 0x1F00];
}
private void SetIo2(int addr, int val)
{
_ram[addr & 0x1FFF] = val & 0xFF;
}
}
}