From d3687bb68d51d5196bccfad608b5d2e1e3511361 Mon Sep 17 00:00:00 2001 From: saxxonpike Date: Sat, 31 Aug 2013 22:54:44 +0000 Subject: [PATCH] Commodore64: Further development in the experimental Vic. The process in which the Vic puts graphics and sprite data into the shift regs should be replicated perfectly, and some graphics mode code can be combined as a result. --- .../Chips/Internals/Vic.Graphics.cs | 61 +++++++++++--- .../Chips/Internals/Vic.Internal.cs | 1 + .../Chips/Internals/Vic.Registers.cs | 1 - .../Chips/Internals/Vic.Sprite.cs | 84 +++++++++++++++++++ .../Experimental/Chips/Internals/Vic.Synth.cs | 19 +++++ 5 files changed, 153 insertions(+), 13 deletions(-) diff --git a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Graphics.cs b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Graphics.cs index 84a69cca05..58d049849b 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Graphics.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Graphics.cs @@ -7,8 +7,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals { sealed public partial class Vic { - const int GRAPHICS_DATA_OUTPUT_MASK = 0xC000; - const int GRAPHICS_DATA_INPUT_SHIFT = 16; + const int GRAPHICS_DATA_00 = 0; + const int GRAPHICS_DATA_01 = 0x4000; + const int GRAPHICS_DATA_10 = GRAPHICS_DATA_01 << 1; + const int GRAPHICS_DATA_11 = GRAPHICS_DATA_01 | GRAPHICS_DATA_10; + const int GRAPHICS_DATA_OUTPUT_MASK = GRAPHICS_DATA_11; enum GraphicsMode { @@ -26,13 +29,14 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals int g_BufferG; int g_DataC; int g_DataG; + bool g_Idle; int g_FillRasterX; GraphicsMode g_Mode; int g_OutData; int g_OutPixel; int g_ShiftRegister; - void RenderG() + void RenderGraphics() { if ((rasterX & 0x7) == g_FillRasterX) { @@ -41,6 +45,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals if (multiColorMode && (bitmapMode || (g_DataC & 0x8) != 0)) { // load multicolor bits + // xx00xx11xx22xx33 g_ShiftRegister = ((g_DataG & 0x03) << 0) | ((g_DataG & 0x0C) << 2) | @@ -49,11 +54,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals ; // duplicate bits + // 0000111122223333 g_ShiftRegister |= g_ShiftRegister << 2; } else { // load single color bits + // 0x1x2x3x4x5x6x7x g_ShiftRegister = ((g_DataG & 0x01) << 1) | ((g_DataG & 0x02) << 2) | @@ -64,29 +71,59 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals ((g_DataG & 0x40) << 7) | ((g_DataG & 0x80) << 8) ; + + if (!bitmapMode) + { + // duplicate bits + // 0011223344556677 + g_ShiftRegister |= g_ShiftRegister << 1; + } + else + { + // convert to bitmap format + g_ShiftRegister = (g_ShiftRegister | 0x5555) ^ (g_ShiftRegister >> 1); + } } } + g_OutData = g_ShiftRegister & GRAPHICS_DATA_OUTPUT_MASK; + switch (g_Mode) { - default: - - break; + case GraphicsMode.Mode000: case GraphicsMode.Mode001: + if (g_OutData == GRAPHICS_DATA_00) + g_OutPixel = backgroundColor[0]; + else if (g_OutData == GRAPHICS_DATA_11) + g_OutPixel = g_Idle ? 0 : ((g_DataC >> 8) & 0x7); + else if (g_OutData == GRAPHICS_DATA_01) + g_OutPixel = g_Idle ? 0 : backgroundColor[1]; + else + g_OutPixel = g_Idle ? 0 : backgroundColor[2]; break; case GraphicsMode.Mode010: - break; case GraphicsMode.Mode011: + if (g_OutData == GRAPHICS_DATA_00) + g_OutPixel = backgroundColor[0]; + else if (g_OutData == GRAPHICS_DATA_01) + g_OutPixel = (g_DataC >> 4) & 0xF; + else if (g_OutData == GRAPHICS_DATA_10) + g_OutPixel = g_DataC & 0xF; + else + g_OutPixel = g_DataC >> 8; break; case GraphicsMode.Mode100: + if (g_OutData == GRAPHICS_DATA_00) + g_OutPixel = backgroundColor[(g_DataC >> 6) & 0x3]; + else + g_OutPixel = g_DataC >> 8; break; - case GraphicsMode.Mode101: - break; - case GraphicsMode.Mode110: - break; - case GraphicsMode.Mode111: + default: + g_OutPixel = 0; break; } + + g_ShiftRegister <<= 2; } void UpdateGraphicsMode() diff --git a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Internal.cs b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Internal.cs index 407c26eb95..5a6354f06a 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Internal.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Internal.cs @@ -20,6 +20,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals public void Clock() { + Render(); } public void Reset() diff --git a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Registers.cs b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Registers.cs index 8f325f8f6d..f0bbda45ef 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Registers.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Registers.cs @@ -31,7 +31,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals bool spriteCollisionInterrupt; bool spriteCollisionInterruptEnable; int[] spriteMultiColor; - Sprite[] sprites; int videoMemory; int xScroll; int yScroll; diff --git a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Sprite.cs b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Sprite.cs index f7933425f7..00ad5c24b4 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Sprite.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Sprite.cs @@ -7,8 +7,21 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals { sealed public partial class Vic { + const int SPRITE_DATA_00 = 0; + const int SPRITE_DATA_01 = 0x400000; + const int SPRITE_DATA_10 = SPRITE_DATA_01 << 1; + const int SPRITE_DATA_11 = SPRITE_DATA_01 | SPRITE_DATA_10; + const int SPRITE_DATA_OUTPUT_MASK = SPRITE_DATA_11; + sealed class Sprite { + public bool CrunchMC; + public bool CrunchX; + public bool CrunchY; + public bool Display; + public int ShiftRegister; + public bool ShiftRegisterEnable; + public int Color; public bool DataCollision; public bool Enabled; @@ -37,5 +50,76 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals } } + Sprite s_CollideSprite; + int s_Data; + bool s_OutData; + int s_OutPixel; + bool s_Priority; + Sprite[] sprites; + + void RenderSprites() + { + s_OutData = false; + s_CollideSprite = null; + + foreach (Sprite sprite in sprites) + { + if (sprite.Display && rasterX == sprite.X) + sprite.ShiftRegisterEnable = true; + + if (sprite.ShiftRegisterEnable) + { + if (sprite.ShiftRegister == 0) + { + sprite.ShiftRegisterEnable = false; + sprite.CrunchMC = true; + sprite.CrunchX = true; + } + else + { + sprite.CrunchX = !sprite.CrunchX || !sprite.ExpandX; + if (sprite.CrunchX) + sprite.CrunchMC = !sprite.CrunchMC || !sprite.Multicolor; + + if (sprite.Multicolor) + s_Data = sprite.ShiftRegister & SPRITE_DATA_11; + else + s_Data = (sprite.ShiftRegister << 1) & SPRITE_DATA_10; + + if (s_CollideSprite == null) + { + if (s_Data == SPRITE_DATA_10) + s_OutPixel = sprite.Color; + else if (s_Data == SPRITE_DATA_01) + s_OutPixel = spriteMultiColor[0]; + else if (s_Data == SPRITE_DATA_11) + s_OutPixel = spriteMultiColor[1]; + + if (s_Data != SPRITE_DATA_00) + { + s_CollideSprite = sprite; + s_OutData = true; + s_Priority = sprite.Priority; + } + } + else if (s_Data != SPRITE_DATA_00) + { + s_CollideSprite.SpriteCollision = true; + sprite.SpriteCollision = true; + spriteCollisionInterrupt = true; + } + + if (s_Data != SPRITE_DATA_00 && g_OutData >= GRAPHICS_DATA_10) + { + sprite.DataCollision = true; + dataCollisionInterrupt = true; + } + + if (sprite.CrunchMC && sprite.CrunchX) + sprite.ShiftRegister <<= sprite.Multicolor ? 2 : 1; + } + } + } + } } } diff --git a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Synth.cs b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Synth.cs index 221917fa96..162d344177 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Synth.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Synth.cs @@ -7,5 +7,24 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals { sealed public partial class Vic { + int v_Pixel; + + public void Render() + { + RenderGraphics(); + RenderSprites(); + + if (s_OutData && (!s_Priority || g_OutData < GRAPHICS_DATA_10)) + { + if (s_Priority && g_OutData < GRAPHICS_DATA_10) + v_Pixel = s_OutPixel; + else + v_Pixel = g_OutPixel; + } + else + { + v_Pixel = g_OutPixel; + } + } } }