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); + } + } +}