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 newAddresses, IList newBanks, IList 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; } } }