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

130 lines
2.9 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
2016-02-22 23:50:11 +00:00
using System.Linq;
using BizHawk.Common;
2016-02-22 23:50:11 +00:00
namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge
{
2017-04-24 13:35:05 +00:00
// This is a mapper used commonly by System 3. It is
// also utilized by the short-lived C64 Game System.
// Bank select is DExx. You select them by writing to the
// register DE00+BankNr. For example, bank 01 is a write
// to DE01.
public abstract partial class CartridgeDevice
{
private class Mapper000F : CartridgeDevice
{
[SaveState.DoNotSave]
private readonly int[][] _banks; //8000
[SaveState.SaveWithName("BankMask")]
private readonly int _bankMask;
[SaveState.SaveWithName("BankNumber")]
private int _bankNumber;
[SaveState.SaveWithName("CurrentBank")]
private int[] _currentBank;
public Mapper000F(IList<int> newAddresses, IList<int> newBanks, IList<int[]> newData)
{
var count = newAddresses.Count;
pinGame = true;
pinExRom = false;
// build dummy bank
var dummyBank = new int[0x2000];
for (var i = 0; i < 0x2000; i++)
dummyBank[i] = 0xFF; // todo: determine if this is correct
switch (count)
{
case 64:
_bankMask = 0x3F;
_banks = new int[64][];
break;
case 32:
_bankMask = 0x1F;
_banks = new int[32][];
break;
case 16:
_bankMask = 0x0F;
_banks = new int[16][];
break;
case 8:
_bankMask = 0x07;
_banks = new int[8][];
break;
case 4:
_bankMask = 0x03;
_banks = new int[4][];
break;
case 2:
_bankMask = 0x01;
_banks = new int[2][];
break;
case 1:
_bankMask = 0x00;
_banks = new int[1][];
break;
default:
throw new Exception("This looks like a System 3/C64GS cartridge but cannot be loaded...");
}
// for safety, initialize all banks to dummy
for (var i = 0; i < _banks.Length; i++)
_banks[i] = dummyBank;
// now load in the banks
for (var i = 0; i < count; i++)
{
if (newAddresses[i] == 0x8000)
{
_banks[newBanks[i] & _bankMask] = newData[i];
}
}
BankSet(0);
}
protected void BankSet(int index)
{
_bankNumber = index & _bankMask;
UpdateState();
}
public override int Peek8000(int addr)
{
return _currentBank[addr];
}
public override void PokeDE00(int addr, int val)
{
BankSet(addr);
}
public override int Read8000(int addr)
{
return _currentBank[addr];
}
private void UpdateState()
{
_currentBank = _banks[_bankNumber];
}
public override void WriteDE00(int addr, int val)
{
BankSet(addr);
}
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
if (ser.IsReader)
BankSet(_bankNumber);
}
}
}
}