HMove update

Fixes Kool Aid Man
This commit is contained in:
alyosha-tas 2016-04-22 09:17:01 -04:00
parent 3e365a2928
commit a0ad9aab36
2 changed files with 941 additions and 888 deletions

View File

@ -245,6 +245,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
// TODO when sound timing is made exact:
// NTSC refclock is actually 315 / 88 mhz
//3546895
int clockrate = _pal ? 3546895 : 3579545;
int clocksperframe = 228 * NominalNumScanlines;
@ -268,12 +269,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private int[] _palette;
private int test_count_p0;
private int test_count_p1;
private int test_count_m0;
private int test_count_m1;
private int test_count_b;
private byte pf0_update = 0;
private byte pf1_update = 0;
private byte pf2_update = 0;
@ -294,6 +289,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private bool enam1_val = false;
private bool enamb_val = false;
private bool p0_stuff = false;
private bool p1_stuff = false;
private bool m0_stuff = false;
private bool m1_stuff = false;
private bool b_stuff = false;
private int HMP0_delay = 0;
private byte HMP0_val = 0;
private int HMP1_delay = 0;
private byte HMP1_val = 0;
private int prg0_delay = 0;
private int prg1_delay = 0;
@ -429,7 +434,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// Still ignoring cycles...
//delay latch to new playfield register
if (pf0_updater==true)
if (pf0_updater == true)
{
pf0_delay_clock++;
if (pf0_delay_clock > pf0_max_delay)
@ -458,10 +463,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
//delay latch to missile enable
if (enam0_delay>0)
if (enam0_delay > 0)
{
enam0_delay++;
if (enam0_delay==3)
if (enam0_delay == 3)
{
enam0_delay = 0;
_player0.Missile.Enabled = enam0_val;
@ -520,6 +525,27 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
// HMP write delay
if (HMP0_delay > 0)
{
HMP0_delay++;
if (HMP0_delay == 4)
{
HMP0_delay = 0;
_player0.HM = HMP0_val;
}
}
if (HMP1_delay > 0)
{
HMP1_delay++;
if (HMP1_delay == 3)
{
HMP1_delay = 0;
_player1.HM = HMP1_val;
}
}
// Reset the RDY flag when we reach hblank
if (_hsyncCnt <= 0)
{
@ -681,7 +707,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
throw new Exception(); // TODO
_scanlinebuffer[_CurrentScanLine * ScreenWidth + x] = pixelColor;
}
} else
}
else
{
do_ticks = true;
}
@ -708,44 +735,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// ---- Things that happen every time ----
// Handle HMOVE
if (_hmove.HMoveEnabled)
{
// On the first time, set the latches and counters
if (_hmove.HMoveJustStarted)
{
_hmove.Player0Latch = true;
_hmove.Player0Cnt = 0;
test_count_p0 = 0;
test_count_p1 = 0;
test_count_m0 = 0;
test_count_m1 = 0;
test_count_b = 0;
_hmove.Missile0Latch = true;
_hmove.Missile0Cnt = 0;
_hmove.Player1Latch = true;
_hmove.Player1Cnt = 0;
_hmove.Missile1Latch = true;
_hmove.Missile1Cnt = 0;
_hmove.BallLatch = true;
_hmove.BallCnt = 0;
_hmove.HMoveCnt = 0;
_hmove.HMoveJustStarted = false;
_hmove.LateHBlankReset = true;
_hmove.DecCntEnabled = false;
}
if (_hmove.DecCntEnabled)
{
@ -760,26 +754,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// If the move counter still has a bit in common with the HM register
if (((15 - _hmove.Player0Cnt) ^ ((_player0.HM & 0x07) | ((~(_player0.HM & 0x08)) & 0x08))) != 0x0F)
{
// "Clock-Stuffing"
if (do_ticks==true)
{
_player0.Tick();
}
// Increase by 1, max of 15
test_count_p0++;
if (test_count_p0 < 16)
{
_hmove.Player0Cnt++;
}
else
{
_hmove.Player0Cnt = 0;
}
//_hmove.Player0Cnt %= 16;
p0_stuff = true;
}
else
{
@ -793,24 +768,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// If the move counter still has a bit in common with the HM register
if (((15 - _hmove.Missile0Cnt) ^ ((_player0.Missile.Hm & 0x07) | ((~(_player0.Missile.Hm & 0x08)) & 0x08))) != 0x0F)
{
// "Clock-Stuffing"
if (do_ticks == true)
{
_player0.Missile.Tick();
}
// Increase by 1, max of 15
test_count_m0++;
if (test_count_m0 < 16)
{
_hmove.Missile0Cnt++;
}
else
{
_hmove.Missile0Cnt = 0;
}
//_hmove.Missile0Cnt %= 16;
m0_stuff = true;
}
else
{
@ -824,22 +782,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// If the move counter still has a bit in common with the HM register
if (((15 - _hmove.Player1Cnt) ^ ((_player1.HM & 0x07) | ((~(_player1.HM & 0x08)) & 0x08))) != 0x0F)
{
// "Clock-Stuffing"
if (do_ticks == true)
{
_player1.Tick();
}
// Increase by 1, max of 15
test_count_p1++;
if (test_count_p1 < 16)
{
_hmove.Player1Cnt++;
}
else
{
_hmove.Player1Cnt = 0;
}
//_hmove.Player1Cnt %= 16;
p1_stuff = true;
}
else
{
@ -852,22 +795,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// If the move counter still has a bit in common with the HM register
if (((15 - _hmove.Missile1Cnt) ^ ((_player1.Missile.Hm & 0x07) | ((~(_player1.Missile.Hm & 0x08)) & 0x08))) != 0x0F)
{
// "Clock-Stuffing"
if (do_ticks == true)
{
_player1.Missile.Tick();
}
// Increase by 1, max of 15
test_count_m1++;
if (test_count_m1 < 16)
{
_hmove.Missile1Cnt++;
}
else
{
_hmove.Missile1Cnt = 0;
}
// _hmove.Missile1Cnt %= 16;
m1_stuff = true;
}
else
{
@ -880,22 +808,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// If the move counter still has a bit in common with the HM register
if (((15 - _hmove.BallCnt) ^ ((_ball.HM & 0x07) | ((~(_ball.HM & 0x08)) & 0x08))) != 0x0F)
{
// "Clock-Stuffing"
if (do_ticks == true)
{
_ball.Tick();
}
// Increase by 1, max of 15
test_count_b++;
if (test_count_b < 16)
{
_hmove.BallCnt++;
}
else
{
_hmove.BallCnt = 0;
}
//_hmove.BallCnt %= 16;
b_stuff = true;
}
else
{
@ -913,6 +826,108 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_hmove.HMoveCnt++;
_hmove.HMoveCnt %= 4;
if (p0_stuff==true && _hsyncCnt%4==0)
{
p0_stuff = false;
// "Clock-Stuffing"
if (do_ticks == true)
{
_player0.Tick();
}
// Increase by 1, max of 15
_hmove.test_count_p0++;
if (_hmove.test_count_p0 < 16)
{
_hmove.Player0Cnt++;
}
else
{
_hmove.Player0Cnt = 0;
}
}
if (p1_stuff == true && _hsyncCnt % 4 == 0)
{
p1_stuff = false;
// "Clock-Stuffing"
if (do_ticks == true)
{
_player1.Tick();
}
// Increase by 1, max of 15
_hmove.test_count_p1++;
if (_hmove.test_count_p1 < 16)
{
_hmove.Player1Cnt++;
}
else
{
_hmove.Player1Cnt = 0;
}
}
if (m0_stuff == true && _hsyncCnt % 4 == 0)
{
m0_stuff = false;
// "Clock-Stuffing"
if (do_ticks == true)
{
_player0.Missile.Tick();
}
// Increase by 1, max of 15
_hmove.test_count_m0++;
if (_hmove.test_count_m0 < 16)
{
_hmove.Missile0Cnt++;
}
else
{
_hmove.Missile0Cnt = 0;
}
}
if (m1_stuff == true && _hsyncCnt % 4 == 0)
{
m1_stuff = false;
// "Clock-Stuffing"
if (do_ticks == true)
{
_player1.Missile.Tick();
}
// Increase by 1, max of 15
_hmove.test_count_m1++;
if (_hmove.test_count_m1 < 16)
{
_hmove.Missile1Cnt++;
}
else
{
_hmove.Missile1Cnt = 0;
}
}
if (b_stuff == true && _hsyncCnt % 4 == 0)
{
b_stuff = false;
// "Clock-Stuffing"
if (do_ticks == true)
{
_ball.Tick();
}
// Increase by 1, max of 15
_hmove.test_count_b++;
if (_hmove.test_count_b < 16)
{
_hmove.BallCnt++;
}
else
{
_hmove.BallCnt = 0;
}
}
}
if (_hmove.HMoveDelayCnt < 5)
@ -925,10 +940,35 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_hmove.HMoveDelayCnt++;
_hmove.HMoveCnt = 0;
_hmove.DecCntEnabled = true;
_hmove.test_count_p0 = 0;
_hmove.test_count_p1 = 0;
_hmove.test_count_m0 = 0;
_hmove.test_count_m1 = 0;
_hmove.test_count_b = 0;
_hmove.Player0Latch = true;
_hmove.Player0Cnt = 0;
_hmove.Missile0Latch = true;
_hmove.Missile0Cnt = 0;
_hmove.Player1Latch = true;
_hmove.Player1Cnt = 0;
_hmove.Missile1Latch = true;
_hmove.Missile1Cnt = 0;
_hmove.BallLatch = true;
_hmove.BallCnt = 0;
_hmove.LateHBlankReset = true;
}
}
// Increment the hsync counter
_hsyncCnt++;
_hsyncCnt %= 228;
@ -1196,7 +1236,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// Resp depends on HMOVE
if (!_hmove.LateHBlankReset)
{
if (_hsyncCnt < 69)
if (_hsyncCnt < 68)
{
_player0.HPosCnt = 0;
_player0.ResetCnt = 2;
@ -1226,16 +1266,18 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// RESP depends on HMOVE
if (!_hmove.LateHBlankReset)
{
if (_hsyncCnt < 69)
if (_hsyncCnt < 68)
{
_player1.HPosCnt = 0;
_player1.ResetCnt = 2;
_player1.Reset = true;
} else
}
else
{
_player1.ResetCnt = 0;
}
} else
}
else
{
if (_hsyncCnt < 76)
{
@ -1255,7 +1297,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
if (!_hmove.LateHBlankReset)
{
_player0.Missile.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4);
} else
}
else
{
_player0.Missile.HPosCnt = (byte)(_hsyncCnt < 76 ? 160 - 2 : 160 - 4);
}
@ -1337,11 +1380,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
else if (maskedAddr == 0x20) // HMP0
{
_player0.HM = (byte)((value & 0xF0) >> 4);
HMP0_val = (byte)((value & 0xF0) >> 4);
HMP0_delay = 1;
}
else if (maskedAddr == 0x21) // HMP1
{
_player1.HM = (byte)((value & 0xF0) >> 4);
HMP1_val = (byte)((value & 0xF0) >> 4);
HMP1_delay = 1;
}
else if (maskedAddr == 0x22) // HMM0
{
@ -1378,7 +1423,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
else if (maskedAddr == 0x2A) // HMOVE
{
_hmove.HMoveEnabled = true;
_hmove.HMoveJustStarted = true;
_hmove.HMoveDelayCnt = 0;
}
else if (maskedAddr == 0x2B) // HMCLR

View File

@ -7,7 +7,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private struct HMoveData
{
public bool HMoveEnabled;
public bool HMoveJustStarted;
public bool LateHBlankReset;
public bool DecCntEnabled;
@ -20,6 +19,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public byte HMoveDelayCnt;
public byte HMoveCnt;
public int test_count_p0;
public int test_count_p1;
public int test_count_m0;
public int test_count_m1;
public int test_count_b;
public byte Player0Cnt;
public byte Player1Cnt;
public byte Missile0Cnt;
@ -30,7 +35,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
ser.BeginSection("HMove");
ser.Sync("hmoveEnabled", ref HMoveEnabled);
ser.Sync("hmoveJustStarted", ref HMoveJustStarted);
ser.Sync("lateHBlankReset", ref LateHBlankReset);
ser.Sync("decCntEnabled", ref DecCntEnabled);
ser.Sync("player0Latch", ref Player0Latch);
@ -44,6 +48,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
ser.Sync("player1Cnt", ref Player1Cnt);
ser.Sync("missile0Cnt", ref Missile0Cnt);
ser.Sync("missile1Cnt", ref Missile1Cnt);
ser.Sync("Test_count_p0", ref test_count_p0);
ser.Sync("Test_count_p1", ref test_count_p1);
ser.Sync("Test_count_m0", ref test_count_m0);
ser.Sync("Test_count_m1", ref test_count_m1);
ser.Sync("Test_count_b", ref test_count_b);
ser.Sync("ballCnt", ref BallCnt);
ser.EndSection();
}