Commodore64: Rewrote the character graphics generator as a shift register like real equipment. Roughly 10% performance increase and looks great. Sprites need work yet.
This commit is contained in:
parent
cfd3f05f1e
commit
c0bad5eccb
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue