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

127 lines
2.7 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
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
// Mapper for a few Domark and HES Australia games.
// It seems a lot of people dumping these have remapped
// them to the Ocean mapper (0005) but this is still here
// for compatibility.
//
// Bank select is DE00, bit 7 enabled means to disable
// ROM in 8000-9FFF.
internal sealed class Mapper0013 : CartridgeDevice
2017-04-24 13:35:05 +00:00
{
[SaveState.DoNotSave]
private readonly int[][] _banks; // 8000
[SaveState.SaveWithName("BankMask")]
private readonly int _bankMask;
[SaveState.SaveWithName("BankNumber")]
private int _bankNumber;
[SaveState.DoNotSave]
private int[] _currentBank;
[SaveState.SaveWithName("ROMEnable")]
private bool _romEnable;
public Mapper0013(IList<int> newAddresses, IList<int> newBanks, IList<int[]> newData)
2017-04-24 13:35:05 +00:00
{
var count = newAddresses.Count;
2017-04-24 13:35:05 +00:00
pinGame = true;
pinExRom = false;
_romEnable = true;
2017-04-24 13:35:05 +00:00
// build dummy bank
var dummyBank = new int[0x2000];
for (var i = 0; i < 0x2000; i++)
dummyBank[i] = 0xFF; // todo: determine if this is correct
2017-04-24 13:35:05 +00:00
switch (count)
{
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;
default:
throw new Exception("This looks like a Domark/HES cartridge but cannot be loaded...");
}
2017-04-24 13:35:05 +00:00
// for safety, initialize all banks to dummy
for (var i = 0; i < _banks.Length; i++)
_banks[i] = dummyBank;
2017-04-24 13:35:05 +00:00
// now load in the banks
for (var i = 0; i < count; i++)
{
if (newAddresses[i] == 0x8000)
2017-04-24 13:35:05 +00:00
{
_banks[newBanks[i] & _bankMask] = newData[i];
2017-04-24 13:35:05 +00:00
}
}
BankSet(0);
}
2017-04-24 13:35:05 +00:00
private void BankSet(int index)
{
_bankNumber = index & _bankMask;
_romEnable = (index & 0x80) == 0;
UpdateState();
}
2017-04-24 13:35:05 +00:00
public override int Peek8000(int addr)
{
return _currentBank[addr];
}
2017-04-24 13:35:05 +00:00
public override void PokeDE00(int addr, int val)
{
if (addr == 0x00)
BankSet(val);
}
2017-04-24 13:35:05 +00:00
public override int Read8000(int addr)
{
return _currentBank[addr];
}
2017-04-24 13:35:05 +00:00
private void UpdateState()
{
_currentBank = _banks[_bankNumber];
if (_romEnable)
2017-04-24 13:35:05 +00:00
{
pinExRom = false;
pinGame = true;
2017-04-24 13:35:05 +00:00
}
else
2017-04-24 13:35:05 +00:00
{
pinExRom = true;
pinGame = true;
2017-04-24 13:35:05 +00:00
}
}
public override void WriteDE00(int addr, int val)
{
if (addr == 0x00)
BankSet(val);
}
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
if (ser.IsReader)
BankSet(_bankNumber | (_romEnable ? 0x00 : 0x80));
}
2017-04-24 13:35:05 +00:00
}
}