diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs
index 7e33d1eae8..c2aa36b04b 100644
--- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs
+++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs
@@ -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)
 				{
diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs
index 8636bf799d..b1f2b12b38 100644
--- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs
+++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs
@@ -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)
diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.State.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.State.cs
index aa6976c443..adda9d09ae 100644
--- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.State.cs
+++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.State.cs
@@ -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();
diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs
index 621a0ea59b..fa0a8ec95c 100644
--- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs
+++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs
@@ -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()