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