Added TIA HMOVE positioning hacks for 'Escape from the Mindmaster',

'Mission Survive', 'Solaris' and 'Swoops!'.  These are temporary hacks
until the new TIA code is written, which *will* be done before the next
major release.  In fact, it might even justify a 3.0 release.  Fixing
the TIA is my number one priority over the next few months.

Added debug code to the TIA class pointing out when object positions
are reset less than 24 cycles after an HMOVE (which incidentally is
the cause of most of the TIA emulation bugs).  Simply uncomment the
DEBUG_HMOVE declaration at the top of the class to activate this.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1467 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2008-04-13 00:14:38 +00:00
parent 206a4a1831
commit 998bba2a35
1 changed files with 74 additions and 6 deletions

View File

@ -13,9 +13,11 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: TIA.cxx,v 1.87 2008-03-23 16:22:41 stephena Exp $ // $Id: TIA.cxx,v 1.88 2008-04-13 00:14:38 stephena Exp $
//============================================================================ //============================================================================
//#define DEBUG_HMOVE
#include <cassert> #include <cassert>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
@ -2387,6 +2389,13 @@ void TIA::poke(uInt16 addr, uInt8 value)
// Find out under what condition the player is being reset // Find out under what condition the player is being reset
Int8 when = ourPlayerPositionResetWhenTable[myNUSIZ0 & 7][myPOSP0][newx]; Int8 when = ourPlayerPositionResetWhenTable[myNUSIZ0 & 7][myPOSP0][newx];
#ifdef DEBUG_HMOVE
if((clock - myLastHMOVEClock) < (24 * 3))
cerr << "Reset Player 0 within 24 cycles of HMOVE: "
<< ((clock - myLastHMOVEClock)/3)
<< " hpos: " << hpos << ", newx = " << newx << endl;
#endif
// Player is being reset during the display of one of its copies // Player is being reset during the display of one of its copies
if(when == 1) if(when == 1)
{ {
@ -2431,6 +2440,13 @@ void TIA::poke(uInt16 addr, uInt8 value)
// Find out under what condition the player is being reset // Find out under what condition the player is being reset
Int8 when = ourPlayerPositionResetWhenTable[myNUSIZ1 & 7][myPOSP1][newx]; Int8 when = ourPlayerPositionResetWhenTable[myNUSIZ1 & 7][myPOSP1][newx];
#ifdef DEBUG_HMOVE
if((clock - myLastHMOVEClock) < (24 * 3))
cerr << "Reset Player 1 within 24 cycles of HMOVE: "
<< ((clock - myLastHMOVEClock)/3)
<< " hpos: " << hpos << ", newx = " << newx << endl;
#endif
// Player is being reset during the display of one of its copies // Player is being reset during the display of one of its copies
if(when == 1) if(when == 1)
{ {
@ -2472,6 +2488,13 @@ void TIA::poke(uInt16 addr, uInt8 value)
int hpos = (clock - myClockWhenFrameStarted) % 228; int hpos = (clock - myClockWhenFrameStarted) % 228;
myPOSM0 = hpos < HBLANK ? 2 : (((hpos - HBLANK) + 4) % 160); myPOSM0 = hpos < HBLANK ? 2 : (((hpos - HBLANK) + 4) % 160);
#ifdef DEBUG_HMOVE
if((clock - myLastHMOVEClock) < (24 * 3))
cerr << "Reset Missle 0 within 24 cycles of HMOVE: "
<< ((clock - myLastHMOVEClock)/3)
<< " hpos: " << hpos << ", myPOSM0 = " << myPOSM0 << endl;
#endif
// TODO: Remove the following special hack for Dolphin by // TODO: Remove the following special hack for Dolphin by
// figuring out what really happens when Reset Missle // figuring out what really happens when Reset Missle
// occurs 20 cycles after an HMOVE (04/13/02). // occurs 20 cycles after an HMOVE (04/13/02).
@ -2479,6 +2502,13 @@ void TIA::poke(uInt16 addr, uInt8 value)
{ {
myPOSM0 = 8; myPOSM0 = 8;
} }
// TODO: Remove the following special hack for Solaris by
// figuring out what really happens when Reset Missle
// occurs 9 cycles after an HMOVE (04/11/08).
if(((clock - myLastHMOVEClock) == (9 * 3)) && (hpos == 36))
{
myPOSM0 = 8;
}
myCurrentM0Mask = &ourMissleMaskTable[myPOSM0 & 0x03] myCurrentM0Mask = &ourMissleMaskTable[myPOSM0 & 0x03]
[myNUSIZ0 & 0x07][(myNUSIZ0 & 0x30) >> 4][160 - (myPOSM0 & 0xFC)]; [myNUSIZ0 & 0x07][(myNUSIZ0 & 0x30) >> 4][160 - (myPOSM0 & 0xFC)];
@ -2490,6 +2520,13 @@ void TIA::poke(uInt16 addr, uInt8 value)
int hpos = (clock - myClockWhenFrameStarted) % 228; int hpos = (clock - myClockWhenFrameStarted) % 228;
myPOSM1 = hpos < HBLANK ? 2 : (((hpos - HBLANK) + 4) % 160); myPOSM1 = hpos < HBLANK ? 2 : (((hpos - HBLANK) + 4) % 160);
#ifdef DEBUG_HMOVE
if((clock - myLastHMOVEClock) < (24 * 3))
cerr << "Reset Missle 1 within 24 cycles of HMOVE: "
<< ((clock - myLastHMOVEClock)/3)
<< " hpos: " << hpos << ", myPOSM1 = " << myPOSM1 << endl;
#endif
// TODO: Remove the following special hack for Pitfall II by // TODO: Remove the following special hack for Pitfall II by
// figuring out what really happens when Reset Missle // figuring out what really happens when Reset Missle
// occurs 3 cycles after an HMOVE (04/13/02). // occurs 3 cycles after an HMOVE (04/13/02).
@ -2508,11 +2545,28 @@ void TIA::poke(uInt16 addr, uInt8 value)
int hpos = (clock - myClockWhenFrameStarted) % 228 ; int hpos = (clock - myClockWhenFrameStarted) % 228 ;
myPOSBL = hpos < HBLANK ? 2 : (((hpos - HBLANK) + 4) % 160); myPOSBL = hpos < HBLANK ? 2 : (((hpos - HBLANK) + 4) % 160);
#ifdef DEBUG_HMOVE
if((clock - myLastHMOVEClock) < (24 * 3))
cerr << "Reset Ball within 24 cycles of HMOVE: "
<< ((clock - myLastHMOVEClock)/3)
<< " hpos: " << hpos << ", myPOSBL = " << myPOSBL << endl;
#endif
// TODO: Remove the following special hack by figuring out what
// really happens when Reset Ball occurs 18 cycles after an HMOVE.
if((clock - myLastHMOVEClock) == (18 * 3))
{
// Escape from the Mindmaster (01/09/99)
if((hpos == 60) || (hpos == 69))
myPOSBL = 10;
// Mission Survive (04/11/08)
else if(hpos == 63)
myPOSBL = 7;
}
// TODO: Remove the following special hack for Escape from the // TODO: Remove the following special hack for Escape from the
// Mindmaster by figuring out what really happens when Reset Ball // Mindmaster by figuring out what really happens when Reset Ball
// occurs 18 cycles after an HMOVE (01/09/99). // occurs 15 cycles after an HMOVE (04/11/08).
if(((clock - myLastHMOVEClock) == (18 * 3)) && else if(((clock - myLastHMOVEClock) == (15 * 3)) && (hpos == 60))
((hpos == 60) || (hpos == 69)))
{ {
myPOSBL = 10; myPOSBL = 10;
} }
@ -2537,6 +2591,20 @@ void TIA::poke(uInt16 addr, uInt8 value)
{ {
myPOSBL = 5; myPOSBL = 5;
} }
// TODO: Remove the following special hack for Swoops! by
// figuring out what really happens when Reset Ball
// occurs 9 cycles after an HMOVE (04/11/08).
else if(((clock - myLastHMOVEClock) == (9 * 3)) && (hpos == 36))
{
myPOSBL = 7;
}
// TODO: Remove the following special hack for Solaris by
// figuring out what really happens when Reset Ball
// occurs 12 cycles after an HMOVE (04/11/08).
else if(((clock - myLastHMOVEClock) == (12 * 3)) && (hpos == 45))
{
myPOSBL = 8;
}
myCurrentBLMask = &ourBallMaskTable[myPOSBL & 0x03] myCurrentBLMask = &ourBallMaskTable[myPOSBL & 0x03]
[(myCTRLPF & 0x30) >> 4][160 - (myPOSBL & 0xFC)]; [(myCTRLPF & 0x30) >> 4][160 - (myPOSBL & 0xFC)];