A2600: Bug fixes and Improvements

This commit is contained in:
alyosha-tas 2019-07-19 20:03:30 -04:00
parent 7f29c4173b
commit cf6cdf4ecc
4 changed files with 102 additions and 73 deletions

View File

@ -1,4 +1,5 @@
using BizHawk.Common;
using System;
namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
@ -75,6 +76,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
Timer.InterruptFlag = false;
}
if (Timer.Overflowed)
{
Timer.Overflowed = false;
}
return Timer.Value;
}
@ -105,6 +111,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// If bit 0x0010 is set, and bit 0x0004 is set, this is a timer write
if ((addr & 0x0014) == 0x0014)
{
Timer.Overflowed = false;
var registerAddr = (ushort)(addr & 0x0007);
// Bit 0x0080 contains interrupt enable/disable
@ -117,7 +125,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// Write to Timer/1
Timer.PrescalerShift = 0;
Timer.Value = value;
Timer.PrescalerCount = 0; // 1 << Timer.PrescalerShift;
Timer.PrescalerCount = 1;// << Timer.PrescalerShift;
Timer.InterruptFlag = false;
}
else if (registerAddr == 0x05)
@ -125,7 +133,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// Write to Timer/8
Timer.PrescalerShift = 3;
Timer.Value = value;
Timer.PrescalerCount = 0; // 1 << Timer.PrescalerShift;
Timer.PrescalerCount = 1;// << Timer.PrescalerShift;
Timer.InterruptFlag = false;
}
else if (registerAddr == 0x06)
@ -133,7 +141,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// Write to Timer/64
Timer.PrescalerShift = 6;
Timer.Value = value;
Timer.PrescalerCount = 0; // 1 << Timer.PrescalerShift;
Timer.PrescalerCount = 1;// << Timer.PrescalerShift;
Timer.InterruptFlag = false;
}
else if (registerAddr == 0x07)
@ -141,7 +149,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// Write to Timer/1024
Timer.PrescalerShift = 10;
Timer.Value = value;
Timer.PrescalerCount = 0; // 1 << Timer.PrescalerShift;
Timer.PrescalerCount = 1;// << Timer.PrescalerShift;
Timer.InterruptFlag = false;
}
}
@ -195,22 +203,25 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public bool InterruptEnabled;
public bool InterruptFlag;
public bool Overflowed;
public void Tick()
{
if (PrescalerCount == 0)
PrescalerCount--;
if ((PrescalerCount == 0) || Overflowed)
{
Value--;
PrescalerCount = 1 << PrescalerShift;
}
PrescalerCount--;
if (PrescalerCount == 0)
{
if (Value == 0)
if (Value == 0xFF)
{
Overflowed = true;
InterruptFlag = true;
PrescalerShift = 0;
}
if (PrescalerCount == 0)
{
PrescalerCount = 1 << PrescalerShift;
}
}
}
@ -222,6 +233,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
ser.Sync("value", ref Value);
ser.Sync("interruptEnabled", ref InterruptEnabled);
ser.Sync("interruptFlag", ref InterruptFlag);
ser.Sync("Overflowed", ref Overflowed);
}
}
}

View File

