From 2e45c73c2fa06cc8dcca9601dce9740d239036f0 Mon Sep 17 00:00:00 2001 From: saxxonpike Date: Fri, 3 Oct 2014 00:53:02 +0000 Subject: [PATCH] Commodore 64: Expanded sprites now show full 21 rows, sprite priority fixed (shadows in Uridium, various demos) --- .../Computers/Commodore64/MOS/Vic.Parse.cs | 77 +++++++++++-------- .../Computers/Commodore64/MOS/Vic.Render.cs | 55 ++++++++----- .../Commodore64/MOS/Vic.SpriteGenerator.cs | 3 + .../Computers/Commodore64/MOS/Vic.cs | 6 -- 4 files changed, 85 insertions(+), 56 deletions(-) diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs index 3fde5da000..1de2c4fd33 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs @@ -118,7 +118,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 else { parsecycleFetchSpriteIndex = (parsefetch & 0x7); - if ((parsefetch & 0xF0) == 0) + if ((parsefetch & 0xF0) == 0) // sprite rule 5 { // fetch P parseaddr = (0x3F8 | pointerVM | parsecycleFetchSpriteIndex); @@ -128,14 +128,22 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 else { // fetch S - if (sprites[parsecycleFetchSpriteIndex].dma) - { - SpriteGenerator spr = sprites[parsecycleFetchSpriteIndex]; - parseaddr = (spr.mc | (spr.pointer << 6)); - spr.sr <<= 8; - spr.sr |= ReadMemory(parseaddr); - spr.mc++; - } + SpriteGenerator spr = sprites[parsecycleFetchSpriteIndex]; + if (spr.dma && spr.mcbase < 63) + { + parseaddr = (spr.mc | (spr.pointer << 6)); + spr.sr <<= 8; + spr.sr |= ReadMemory(parseaddr); + spr.srMask <<= 8; + spr.srMask |= 0xFF; + spr.mc++; + spr.dmaCount++; + } + else + { + spr.dma = false; + //spr.mc = 0; + } } } @@ -169,23 +177,23 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 if (parseact != 0) { - if ((parseact & pipelineChkSprCrunch) != 0) + if ((parseact & pipelineChkSprCrunch) != 0) // sprite rule 7 { foreach (SpriteGenerator spr in sprites) { - if (spr.yCrunch) - spr.mcbase += 2; + spr.yCrunch |= !spr.yExpand; // sprite rule 1 spr.shiftEnable = false; spr.xCrunch = !spr.xExpand; spr.multicolorCrunch = !spr.multicolor; } } - else if ((parseact & pipelineChkSprDisp) != 0) + else if ((parseact & pipelineChkSprDisp) != 0) // sprite rule 4 { foreach (SpriteGenerator spr in sprites) { - spr.mc = spr.mcbase; + spr.yCrunch |= !spr.yExpand; // sprite rule 1 + spr.mc = spr.mcbase; if (spr.dma && spr.y == (rasterLine & 0xFF)) { spr.display = true; @@ -193,45 +201,54 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 } } - else if ((parseact & pipelineChkSprDma) != 0) + else if ((parseact & pipelineChkSprDma) != 0) // sprite rule 3 { foreach (SpriteGenerator spr in sprites) { - if (spr.enable && spr.y == (rasterLine & 0xFF) && !spr.dma) + spr.yCrunch |= !spr.yExpand; // sprite rule 1 + if (spr.enable && spr.y == (rasterLine & 0xFF) && !spr.dma) { spr.dma = true; spr.mcbase = 0; spr.yCrunch = !spr.yExpand; + spr.mc = 0; + spr.dmaCount = 0; } } } - else if ((parseact & pipelineChkSprExp) != 0) + else if ((parseact & pipelineChkSprExp) != 0) // sprite rule 2 { foreach (SpriteGenerator spr in sprites) { - if (spr.yExpand) + spr.yCrunch |= !spr.yExpand; // sprite rule 1 + if (spr.yExpand) spr.yCrunch ^= true; - } + if (spr.yCrunch) + { + spr.mcbase = spr.mc; + } + } } - else if ((parseact & pipelineUpdateMcBase) != 0) + else if ((parseact & pipelineUpdateMcBase) != 0) // sprite rule 8 { foreach (SpriteGenerator spr in sprites) { - if (spr.yCrunch) + if (spr.yCrunch && spr.display) { - spr.mcbase++; - if (spr.mcbase == 63) - { - spr.dma = false; - spr.display = false; - } + //spr.mcbase = spr.mc; + if (spr.mcbase == 63 && spr.dma) + { + //spr.display = false; + //spr.dma = false; + } } - } + spr.yCrunch |= !spr.yExpand; // sprite rule 1 + } } - else if ((parseact & pipelineUpdateRc) != 0) + else if ((parseact & pipelineUpdateRc) != 0) // VC/RC rule 5 { if (rc == 7) { @@ -242,7 +259,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 rc = (rc + 1) & 0x7; } - else if ((parseact & pipelineUpdateVc) != 0) + else if ((parseact & pipelineUpdateVc) != 0) // VC/RC rule 2 { vc = vcbase; vmli = 0; diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs index beecf7ce0d..cedad91361 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs @@ -141,24 +141,31 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 { sprData = 0; sprPixel = pixel; + spr.srMask &= 0xFFFFFF; if (spr.x == rasterX) - spr.shiftEnable = true; + spr.shiftEnable = spr.display && spr.srMask != 0; - if (spr.shiftEnable) + if (spr.shiftEnable) // sprite rule 6 { if (spr.multicolor) { sprData = (spr.sr & srSpriteMaskMC); - if (spr.multicolorCrunch && spr.xCrunch && !rasterXHold) - spr.sr <<= 2; + if (spr.multicolorCrunch && spr.xCrunch && !rasterXHold) + { + spr.sr <<= 2; + spr.srMask <<= 2; + } spr.multicolorCrunch ^= spr.xCrunch; } else { sprData = (spr.sr & srSpriteMask); - if (spr.xCrunch && !rasterXHold) - spr.sr <<= 1; + if (spr.xCrunch && !rasterXHold) + { + spr.sr <<= 1; + spr.srMask <<= 1; + } } spr.xCrunch ^= spr.xExpand; @@ -167,16 +174,13 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 // sprite-sprite collision if (pixelOwner == null) { - 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; + if (sprData == srSpriteMask1) + sprPixel = spriteMulticolor0; + else if (sprData == srSpriteMask2) + sprPixel = spr.color; + else if (sprData == srSpriteMask3) + sprPixel = spriteMulticolor1; + pixelOwner = spr; } else { @@ -188,13 +192,24 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 } // sprite-data collision - if (!borderOnVertical && (pixelData < srMask2)) + if (!borderOnVertical && (pixelData >= srMask2)) { spr.collideData = true; } - } - if (spr.sr == 0) - spr.shiftEnable = false; //optimization + + // sprite priority logic + if (spr.priority) + { + pixel = (pixelData >= srMask2) ? pixel : sprPixel; + } + else + { + pixel = sprPixel; + } + } + if (spr.srMask == 0) + spr.shiftEnable = false; + //pixel = (spr.mcbase / 3) & 0xF; } } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.SpriteGenerator.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.SpriteGenerator.cs index e6212195f0..b8b8e2591e 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.SpriteGenerator.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.SpriteGenerator.cs @@ -16,6 +16,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 public int color; public bool display; public bool dma; + public int dmaCount; public bool enable; public int mc; public int mcbase; @@ -25,6 +26,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 public bool priority; public bool shiftEnable; public int sr; + public int srMask; public int x; public bool xCrunch; public bool xExpand; @@ -39,6 +41,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 color = 0; display = false; dma = false; + dmaCount = 0; enable = false; mc = 0; mcbase = 0; diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs index b46c4e2d19..109cced622 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs @@ -64,7 +64,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 public void ExecutePhase1() { - //xScroll = 1; { // raster IRQ compare if ((cycle == rasterIrqLineXCycle && rasterLine > 0) || (cycle == rasterIrqLine0Cycle && rasterLine == 0)) @@ -93,13 +92,8 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 if (badline) idle = false; - // process some sprite crunch vars - foreach (SpriteGenerator spr in sprites) - if (!spr.yExpand) spr.yCrunch = true; - ParseCycle(); - //xOffset = 0; Render(); // if the BA counter is nonzero, allow CPU bus access