VIC: More accurate pixel pipeline
This commit is contained in:
parent
3efea15038
commit
9f733d3e7a
|
@ -42,6 +42,10 @@
|
|||
private int _parseBa;
|
||||
private int _parseAct;
|
||||
private bool _parseIsSprCrunch;
|
||||
private int _parsePixelData;
|
||||
private int _parsePixelDataIndex;
|
||||
private int _parseSrData0;
|
||||
private int _parseSrData1;
|
||||
|
||||
private void ParseCycle()
|
||||
{
|
||||
|
@ -80,8 +84,6 @@
|
|||
_dataC = 0;
|
||||
_bufferC[_vmli] = _dataC;
|
||||
}
|
||||
|
||||
_srColorSync |= 0x01 << (7 - _xScroll);
|
||||
break;
|
||||
case FetchTypeGraphics:
|
||||
// fetch G
|
||||
|
@ -96,14 +98,114 @@
|
|||
if (_extraColorModeBuffer)
|
||||
_parseAddr &= AddressMaskEc;
|
||||
_dataG = ReadMemory(_parseAddr);
|
||||
_sr |= _dataG << (7 - _xScroll);
|
||||
_srSync |= 0xAA << (7 - _xScroll);
|
||||
|
||||
if (!_idle)
|
||||
{
|
||||
_bufferG[_vmli] = _dataG;
|
||||
_vmli = (_vmli + 1) & 0x3F;
|
||||
_vc = (_vc + 1) & 0x3FF;
|
||||
}
|
||||
|
||||
// graphics data shift register
|
||||
_srData1 &= ~(0xFF << (7 - _xScroll));
|
||||
_srActive |= 0xFF << (7 - _xScroll);
|
||||
|
||||
if (_multicolorMode && (_bitmapMode || (_dataC & 0x800) != 0))
|
||||
{
|
||||
_parseSrData0 = (_dataG & 0x55) | ((_dataG & 0x55) << 1);
|
||||
_parseSrData1 = (_dataG & 0xAA) | ((_dataG & 0xAA) >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_parseSrData0 = _bitmapMode ? 0 : _dataG;
|
||||
_parseSrData1 = _dataG;
|
||||
}
|
||||
_srData1 |= _parseSrData1 << (7 - _xScroll);
|
||||
|
||||
// graphics color shift register
|
||||
_srColor0 &= ~(0xFF << (7 - _xScroll));
|
||||
_srColor1 &= ~(0xFF << (7 - _xScroll));
|
||||
_srColor2 &= ~(0xFF << (7 - _xScroll));
|
||||
_srColor3 &= ~(0xFF << (7 - _xScroll));
|
||||
for (_parsePixelDataIndex = 7; _parsePixelDataIndex >= 0; _parsePixelDataIndex--)
|
||||
{
|
||||
_parsePixelData = ((_parseSrData0 & 0x80) >> 7) | ((_parseSrData1 & 0x80) >> 6);
|
||||
switch (_videoMode)
|
||||
{
|
||||
case VideoMode000:
|
||||
case VideoMode001:
|
||||
switch (_parsePixelData)
|
||||
{
|
||||
case 0:
|
||||
_pixel = _backgroundColor0;
|
||||
break;
|
||||
case 1:
|
||||
_pixel = _idle ? 0 : _backgroundColor1;
|
||||
break;
|
||||
case 2:
|
||||
_pixel = _idle ? 0 :_backgroundColor2;
|
||||
break;
|
||||
default:
|
||||
_pixel = _idle ? 0 : (_multicolorMode ? _dataC & 0x700 : _dataC) >> 8;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VideoMode010:
|
||||
case VideoMode011:
|
||||
switch (_parsePixelData)
|
||||
{
|
||||
case 0:
|
||||
_pixel = _backgroundColor0;
|
||||
break;
|
||||
case 1:
|
||||
_pixel = _idle ? 0 : _dataC >> 4;
|
||||
break;
|
||||
case 2:
|
||||
_pixel = _idle ? 0 : _dataC;
|
||||
break;
|
||||
default:
|
||||
_pixel = _idle ? 0 : _dataC >> 8;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VideoMode100:
|
||||
if (_parsePixelData != 0)
|
||||
{
|
||||
_pixel = _idle ? 0 : _dataC >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pixel = (_dataC & 0xC0) >> 6;
|
||||
switch (_pixel)
|
||||
{
|
||||
case 0:
|
||||
_pixel = _backgroundColor0;
|
||||
break;
|
||||
case 1:
|
||||
_pixel = _idle ? 0 : _backgroundColor1;
|
||||
break;
|
||||
case 2:
|
||||
_pixel = _idle ? 0 : _backgroundColor2;
|
||||
break;
|
||||
default:
|
||||
_pixel = _idle ? 0 : _backgroundColor3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_parsePixelData = 0;
|
||||
_pixel = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
_parseSrData0 <<= 1;
|
||||
_parseSrData1 <<= 1;
|
||||
_srColor0 |= (_pixel & 1) << (7 - _xScroll + _parsePixelDataIndex);
|
||||
_srColor1 |= ((_pixel >> 1) & 1) << (7 - _xScroll + _parsePixelDataIndex);
|
||||
_srColor2 |= ((_pixel >> 2) & 1) << (7 - _xScroll + _parsePixelDataIndex);
|
||||
_srColor3 |= ((_pixel >> 3) & 1) << (7 - _xScroll + _parsePixelDataIndex);
|
||||
}
|
||||
|
||||
break;
|
||||
case FetchTypeNone:
|
||||
// fetch none
|
||||
|
@ -221,7 +323,6 @@
|
|||
if ((_parseAct & PipelineUpdateVc) != 0) // VC/RC rule 2
|
||||
{
|
||||
_vc = _vcbase;
|
||||
_srColorIndexLatch = 0;
|
||||
_vmli = 0;
|
||||
if (_badline)
|
||||
{
|
||||
|
|
|
@ -4,18 +4,19 @@
|
|||
{
|
||||
private int _borderPixel;
|
||||
private int _bufferPixel;
|
||||
private int _ecmPixel;
|
||||
private int _pixel;
|
||||
private int _pixelCounter;
|
||||
private int _pixelData;
|
||||
private int _pixelOwner;
|
||||
private Sprite _spr;
|
||||
private int _sprData;
|
||||
private int _sprIndex;
|
||||
private int _sprPixel;
|
||||
private int _srSync;
|
||||
private int _srColorSync;
|
||||
private int _srColorIndexLatch;
|
||||
private int _srColor0;
|
||||
private int _srColor1;
|
||||
private int _srColor2;
|
||||
private int _srColor3;
|
||||
private int _srData1;
|
||||
private int _srActive;
|
||||
private int _videoMode;
|
||||
private int _borderOnShiftReg;
|
||||
|
||||
|
@ -26,10 +27,7 @@
|
|||
private const int VideoMode100 = 4;
|
||||
private const int VideoModeInvalid = -1;
|
||||
|
||||
private const int SrMask1 = 0x20000;
|
||||
private const int SrMask2 = SrMask1 << 1;
|
||||
private const int SrMask3 = SrMask1 | SrMask2;
|
||||
private const int SrColorMask = 0x8000;
|
||||
private const int SrMask1 = 0x40000;
|
||||
private const int SrSpriteMask = SrSpriteMask2;
|
||||
private const int SrSpriteMask1 = 0x400000;
|
||||
private const int SrSpriteMask2 = SrSpriteMask1 << 1;
|
||||
|
@ -47,13 +45,6 @@
|
|||
_pixelCounter = 4;
|
||||
while (--_pixelCounter >= 0)
|
||||
{
|
||||
|
||||
if ((_srColorSync & SrColorMask) != 0)
|
||||
{
|
||||
_displayC = _bufferC[_srColorIndexLatch];
|
||||
_srColorIndexLatch = (_srColorIndexLatch + 1) & 0x3F;
|
||||
}
|
||||
|
||||
#region PRE-RENDER BORDER
|
||||
|
||||
// check left border
|
||||
|
@ -73,105 +64,14 @@
|
|||
|
||||
#endregion
|
||||
|
||||
#region CHARACTER GRAPHICS
|
||||
switch (_videoMode)
|
||||
{
|
||||
case VideoMode000:
|
||||
_pixelData = _sr & SrMask2;
|
||||
_pixel = _pixelData != 0 ? _displayC >> 8 : _backgroundColor0;
|
||||
break;
|
||||
case VideoMode001:
|
||||
if ((_displayC & 0x800) != 0)
|
||||
{
|
||||
// multicolor 001
|
||||
if ((_srSync & SrMask2) != 0)
|
||||
_pixelData = _sr & SrMask3;
|
||||
// render graphics
|
||||
_pixel = (_srActive & SrMask1) != 0
|
||||
? ((_srColor0 & SrMask1) >> 18) |
|
||||
((_srColor1 & SrMask1) >> 17) |
|
||||
((_srColor2 & SrMask1) >> 16) |
|
||||
((_srColor3 & SrMask1) >> 15)
|
||||
: _backgroundColor0;
|
||||
|
||||
switch (_pixelData)
|
||||
{
|
||||
case 0:
|
||||
_pixel = _backgroundColor0;
|
||||
break;
|
||||
case SrMask1:
|
||||
_pixel = _idle ? 0 : _backgroundColor1;
|
||||
break;
|
||||
case SrMask2:
|
||||
_pixel = _idle ? 0 :_backgroundColor2;
|
||||
break;
|
||||
default:
|
||||
_pixel = _idle ? 0 : (_displayC & 0x700) >> 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// standard 001
|
||||
_pixelData = _sr & SrMask2;
|
||||
_pixel = _pixelData != 0 ? (_idle ? 0 : _displayC >> 8) : _backgroundColor0;
|
||||
}
|
||||
break;
|
||||
case VideoMode010:
|
||||
_pixelData = _sr & SrMask2;
|
||||
_pixel = _idle ? 0 : _pixelData != 0 ? _displayC >> 4 : _displayC;
|
||||
break;
|
||||
case VideoMode011:
|
||||
if ((_srSync & SrMask2) != 0)
|
||||
_pixelData = _sr & SrMask3;
|
||||
|
||||
switch (_pixelData)
|
||||
{
|
||||
case 0:
|
||||
_pixel = _backgroundColor0;
|
||||
break;
|
||||
case SrMask1:
|
||||
_pixel = _idle ? 0 : _displayC >> 4;
|
||||
break;
|
||||
case SrMask2:
|
||||
_pixel = _idle ? 0 : _displayC;
|
||||
break;
|
||||
default:
|
||||
_pixel = _idle ? 0 : _displayC >> 8;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VideoMode100:
|
||||
_pixelData = _sr & SrMask2;
|
||||
if (_pixelData != 0)
|
||||
{
|
||||
_pixel = _idle ? 0 : _displayC >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ecmPixel = (_displayC & 0xC0) >> 6;
|
||||
switch (_ecmPixel)
|
||||
{
|
||||
case 0:
|
||||
_pixel = _backgroundColor0;
|
||||
break;
|
||||
case 1:
|
||||
_pixel = _idle ? 0 : _backgroundColor1;
|
||||
break;
|
||||
case 2:
|
||||
_pixel = _idle ? 0 : _backgroundColor2;
|
||||
break;
|
||||
default:
|
||||
_pixel = _idle ? 0 : _backgroundColor3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_pixelData = 0;
|
||||
_pixel = 0;
|
||||
break;
|
||||
}
|
||||
_pixel &= 0xF;
|
||||
_sr <<= 1;
|
||||
_srSync <<= 1;
|
||||
_srColorSync <<= 1;
|
||||
#endregion
|
||||
|
||||
#region SPRITES
|
||||
// render sprites
|
||||
_pixelOwner = -1;
|
||||
for (_sprIndex = 0; _sprIndex < 8; _sprIndex++)
|
||||
|
@ -252,7 +152,7 @@
|
|||
}
|
||||
|
||||
// sprite-data collision
|
||||
if (!_borderOnVertical && (_pixelData >= SrMask2))
|
||||
if (!_borderOnVertical && (_srData1 & SrMask1) != 0)
|
||||
{
|
||||
_spr.CollideData = true;
|
||||
_intSpriteDataCollision = true;
|
||||
|
@ -261,7 +161,7 @@
|
|||
// sprite priority logic
|
||||
if (_spr.Priority)
|
||||
{
|
||||
_pixel = _pixelData >= SrMask2 ? _pixel : _sprPixel;
|
||||
_pixel = (_srData1 & SrMask1) != 0 ? _pixel : _sprPixel;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -271,8 +171,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region POST-RENDER BORDER
|
||||
|
||||
// border doesn't work with the background buffer
|
||||
|
@ -298,6 +196,13 @@
|
|||
|
||||
if (!_rasterXHold)
|
||||
_rasterX++;
|
||||
|
||||
_srColor0 <<= 1;
|
||||
_srColor1 <<= 1;
|
||||
_srColor2 <<= 1;
|
||||
_srColor3 <<= 1;
|
||||
_srData1 <<= 1;
|
||||
_srActive <<= 1;
|
||||
}
|
||||
|
||||
if (_pixBufferBorderIndex >= PixBorderBufferSize)
|
||||
|
|
|
@ -22,14 +22,12 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
private int _borderR;
|
||||
private int _borderT;
|
||||
private int[] _bufferC;
|
||||
private int[] _bufferG;
|
||||
private int _cycle;
|
||||
private int _cycleIndex;
|
||||
private bool _columnSelect;
|
||||
private int _dataC;
|
||||
private int _dataG;
|
||||
private bool _displayEnable;
|
||||
private int _displayC;
|
||||
private bool _enableIntLightPen;
|
||||
private bool _enableIntRaster;
|
||||
private bool _enableIntSpriteCollision;
|
||||
|
@ -72,7 +70,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
private readonly Sprite _sprite6;
|
||||
private readonly Sprite _sprite7;
|
||||
private readonly Sprite[] _sprites;
|
||||
private int _sr;
|
||||
private bool _vblank;
|
||||
private int _vblankEnd;
|
||||
private int _vblankStart;
|
||||
|
@ -130,7 +127,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
_spriteSpriteCollisionClearPending = false;
|
||||
_spriteMulticolor0 = 0;
|
||||
_spriteMulticolor1 = 0;
|
||||
_sr = 0;
|
||||
_vc = 0;
|
||||
_vcbase = 0;
|
||||
_vmli = 0;
|
||||
|
@ -149,7 +145,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
for (var i = 0; i < 40; i++)
|
||||
{
|
||||
_bufferC[i] = 0;
|
||||
_bufferG[i] = 0;
|
||||
}
|
||||
|
||||
_pixBuffer = new int[PixBufferSize];
|
||||
|
@ -161,11 +156,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
ser.Sync(nameof(_cyclesExecuted), ref _cyclesExecuted);
|
||||
ser.Sync(nameof(_parseIsSprCrunch), ref _parseIsSprCrunch);
|
||||
ser.Sync(nameof(_srSync), ref _srSync);
|
||||
ser.Sync(nameof(_srColorSync), ref _srColorSync);
|
||||
ser.Sync(nameof(_srColorIndexLatch), ref _srColorIndexLatch);
|
||||
ser.Sync(nameof(_videoMode), ref _videoMode);
|
||||
ser.Sync(nameof(_borderOnShiftReg), ref _borderOnShiftReg);
|
||||
ser.Sync(nameof(_backgroundColor0), ref _backgroundColor0);
|
||||
|
@ -186,14 +177,12 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
ser.Sync(nameof(_borderR), ref _borderR);
|
||||
ser.Sync(nameof(_borderT), ref _borderT);
|
||||
ser.Sync(nameof(_bufferC), ref _bufferC, useNull: false);
|
||||
ser.Sync(nameof(_bufferG), ref _bufferG, useNull: false);
|
||||
ser.Sync(nameof(_cycle), ref _cycle);
|
||||
ser.Sync(nameof(_cycleIndex), ref _cycleIndex);
|
||||
ser.Sync(nameof(_columnSelect), ref _columnSelect);
|
||||
ser.Sync(nameof(_dataC), ref _dataC);
|
||||
ser.Sync(nameof(_dataG), ref _dataG);
|
||||
ser.Sync(nameof(_displayEnable), ref _displayEnable);
|
||||
ser.Sync(nameof(_displayC), ref _displayC);
|
||||
ser.Sync(nameof(_enableIntLightPen), ref _enableIntLightPen);
|
||||
ser.Sync(nameof(_enableIntRaster), ref _enableIntRaster);
|
||||
ser.Sync(nameof(_enableIntSpriteCollision), ref _enableIntSpriteCollision);
|
||||
|
@ -234,7 +223,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
ser.EndSection();
|
||||
}
|
||||
|
||||
ser.Sync(nameof(_sr), ref _sr);
|
||||
ser.Sync(nameof(_vc), ref _vc);
|
||||
ser.Sync(nameof(_vcbase), ref _vcbase);
|
||||
ser.Sync(nameof(_vmli), ref _vmli);
|
||||
|
@ -245,7 +233,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
ser.Sync(nameof(_pixBufferIndex), ref _pixBufferIndex);
|
||||
ser.Sync(nameof(_pixBorderBuffer), ref _pixBorderBuffer, useNull: false);
|
||||
ser.Sync(nameof(_pixBufferBorderIndex), ref _pixBufferBorderIndex);
|
||||
|
||||
|
||||
if (ser.IsReader)
|
||||
{
|
||||
UpdateBorder();
|
||||
|
|
|
@ -36,7 +36,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
private readonly int _totalCycles;
|
||||
private readonly int _totalLines;
|
||||
|
||||
private int _cyclesExecuted;
|
||||
private int _hblankStartCheckXRaster;
|
||||
private int _hblankEndCheckXRaster;
|
||||
|
||||
|
@ -81,7 +80,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
_sprite7 = _sprites[7];
|
||||
|
||||
_bufferC = new int[40];
|
||||
_bufferG = new int[40];
|
||||
}
|
||||
|
||||
private void ConfigureBlanking(int lines, int hblankStart, int hblankEnd, int vblankStart, int vblankEnd,
|
||||
|
@ -228,7 +226,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
_vc = 0;
|
||||
_badlineEnable = false;
|
||||
_refreshCounter = 0xFF;
|
||||
_cyclesExecuted = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,8 +324,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
|
||||
// must always come last
|
||||
UpdatePins();
|
||||
|
||||
_cyclesExecuted++;
|
||||
}
|
||||
|
||||
private void UpdateBorder()
|
||||
|
|
Loading…
Reference in New Issue