@ -1177,11 +1177,14 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
else if (maskedAddr == 0x10) // RESP0
{
// RESP delays draw signal clocking
_player0.Resp_check();
// Resp depends on HMOVE
if (!_hmove.LateHBlankReset)
{
_player0.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4);
if (_hsyncCnt == 67 || _hsyncCnt==0)
if (_hsyncCnt == 67)
{
_player0.HPosCnt = 160 - 3;
}
@ -1189,7 +1192,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
else
{
_player0.HPosCnt = (byte)(_hsyncCnt < 76 ? 160 - 2 : 160 - 4);
if (_hsyncCnt == 75 || _hsyncCnt == 0)
if (_hsyncCnt == 75)
{
_player0.HPosCnt = 160 - 3;
}
@ -1197,11 +1200,14 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
else if (maskedAddr == 0x11) // RESP1
{
// RESP delays draw signal clocking
_player1.Resp_check();
// RESP depends on HMOVE
if (!_hmove.LateHBlankReset)
{
_player1.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4);
if (_hsyncCnt == 67 || _hsyncCnt == 0)
if (_hsyncCnt == 67)
{
_player1.HPosCnt = 160 - 3;
}
@ -1209,7 +1215,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
else
{
_player1.HPosCnt = (byte)(_hsyncCnt < 76 ? 160 - 2 : 160 - 4);
if (_hsyncCnt == 75 || _hsyncCnt == 0)
if (_hsyncCnt == 75)
{
_player1.HPosCnt = 160 - 3;
}
@ -1217,10 +1223,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
else if (maskedAddr == 0x12) // RESM0
{
// RESP delays draw signal clocking
_player0.Missile.Resp_check();
if (!_hmove.LateHBlankReset)
{
_player0.Missile.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4);
if (_hsyncCnt == 67 || _hsyncCnt == 0)
if (_hsyncCnt == 67)
{
_player0.Missile.HPosCnt = 160 - 3;
}
@ -1228,7 +1237,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
else
{
_player0.Missile.HPosCnt = (byte)(_hsyncCnt < 76 ? 160 - 2 : 160 - 4);
if (_hsyncCnt == 75 || _hsyncCnt == 0)
if (_hsyncCnt == 75)
{
_player0.Missile.HPosCnt = 160 - 3;
}
@ -1236,10 +1245,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
else if (maskedAddr == 0x13) // RESM1
{
// RESP delays draw signal clocking
_player1.Missile.Resp_check();
if (!_hmove.LateHBlankReset)
{
_player1.Missile.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4);
if (_hsyncCnt == 67 || _hsyncCnt == 0)
if (_hsyncCnt == 67)
{
_player1.Missile.HPosCnt = 160 - 3;
}
@ -1247,7 +1259,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
else
{
_player1.Missile.HPosCnt = (byte)(_hsyncCnt < 76 ? 160 - 2 : 160 - 4);
if (_hsyncCnt == 75 || _hsyncCnt == 0)
if (_hsyncCnt == 75)
{
_player1.Missile.HPosCnt = 160 - 3;
}
@ -1258,7 +1270,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
if (!_hmove.LateHBlankReset)
{
_ball.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4);
if (_hsyncCnt == 67 || _hsyncCnt == 0)
if (_hsyncCnt == 67)
{
_ball.HPosCnt = 160 - 3;
}
@ -1266,7 +1278,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
else
{
_ball.HPosCnt = (byte)(_hsyncCnt < 76 ? 160 - 2 : 160 - 4);
if (_hsyncCnt == 75 || _hsyncCnt == 0)
if (_hsyncCnt == 75)
{
_ball.HPosCnt = 160 - 3;
}
@ -1374,9 +1386,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
else if (maskedAddr == 0x2B) // HMCLR
{
_hmClrDelay = 1;
_hmClrDelay = 1;
}
else if (maskedAddr == 0x2C) // CXCLR
{

View File

@ -20,6 +20,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private bool _scanCntInit;
private int _startSignal;
private int _signalReached;
public bool _draw_signaled;
public bool Tick()
{
@ -38,53 +39,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
}
/*
// At hPosCnt == 0, start drawing the missile, if enabled
if (HPosCnt < (1 << Size))
{
if (Enabled && !ResetToPlayer)
{
// Draw the missile
result = true;
}
}
if ((Number & 0x07) == 0x01 || ((Number & 0x07) == 0x03))
{
if (HPosCnt >= 16 && HPosCnt <= (16 + (1 << Size) - 1))
{
if (Enabled && !ResetToPlayer)
{
// Draw the missile
result = true;
}
}
}
if ((Number & 0x07) == 0x02 || ((Number & 0x07) == 0x03) || ((Number & 0x07) == 0x06))
{
if (HPosCnt >= 32 && HPosCnt <= (32 + (1 << Size) - 1))
{
if (Enabled && !ResetToPlayer)
{
// Draw the missile
result = true;
}
}
}
if ((Number & 0x07) == 0x04 || (Number & 0x07) == 0x06)
{
if (HPosCnt >= 64 && HPosCnt <= (64 + (1 << Size) - 1))
{
if (Enabled && !ResetToPlayer)
{
// Draw the missile
result = true;
}
}
}*/
if (_startSignal == 160)
{
_scanCnt = 0;
@ -97,6 +51,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_scanCnt = 0;
_startSignal++;
_scanCntInit = true;
_draw_signaled = false;
}
if (_startSignal == 32 && ((Number & 0x07) == 0x02 || ((Number & 0x07) == 0x03) || ((Number & 0x07) == 0x06)))
@ -104,6 +59,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_scanCnt = 0;
_startSignal++;
_scanCntInit = true;
_draw_signaled = false;
}
if (_startSignal == 64 && ((Number & 0x07) == 0x04 || ((Number & 0x07) == 0x06)))
@ -111,6 +67,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_scanCnt = 0;
_startSignal++;
_scanCntInit = true;
_draw_signaled = false;
}
// Increment the counter
@ -125,6 +82,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
_startSignal = HPosCnt;
_signalReached = HPosCnt + 5;
if (HPosCnt != 156) { _draw_signaled = true; }
}
if (_startSignal < _signalReached)
@ -135,6 +93,27 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
return result;
}
public void Resp_check()
{
if (_draw_signaled)
{
if (_startSignal < 17)
{
_startSignal -= _startSignal - 12;
}
else if (_startSignal < 33)
{
_startSignal -= _startSignal - 28;
}
else if (_startSignal < 65)
{
_startSignal -= _startSignal - 60;
}
}
}
public void SyncState(Serializer ser)
{
ser.BeginSection("Missile");
@ -150,6 +129,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
ser.Sync("draw_to", ref _drawTo);
ser.Sync("scanCnt", ref _scanCnt);
ser.Sync("scanCntInit", ref _scanCntInit);
ser.Sync("_draw_signaled", ref _draw_signaled);
ser.EndSection();
}
}

View File

@ -21,8 +21,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public byte Collisions;
// Resp commands do not trigger start signals for main copies. We need to model this
private int _startSignal;
public int _startSignal;
private int _signalReached;
public bool _draw_signaled;
public bool Tick()
{
@ -134,18 +135,21 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
ScanCnt = 0;
_startSignal++;
_draw_signaled = false;
}
if (_startSignal == 32 && ((Nusiz & 0x07) == 0x02 || ((Nusiz & 0x07) == 0x03) || ((Nusiz & 0x07) == 0x06)))
{
ScanCnt = 0;
_startSignal++;
_draw_signaled = false;
}
if (_startSignal == 64 && ((Nusiz & 0x07) == 0x04 || ((Nusiz & 0x07) == 0x06)))
{
ScanCnt = 0;
_startSignal++;
_draw_signaled = false;
}
// Increment the counter
@ -160,6 +164,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
_startSignal = HPosCnt - 1;
_signalReached = HPosCnt + 5;
if (HPosCnt != 156) { _draw_signaled = true; }
}
if (_startSignal < _signalReached)
@ -170,6 +175,27 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
return result;
}
public void Resp_check()
{
if (_draw_signaled)
{
if (_startSignal < 17)
{
_startSignal -= _startSignal - 12;
}
else if (_startSignal < 33)
{
_startSignal -= _startSignal - 28;
}
else if (_startSignal < 65)
{
_startSignal -= _startSignal - 60;
}
}
}
public void SyncState(Serializer ser)
{
Missile.SyncState(ser);
@ -186,6 +212,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
ser.Sync("collisions", ref Collisions);
ser.Sync("start_signal", ref _startSignal);
ser.Sync("signal_reached", ref _signalReached);
ser.Sync("_draw_signaled", ref _draw_signaled);
}
}
}