diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index 3bd0deadd4..b55814f577 100644 --- a/BizHawk.Emulation/BizHawk.Emulation.csproj +++ b/BizHawk.Emulation/BizHawk.Emulation.csproj @@ -163,6 +163,7 @@ + diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.Motherboard.cs b/BizHawk.Emulation/Computers/Commodore64/C64.Motherboard.cs index 7dfc802882..59f4a33d18 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.Motherboard.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.Motherboard.cs @@ -51,8 +51,8 @@ namespace BizHawk.Emulation.Computers.Commodore64 sid = new MOS6581(44100, initRegion); switch (initRegion) { - case Region.NTSC: vic = new MOS6567(); break; - case Region.PAL: vic = new MOS6569(); break; + case Region.NTSC: vic = MOS6567.Create(); break; + case Region.PAL: vic = MOS6569.Create(); break; } userPort = new UserPort(); } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6567.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6567.cs index 39feeada28..d0e0ad4367 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6567.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6567.cs @@ -1,13 +1,12 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS { // vic ntsc - public class MOS6567 : Vic + static public class MOS6567 { - static protected int[][] pipeline = new int[5][]; - - public MOS6567() - : base(65, 263, pipeline, 14318181 / 14) - { - } + static int[][] pipeline = new int[5][]; + static public Vic Create() + { + return new Vic(65, 263, pipeline, 14318181 / 14); + } } } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6569.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6569.cs index e648fe349f..acb32630f3 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6569.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6569.cs @@ -1,244 +1,17 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS { // vic pal - public class MOS6569 : Vic + public class MOS6569 { - static protected int[][] pipeline = new int[][] - { - new int[] // xposition - { - 0x0194, 0x0198, - 0x019C, 0x01A0, - 0x01A4, 0x01A8, - 0x01AC, 0x01B0, - 0x01B4, 0x01B8, + static int[] timing = Vic.TimingBuilder_XRaster(0x194, 0x1F8, 0x1F8, -1, -1); + static int[] fetch = Vic.TimingBuilder_Fetch(timing, 0x164); + static int[] ba = Vic.TimingBuilder_BA(fetch); - 0x01BC, 0x01C0, - 0x01C4, 0x01C8, - 0x01CC, 0x01D0, - 0x01D4, 0x01D8, - 0x01DC, 0x01E0, - - 0x01E4, 0x01E8, - 0x01EC, 0x01F0, - 0x01F4, 0x0000, - 0x0004, 0x0008, - 0x000C, 0x0010, - - 0x0014, 0x0018, - 0x001C, 0x0020, - 0x0024, 0x0028, - 0x002C, 0x0030, - 0x0034, 0x0038, - - 0x003C, 0x0040, - 0x0044, 0x0048, - 0x004C, 0x0050, - 0x0054, 0x0058, - 0x005C, 0x0060, - - 0x0064, 0x0068, - 0x006C, 0x0070, - 0x0074, 0x0078, - 0x007C, 0x0080, - 0x0084, 0x0088, - - 0x008C, 0x0090, - 0x0094, 0x0098, - 0x009C, 0x00A0, - 0x00A4, 0x00A8, - 0x00AC, 0x00B0, - - 0x00B4, 0x00B8, - 0x00BC, 0x00C0, - 0x00C4, 0x00C8, - 0x00CC, 0x00D0, - 0x00D4, 0x00D8, - - 0x00DC, 0x00E0, - 0x00E4, 0x00E8, - 0x00EC, 0x00F0, - 0x00F4, 0x00F8, - 0x00FC, 0x0100, - - 0x0104, 0x0108, - 0x010C, 0x0110, - 0x0114, 0x0118, - 0x011C, 0x0120, - 0x0124, 0x0128, - - 0x012C, 0x0130, - 0x0134, 0x0138, - 0x013C, 0x0140, - 0x0144, 0x0148, - 0x014C, 0x0150, - - 0x0154, 0x0158, - 0x015C, 0x0160, - 0x0164, 0x0168, - 0x016C, 0x0170, - 0x0174, 0x0178, - - 0x017C, 0x0180, - 0x0184, 0x0188, - 0x018C, 0x0190 - }, - new int[] // fetch (100=ref 200=c 300=g 400=i 500=none) - { - 0x0003, 0x0013, - 0x0023, 0x0033, - 0x0004, 0x0014, - 0x0024, 0x0034, - 0x0005, 0x0015, - - 0x0025, 0x0035, - 0x0006, 0x0016, - 0x0026, 0x0036, - 0x0007, 0x0017, - 0x0027, 0x0037, - - 0x0100, 0x0500, - 0x0100, 0x0500, - 0x0100, 0x0500, - 0x0100, 0x0500, - 0x0100, 0x0200, - - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0200, - 0x0300, 0x0500, - - 0x0400, 0x0500, - 0x0400, 0x0500, - 0x0000, 0x0010, - 0x0020, 0x0030, - 0x0001, 0x0011, - - 0x0021, 0x0031, - 0x0002, 0x0012, - 0x0022, 0x0032 - }, - new int[] // BA - { - 0x0843, 0x0843, - 0x0543, 0x0543, - 0x0548, 0x0548, - 0x0546, 0x0546, - 0x0586, 0x0586, - - 0x0576, 0x0576, - 0x0876, 0x0876, - 0x0876, 0x0876, - 0x0878, 0x0878, - 0x0878, 0x0878, - - 0x0000, 0x0000, - 0x1000, 0x1000, // 12: badline ba start - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, // 15: badline start - - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x1000, 0x1000, - 0x0880, 0x0880, // 55: sprites - - 0x0880, 0x0880, - 0x0810, 0x0810, - 0x0810, 0x0810, - 0x0210, 0x0210, - 0x0218, 0x0218, - - 0x0213, 0x0213, - 0x0283, 0x0283, - 0x0243, 0x0243 - }, + static int[][] pipeline = new int[][] + { + timing, + fetch, + ba, new int[] // actions { 0, 0, @@ -256,12 +29,12 @@ 0, 0, 0, 0, 0, 0, - 0, pipelineUpdateVc, - 0, pipelineChkSprChunch, + 0, Vic.pipelineUpdateVc, + 0, Vic.pipelineChkSprChunch, - 0, pipelineUpdateMcBase, - 0, pipelineChkBrdL1, - 0, pipelineChkBrdL0, + 0, Vic.pipelineUpdateMcBase, + 0, Vic.pipelineChkBrdL1, + 0, Vic.pipelineChkBrdL0, 0, 0, 0, 0, @@ -305,11 +78,11 @@ 0, 0, 0, 0, 0, 0, - pipelineChkSprDma, 0, + Vic.pipelineChkSprDma, 0, - pipelineChkSprDma, pipelineChkBrdR0 | pipelineChkSprExp, - 0, pipelineChkBrdR1, - pipelineChkSprDisp, pipelineUpdateRc, + Vic.pipelineChkSprDma, Vic.pipelineChkBrdR0 | Vic.pipelineChkSprExp, + 0, Vic.pipelineChkBrdR1, + Vic.pipelineChkSprDisp, Vic.pipelineUpdateRc, 0, 0, 0, 0, @@ -319,9 +92,9 @@ } }; - public MOS6569() - : base(63, 312, pipeline, 17734472 / 18) - { - } + static public Vic Create() + { + return new Vic(63, 312, pipeline, 17734472 / 18); + } } } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Parse.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Parse.cs index c5d4268fae..2cbf87ddfd 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Parse.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Parse.cs @@ -5,22 +5,22 @@ using System.Text; namespace BizHawk.Emulation.Computers.Commodore64.MOS { - public abstract partial class Vic + sealed public partial class Vic { - protected const int baResetCounter = 6; - protected const int pipelineUpdateVc = 1; - protected const int pipelineChkSprChunch = 2; - protected const int pipelineUpdateMcBase = 4; - protected const int pipelineChkBrdL1 = 8; - protected const int pipelineChkBrdL0 = 16; - protected const int pipelineChkSprDma = 32; - protected const int pipelineChkBrdR0 = 64; - protected const int pipelineChkSprExp = 128; - protected const int pipelineChkBrdR1 = 256; - protected const int pipelineChkSprDisp = 512; - protected const int pipelineUpdateRc = 1024; - protected const int rasterIrqLine0Cycle = 1; - protected const int rasterIrqLineXCycle = 0; + public const int baResetCounter = 6; + public const int pipelineUpdateVc = 1; + public const int pipelineChkSprChunch = 2; + public const int pipelineUpdateMcBase = 4; + public const int pipelineChkBrdL1 = 8; + public const int pipelineChkBrdL0 = 16; + public const int pipelineChkSprDma = 32; + public const int pipelineChkBrdR0 = 64; + public const int pipelineChkSprExp = 128; + public const int pipelineChkBrdR1 = 256; + public const int pipelineChkSprDisp = 512; + public const int pipelineUpdateRc = 1024; + public const int rasterIrqLine0Cycle = 1; + public const int rasterIrqLineXCycle = 0; protected int parseaddr; protected int parsecycleBAsprite0; diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Registers.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Registers.cs index 5b448d48bb..3625be0f54 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Registers.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Registers.cs @@ -5,7 +5,7 @@ using System.Text; namespace BizHawk.Emulation.Computers.Commodore64.MOS { - public abstract partial class Vic + sealed public partial class Vic { public byte Peek(int addr) diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs index a57d76211c..f86487a08e 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs @@ -5,7 +5,7 @@ using System.Text; namespace BizHawk.Emulation.Computers.Commodore64.MOS { - public abstract partial class Vic + sealed public partial class Vic { protected int ecmPixel; protected int pixel; @@ -33,222 +33,138 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS private void Render() { + renderEnabled = bufRect.Contains(bufPoint); + for (int i = 0; i < 4; i++) { - renderEnabled = bufRect.Contains(bufPoint); - - for (int i = 0; i < 4; i++) + if (borderCheckLEnable && rasterX == borderL) { - if (borderCheckLEnable && rasterX == borderL) + if (rasterLine == borderB) + borderOnVertical = true; + if (rasterLine == borderT && displayEnable) + borderOnVertical = false; + if (!borderOnVertical) + borderOnMain = false; + } + if (borderCheckREnable && rasterX == borderR) + { + borderOnMain = true; + } + + // recall pixel from buffer + pixel = pixelBuffer[pixelBufferIndex]; + + // plot pixel if within viewing area + if (renderEnabled) + { + buf[bufOffset] = palette[pixel]; + bufOffset++; + if (bufOffset == bufLength) + bufOffset = 0; + } + bufPoint.X++; + if (bufPoint.X == bufWidth) + { + bufPoint.X = 0; + bufPoint.Y++; + if (bufPoint.Y == bufHeight) + bufPoint.Y = 0; + } + + // put the pixel from the background buffer into the main buffer + pixel = pixelBackgroundBuffer[pixelBackgroundBufferIndex]; + + // render sprite + pixelOwner = 8; + for (int j = 0; j < 8; j++) + { + sprData = 0; + sprPixel = pixel; + + Sprite spr = sprites[j]; + + if (spr.x == rasterX) + spr.shiftEnable = true; + + if (spr.shiftEnable) { - if (rasterLine == borderB) - borderOnVertical = true; - if (rasterLine == borderT && displayEnable) - borderOnVertical = false; - if (!borderOnVertical) - borderOnMain = false; - } - if (borderCheckREnable && rasterX == borderR) - { - borderOnMain = true; - } - - // recall pixel from buffer - pixel = pixelBuffer[pixelBufferIndex]; - - // plot pixel if within viewing area - if (renderEnabled) - { - buf[bufOffset] = palette[pixel]; - bufOffset++; - if (bufOffset == bufLength) - bufOffset = 0; - } - bufPoint.X++; - if (bufPoint.X == bufWidth) - { - bufPoint.X = 0; - bufPoint.Y++; - if (bufPoint.Y == bufHeight) - bufPoint.Y = 0; - } - - // put the pixel from the background buffer into the main buffer - pixel = pixelBackgroundBuffer[pixelBackgroundBufferIndex]; - - // render sprite - pixelOwner = 8; - for (int j = 0; j < 8; j++) - { - sprData = 0; - sprPixel = pixel; - - Sprite spr = sprites[j]; - - if (spr.x == rasterX) - spr.shiftEnable = true; - - if (spr.shiftEnable) + if (spr.multicolor) { - if (spr.multicolor) - { - sprData = (spr.sr & 0xC00000); - if (spr.multicolorCrunch && spr.xCrunch) - spr.sr <<= 2; - spr.multicolorCrunch ^= spr.xCrunch; - } - else - { - sprData = (spr.sr & 0x800000); - if (spr.xCrunch) - spr.sr <<= 1; - } - spr.xCrunch ^= spr.xExpand; - - 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 (!spr.priority || (pixelDataBuffer[pixelBackgroundBufferIndex] < 0x2)) - pixel = sprPixel; - pixelOwner = j; - } - else - { - if (!borderOnVertical) - { - spr.collideSprite = true; - sprites[pixelOwner].collideSprite = true; - } - } - - // sprite-data collision - if (!borderOnVertical && (pixelDataBuffer[pixelBackgroundBufferIndex] == 0x80)) - { - spr.collideData = true; - } - } - if (spr.sr == 0) - spr.shiftEnable = false; //optimization + sprData = (spr.sr & 0xC00000); + if (spr.multicolorCrunch && spr.xCrunch) + spr.sr <<= 2; + spr.multicolorCrunch ^= spr.xCrunch; } - } - - // border doesn't work with the background buffer - if (borderOnMain || borderOnVertical) - pixel = borderColor; - - // store pixel in buffer - pixelBuffer[pixelBufferIndex] = pixel; - - // fill shift register - if (xOffset == xScroll) - { - if (displayIndex < 40 && !idle) + else { - displayC = bufferC[displayIndex]; - sr |= bufferG[displayIndex]; + sprData = (spr.sr & 0x800000); + if (spr.xCrunch) + spr.sr <<= 1; } - bitmapColumn = 0; + spr.xCrunch ^= spr.xExpand; + + 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 (!spr.priority || (pixelDataBuffer[pixelBackgroundBufferIndex] < 0x80)) + pixel = sprPixel; + pixelOwner = j; + } + else + { + if (!borderOnVertical) + { + spr.collideSprite = true; + sprites[pixelOwner].collideSprite = true; + } + } + + // sprite-data collision + if (!borderOnVertical && (pixelDataBuffer[pixelBackgroundBufferIndex] == 0x80)) + { + spr.collideData = true; + } + } + if (spr.sr == 0) + spr.shiftEnable = false; //optimization } + } -#if true - switch (videoMode) + // border doesn't work with the background buffer + if (borderOnMain || borderOnVertical) + pixel = borderColor; + + // store pixel in buffer + pixelBuffer[pixelBufferIndex] = pixel; + + // fill shift register + if (xOffset == xScroll) + { + if (displayIndex < 40 && !idle) { - case VicVideoMode.Mode000: - pixelData = (sr & 0x80); - sr <<= 1; - pixel = (pixelData != 0) ? displayC >> 8 : backgroundColor0; - break; - case VicVideoMode.Mode001: - if ((displayC & 0x800) != 0) - { - // multicolor 001 - pixelData = (sr & 0xC0); - if ((bitmapColumn & 1) != 0) - sr <<= 2; - - if (pixelData == 0x00) - pixel = backgroundColor0; - else if (pixelData == 0x40) - pixel = backgroundColor1; - else if (pixelData == 0x80) - pixel = backgroundColor2; - else - pixel = (displayC & 0x700) >> 8; - } - else - { - // standard 001 - pixelData = (sr & 0x80); - sr <<= 1; - pixel = (pixelData != 0) ? (displayC >> 8) : backgroundColor0; - } - break; - case VicVideoMode.Mode010: - pixelData = (sr & 0x80); - sr <<= 1; - pixel = (pixelData != 0) ? ((displayC >> 4) & 0xF) : (displayC & 0xF); - break; - case VicVideoMode.Mode011: - pixelData = (sr & 0xC0); - if ((bitmapColumn & 1) != 0) - sr <<= 2; - - if (pixelData == 0x00) - pixel = backgroundColor0; - else if (pixelData == 0x40) - pixel = (displayC >> 4) & 0xF; - else if (pixelData == 0x80) - pixel = displayC & 0xF; - else - pixel = (displayC >> 8) & 0xF; - break; - case VicVideoMode.Mode100: - pixelData = (sr & 0x80); - sr <<= 1; - if (pixelData != 0) - { - pixel = displayC >> 8; - } - else - { - ecmPixel = (displayC) & 0xC0; - if (ecmPixel == 0x00) - pixel = backgroundColor0; - else if (ecmPixel == 0x40) - pixel = backgroundColor1; - else if (ecmPixel == 0x80) - pixel = backgroundColor2; - else - pixel = backgroundColor3; - } - break; - default: - pixelData = 0; - pixel = 0; - break; + displayC = bufferC[displayIndex]; + sr |= bufferG[displayIndex]; } + bitmapColumn = 0; + } -#else - - if (!extraColorMode && !bitmapMode & !multicolorMode) - { - // 000 + switch (videoMode) + { + case VicVideoMode.Mode000: pixelData = (sr & 0x80); sr <<= 1; pixel = (pixelData != 0) ? displayC >> 8 : backgroundColor0; - } - else if (!extraColorMode && !bitmapMode & multicolorMode) - { - // 001 + break; + case VicVideoMode.Mode001: if ((displayC & 0x800) != 0) { // multicolor 001 @@ -272,33 +188,27 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS sr <<= 1; pixel = (pixelData != 0) ? (displayC >> 8) : backgroundColor0; } - } - else if (!extraColorMode && bitmapMode & !multicolorMode) - { - // 010 + break; + case VicVideoMode.Mode010: pixelData = (sr & 0x80); sr <<= 1; pixel = (pixelData != 0) ? ((displayC >> 4) & 0xF) : (displayC & 0xF); - } - else if (!extraColorMode && bitmapMode & multicolorMode) - { - // 011 + break; + case VicVideoMode.Mode011: pixelData = (sr & 0xC0); if ((bitmapColumn & 1) != 0) sr <<= 2; - if (pixelData == 0x00) + if (pixelData == 0x00) pixel = backgroundColor0; - else if (pixelData == 0x40) + else if (pixelData == 0x40) pixel = (displayC >> 4) & 0xF; - else if (pixelData == 0x80) + else if (pixelData == 0x80) pixel = displayC & 0xF; - else + else pixel = (displayC >> 8) & 0xF; - } - else if (extraColorMode && !bitmapMode & !multicolorMode) - { - // 100 + break; + case VicVideoMode.Mode100: pixelData = (sr & 0x80); sr <<= 1; if (pixelData != 0) @@ -317,44 +227,28 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS else pixel = backgroundColor3; } - } - else if (extraColorMode && !bitmapMode & multicolorMode) - { - // 101 + break; + default: pixelData = 0; pixel = 0; - } - else if (extraColorMode && bitmapMode & !multicolorMode) - { - // 110 - pixelData = 0; - pixel = 0; - } - else - { - // 111 - pixelData = 0; - pixel = 0; - } - -#endif - - // put the rendered pixel into the background buffer - pixelDataBuffer[pixelBackgroundBufferIndex] = pixelData; - pixelBackgroundBuffer[pixelBackgroundBufferIndex] = pixel; - pixelBackgroundBufferIndex++; - if (pixelBackgroundBufferIndex == pixelBackgroundBufferDelay) - pixelBackgroundBufferIndex = 0; - - // advance pixel buffer - pixelBufferIndex++; - if (pixelBufferIndex == pixelBufferDelay) - pixelBufferIndex = 0; - - rasterX++; - xOffset++; - bitmapColumn++; + break; } + + // put the rendered pixel into the background buffer + pixelDataBuffer[pixelBackgroundBufferIndex] = pixelData; + pixelBackgroundBuffer[pixelBackgroundBufferIndex] = pixel; + pixelBackgroundBufferIndex++; + if (pixelBackgroundBufferIndex == pixelBackgroundBufferDelay) + pixelBackgroundBufferIndex = 0; + + // advance pixel buffer + pixelBufferIndex++; + if (pixelBufferIndex == pixelBufferDelay) + pixelBufferIndex = 0; + + rasterX++; + xOffset++; + bitmapColumn++; } } } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Sprite.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Sprite.cs index e0c83332a6..55ef67e15b 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Sprite.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Sprite.cs @@ -5,7 +5,7 @@ using System.Text; namespace BizHawk.Emulation.Computers.Commodore64.MOS { - public abstract partial class Vic + sealed public partial class Vic { protected class Sprite { diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.State.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.State.cs index 33be190729..50b44c1f15 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.State.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.State.cs @@ -6,7 +6,7 @@ using System.Text; namespace BizHawk.Emulation.Computers.Commodore64.MOS { - public abstract partial class Vic + sealed public partial class Vic { protected int backgroundColor0; protected int backgroundColor1; diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.TimingBuilder.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.TimingBuilder.cs new file mode 100644 index 0000000000..0988084688 --- /dev/null +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.TimingBuilder.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BizHawk.Emulation.Computers.Commodore64.MOS +{ + sealed public partial class Vic + { + static public int[] TimingBuilder_BA(int[] fetch) + { + int baRestart = 7; + int bacounter = 0; + int start = 0; + int length = fetch.Length; + int[] result = new int[length]; + int[] spriteBA = new int[8]; + int charBA = 0; + + while (true) + { + if (fetch[start] == 0) + break; + start++; + } + + while (true) + { + if (fetch[start] == 0x200) + break; + start--; + } + + if (start < 0) + start += length; + int offset = start; + + while (true) + { + int ba = 0x0888; + + if (fetch[offset] == 0x200) + charBA = baRestart; + else if ((fetch[offset] & 0xFF00) == 0x0000) + spriteBA[fetch[offset] & 0x007] = baRestart; + + for (int i = 0; i < 8; i++) + { + if (spriteBA[i] > 0) + { + ba <<= 4; + ba |= i; + spriteBA[i]--; + } + } + ba &= 0x0FFF; + + if (charBA > 0) + { + ba = 0x1000; + charBA--; + } + + result[offset] = ba; + + offset--; + if (offset < 0) + offset += length; + + if (offset == start) + break; + } + + for (int i = 0; i < length; i += 2) + { + result[i] = result[i + 1]; + } + + return result; + } + + static public int[] TimingBuilder_Fetch(int[] timing, int sprite) + { + int length = timing.Length; + int[] result = new int[length]; + int offset; + int index = -1; + int refreshCounter = 0; + bool spriteActive = false; + int spriteIndex = 0; + int spritePhase = 0; + int charCounter = 0; + + for (int i = 0; i < length; i++) + { + result[i++] = 0x500; + result[i] = 0x100; + } + + while (true) + { + index++; + if (index >= length) + index -= length; + offset = timing[index]; + + if (charCounter > 0) + { + result[index] = (charCounter & 1) == 0 ? 0x200 : 0x300; + charCounter--; + if (charCounter == 0) + break; + } + + if (refreshCounter > 0) + { + result[index] = (refreshCounter & 1) == 0 ? 0x500 : 0x100; + refreshCounter--; + if (refreshCounter == 0) + charCounter = 80; + } + + if (offset == sprite) + { + spriteActive = true; + } + + if (spriteActive) + { + result[index] = (spriteIndex | (spritePhase << 4)); + spritePhase++; + if (spritePhase == 4) + { + spritePhase = 0; + spriteIndex++; + if (spriteIndex == 8) + { + spriteActive = false; + refreshCounter = 9; + } + } + } + } + + return result.ToArray(); + } + + static public int[] TimingBuilder_XRaster(int start, int width, int count, int delayOffset, int delayAmount) + { + List result = new List(); + int rasterX = start; + bool delayed = false; + count >>= 2; + + for (int i = 0; i < count; i++) + { + result.Add(rasterX); + + if (!delayed) + { + rasterX += 4; + if (rasterX >= width) + rasterX -= width; + } + else + { + delayAmount--; + if (delayAmount <= 0) + delayed = false; + continue; + } + + if (rasterX == delayOffset && delayAmount > 0) + delayed = true; + } + + return result.ToArray(); + } + } +} diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.VideoProvider.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.VideoProvider.cs index 0050b8c3b8..907da7e643 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.VideoProvider.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.VideoProvider.cs @@ -2,7 +2,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS { - public abstract partial class Vic : IVideoProvider + sealed public partial class Vic : IVideoProvider { protected int[] buf; protected int bufHeight; diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs index d97c08e836..320f858758 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs @@ -3,7 +3,7 @@ using System.Drawing; namespace BizHawk.Emulation.Computers.Commodore64.MOS { - public abstract partial class Vic + sealed public partial class Vic { public Func ReadColorRam; public Func ReadMemory;