diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj
index c6df43885f..beead85920 100644
--- a/BizHawk.Emulation/BizHawk.Emulation.csproj
+++ b/BizHawk.Emulation/BizHawk.Emulation.csproj
@@ -84,6 +84,7 @@
+
diff --git a/BizHawk.Emulation/Computers/Commodore64/Cartridges/Cartridge.cs b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Cartridge.cs
index d9b70fef38..a5d3ce9f1b 100644
--- a/BizHawk.Emulation/Computers/Commodore64/Cartridges/Cartridge.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Cartridge.cs
@@ -70,6 +70,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.Cartridges
case 0x0005:
result = new Mapper0005(chipAddress, chipBank, chipData);
break;
+ case 0x000F:
+ result = new Mapper000F(chipAddress, chipBank, chipData);
+ break;
case 0x0012:
result = new Mapper0012(chipAddress, chipBank, chipData);
break;
diff --git a/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0005.cs b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0005.cs
index e6079d6ed3..c2a48e2fd1 100644
--- a/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0005.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0005.cs
@@ -33,6 +33,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Cartridges
}
else if (count == 32) //256k
{
+ // this specific config is a weird exception
pinGame = false;
pinExRom = false;
bankMask = 0x0F;
@@ -46,6 +47,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.Cartridges
bankMask = 0x0F;
banksA = new byte[16][];
}
+ else if (count == 8) //64k
+ {
+ pinGame = true;
+ pinExRom = false;
+ bankMask = 0x07;
+ banksA = new byte[8][];
+ }
else if (count == 4) //32k
{
pinGame = true;
@@ -53,6 +61,20 @@ namespace BizHawk.Emulation.Computers.Commodore64.Cartridges
bankMask = 0x03;
banksA = new byte[4][];
}
+ else if (count == 2) //16k
+ {
+ pinGame = true;
+ pinExRom = false;
+ bankMask = 0x01;
+ banksA = new byte[2][];
+ }
+ else if (count == 1) //8k
+ {
+ pinGame = true;
+ pinExRom = false;
+ bankMask = 0x00;
+ banksA = new byte[1][];
+ }
else
{
// we don't know what format this is...
diff --git a/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper000F.cs b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper000F.cs
new file mode 100644
index 0000000000..1349679c66
--- /dev/null
+++ b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper000F.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BizHawk.Emulation.Computers.Commodore64.Cartridges
+{
+ // 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 class Mapper000F : Cartridge
+ {
+ private byte[][] banks = new byte[0][]; //8000
+ private uint bankMask;
+ private uint bankNumber;
+ private byte[] currentBank;
+ private byte[] dummyBank;
+
+ public Mapper000F(List newAddresses, List newBanks, List newData)
+ {
+ uint count = (uint)newAddresses.Count;
+
+ pinGame = true;
+ pinExRom = false;
+
+ // 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
+ {
+ bankMask = 0x3F;
+ banks = new byte[64][];
+ }
+ else if (count == 32) //256k
+ {
+ bankMask = 0x1F;
+ banks = new byte[32][];
+ }
+ else if (count == 16) //128k
+ {
+ bankMask = 0x0F;
+ banks = new byte[16][];
+ }
+ else if (count == 8) //64k
+ {
+ bankMask = 0x07;
+ banks = new byte[8][];
+ }
+ else if (count == 4) //32k
+ {
+ bankMask = 0x03;
+ banks = new byte[4][];
+ }
+ else if (count == 2) //16k
+ {
+ bankMask = 0x01;
+ banks = new byte[2][];
+ }
+ else if (count == 1) //8k
+ {
+ bankMask = 0x00;
+ banks = new byte[1][];
+ }
+ else
+ {
+ // we don't know what format this is...
+ throw new Exception("This looks like a System 3/C64GS cartridge but cannot be loaded...");
+ }
+
+ // for safety, initialize all banks to dummy
+ for (uint i = 0; i < banks.Length; i++)
+ banks[i] = dummyBank;
+
+ // now load in the banks
+ for (int i = 0; i < count; i++)
+ {
+ if (newAddresses[i] == 0x8000)
+ {
+ banks[newBanks[i] & bankMask] = newData[i];
+ }
+ }
+
+ BankSet(0);
+ }
+
+ private void BankSet(uint index)
+ {
+ bankNumber = index & bankMask;
+ UpdateState();
+ }
+
+ public override byte Peek8000(int addr)
+ {
+ return currentBank[addr];
+ }
+
+ public override void PokeDE00(int addr, byte val)
+ {
+ BankSet((uint)addr);
+ }
+
+ public override byte Read8000(ushort addr)
+ {
+ return currentBank[addr];
+ }
+
+ private void UpdateState()
+ {
+ currentBank = banks[bankNumber];
+ }
+
+ public override void WriteDE00(ushort addr, byte val)
+ {
+ BankSet((uint)addr);
+ }
+ }
+}