2012-11-28 03:30:59 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2016-02-22 23:50:11 +00:00
|
|
|
|
using System.Linq;
|
2012-11-28 03:30:59 +00:00
|
|
|
|
|
2016-02-22 23:50:11 +00:00
|
|
|
|
namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge
|
2012-11-28 03:30:59 +00:00
|
|
|
|
{
|
2016-02-22 23:50:11 +00:00
|
|
|
|
public abstract partial class CartridgeDevice
|
|
|
|
|
{
|
|
|
|
|
private sealed class Mapper0000 : CartridgeDevice
|
|
|
|
|
{
|
2016-03-01 19:50:07 +00:00
|
|
|
|
[SaveState.DoNotSave]
|
2016-02-22 23:50:11 +00:00
|
|
|
|
private readonly int[] _romA;
|
2016-03-01 19:50:07 +00:00
|
|
|
|
[SaveState.SaveWithName("RomMaskA")]
|
2016-02-22 23:50:11 +00:00
|
|
|
|
private readonly int _romAMask;
|
2016-03-01 19:50:07 +00:00
|
|
|
|
[SaveState.DoNotSave]
|
2016-02-22 23:50:11 +00:00
|
|
|
|
private readonly int[] _romB;
|
2016-03-01 19:50:07 +00:00
|
|
|
|
[SaveState.SaveWithName("RomMaskB")]
|
2016-02-22 23:50:11 +00:00
|
|
|
|
private readonly int _romBMask;
|
2012-11-28 03:30:59 +00:00
|
|
|
|
|
2016-02-22 23:50:11 +00:00
|
|
|
|
// standard cartridge mapper (Commodore)
|
|
|
|
|
// note that this format also covers Ultimax carts
|
2012-11-29 16:33:04 +00:00
|
|
|
|
|
2016-03-01 19:50:07 +00:00
|
|
|
|
public Mapper0000(IList<int> newAddresses, IList<int[]> newData, bool game, bool exrom)
|
2016-02-22 23:50:11 +00:00
|
|
|
|
{
|
|
|
|
|
pinGame = game;
|
|
|
|
|
pinExRom = exrom;
|
2012-11-28 03:30:59 +00:00
|
|
|
|
|
2016-02-22 23:50:11 +00:00
|
|
|
|
validCartridge = true;
|
2012-11-28 03:30:59 +00:00
|
|
|
|
|
2016-02-22 23:50:11 +00:00
|
|
|
|
// default to empty banks
|
|
|
|
|
_romA = new int[1];
|
|
|
|
|
_romB = new int[1];
|
|
|
|
|
_romA[0] = 0xFF;
|
|
|
|
|
_romB[0] = 0xFF;
|
2012-11-28 03:30:59 +00:00
|
|
|
|
|
2016-02-22 23:50:11 +00:00
|
|
|
|
for (var i = 0; i < newAddresses.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (newAddresses[i] == 0x8000)
|
|
|
|
|
{
|
|
|
|
|
switch (newData[i].Length)
|
|
|
|
|
{
|
|
|
|
|
case 0x1000:
|
|
|
|
|
_romAMask = 0x0FFF;
|
|
|
|
|
_romA = newData[i];
|
|
|
|
|
break;
|
|
|
|
|
case 0x2000:
|
|
|
|
|
_romAMask = 0x1FFF;
|
|
|
|
|
_romA = newData[i];
|
|
|
|
|
break;
|
|
|
|
|
case 0x4000:
|
|
|
|
|
_romAMask = 0x1FFF;
|
|
|
|
|
_romBMask = 0x1FFF;
|
|
|
|
|
// split the rom into two banks
|
|
|
|
|
_romA = new int[0x2000];
|
|
|
|
|
_romB = new int[0x2000];
|
|
|
|
|
Array.Copy(newData[i], 0x0000, _romA, 0x0000, 0x2000);
|
|
|
|
|
Array.Copy(newData[i], 0x2000, _romB, 0x0000, 0x2000);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
validCartridge = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (newAddresses[i] == 0xA000 || newAddresses[i] == 0xE000)
|
|
|
|
|
{
|
|
|
|
|
switch (newData[i].Length)
|
|
|
|
|
{
|
|
|
|
|
case 0x1000:
|
|
|
|
|
_romBMask = 0x0FFF;
|
|
|
|
|
break;
|
|
|
|
|
case 0x2000:
|
|
|
|
|
_romBMask = 0x1FFF;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
validCartridge = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_romB = newData[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-11-28 03:30:59 +00:00
|
|
|
|
|
2016-02-22 23:50:11 +00:00
|
|
|
|
public override int Peek8000(int addr)
|
|
|
|
|
{
|
|
|
|
|
return _romA[addr & _romAMask];
|
|
|
|
|
}
|
2012-11-28 03:30:59 +00:00
|
|
|
|
|
2016-02-22 23:50:11 +00:00
|
|
|
|
public override int PeekA000(int addr)
|
|
|
|
|
{
|
|
|
|
|
return _romB[addr & _romBMask];
|
|
|
|
|
}
|
2012-11-28 03:30:59 +00:00
|
|
|
|
|
2016-02-22 23:50:11 +00:00
|
|
|
|
public override int Read8000(int addr)
|
|
|
|
|
{
|
|
|
|
|
return _romA[addr & _romAMask];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int ReadA000(int addr)
|
|
|
|
|
{
|
|
|
|
|
return _romB[addr & _romBMask];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-11-28 03:30:59 +00:00
|
|
|
|
}
|