diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs index 298bcebb88..d104ac0ec1 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs @@ -301,7 +301,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS // underflow? if (u) { - //timerDelay[index] = 2; + timerDelay[index] = 1; t = timerLatch[index]; if (timerRunMode[index] == RunMode.Oneshot) timerOn[index] = false; diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6567.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6567.cs index 6a827eeb5c..fdbb852026 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6567.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6567.cs @@ -6,12 +6,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS static public class MOS6567 { static int cycles = 65; - static int lines = 263; - static int vblankstart = 0x00D; - static int vblankend = 0x018; - static int hblankstart = 0x18C; - static int hblankend = 0x1F0; static int scanwidth = cycles * 8; + static int lines = 263; + static int vblankstart = 0x00D % lines; + static int vblankend = 0x018 % lines; + static int hblankoffset = 20; + static int hblankstart = (0x18C + hblankoffset) % scanwidth; + static int hblankend = (0x1F0 + hblankoffset) % scanwidth; static int[] timing = Vic.TimingBuilder_XRaster(0x19C, 0x200, scanwidth, 0x18C, 8); static int[] fetch = Vic.TimingBuilder_Fetch(timing, 0x174); diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6569.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6569.cs index 3ed96d82b3..80e2d10c19 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6569.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6569.cs @@ -6,12 +6,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS static public class MOS6569 { static int cycles = 63; - static int lines = 312; - static int vblankstart = 0x12C; - static int vblankend = 0x00F; - static int hblankstart = 0x17C; - static int hblankend = 0x1E0; static int scanwidth = cycles * 8; + static int lines = 312; + static int vblankstart = 0x12C % lines; + static int vblankend = 0x00F % lines; + static int hblankoffset = 20; + static int hblankstart = (0x17C + hblankoffset) % scanwidth; + static int hblankend = (0x1E0 + hblankoffset) % scanwidth; static int[] timing = Vic.TimingBuilder_XRaster(0x194, 0x1F8, scanwidth, -1, -1); static int[] fetch = Vic.TimingBuilder_Fetch(timing, 0x164); diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Parse.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Parse.cs index 6002ce5714..3d09fdee67 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Parse.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Parse.cs @@ -94,6 +94,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS if (extraColorMode) parseaddr &= 0x39FF; dataG = ReadMemory(parseaddr); + sr |= dataG << (7 - xScroll); if (!idle) { bufferG[vmli] = dataG; diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs index db5a9e1899..59bd6bab44 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs @@ -10,16 +10,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS int borderSR; int ecmPixel; int pixel; - int[] pixelBackgroundBuffer; - int pixelBackgroundBufferDelay; - int pixelBackgroundBufferIndex; - int[] pixelBuffer; - int pixelBufferDelay; - int pixelBufferIndex; int pixelData; int pixelOwner; int sprData; int sprPixel; + int srOutput = 0; + int srOutputMC = 0; + int hblankSR = 0; VicVideoMode videoMode; enum VicVideoMode : int @@ -44,10 +41,22 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS if (rasterX == hblankStart) hblank = true; } - renderEnabled = !hblank && !vblank; //bufRect.Contains(bufPoint); + 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 (borderCheckLEnable && (rasterX == borderL)) { if (rasterLine == borderB) @@ -58,32 +67,80 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS borderOnMain = false; } - if (borderCheckREnable && (rasterX == borderR)) - borderOnMain = true; - - // recall pixel from buffer - pixel = pixelBuffer[pixelBufferIndex]; - - // border doesn't work with the background buffer - borderSR <<= 1; - if (borderOnMain || borderOnVertical) - borderSR |= 1; - if ((borderSR & 0x100) != 0) - pixel = borderColor; - - // plot pixel if within viewing area - if (renderEnabled) + srOutput = sr & srMask2; + if ((bitmapColumn & 1) == 0) + srOutputMC = sr & srMask3; + switch (videoMode) { + case VicVideoMode.Mode000: + pixelData = srOutput; + pixel = (pixelData != 0) ? (displayC >> 8) : backgroundColor0; + break; + case VicVideoMode.Mode001: + if ((displayC & 0x800) != 0) + { + // multicolor 001 + pixelData = srOutputMC; - buf[bufOffset] = palette[pixel]; - bufOffset++; - if (bufOffset == bufLength) - bufOffset = 0; + if (pixelData == srMask0) + pixel = backgroundColor0; + else if (pixelData == srMask1) + pixel = backgroundColor1; + else if (pixelData == srMask2) + pixel = backgroundColor2; + else + pixel = (displayC & 0x700) >> 8; + } + else + { + // standard 001 + pixelData = srOutput; + pixel = (pixelData != 0) ? (displayC >> 8) : backgroundColor0; + } + break; + case VicVideoMode.Mode010: + pixelData = srOutput; + pixel = (pixelData != 0) ? (displayC >> 4) : (displayC); + break; + case VicVideoMode.Mode011: + pixelData = srOutputMC; + + if (pixelData == srMask0) + pixel = backgroundColor0; + else if (pixelData == srMask1) + pixel = (displayC >> 4); + else if (pixelData == srMask2) + pixel = displayC; + else + pixel = (displayC >> 8); + break; + case VicVideoMode.Mode100: + pixelData = srOutput; + 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; } - - // put the pixel from the background buffer into the main buffer - pixel = pixelBackgroundBuffer[pixelBackgroundBufferIndex]; - + pixel &= 0xF; + sr <<= 1; + // render sprite pixelOwner = 8; for (int j = 0; j < 8; j++) @@ -125,7 +182,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS // sprite-sprite collision if (pixelOwner >= 8) { - if (!spr.priority || (pixelDataBuffer[pixelBackgroundBufferIndex] < 0x80)) + if (!spr.priority || ((sr & srMask) == 0)) pixel = sprPixel; pixelOwner = j; } @@ -139,7 +196,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS } // sprite-data collision - if (!borderOnVertical && (pixelDataBuffer[pixelBackgroundBufferIndex] == 0x80)) + if (!borderOnVertical && ((sr & srMask) != 0)) { spr.collideData = true; } @@ -149,113 +206,31 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS } } - // store pixel in buffer - pixelBuffer[pixelBufferIndex] = pixel; + if (borderCheckREnable && (rasterX == borderR)) + borderOnMain = true; - // fill shift register - if (xOffset == xScroll) + // border doesn't work with the background buffer + if (borderOnMain || borderOnVertical) + pixel = borderColor; + + // plot pixel if within viewing area + if (renderEnabled) { - if (displayIndex < 40 && !idle) - { - displayC = bufferC[displayIndex]; - sr |= bufferG[displayIndex]; - } - bitmapColumn = 0; + buf[bufOffset] = palette[pixBuffer[pixBufferIndex]]; + bufOffset++; + if (bufOffset == bufLength) + bufOffset = 0; } + pixBuffer[pixBufferIndex] = pixel; + pixBufferIndex++; - switch (videoMode) - { - 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; - } - - // 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++; + if (!rasterXHold) + rasterX++; bitmapColumn++; } + + if (pixBufferIndex >= pixBufferSize) + pixBufferIndex = 0; } } } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.State.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.State.cs index 9eb7a1d135..857dc3ec11 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.State.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.State.cs @@ -34,8 +34,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS int dataC; int dataG; bool debugScreen; + int delayedC; bool displayEnable; - int displayIndex; int displayC; bool enableIntLightPen; bool enableIntRaster; @@ -59,7 +59,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS bool pinAEC = true; bool pinBA = true; bool pinIRQ = true; - int[] pixelDataBuffer; + //int[] pixelDataBuffer; int pointerCB; int pointerVM; int rasterInterruptLine; @@ -74,13 +74,19 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS int spriteMulticolor1; Sprite[] sprites; int sr; + int srMask; + int srMask0; + int srMask1; + int srMask2; + int srMask3; + int srMaskMC; bool vblank; int vblankEnd; int vblankStart; int vc; int vcbase; int vmli; - int xOffset; + //int xOffset; int xScroll; int yScroll; @@ -107,7 +113,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS borderOnVertical = true; columnSelect = false; displayEnable = false; - displayIndex = 0; enableIntLightPen = false; enableIntRaster = false; enableIntSpriteCollision = false; @@ -123,8 +128,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS lightPenX = 0; lightPenY = 0; multicolorMode = false; - pixelBufferIndex = 0; - pixelBackgroundBufferIndex = 0; + //pixelBufferIndex = 0; + //pixelBackgroundBufferIndex = 0; pointerCB = 0; pointerVM = 0; rasterInterruptLine = 0; @@ -136,11 +141,17 @@ 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; vmli = 0; - xOffset = 0; + //xOffset = 0; xScroll = 0; yScroll = 0; @@ -156,13 +167,15 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS } // clear pixel buffer - for (int i = 0; i < pixelBufferDelay; i++) - { - pixelBuffer[i] = 0; - pixelDataBuffer[i] = 0; - } - for (int i = 0; i < pixelBackgroundBufferDelay; i++) - pixelBackgroundBuffer[i] = 0; + //for (int i = 0; i < pixelBufferDelay; i++) + //{ + // pixelBuffer[i] = 0; + // pixelDataBuffer[i] = 0; + //} + //for (int i = 0; i < pixelBackgroundBufferDelay; i++) + // pixelBackgroundBuffer[i] = 0; + + pixBuffer = new int[pixBufferSize]; UpdateBorder(); } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.VideoProvider.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.VideoProvider.cs index 74b1b34dfa..0d8c79e61b 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.VideoProvider.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.VideoProvider.cs @@ -9,6 +9,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS int bufLength; int bufOffset; int bufWidth; + int pixBufferSize = 12; + int[] pixBuffer; + int pixBufferIndex; // palette int[] palette = diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs index e6473cd411..8393487a1c 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs @@ -20,7 +20,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS public Vic(int newCycles, int newLines, int[][] newPipeline, int newCyclesPerSec, int hblankStart, int hblankEnd, int vblankStart, int vblankEnd) { - { + { debugScreen = false; this.hblankStart = hblankStart; @@ -32,8 +32,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS totalLines = newLines; pipeline = newPipeline; cyclesPerSec = newCyclesPerSec; - pixelBufferDelay = 12; - pixelBackgroundBufferDelay = 4; + //pixelBufferDelay = 4; + //pixelBackgroundBufferDelay = 12; bufWidth = TimingBuilder_ScreenWidth(pipeline[0], hblankStart, hblankEnd); bufHeight = TimingBuilder_ScreenHeight(vblankStart, vblankEnd, newLines); @@ -47,9 +47,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS bufferC = new int[40]; bufferG = new int[40]; - pixelBuffer = new int[pixelBufferDelay]; - pixelDataBuffer = new int[pixelBufferDelay]; - pixelBackgroundBuffer = new int[pixelBackgroundBufferDelay]; + //pixelBuffer = new int[pixelBufferDelay]; + //pixelDataBuffer = new int[pixelBufferDelay]; + //pixelBackgroundBuffer = new int[pixelBackgroundBufferDelay]; } } @@ -71,7 +71,8 @@ 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)) @@ -88,9 +89,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS // badline compare if (badlineEnable && rasterLine >= 0x030 && rasterLine < 0x0F7 && ((rasterLine & 0x7) == yScroll)) + { badline = true; + } else + { badline = false; + } // go into display state on a badline if (badline) @@ -106,15 +111,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS if (!sprites[6].yExpand) sprites[6].yCrunch = true; if (!sprites[7].yExpand) sprites[7].yCrunch = true; - // set up display index for rendering - if (cycle == 15) - displayIndex = 0; - else if (cycle > 15 && cycle <= 55) - displayIndex++; - ParseCycle(); - xOffset = 0; + //xOffset = 0; Render(); // if the BA counter is nonzero, allow CPU bus access @@ -197,7 +196,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS irqShift <<= 1; irqShift |= (irqTemp ? 0x1 : 0x0); - pinIRQ = (irqShift & 0x2) != 0; + pinIRQ = (irqShift & 0x1) != 0; } private void UpdateVideoMode()