From 1eca7805cf1495cba77598efcf77af6a3c43bff7 Mon Sep 17 00:00:00 2001 From: saxxonpike Date: Thu, 29 Nov 2012 16:33:04 +0000 Subject: [PATCH] commodore64: add cartridge mapper 0012 (Zaxxon, Super Zaxxon), fix mapper 0000 to support 4k roms --- BizHawk.Emulation/BizHawk.Emulation.csproj | 1 + .../Commodore64/Cartridges/Cartridge.cs | 3 + .../Commodore64/Cartridges/Mapper0000.cs | 23 +++++- .../Commodore64/Cartridges/Mapper0012.cs | 72 +++++++++++++++++++ .../Computers/Commodore64/MOS/MOS6569.cs | 38 +++++----- .../Computers/Commodore64/MOS/Vic.cs | 29 ++++---- 6 files changed, 132 insertions(+), 34 deletions(-) create mode 100644 BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0012.cs diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index e528f878c1..899df90f54 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 72fdea9256..58993eaf8f 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 0x0012: + result = new Mapper0012(chipAddress, chipBank, chipData); + break; default: break; } diff --git a/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0000.cs b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0000.cs index af20981372..febd5d6a79 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0000.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0000.cs @@ -10,6 +10,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.Cartridges private byte[] romA; private byte[] romB; + // standard cartridge mapper (Commodore) + public Mapper0000(byte[] data, bool exrom, bool game) { pinGame = game; @@ -17,17 +19,32 @@ namespace BizHawk.Emulation.Computers.Commodore64.Cartridges romA = new byte[0x2000]; romB = new byte[0x2000]; + validCartridge = true; - Array.Copy(data, 0x0000, romA, 0x0000, 0x2000); + // we can expect three different configurations: + // bank of 4k, bank of 8k, or two banks of 8k - if (data.Length == 0x2000) + if (data.Length == 0x1000) { + Array.Copy(data, 0x0000, romA, 0x0000, 0x1000); + Array.Copy(data, 0x0000, romA, 0x1000, 0x1000); for (int i = 0; i < 0x2000; i++) romB[i] = 0xFF; } + else if (data.Length == 0x2000) + { + Array.Copy(data, 0x0000, romA, 0x0000, 0x2000); + for (int i = 0; i < 0x2000; i++) + romB[i] = 0xFF; + } + else if (data.Length == 0x4000) + { + Array.Copy(data, 0x0000, romA, 0x0000, 0x2000); + Array.Copy(data, 0x2000, romB, 0x0000, 0x2000); + } else { - Array.Copy(data, 0x2000, romB, 0x0000, 0x2000); + validCartridge = false; } HardReset(); diff --git a/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0012.cs b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0012.cs new file mode 100644 index 0000000000..d1f8d58241 --- /dev/null +++ b/BizHawk.Emulation/Computers/Commodore64/Cartridges/Mapper0012.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BizHawk.Emulation.Computers.Commodore64.Cartridges +{ + public class Mapper0012 : Cartridge + { + private byte[] bankMain; + private byte[][] bankHigh; + private byte[] bankHighSelected; + private byte[] dummyBank; + + // Zaxxon and Super Zaxxon cartridges + // - read to 8xxx selects bank 0 in A000-BFFF + // - read to 9xxx selects bank 1 in A000-BFFF + + public Mapper0012(List newAddresses, List newBanks, List newData) + { + bankMain = new byte[0x2000]; + bankHigh = new byte[2][]; + dummyBank = new byte[0x2000]; + + // create dummy bank just in case + for (uint i = 0; i < 0x2000; i++) + dummyBank[i] = 0xFF; + + bankHigh[0] = dummyBank; + bankHigh[1] = dummyBank; + + // load in the banks + for (int i = 0; i < newAddresses.Count; i++) + { + if (newAddresses[i] == 0x8000) + Array.Copy(newData[i], bankMain, 0x1000); + else if (newAddresses[i] == 0xA000 && newBanks[i] < 2) + bankHigh[newBanks[i]] = newData[i]; + } + + // mirror the main rom from 8000 to 9000 + Array.Copy(bankMain, 0x0000, bankMain, 0x1000, 0x1000); + + // set both pins low for 16k rom config + pinExRom = false; + pinGame = false; + + } + + public override byte Peek8000(int addr) + { + return bankMain[addr]; + } + + public override byte PeekA000(int addr) + { + return bankHighSelected[addr]; + } + + public override byte Read8000(ushort addr) + { + uint bank = (addr & (uint)0x1000) >> 12; + bankHighSelected = bankHigh[bank]; + return bankMain[addr]; + } + + public override byte ReadA000(ushort addr) + { + return bankHighSelected[addr]; + } + } +} diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6569.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6569.cs index 445aad39b1..ba5d1f2280 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6569.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6569.cs @@ -168,20 +168,20 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS }, new uint[] // BA { - 0x0834, 0x0834, - 0x0345, 0x0345, - 0x0845, 0x0845, - 0x0456, 0x0456, - 0x0856, 0x0856, + 0x0843, 0x0843, + 0x0543, 0x0543, + 0x0548, 0x0548, + 0x0546, 0x0546, + 0x0586, 0x0586, - 0x0567, 0x0567, - 0x0867, 0x0867, - 0x0887, 0x0887, - 0x0887, 0x0887, - 0x0000, 0x0000, + 0x0576, 0x0576, + 0x0876, 0x0876, + 0x0876, 0x0876, + 0x0878, 0x0878, + 0x0878, 0x0878, 0x0000, 0x0000, - 0x1000, 0x1000, + 0x1000, 0x1000, // 12: badline 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, @@ -232,17 +232,17 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, + 0x0880, 0x0880, // 55: sprites 0x0880, 0x0880, - 0x0880, 0x0880, - 0x0801, 0x0801, - 0x0012, 0x0012, - 0x0812, 0x0812, + 0x0810, 0x0810, + 0x0810, 0x0810, + 0x0210, 0x0210, + 0x0218, 0x0218, - 0x0123, 0x0123, - 0x0823, 0x0823, - 0x0234, 0x0234 + 0x0213, 0x0213, + 0x0283, 0x0283, + 0x0243, 0x0243 }, new uint[] // actions { diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs index bf67710557..c97b156213 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs @@ -171,7 +171,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS backgroundColor1 = 0; backgroundColor2 = 0; backgroundColor3 = 0; - baCount = 4; + baCount = baResetCounter; badline = false; badlineEnable = false; bitmapMode = false; @@ -243,9 +243,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS private void UpdateBA() { if (pinBA) - baCount = 4; + baCount = baResetCounter; else if (baCount > 0) baCount--; + pinAEC = (baCount > 0); } private void UpdateBorder() @@ -279,12 +280,17 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS protected const uint pipelineChkSprDisp = 512; protected const uint pipelineUpdateRc = 1024; + protected const uint rasterIrqLine0Cycle = 1; + protected const uint rasterIrqLineXCycle = 0; + + protected const uint baResetCounter = 4; + // ------------------------------------ public void ExecutePhase1() { // raster IRQ compare - if ((cycle == 0 && rasterLine > 0) || (cycle == 1 && rasterLine == 0)) + if ((cycle == rasterIrqLineXCycle && rasterLine > 0) || (cycle == rasterIrqLine0Cycle && rasterLine == 0)) { if (rasterLine != lastRasterLine) if (rasterLine == rasterInterruptLine) @@ -327,6 +333,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS xOffset = 0; Render(); + // if the BA counter is nonzero, allow CPU bus access + UpdateBA(); + // must always come last UpdatePins(); } @@ -355,10 +364,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS } } - // if the BA counter is nonzero, allow CPU bus access - UpdateBA(); - pinAEC = (baCount > 0); - Render(); // must always come last @@ -367,7 +372,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS private void ParseCycle() { - bool baPinThisCycle = true; ushort addr = 0x3FFF; uint cycleBAsprite0; uint cycleBAsprite1; @@ -477,10 +481,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS switch (ba) { case 0x0000: - baPinThisCycle = true; + pinBA = true; break; case 0x1000: - baPinThisCycle = !badline; + pinBA = !badline; break; default: cycleBAsprite0 = ba & 0x000F; @@ -489,10 +493,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS if ((cycleBAsprite0 < 8 && sprites[cycleBAsprite0].dma) || (cycleBAsprite1 < 8 && sprites[cycleBAsprite1].dma) || (cycleBAsprite2 < 8 && sprites[cycleBAsprite2].dma)) - baPinThisCycle = false; + pinBA = false; + else + pinBA = true; break; } - pinBA = baPinThisCycle; // perform actions borderCheckLEnable = true;