diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj
index c1c817d1ed..e528f878c1 100644
--- a/BizHawk.Emulation/BizHawk.Emulation.csproj
+++ b/BizHawk.Emulation/BizHawk.Emulation.csproj
@@ -83,6 +83,7 @@
+
diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.Core.cs b/BizHawk.Emulation/Computers/Commodore64/C64.Core.cs
index e187b6b101..3dac6bc654 100644
--- a/BizHawk.Emulation/Computers/Commodore64/C64.Core.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/C64.Core.cs
@@ -167,6 +167,10 @@ namespace BizHawk.Emulation.Computers.Commodore64
public void ExecutePhase1()
{
+ // sync cartridge lines (these can change)
+ pla.ExRom = cartPort.ExRom;
+ pla.Game = cartPort.Game;
+
cia0.ExecutePhase1();
cia1.ExecutePhase1();
sid.ExecutePhase1();
diff --git a/BizHawk.Emulation/Computers/Commodore64/Cartridges/Cartridge.cs b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Cartridge.cs
index a6b122d8c0..72fdea9256 100644
--- a/BizHawk.Emulation/Computers/Commodore64/Cartridges/Cartridge.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Cartridge.cs
@@ -64,9 +64,12 @@ namespace BizHawk.Emulation.Computers.Commodore64.Cartridges
{
switch (mapper)
{
- case 0:
+ case 0x0000:
result = new Mapper0000(chipData[0], exrom, game);
break;
+ case 0x0005:
+ result = new Mapper0005(chipAddress, chipBank, chipData);
+ break;
default:
break;
}
diff --git a/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0005.cs b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0005.cs
new file mode 100644
index 0000000000..d20ed8c125
--- /dev/null
+++ b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0005.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BizHawk.Emulation.Computers.Commodore64.Cartridges
+{
+ public class Mapper0005 : Cartridge
+ {
+ private byte[][] banksA = new byte[0][]; //8000
+ private byte[][] banksB = new byte[0][]; //A000
+ private uint bankMask;
+ private uint bankNumber;
+ private byte[] currentBankA;
+ private byte[] currentBankB;
+ private byte[] dummyBank;
+
+ public Mapper0005(List newAddresses, List newBanks, List newData)
+ {
+ uint count = (uint)newAddresses.Count;
+
+ // build dummy bank
+ dummyBank = new byte[0x2000];
+ for (uint i = 0; i < 0x2000; i++)
+ dummyBank[i] = 0xFF; // todo: determine if this is correct
+
+ if (count == 64) //512k
+ {
+ pinGame = true;
+ pinExRom = false;
+ bankMask = 0x3F;
+ banksA = new byte[64][];
+ }
+ else if (count == 32) //256k
+ {
+ pinGame = false;
+ pinExRom = false;
+ bankMask = 0x0F;
+ banksA = new byte[16][];
+ banksB = new byte[16][];
+ }
+ else if (count == 16) //128k
+ {
+ pinGame = true;
+ pinExRom = false;
+ bankMask = 0x0F;
+ banksA = new byte[16][];
+ }
+ else if (count == 4) //32k
+ {
+ pinGame = true;
+ pinExRom = false;
+ bankMask = 0x03;
+ banksA = new byte[4][];
+ }
+ else
+ {
+ // we don't know what format this is...
+ throw new Exception("This looks like an Ocean cartridge but cannot be loaded...");
+ }
+
+ // for safety, initialize all banks to dummy
+ for (uint i = 0; i < banksA.Length; i++)
+ banksA[i] = dummyBank;
+ for (uint i = 0; i < banksB.Length; i++)
+ banksB[i] = dummyBank;
+
+ // now load in the banks
+ for (int i = 0; i < count; i++)
+ {
+ if (newAddresses[i] == 0x8000)
+ {
+ banksA[newBanks[i]] = newData[i];
+ }
+ else if (newAddresses[i] == 0xA000)
+ {
+ banksB[newBanks[i]] = newData[i];
+ }
+ }
+
+ BankSet(0);
+ }
+
+ private void BankSet(uint index)
+ {
+ bankNumber = index & bankMask;
+ if (!pinExRom)
+ currentBankA = banksA[bankNumber];
+ else
+ currentBankA = dummyBank;
+
+ if (!pinGame)
+ currentBankB = banksB[bankNumber];
+ else
+ currentBankB = dummyBank;
+ }
+
+ public override byte Peek8000(int addr)
+ {
+ return currentBankA[addr];
+ }
+
+ public override byte PeekA000(int addr)
+ {
+ return currentBankB[addr];
+ }
+
+ public override void PokeDE00(int addr, byte val)
+ {
+ if (addr == 0x00)
+ BankSet(val);
+ }
+
+ public override byte Read8000(ushort addr)
+ {
+ return currentBankA[addr];
+ }
+
+ public override byte ReadA000(ushort addr)
+ {
+ return currentBankB[addr];
+ }
+
+ public override void WriteDE00(ushort addr, byte val)
+ {
+ if (addr == 0x00)
+ BankSet(val);
+ }
+ }
+}
diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOSPLA.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOSPLA.cs
index ac9108d65c..f619d906a3 100644
--- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOSPLA.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOSPLA.cs
@@ -557,6 +557,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
case PLABank.None:
break;
case PLABank.RAM:
+ // RAM is written through anyway, don't do it here
break;
case PLABank.Sid:
chips.sid.Write(addr, val);