From 3dc1e8dba2bf5507590dab3deb222246ac25d59a Mon Sep 17 00:00:00 2001 From: saxxonpike Date: Sun, 25 Aug 2013 07:58:25 +0000 Subject: [PATCH] Commodore64: Fix sprites and tweaked timing, should now be pixel perfect with test intro "rem-17". --- .../Computers/Commodore64/MOS/MOS6526.cs | 15 ++-- .../Computers/Commodore64/MOS/Vic.Parse.cs | 7 +- .../Computers/Commodore64/MOS/Vic.Render.cs | 82 +++++++++---------- .../Computers/Commodore64/MOS/Vic.State.cs | 26 ++++-- .../Commodore64/MOS/Vic.TimingBuilder.cs | 11 +-- .../Computers/Commodore64/MOS/Vic.cs | 9 +- 6 files changed, 78 insertions(+), 72 deletions(-) diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs index d104ac0ec1..d403ca56e2 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs @@ -110,6 +110,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS public void ExecutePhase1() { // unsure if the timer actually operates in ph1 + pinIRQ = !( + (intTimer[0] && enableIntTimer[0]) || + (intTimer[1] && enableIntTimer[1]) || + (intAlarm && enableIntAlarm) || + (intSP && enableIntSP) || + (intFlag && enableIntFlag) + ); } public void ExecutePhase2() @@ -151,14 +158,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS cntPos = false; underflow[0] = false; underflow[1] = false; - - pinIRQ = !( - (intTimer[0] && enableIntTimer[0]) || - (intTimer[1] && enableIntTimer[1]) || - (intAlarm && enableIntAlarm) || - (intSP && enableIntSP) || - (intFlag && enableIntFlag) - ); } } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Parse.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Parse.cs index 3d09fdee67..5425d99366 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Parse.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Parse.cs @@ -58,7 +58,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS } else if (parsefetchType == 0x200) { - // fetch C + delayC = xScroll; if (!idle) { if (badline) @@ -78,6 +78,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS dataC = 0; bufferC[vmli] = dataC; } + srC <<= 12; + srC |= dataC; } else if (parsefetchType == 0x300) { @@ -95,6 +97,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS parseaddr &= 0x39FF; dataG = ReadMemory(parseaddr); sr |= dataG << (7 - xScroll); + srSync |= 0xAA << (7 - xScroll); if (!idle) { bufferG[vmli] = dataG; @@ -107,7 +110,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS // fetch I parseaddr = (extraColorMode ? 0x39FF : 0x3FFF); dataG = ReadMemory(parseaddr); - dataC = 0; + //dataC = 0; } else if (parsefetchType == 0x500) { diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs index 59bd6bab44..b2e5d711b1 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs @@ -7,16 +7,16 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS { sealed public partial class Vic { - int borderSR; + int delayC; int ecmPixel; int pixel; int pixelData; - int pixelOwner; + //int pixelOwner; + Sprite pixelOwner; int sprData; int sprPixel; - int srOutput = 0; - int srOutputMC = 0; - int hblankSR = 0; + int srC = 0; + int srSync = 0; VicVideoMode videoMode; enum VicVideoMode : int @@ -45,17 +45,12 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS renderEnabled = (!hblank && !vblank); for (int i = 0; i < 4; i++) { - // fill shift register - if (bitmapColumn >= 8) - { - displayC >>= 12; - displayC &= 0xFFF; - if (!idle) - { - displayC |= (dataC << 12); - } - bitmapColumn &= 7; - } + + if (delayC > 0) + delayC--; + else + displayC = (srC >> 12) & 0xFFF; + if (borderCheckLEnable && (rasterX == borderL)) { @@ -67,20 +62,18 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS borderOnMain = false; } - srOutput = sr & srMask2; - if ((bitmapColumn & 1) == 0) - srOutputMC = sr & srMask3; switch (videoMode) { case VicVideoMode.Mode000: - pixelData = srOutput; + pixelData = sr & srMask2; pixel = (pixelData != 0) ? (displayC >> 8) : backgroundColor0; break; case VicVideoMode.Mode001: if ((displayC & 0x800) != 0) { // multicolor 001 - pixelData = srOutputMC; + if ((srSync & srMask2) != 0) + pixelData = sr & srMask3; if (pixelData == srMask0) pixel = backgroundColor0; @@ -94,16 +87,17 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS else { // standard 001 - pixelData = srOutput; + pixelData = sr & srMask2; pixel = (pixelData != 0) ? (displayC >> 8) : backgroundColor0; } break; case VicVideoMode.Mode010: - pixelData = srOutput; + pixelData = sr & srMask2; pixel = (pixelData != 0) ? (displayC >> 4) : (displayC); break; case VicVideoMode.Mode011: - pixelData = srOutputMC; + if ((srSync & srMask2) != 0) + pixelData = sr & srMask3; if (pixelData == srMask0) pixel = backgroundColor0; @@ -115,7 +109,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS pixel = (displayC >> 8); break; case VicVideoMode.Mode100: - pixelData = srOutput; + pixelData = sr & srMask2; if (pixelData != 0) { pixel = displayC >> 8; @@ -140,16 +134,16 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS } pixel &= 0xF; sr <<= 1; + srSync <<= 1; // render sprite - pixelOwner = 8; - for (int j = 0; j < 8; j++) + //pixelOwner = 8; + pixelOwner = null; + foreach (Sprite spr in sprites) { sprData = 0; sprPixel = pixel; - Sprite spr = sprites[j]; - if (spr.x == rasterX) spr.shiftEnable = true; @@ -157,14 +151,14 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS { if (spr.multicolor) { - sprData = (spr.sr & 0xC00000); + sprData = (spr.sr & srSpriteMaskMC); if (spr.multicolorCrunch && spr.xCrunch && !rasterXHold) spr.sr <<= 2; spr.multicolorCrunch ^= spr.xCrunch; } else { - sprData = (spr.sr & 0x800000); + sprData = (spr.sr & srSpriteMask); if (spr.xCrunch && !rasterXHold) spr.sr <<= 1; } @@ -172,31 +166,31 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS if (sprData != 0) { - if (sprData == 0x400000) - sprPixel = spriteMulticolor0; - else if (sprData == 0x800000) - sprPixel = spr.color; - else if (sprData == 0xC00000) - sprPixel = spriteMulticolor1; - // sprite-sprite collision - if (pixelOwner >= 8) + if (pixelOwner == null) { - if (!spr.priority || ((sr & srMask) == 0)) - pixel = sprPixel; - pixelOwner = j; + if (!spr.priority || (pixelData == 0)) + { + if (sprData == srSpriteMask1) + pixel = spriteMulticolor0; + else if (sprData == srSpriteMask2) + pixel = spr.color; + else if (sprData == srSpriteMask3) + pixel = spriteMulticolor1; + } + pixelOwner = spr; } else { if (!borderOnVertical) { spr.collideSprite = true; - sprites[pixelOwner].collideSprite = true; + pixelOwner.collideSprite = true; } } // sprite-data collision - if (!borderOnVertical && ((sr & srMask) != 0)) + if (!borderOnVertical && (pixelData < srMask2)) { spr.collideData = true; } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.State.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.State.cs index 857dc3ec11..7f4c09ffb9 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.State.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.State.cs @@ -80,6 +80,12 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS int srMask2; int srMask3; int srMaskMC; + int srSpriteMask; + int srSpriteMask0; + int srSpriteMask1; + int srSpriteMask2; + int srSpriteMask3; + int srSpriteMaskMC; bool vblank; int vblankEnd; int vblankStart; @@ -92,6 +98,20 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS public void HardReset() { + // *** SHIFT REGISTER BITMASKS *** + srMask0 = 0x00000; + srMask1 = 0x20000; + srMask2 = srMask1 << 1; + srMask3 = srMask1 | srMask2; + srMask = srMask2; + srMaskMC = srMask3; + srSpriteMask0 = 0x000000; + srSpriteMask1 = 0x400000; + srSpriteMask2 = srSpriteMask1 << 1; + srSpriteMask3 = srSpriteMask1 | srSpriteMask2; + srSpriteMask = srSpriteMask2; + srSpriteMaskMC = srSpriteMask3; + pinAEC = true; pinBA = true; pinIRQ = true; @@ -141,12 +161,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS spriteMulticolor0 = 0; spriteMulticolor1 = 0; sr = 0; - srMask0 = 0x000000; - srMask1 = 0x200000; - srMask2 = srMask1 << 1; - srMask3 = srMask1 | srMask2; - srMask = srMask2; - srMaskMC = srMask3; vblank = true; vc = 0; vcbase = 0; diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.TimingBuilder.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.TimingBuilder.cs index a7030f07b9..aafc10553f 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.TimingBuilder.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.TimingBuilder.cs @@ -38,9 +38,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS else result.Add(0); } - - bool hBlankL = false; - bool hBlankR = false; for (int i = 0; i < length; i++) { // pipeline raster X delay @@ -48,13 +45,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS result[i] |= pipelineHoldX; // pipeline border checks - if (timing[i] == 0x01C) + if (timing[i] == 0x018) result[i] |= pipelineChkBrdL1; - if (timing[i] == 0x020) + if (timing[i] == 0x01C) result[i] |= pipelineChkBrdL0; - if (timing[i] == 0x150) + if (timing[i] == 0x14C) result[i] |= pipelineChkBrdR0; - if (timing[i] == 0x15C) + if (timing[i] == 0x158) result[i] |= pipelineChkBrdR1; if (timing[i] == (hblankStart & 0xFFD)) result[i] |= pipelineHBlankR; diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs index 8393487a1c..271e2fa15c 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs @@ -72,7 +72,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS public void ExecutePhase1() { //xScroll = 1; - bitmapColumn = 8 - xScroll; { // raster IRQ compare if ((cycle == rasterIrqLineXCycle && rasterLine > 0) || (cycle == rasterIrqLine0Cycle && rasterLine == 0)) @@ -177,10 +176,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS { { - //borderL = columnSelect ? 0x018 : 0x01F; - //borderR = columnSelect ? 0x158 : 0x14F; - borderL = columnSelect ? 28 : 35; - borderR = columnSelect ? 348 : 339; + borderL = columnSelect ? 0x018 : 0x01F; + borderR = columnSelect ? 0x158 : 0x14F; + //borderL = columnSelect ? 28 : 35; + //borderR = columnSelect ? 348 : 339; borderT = rowSelect ? 0x033 : 0x037; borderB = rowSelect ? 0x0FB : 0x0F7; }