diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs index c534234acd..dc1fd28fbd 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs @@ -67,12 +67,7 @@ private int _parseBa; private int _parseAct; private bool _parseIsSprCrunch; - private int _parsePixelData; - private int _parsePixelDataIndex; - private int _parseSrData0; - private int _parseSrData1; private int _parseSrShift; - private bool _parseSrColorEnable; private void ParseCycle() { @@ -135,92 +130,7 @@ // graphics data shift register _parseSrShift = 7 - _xScroll; _srData1 &= ~(0xFF << _parseSrShift); - _srColorEnable &= ~(0xFF << _parseSrShift); - - if (_multicolorMode && (_bitmapMode || (_dataC & 0x800) != 0)) - { - _parseSrData0 = (_dataG & 0x55) | ((_dataG & 0x55) << 1); - _parseSrData1 = (_dataG & 0xAA) | ((_dataG & 0xAA) >> 1); - } - else - { - _parseSrData0 = _parseSrData1 = _dataG; - } - _srData1 |= _parseSrData1 << _parseSrShift; - - if (_bitmapMode && !_multicolorMode) - _parseSrData1 ^= 0xFF; - - // graphics color shift register - _srColor0 &= ~(0xFF << _parseSrShift); - _srColor1 &= ~(0xFF << _parseSrShift); - _srColor2 &= ~(0xFF << _parseSrShift); - _srColor3 &= ~(0xFF << _parseSrShift); - for (_parsePixelDataIndex = 7; _parsePixelDataIndex >= 0; _parsePixelDataIndex--) - { - _parsePixelData = ((_parseSrData0 & 0x80) >> 7) | ((_parseSrData1 & 0x80) >> 6); - switch (_videoMode) - { - case VideoMode000: - case VideoMode001: - if (_parsePixelData == 3) - { - _pixel = _idle ? 0 : (_multicolorMode ? _dataC & 0x700 : _dataC) >> 8; - _parseSrColorEnable = true; - } - else - { - _pixel = _parsePixelData; - _parseSrColorEnable = false; - } - break; - case VideoMode010: - case VideoMode011: - _parseSrColorEnable = _parsePixelData != 0; - switch (_parsePixelData) - { - case 0: - _pixel = 0; - 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; - _parseSrColorEnable = true; - } - else - { - _pixel = (_dataC & 0xC0) >> 6; - _parseSrColorEnable = false; - } - break; - default: - _parsePixelData = 0; - _pixel = 0; - _parseSrColorEnable = true; - break; - } - - _parseSrData0 <<= 1; - _parseSrData1 <<= 1; - _srColor0 |= (_pixel & 1) << (_parseSrShift + _parsePixelDataIndex); - _srColor1 |= ((_pixel >> 1) & 1) << (_parseSrShift + _parsePixelDataIndex); - _srColor2 |= ((_pixel >> 2) & 1) << (_parseSrShift + _parsePixelDataIndex); - _srColor3 |= ((_pixel >> 3) & 1) << (_parseSrShift + _parsePixelDataIndex); - _srColorEnable |= (_parseSrColorEnable ? 1 : 0) << (_parseSrShift + _parsePixelDataIndex); - } - + _srData1 |= _dataG << _parseSrShift; break; case FetchTypeNone: // fetch none diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs index 89a04518a5..3ee574365d 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs @@ -4,19 +4,20 @@ { private int _borderPixel; private int _bufferPixel; + private int _gfxData; + private bool _gfxSense; + private int _gfxJitter; + private bool _gfxMc; private int _pixel; private int _pixelCounter; - private int _pixelOwner; + private int _sprOwner; private Sprite _spr; private int _sprData; private int _sprIndex; private int _sprPixel; - private int _srColor0; - private int _srColor1; - private int _srColor2; - private int _srColor3; + private bool _sprSense; + private bool _sprPriority; private int _srData1; - private int _srColorEnable; private int _videoMode; private int _borderOnShiftReg; @@ -29,7 +30,7 @@ private const int SrMask0 = 0x4000000; private const int SrSpriteMask = SrSpriteMask2; - private const int SrSpriteMask1 = 0x40000000; + private const int SrSpriteMask1 = 0x400000; private const int SrSpriteMask2 = SrSpriteMask1 << 1; private const int SrSpriteMask3 = SrSpriteMask1 | SrSpriteMask2; private const int SrSpriteMaskMc = SrSpriteMask3; @@ -65,39 +66,116 @@ #endregion // render graphics - if ((_srColorEnable & SrMask0) != 0) + + #region Graphics Sequencer + + if (_xScroll == (_rasterX & 0x7)) { - _pixel = ((_srColor0 & SrMask0) >> 26) | - ((_srColor1 & SrMask0) >> 25) | - ((_srColor2 & SrMask0) >> 24) | - ((_srColor3 & SrMask0) >> 23); - } - else - { - switch (((_srColor0 & SrMask0) >> 26) | ((_srColor1 & SrMask0) >> 25)) - { - case 1: - _pixel = _idle ? 0 : _backgroundColor1; - break; - case 2: - _pixel = _idle ? 0 : _backgroundColor2; - break; - case 3: - _pixel = _idle ? 0 : _backgroundColor3; - break; - default: - _pixel = _backgroundColor0; - break; - } + _displayC = _dataCPrev & 0xFFF; + _gfxMc = _multicolorMode && (_bitmapMode || (_displayC & 0x800) != 0); } + _pixel = _backgroundColor0; + _gfxJitter = _gfxMc ? (_xScroll ^ _rasterX) & 1 : 0; + _srData1 <<= 1; + _gfxData = _srData1 >> (18 + _gfxJitter); // bit 1-0 has the histogram + _gfxSense = (_gfxData & 2) != 0; // bit 1 is used for foreground data purposes too + + switch (_videoMode) + { + case VideoMode000: + { + if (_gfxSense) + _pixel = _displayC >> 8; + break; + } + case VideoMode001: + { + if (_gfxMc) + { + switch (_gfxData & 0x3) + { + case 0x1: + _pixel = _backgroundColor1; + break; + case 0x2: + _pixel = _backgroundColor2; + break; + case 0x3: + _pixel = (_displayC >> 8) & 7; + break; + } + } + else if (_gfxSense) + { + _pixel = _displayC >> 8; + } + break; + } + case VideoMode010: + { + _pixel = (_gfxSense ? _displayC >> 4 : _displayC) & 0xF; + break; + } + case VideoMode011: + { + switch (_gfxData & 0x3) + { + case 0x1: + _pixel = (_displayC >> 4) & 0xF; + break; + case 0x2: + _pixel = _displayC & 0xF; + break; + case 0x3: + _pixel = (_displayC >> 8) & 0xF; + break; + } + break; + } + case VideoMode100: + { + if (_gfxSense) + { + _pixel = (_displayC >> 8) & 0xF; + } + else + { + switch (_displayC & 0xC0) + { + case 0x40: + { + _pixel = _backgroundColor1; + break; + } + case 0x80: + { + _pixel = _backgroundColor2; + break; + } + case 0xC0: + { + _pixel = _backgroundColor3; + break; + } + } + } + break; + } + } + + #endregion Graphics Sequencer + // render sprites - _pixelOwner = -1; + + #region Sprite Sequencer + Mux Collision + + _sprOwner = -1; + _sprSense = false; for (_sprIndex = 0; _sprIndex < 8; _sprIndex++) { _spr = _sprites[_sprIndex]; _sprData = 0; - _sprPixel = _pixel; if (_spr.X == _rasterX) { @@ -142,8 +220,20 @@ if (_sprData != 0) { // sprite-sprite collision - if (_pixelOwner < 0) + if (_sprSense) { + if (!_borderOnVertical) + { + _spr.CollideSprite = true; + _sprites[_sprOwner].CollideSprite = true; + _intSpriteCollision = true; + } + } + else + { + _sprSense = true; + _sprOwner = _sprIndex; + _sprPriority = _spr.Priority; switch (_sprData) { case SrSpriteMask1: @@ -156,45 +246,33 @@ _sprPixel = _spriteMulticolor1; break; } - _pixelOwner = _sprIndex; - } - else - { - if (!_borderOnVertical) - { - _spr.CollideSprite = true; - _sprites[_pixelOwner].CollideSprite = true; - _intSpriteCollision = true; - } } // sprite-data collision - if (!_borderOnVertical && (_srData1 & SrMask0) != 0) + if (!_borderOnVertical && _gfxSense) { _spr.CollideData = true; _intSpriteDataCollision = true; } - - // sprite priority logic - if (_spr.Priority) - { - _pixel = (_srData1 & SrMask0) != 0 ? _pixel : _sprPixel; - } - else - { - _pixel = _sprPixel; - } } } } + + #endregion Sprite Sequencer + Mux Collision + #region Mux Color + + // sprite priority logic + if (_sprSense && (!_sprPriority || !_gfxSense)) + _pixel = _sprPixel; + + #endregion Mux Color + // plot pixel if within viewing area - _borderOnShiftReg >>= 1; - _borderOnShiftReg |= (_borderOnVertical || _borderOnMain) ? 0x100 : 0x00; if (_renderEnabled) { - _bufferPixel = (_borderOnShiftReg & 1) != 0 ? _borderColor : _pixel; - _bufferPixel = ((_rasterX & 0xF) == 0) ? _rasterX >> 4 : _bufferPixel; + _bufferPixel = (_borderOnVertical || _borderOnMain) ? _borderColor : _pixel; + //_bufferPixel = ((_rasterX & 0xF) == 0) ? _rasterX >> 4 : _bufferPixel; _buf[_bufOffset++] = Palette[_bufferPixel & 0xF]; if (_bufOffset == _bufLength) _bufOffset = 0; @@ -202,13 +280,6 @@ if (!_rasterXHold) _rasterX++; - - _srColor0 <<= 1; - _srColor1 <<= 1; - _srColor2 <<= 1; - _srColor3 <<= 1; - _srData1 <<= 1; - _srColorEnable <<= 1; } } } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.State.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.State.cs index f2ee5ad211..90e59b55e8 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.State.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.State.cs @@ -27,7 +27,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS private int _cycleIndex; private bool _columnSelect; private int _dataC; + private int _dataCPrev; private int _dataG; + private int _displayC; private bool _displayEnable; private bool _enableIntLightPen; private bool _enableIntRaster; diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs index 4cba3604d6..db446a2166 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs @@ -189,6 +189,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS public void ExecutePhase1() { // phi1 + _dataCPrev |= (_dataC & 0xFFF) << 12; // advance cycle and optionally raster line _cycle++; @@ -269,6 +270,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS public void ExecutePhase2() { // phi2 + _dataCPrev >>= 12; // check top and bottom border if (_rasterLine == _borderB)