diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs index 88982c7c1c..b84c4f8edd 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Render.cs @@ -196,7 +196,7 @@ _sprOwner = -1; _sprSense = false; - for (_sprIndex = 0; _sprIndex < 8; _sprIndex++) + for (_sprIndex = 7; _sprIndex >= 0; _sprIndex--) { _spr = _sprites[_sprIndex]; _sprData = 0; @@ -246,34 +246,35 @@ // sprite-sprite collision if (_sprSense) { + // "One any collision bit within a register is set high, subsequent + // collisions will not set the interrupt latch until that collision register + // has been cleared to all "0"s by a read." + _intSpriteCollision |= !_intSpriteCollisionTriggered; _spr.CollideSprite = true; _sprites[_sprOwner].CollideSprite = true; - _intSpriteCollision = true; } - else + + _sprSense = true; + _sprOwner = _sprIndex; + _sprPriority = _spr.Priority; + switch (_sprData) { - _sprSense = true; - _sprOwner = _sprIndex; - _sprPriority = _spr.Priority; - switch (_sprData) - { - case SrSpriteMask1: - _sprDecode = ColorRegisterSelect.SpriteMc0; - break; - case SrSpriteMask2: - _sprDecode = ColorRegisterSelect.Sprite0 + _sprOwner; - break; - case SrSpriteMask3: - _sprDecode = ColorRegisterSelect.SpriteMc1; - break; - } + case SrSpriteMask1: + _sprDecode = ColorRegisterSelect.SpriteMc0; + break; + case SrSpriteMask2: + _sprDecode = ColorRegisterSelect.Sprite0 + _sprOwner; + break; + case SrSpriteMask3: + _sprDecode = ColorRegisterSelect.SpriteMc1; + break; } // sprite-data collision if (_gfxSense) { _spr.CollideData = true; - _intSpriteDataCollision = true; + _intSpriteDataCollision = !_intSpriteDataCollisionTriggered; } } } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.State.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.State.cs index d56e742769..420ce16d92 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.State.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.State.cs @@ -39,7 +39,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS private bool _intLightPen; private bool _intRaster; private bool _intSpriteCollision; + private bool _intSpriteCollisionTriggered; private bool _intSpriteDataCollision; + private bool _intSpriteDataCollisionTriggered; private int _lightPenX; private int _lightPenY; private bool _multicolorMode; @@ -112,7 +114,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS _intLightPen = false; _intRaster = false; _intSpriteCollision = false; + _intSpriteCollisionTriggered = false; _intSpriteDataCollision = false; + _intSpriteDataCollisionTriggered = false; _irqBuffer = 0; _lightPenX = 0; _lightPenY = 0; @@ -189,7 +193,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS ser.Sync(nameof(_intLightPen), ref _intLightPen); ser.Sync(nameof(_intRaster), ref _intRaster); ser.Sync(nameof(_intSpriteCollision), ref _intSpriteCollision); + ser.Sync(nameof(_intSpriteCollisionTriggered), ref _intSpriteCollision); ser.Sync(nameof(_intSpriteDataCollision), ref _intSpriteDataCollision); + ser.Sync(nameof(_intSpriteDataCollisionTriggered), ref _intSpriteDataCollision); ser.Sync(nameof(_irqBuffer), ref _irqBuffer); ser.Sync(nameof(_lightPenX), ref _lightPenX); ser.Sync(nameof(_lightPenY), ref _lightPenY); diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs index 01acdb852c..d71d0ae28d 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs @@ -233,16 +233,16 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS spr.CollideData = false; } _spriteBackgroundCollisionClearPending = false; + _intSpriteDataCollisionTriggered = false; } // sprite collision clear if (_spriteSpriteCollisionClearPending) { foreach (var spr in _sprites) - { spr.CollideSprite = false; - } _spriteSpriteCollisionClearPending = false; + _intSpriteCollisionTriggered = false; } // raster IRQ is edge triggered