From 24ee005be7c4b174c633716ad75f29271de91f86 Mon Sep 17 00:00:00 2001 From: saxxonpike Date: Fri, 23 Nov 2012 12:02:26 +0000 Subject: [PATCH] commodore64: badline timing fix --- .../Computers/Commodore64/C64.cs | 8 +- .../Computers/Commodore64/Cia.cs | 4 +- .../Computers/Commodore64/MemBus.cs | 5 + .../Commodore64/_VicIINewPipeline.cs | 195 +++++++++++++++--- .../Computers/Commodore64/_VicState.cs | 1 - 5 files changed, 182 insertions(+), 31 deletions(-) diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.cs b/BizHawk.Emulation/Computers/Commodore64/C64.cs index c17bc06834..ba3f219d2b 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.cs @@ -102,6 +102,10 @@ namespace BizHawk.Emulation.Computers.Commodore64 // perform the cycle for (int i = 0; i < cyclesPerFrame; i++) { + if (signal.CpuAEC) + { + cpu.ExecuteOne(); + } vic.PerformCycle(); cpu.IRQ = signal.CpuIRQ; cpu.NMI = signal.CpuNMI; @@ -112,10 +116,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 sid.PerformCycle(); if (diskDriveAttached) diskDrive.PerformCycle(); - if (signal.CpuAEC) - { - cpu.ExecuteOne(); - } } _islag = !mem.inputWasRead; diff --git a/BizHawk.Emulation/Computers/Commodore64/Cia.cs b/BizHawk.Emulation/Computers/Commodore64/Cia.cs index faf07f29d6..5a84ef3385 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Cia.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Cia.cs @@ -475,7 +475,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 { int timer = regs.T[index]; timer--; - if (timer < 0) + if (timer == 0) { underflow[index] = true; if (regs.RUNMODE[index]) @@ -491,7 +491,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 } regs.IT[index] |= underflow[index]; - regs.T[index] = timer; + regs.T[index] = timer & 0xFFFF; } public void TimerTick(int index) diff --git a/BizHawk.Emulation/Computers/Commodore64/MemBus.cs b/BizHawk.Emulation/Computers/Commodore64/MemBus.cs index 71011f3b0c..0bddda535b 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MemBus.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MemBus.cs @@ -67,6 +67,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 public bool writeTrigger = true; // ports + public DataPortConnector cpuIO; public DataPortConnector cpuPort; public DataPortBus cpuPortBus = new DataPortBus(); @@ -101,6 +102,10 @@ namespace BizHawk.Emulation.Computers.Commodore64 cpuPort = cpuPortBus.Connect(); cpuPortBus.AttachWriteHook(UpdateLayout); + + cpuIO = cpuPortBus.Connect(); + cpuIO.Latch = 0x17; + cia1.AttachWriteHook(0, UpdateVicOffset); HardReset(); } diff --git a/BizHawk.Emulation/Computers/Commodore64/_VicIINewPipeline.cs b/BizHawk.Emulation/Computers/Commodore64/_VicIINewPipeline.cs index 7e1cccd2ae..2ff846a4da 100644 --- a/BizHawk.Emulation/Computers/Commodore64/_VicIINewPipeline.cs +++ b/BizHawk.Emulation/Computers/Commodore64/_VicIINewPipeline.cs @@ -7,17 +7,17 @@ namespace BizHawk.Emulation.Computers.Commodore64 { public partial class VicIINew : IVideoProvider { + private int baCount; private int cycle; private Action[][] pipeline; private bool pipelineGAccess; - private bool pipelineMemoryBusy; private int pipelineLength; private void ExecutePipeline() { pipelineGAccess = false; - pipelineMemoryBusy = false; advanceX = true; + baCount = 0; foreach (Action a in pipeline[cycle]) a(); @@ -29,7 +29,18 @@ namespace BizHawk.Emulation.Computers.Commodore64 PipelineRasterAdvance(); } - signal.VicAEC = !pipelineMemoryBusy; + PipelineBA(baCount > 0); + if (baCount > 0) + { + if (fetchCounter > 0) + fetchCounter--; + signal.VicAEC = (fetchCounter != 0); + } + else + { + fetchCounter = 0; + signal.VicAEC = true; + } } private void InitPipeline(Region region) @@ -374,7 +385,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 { // 54 PipelineCycle, PipelineFetchC, - PipelineSpriteMYEFlip, PipelineSpriteEnable0, PipelineRender }, @@ -382,6 +392,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 { // 55 PipelineCycle, PipelineSpriteEnable1, + PipelineSpriteMYEFlip, PipelineIdle, PipelineRender }, @@ -456,6 +467,8 @@ namespace BizHawk.Emulation.Computers.Commodore64 PipelineCycle, PipelineIRQ0, PipelineFetchSprite3P, + PipelineBASprite3, + PipelineBASprite4, PipelineRender }, new Action[] @@ -463,72 +476,96 @@ namespace BizHawk.Emulation.Computers.Commodore64 PipelineCycle, PipelineIRQ1, PipelineFetchSprite3S, + PipelineBASprite3, + PipelineBASprite4, + PipelineBASprite5, PipelineRender }, new Action[] { // 2 PipelineCycle, PipelineFetchSprite4P, + PipelineBASprite4, + PipelineBASprite5, PipelineRender }, new Action[] { // 3 PipelineCycle, PipelineFetchSprite4S, + PipelineBASprite4, + PipelineBASprite5, + PipelineBASprite6, PipelineRender }, new Action[] { // 4 PipelineCycle, PipelineFetchSprite5P, + PipelineBASprite5, + PipelineBASprite6, PipelineRender }, new Action[] { // 5 PipelineCycle, PipelineFetchSprite5S, + PipelineBASprite5, + PipelineBASprite6, + PipelineBASprite7, PipelineRender }, new Action[] { // 6 PipelineCycle, PipelineFetchSprite6P, + PipelineBASprite6, + PipelineBASprite7, PipelineRender }, new Action[] { // 7 PipelineCycle, PipelineFetchSprite6S, + PipelineBASprite6, + PipelineBASprite7, PipelineRender }, new Action[] { // 8 PipelineCycle, PipelineFetchSprite7P, + PipelineBASprite7, + PipelineBAForceLag, PipelineRender }, new Action[] { // 9 PipelineCycle, PipelineFetchSprite7S, + PipelineBASprite7, + PipelineBAForceLag, PipelineRender }, new Action[] { // 10 PipelineCycle, PipelineDramRefresh, + PipelineBAForceLag, PipelineRender }, new Action[] { // 11 PipelineCycle, PipelineDramRefresh, + PipelineBAFetch, PipelineRender }, new Action[] { // 12 PipelineCycle, PipelineDramRefresh, + PipelineBAFetch, PipelineRender }, new Action[] @@ -536,13 +573,14 @@ namespace BizHawk.Emulation.Computers.Commodore64 PipelineCycle, PipelineVCReset, PipelineDramRefresh, + PipelineBAFetch, PipelineRender }, new Action[] { // 14 PipelineCycle, PipelineDramRefresh, - PipelineBadlineDelay, + PipelineBAFetch, PipelineRender }, new Action[] @@ -550,234 +588,273 @@ namespace BizHawk.Emulation.Computers.Commodore64 PipelineCycle, PipelineSpriteMCBASEAdvance, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 16 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 17 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 18 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 19 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 20 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 21 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 22 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 23 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 24 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 25 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 26 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 27 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 28 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 29 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 30 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 31 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 32 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 33 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 34 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 35 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 36 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 37 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 38 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 39 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 40 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 41 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 42 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 43 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 44 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 45 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 46 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 47 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 48 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 49 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 50 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 51 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 52 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] { // 53 PipelineCycle, PipelineFetchC, + PipelineBAFetch, PipelineRender }, new Action[] @@ -785,6 +862,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 PipelineCycle, PipelineFetchC, PipelineSpriteEnable0, + PipelineBASprite0, PipelineRender }, new Action[] @@ -793,12 +871,15 @@ namespace BizHawk.Emulation.Computers.Commodore64 PipelineSpriteEnable1, PipelineSpriteMYEFlip, PipelineIdle, + PipelineBASprite0, PipelineRender }, new Action[] { // 56 PipelineCycle, PipelineIdle, + PipelineBASprite0, + PipelineBASprite1, PipelineRender }, new Action[] @@ -807,30 +888,42 @@ namespace BizHawk.Emulation.Computers.Commodore64 PipelineSpriteDMA, PipelineRCReset, PipelineFetchSprite0P, + PipelineBASprite0, + PipelineBASprite1, PipelineRender }, new Action[] { // 58 PipelineCycle, PipelineFetchSprite0S, + PipelineBASprite0, + PipelineBASprite1, + PipelineBASprite2, PipelineRender }, new Action[] { // 59 PipelineCycle, PipelineFetchSprite1P, + PipelineBASprite1, + PipelineBASprite2, PipelineRender }, new Action[] { // 60 PipelineCycle, PipelineFetchSprite1S, + PipelineBASprite1, + PipelineBASprite2, + PipelineBASprite3, PipelineRender }, new Action[] { // 61 PipelineCycle, PipelineFetchSprite2P, + PipelineBASprite2, + PipelineBASprite3, PipelineRender }, new Action[] @@ -838,6 +931,9 @@ namespace BizHawk.Emulation.Computers.Commodore64 PipelineCycle, PipelineFetchSprite2S, PipelineBorderCheck, + PipelineBASprite2, + PipelineBASprite3, + PipelineBASprite4, PipelineRender } }; @@ -847,10 +943,76 @@ namespace BizHawk.Emulation.Computers.Commodore64 pipelineLength = pipeline.Length; } - private void PipelineBadlineDelay() + private void PipelineBA(bool val) + { + if (val) + { + if (signal.VicAEC == true && fetchCounter == 0) + fetchCounter = 4; + } + else + { + fetchCounter = 0; + } + } + + private void PipelineBAFetch() { if (badline) - pipelineMemoryBusy = true; + baCount++; + } + + private void PipelineBAForceLag() + { + baCount++; + } + + private void PipelineBASprite0() + { + if (sprites[0].MDMA) + baCount++; + } + + private void PipelineBASprite1() + { + if (sprites[1].MDMA) + baCount++; + } + + private void PipelineBASprite2() + { + if (sprites[2].MDMA) + baCount++; + } + + private void PipelineBASprite3() + { + if (sprites[3].MDMA) + baCount++; + } + + private void PipelineBASprite4() + { + if (sprites[4].MDMA) + baCount++; + } + + private void PipelineBASprite5() + { + if (sprites[5].MDMA) + baCount++; + } + + private void PipelineBASprite6() + { + if (sprites[6].MDMA) + baCount++; + } + + private void PipelineBASprite7() + { + if (sprites[7].MDMA) + baCount++; } private void PipelineBorderCheck() @@ -867,7 +1029,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 displayEnabled = (displayEnabled | DEN); if (RASTER >= 0x030 && RASTER < 0x0F8) - badline = ((YSCROLL == (RASTER & 0x07)) && displayEnabled); + badline = badline | ((YSCROLL == (RASTER & 0x07)) && displayEnabled); else badline = false; @@ -906,7 +1068,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 int cAddress = (VM << 10) | VC; characterDataBus = mem.VicRead((ushort)cAddress); colorDataBus = mem.colorRam[VC]; - pipelineMemoryBusy = true; } else { @@ -1053,7 +1214,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 { sprites[index].MSR = mem.VicRead((ushort)((sprites[index].MPTR << 6) | (sprites[index].MC))); sprites[index].MC++; - pipelineMemoryBusy = true; } } @@ -1067,7 +1227,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 sprites[index].MSR |= mem.VicRead((ushort)((sprites[index].MPTR << 6) | (sprites[index].MC))); sprites[index].MC++; } - pipelineMemoryBusy = true; } } @@ -1280,6 +1439,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 displayEnabled = false; rasterX = rasterLeft; } + badline = false; } private void PipelineRCReset() @@ -1354,19 +1514,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 } } - private void PipelineSetBA(bool val) - { - if (val) - { - if (fetchCounter == 0) - fetchCounter = 4; - } - else - { - fetchCounter = 0; - } - } - private void PipelineSprites() { int pixelOwner = -1; diff --git a/BizHawk.Emulation/Computers/Commodore64/_VicState.cs b/BizHawk.Emulation/Computers/Commodore64/_VicState.cs index 82f639d4c7..3002301d0a 100644 --- a/BizHawk.Emulation/Computers/Commodore64/_VicState.cs +++ b/BizHawk.Emulation/Computers/Commodore64/_VicState.cs @@ -74,7 +74,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 // pipeline ser.Sync("CYCLE", ref cycle); ser.Sync("PIPELINEGACCESS", ref pipelineGAccess); - ser.Sync("PIPELINEMEMORYBUSY", ref pipelineMemoryBusy); // sprites for (int i = 0; i < 8; i++)