Commodore64: Fix sprites and tweaked timing, should now be pixel perfect with test intro "rem-17".

This commit is contained in:
saxxonpike 2013-08-25 07:58:25 +00:00
parent 4bd6103574
commit 3dc1e8dba2
6 changed files with 78 additions and 72 deletions

View File

@ -110,6 +110,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void ExecutePhase1()
{
// unsure if the timer actually operates in ph1
pinIRQ = !(
(intTimer[0] && enableIntTimer[0]) ||
(intTimer[1] && enableIntTimer[1]) ||
(intAlarm && enableIntAlarm) ||
(intSP && enableIntSP) ||
(intFlag && enableIntFlag)
);
}
public void ExecutePhase2()
@ -151,14 +158,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
cntPos = false;
underflow[0] = false;
underflow[1] = false;
pinIRQ = !(
(intTimer[0] && enableIntTimer[0]) ||
(intTimer[1] && enableIntTimer[1]) ||
(intAlarm && enableIntAlarm) ||
(intSP && enableIntSP) ||
(intFlag && enableIntFlag)
);
}
}

View File

@ -58,7 +58,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
}
else if (parsefetchType == 0x200)
{
// fetch C
delayC = xScroll;
if (!idle)
{
if (badline)
@ -78,6 +78,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
dataC = 0;
bufferC[vmli] = dataC;
}
srC <<= 12;
srC |= dataC;
}
else if (parsefetchType == 0x300)
{
@ -95,6 +97,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
parseaddr &= 0x39FF;
dataG = ReadMemory(parseaddr);
sr |= dataG << (7 - xScroll);
srSync |= 0xAA << (7 - xScroll);
if (!idle)
{
bufferG[vmli] = dataG;
@ -107,7 +110,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
// fetch I
parseaddr = (extraColorMode ? 0x39FF : 0x3FFF);
dataG = ReadMemory(parseaddr);
dataC = 0;
//dataC = 0;
}
else if (parsefetchType == 0x500)
{

View File

@ -7,16 +7,16 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
sealed public partial class Vic
{
int borderSR;
int delayC;
int ecmPixel;
int pixel;
int pixelData;
int pixelOwner;
//int pixelOwner;
Sprite pixelOwner;
int sprData;
int sprPixel;
int srOutput = 0;
int srOutputMC = 0;
int hblankSR = 0;
int srC = 0;
int srSync = 0;
VicVideoMode videoMode;
enum VicVideoMode : int
@ -45,17 +45,12 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
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 (delayC > 0)
delayC--;
else
displayC = (srC >> 12) & 0xFFF;
if (borderCheckLEnable && (rasterX == borderL))
{
@ -67,20 +62,18 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
borderOnMain = false;
}
srOutput = sr & srMask2;
if ((bitmapColumn & 1) == 0)
srOutputMC = sr & srMask3;
switch (videoMode)
{
case VicVideoMode.Mode000:
pixelData = srOutput;
pixelData = sr & srMask2;
pixel = (pixelData != 0) ? (displayC >> 8) : backgroundColor0;
break;
case VicVideoMode.Mode001:
if ((displayC & 0x800) != 0)
{
// multicolor 001
pixelData = srOutputMC;
if ((srSync & srMask2) != 0)
pixelData = sr & srMask3;
if (pixelData == srMask0)
pixel = backgroundColor0;
@ -94,16 +87,17 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
else
{
// standard 001
pixelData = srOutput;
pixelData = sr & srMask2;
pixel = (pixelData != 0) ? (displayC >> 8) : backgroundColor0;
}
break;
case VicVideoMode.Mode010:
pixelData = srOutput;
pixelData = sr & srMask2;
pixel = (pixelData != 0) ? (displayC >> 4) : (displayC);
break;
case VicVideoMode.Mode011:
pixelData = srOutputMC;
if ((srSync & srMask2) != 0)
pixelData = sr & srMask3;
if (pixelData == srMask0)
pixel = backgroundColor0;
@ -115,7 +109,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
pixel = (displayC >> 8);
break;
case VicVideoMode.Mode100:
pixelData = srOutput;
pixelData = sr & srMask2;
if (pixelData != 0)
{
pixel = displayC >> 8;
@ -140,16 +134,16 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
}
pixel &= 0xF;
sr <<= 1;
srSync <<= 1;
// render sprite
pixelOwner = 8;
for (int j = 0; j < 8; j++)
//pixelOwner = 8;
pixelOwner = null;
foreach (Sprite spr in sprites)
{
sprData = 0;
sprPixel = pixel;
Sprite spr = sprites[j];
if (spr.x == rasterX)
spr.shiftEnable = true;
@ -157,14 +151,14 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
if (spr.multicolor)
{
sprData = (spr.sr & 0xC00000);
sprData = (spr.sr & srSpriteMaskMC);
if (spr.multicolorCrunch && spr.xCrunch && !rasterXHold)
spr.sr <<= 2;
spr.multicolorCrunch ^= spr.xCrunch;
}
else
{
sprData = (spr.sr & 0x800000);
sprData = (spr.sr & srSpriteMask);
if (spr.xCrunch && !rasterXHold)
spr.sr <<= 1;
}
@ -172,31 +166,31 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
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 (pixelOwner == null)
{
if (!spr.priority || ((sr & srMask) == 0))
pixel = sprPixel;
pixelOwner = j;
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;
}
else
{
if (!borderOnVertical)
{
spr.collideSprite = true;
sprites[pixelOwner].collideSprite = true;
pixelOwner.collideSprite = true;
}
}
// sprite-data collision
if (!borderOnVertical && ((sr & srMask) != 0))
if (!borderOnVertical && (pixelData < srMask2))
{
spr.collideData = true;
}

View File

@ -80,6 +80,12 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
int srMask2;
int srMask3;
int srMaskMC;
int srSpriteMask;
int srSpriteMask0;
int srSpriteMask1;
int srSpriteMask2;
int srSpriteMask3;
int srSpriteMaskMC;
bool vblank;
int vblankEnd;
int vblankStart;
@ -92,6 +98,20 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void HardReset()
{
// *** SHIFT REGISTER BITMASKS ***
srMask0 = 0x00000;
srMask1 = 0x20000;
srMask2 = srMask1 << 1;
srMask3 = srMask1 | srMask2;
srMask = srMask2;
srMaskMC = srMask3;
srSpriteMask0 = 0x000000;
srSpriteMask1 = 0x400000;
srSpriteMask2 = srSpriteMask1 << 1;
srSpriteMask3 = srSpriteMask1 | srSpriteMask2;
srSpriteMask = srSpriteMask2;
srSpriteMaskMC = srSpriteMask3;
pinAEC = true;
pinBA = true;
pinIRQ = true;
@ -141,12 +161,6 @@ 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;

View File

@ -38,9 +38,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
else
result.Add(0);
}
bool hBlankL = false;
bool hBlankR = false;
for (int i = 0; i < length; i++)
{
// pipeline raster X delay
@ -48,13 +45,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
result[i] |= pipelineHoldX;
// pipeline border checks
if (timing[i] == 0x01C)
if (timing[i] == 0x018)
result[i] |= pipelineChkBrdL1;
if (timing[i] == 0x020)
if (timing[i] == 0x01C)
result[i] |= pipelineChkBrdL0;
if (timing[i] == 0x150)
if (timing[i] == 0x14C)
result[i] |= pipelineChkBrdR0;
if (timing[i] == 0x15C)
if (timing[i] == 0x158)
result[i] |= pipelineChkBrdR1;
if (timing[i] == (hblankStart & 0xFFD))
result[i] |= pipelineHBlankR;

View File

@ -72,7 +72,6 @@ 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))
@ -177,10 +176,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
{
//borderL = columnSelect ? 0x018 : 0x01F;
//borderR = columnSelect ? 0x158 : 0x14F;
borderL = columnSelect ? 28 : 35;
borderR = columnSelect ? 348 : 339;
borderL = columnSelect ? 0x018 : 0x01F;
borderR = columnSelect ? 0x158 : 0x14F;
//borderL = columnSelect ? 28 : 35;
//borderR = columnSelect ? 348 : 339;
borderT = rowSelect ? 0x033 : 0x037;
borderB = rowSelect ? 0x0FB : 0x0F7;
}