C64: Sprite collision interrupts do not fire if the collision registers are not already clear

This commit is contained in:
SaxxonPike 2019-07-28 09:44:47 -05:00
parent f4c64ddf38
commit cc077ac459
3 changed files with 28 additions and 21 deletions

View File

@ -196,7 +196,7 @@
_sprOwner = -1; _sprOwner = -1;
_sprSense = false; _sprSense = false;
for (_sprIndex = 0; _sprIndex < 8; _sprIndex++) for (_sprIndex = 7; _sprIndex >= 0; _sprIndex--)
{ {
_spr = _sprites[_sprIndex]; _spr = _sprites[_sprIndex];
_sprData = 0; _sprData = 0;
@ -246,12 +246,14 @@
// sprite-sprite collision // sprite-sprite collision
if (_sprSense) 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; _spr.CollideSprite = true;
_sprites[_sprOwner].CollideSprite = true; _sprites[_sprOwner].CollideSprite = true;
_intSpriteCollision = true;
} }
else
{
_sprSense = true; _sprSense = true;
_sprOwner = _sprIndex; _sprOwner = _sprIndex;
_sprPriority = _spr.Priority; _sprPriority = _spr.Priority;
@ -267,13 +269,12 @@
_sprDecode = ColorRegisterSelect.SpriteMc1; _sprDecode = ColorRegisterSelect.SpriteMc1;
break; break;
} }
}
// sprite-data collision // sprite-data collision
if (_gfxSense) if (_gfxSense)
{ {
_spr.CollideData = true; _spr.CollideData = true;
_intSpriteDataCollision = true; _intSpriteDataCollision = !_intSpriteDataCollisionTriggered;
} }
} }
} }

View File

@ -39,7 +39,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
private bool _intLightPen; private bool _intLightPen;
private bool _intRaster; private bool _intRaster;
private bool _intSpriteCollision; private bool _intSpriteCollision;
private bool _intSpriteCollisionTriggered;
private bool _intSpriteDataCollision; private bool _intSpriteDataCollision;
private bool _intSpriteDataCollisionTriggered;
private int _lightPenX; private int _lightPenX;
private int _lightPenY; private int _lightPenY;
private bool _multicolorMode; private bool _multicolorMode;
@ -112,7 +114,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
_intLightPen = false; _intLightPen = false;
_intRaster = false; _intRaster = false;
_intSpriteCollision = false; _intSpriteCollision = false;
_intSpriteCollisionTriggered = false;
_intSpriteDataCollision = false; _intSpriteDataCollision = false;
_intSpriteDataCollisionTriggered = false;
_irqBuffer = 0; _irqBuffer = 0;
_lightPenX = 0; _lightPenX = 0;
_lightPenY = 0; _lightPenY = 0;
@ -189,7 +193,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
ser.Sync(nameof(_intLightPen), ref _intLightPen); ser.Sync(nameof(_intLightPen), ref _intLightPen);
ser.Sync(nameof(_intRaster), ref _intRaster); ser.Sync(nameof(_intRaster), ref _intRaster);
ser.Sync(nameof(_intSpriteCollision), ref _intSpriteCollision); ser.Sync(nameof(_intSpriteCollision), ref _intSpriteCollision);
ser.Sync(nameof(_intSpriteCollisionTriggered), ref _intSpriteCollision);
ser.Sync(nameof(_intSpriteDataCollision), ref _intSpriteDataCollision); ser.Sync(nameof(_intSpriteDataCollision), ref _intSpriteDataCollision);
ser.Sync(nameof(_intSpriteDataCollisionTriggered), ref _intSpriteDataCollision);
ser.Sync(nameof(_irqBuffer), ref _irqBuffer); ser.Sync(nameof(_irqBuffer), ref _irqBuffer);
ser.Sync(nameof(_lightPenX), ref _lightPenX); ser.Sync(nameof(_lightPenX), ref _lightPenX);
ser.Sync(nameof(_lightPenY), ref _lightPenY); ser.Sync(nameof(_lightPenY), ref _lightPenY);

View File

@ -233,16 +233,16 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
spr.CollideData = false; spr.CollideData = false;
} }
_spriteBackgroundCollisionClearPending = false; _spriteBackgroundCollisionClearPending = false;
_intSpriteDataCollisionTriggered = false;
} }
// sprite collision clear // sprite collision clear
if (_spriteSpriteCollisionClearPending) if (_spriteSpriteCollisionClearPending)
{ {
foreach (var spr in _sprites) foreach (var spr in _sprites)
{
spr.CollideSprite = false; spr.CollideSprite = false;
}
_spriteSpriteCollisionClearPending = false; _spriteSpriteCollisionClearPending = false;
_intSpriteCollisionTriggered = false;
} }
// raster IRQ is edge triggered // raster IRQ is edge triggered