Converted OSystem::getTicks() to use 64-bit integers. This should fix the

problems with integer overflow, which could sometimes cause Stella to
sleep for long periods of time.  For those who are interested, the
problem was that SDL_GetTicks() wraps every 49 days (32-bit int
overflow), but since OSystem::getTicks() provides info in microseconds,
it multiplied the value by 1000.  This caused wraparound in 49/1000
days, or 70.56 minutes.  This almost exactly matches the reports on
AtariAge of 'lockups' occuring every 71 minutes or so.  It also
explains why attaching to Stella with GDB and bypassing the delay
allows the program to continue (as reported by another bugtester).

Added signature to detect UA bankswitching for Gingerbread Man ROM.

Bumped version number.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1823 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2009-07-01 14:39:01 +00:00
parent 1c829fc425
commit 8a8d04031a
17 changed files with 61 additions and 55 deletions

View File

@ -19,7 +19,7 @@
#ifndef VERSION_HXX
#define VERSION_HXX
#define STELLA_BASE_VERSION "2.8.3"
#define STELLA_BASE_VERSION "2.8.4_svn"
#ifdef NIGHTLY_BUILD
#define STELLA_VERSION STELLA_BASE_VERSION "pre-" NIGHTLY_BUILD

View File

@ -527,14 +527,17 @@ bool Cartridge::isProbablyUA(const uInt8* image, uInt32 size)
{
// UA cart bankswitching switches to bank 1 by accessing address 0x240
// using 'STA $240' or 'LDA $240'
uInt8 signature[2][3] = {
uInt8 signature[3][3] = {
{ 0x8D, 0x40, 0x02 }, // STA $240
{ 0xAD, 0x40, 0x02 } // LDA $240
{ 0xAD, 0x40, 0x02 }, // LDA $240
{ 0xBD, 0x1F, 0x02 } // LDA $21F,X
};
if(searchForBytes(image, size, signature[0], 3, 1))
for(uInt32 i = 0; i < 3; ++i)
{
if(searchForBytes(image, size, signature[i], 3, 1))
return true;
else
return searchForBytes(image, size, signature[1], 3, 1);
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -307,7 +307,7 @@ void EventHandler::mapStelladaptors(const string& sa1, const string& sa2)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::poll(uInt32 time)
void EventHandler::poll(uInt64 time)
{
// Synthesize events for platform-specific hardware
myOSystem->pollEvent();

View File

@ -118,9 +118,9 @@ class EventHandler
Collects and dispatches any pending events. This method should be
called regularly (at X times per second, where X is the game framerate).
@param time The current time in milliseconds.
@param time The current time in microseconds.
*/
void poll(uInt32 time);
void poll(uInt64 time);
/**
Set the default action for a joystick button to the given event

View File

@ -797,8 +797,7 @@ string OSystem::getROMInfo(const Console* console)
void OSystem::resetLoopTiming()
{
memset(&myTimingInfo, 0, sizeof(TimingInfo));
myTimingInfo.start = getTicks();
myTimingInfo.virt = getTicks();
myTimingInfo.start = myTimingInfo.virt = getTicks();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -368,7 +368,7 @@ class OSystem
@return Current time in microseconds.
*/
virtual uInt32 getTicks() const = 0;
virtual uInt64 getTicks() const = 0;
//////////////////////////////////////////////////////////////////////
// The following methods are system-specific and can be overrided in
@ -520,11 +520,11 @@ class OSystem
// Indicates whether the main processing loop should proceed
struct TimingInfo {
uInt32 start;
uInt32 current;
uInt32 virt;
uInt32 totalTime;
uInt32 totalFrames;
uInt64 start;
uInt64 current;
uInt64 virt;
uInt64 totalTime;
uInt64 totalFrames;
};
TimingInfo myTimingInfo;

View File

@ -27,17 +27,25 @@
@version $Id$
*/
#ifdef HAVE_INTTYPES
#include <inttypes.h>
#endif
// Types for 8-bit signed and unsigned integers
typedef signed char Int8;
typedef unsigned char uInt8;
typedef int8_t Int8;
typedef uint8_t uInt8;
// Types for 16-bit signed and unsigned integers
typedef signed short Int16;
typedef unsigned short uInt16;
typedef int16_t Int16;
typedef uint16_t uInt16;
// Types for 32-bit signed and unsigned integers
typedef signed int Int32;
typedef unsigned int uInt32;
typedef int32_t Int32;
typedef uint32_t uInt32;
// Types for 64-bit signed and unsigned integers
typedef int64_t Int64;
typedef uint64_t uInt64;
// The following code should provide access to the standard C++ objects and
// types: cout, cerr, string, ostream, istream, etc.
@ -54,10 +62,6 @@ typedef unsigned int uInt32;
#include <algorithm>
#ifdef HAVE_INTTYPES
#include <inttypes.h>
#endif
// Defines to help with path handling
#if defined BSPF_UNIX
#define BSPF_PATH_SEPARATOR "/"

View File

@ -41,7 +41,7 @@ DialogContainer::~DialogContainer()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DialogContainer::updateTime(uInt32 time)
void DialogContainer::updateTime(uInt64 time)
{
// We only need millisecond precision
myTime = time / 1000;

View File

@ -60,7 +60,7 @@ class DialogContainer
@param time The current time in microseconds
*/
void updateTime(uInt32 time);
void updateTime(uInt64 time);
/**
Handle a keyboard event.
@ -159,7 +159,7 @@ class DialogContainer
};
// Indicates the most current time (in milliseconds) as set by updateTime()
int myTime;
uInt64 myTime;
// For continuous 'key down' events
struct {
@ -167,7 +167,7 @@ class DialogContainer
int keycode;
int flags;
} myCurrentKeyDown;
int myKeyRepeatTime;
uInt64 myKeyRepeatTime;
// For continuous 'mouse down' events
struct {
@ -175,14 +175,14 @@ class DialogContainer
int y;
int button;
} myCurrentMouseDown;
int myClickRepeatTime;
uInt64 myClickRepeatTime;
// For continuous 'joy button down' events
struct {
int stick;
int button;
} myCurrentButtonDown;
int myButtonRepeatTime;
uInt64 myButtonRepeatTime;
// For continuous 'joy axis down' events
struct {
@ -190,7 +190,7 @@ class DialogContainer
int axis;
int value;
} myCurrentAxisDown;
int myAxisRepeatTime;
uInt64 myAxisRepeatTime;
// For continuous 'joy hat' events
struct {
@ -198,13 +198,13 @@ class DialogContainer
int hat;
int value;
} myCurrentHatDown;
int myHatRepeatTime;
uInt64 myHatRepeatTime;
// Position and time of last mouse click (used to detect double clicks)
struct {
int x, y; // Position of mouse when the click occured
int time; // Time
int x, y; // Position of mouse when the click occurred
int count; // How often was it already pressed?
uInt64 time; // Time
} myLastClick;
};

View File

@ -227,7 +227,7 @@ bool ListWidget::handleKeyDown(int ascii, int keycode, int modifiers)
// Only works in a useful fashion if the list entries are sorted.
// TODO: Maybe this should be off by default, and instead we add a
// method "enableQuickSelect()" or so ?
int time = instance().getTicks() / 1000;
uInt64 time = instance().getTicks() / 1000;
if (_quickSelectTime < time)
_quickSelectStr = (char)ascii;
else
@ -456,4 +456,4 @@ void ListWidget::abortEditMode()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int ListWidget::_QUICK_SELECT_DELAY = 300;
uInt64 ListWidget::_QUICK_SELECT_DELAY = 300;

View File

@ -77,7 +77,7 @@ class ListWidget : public EditableWidget
void startEditMode();
void endEditMode();
static void setQuickSelectDelay(int time) { _QUICK_SELECT_DELAY = time; }
static void setQuickSelectDelay(uInt64 time) { _QUICK_SELECT_DELAY = time; }
protected:
virtual void drawWidget(bool hilite) = 0;
@ -113,10 +113,10 @@ class ListWidget : public EditableWidget
string _backupString;
bool _quickSelect;
string _quickSelectStr;
int _quickSelectTime;
uInt64 _quickSelectTime;
private:
static int _QUICK_SELECT_DELAY;
static uInt64 _QUICK_SELECT_DELAY;
};
#endif

View File

@ -102,15 +102,15 @@ OSystemMACOSX::~OSystemMACOSX()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 OSystemMACOSX::getTicks() const
uInt64 OSystemMACOSX::getTicks() const
{
#ifdef HAVE_GETTIMEOFDAY
timeval now;
gettimeofday(&now, 0);
return (uInt32) (now.tv_sec * 1000000 + now.tv_usec);
return uInt64(now.tv_sec) * 1000000 + now.tv_usec;
#else
return (uInt32) SDL_GetTicks() * 1000;
return uInt64(SDL_GetTicks()) * 1000;
#endif
}

View File

@ -47,7 +47,7 @@ class OSystemMACOSX : public OSystem
@return Current time in microseconds.
*/
virtual uInt32 getTicks() const;
virtual uInt64 getTicks() const;
/**
This method queries the dimensions of the screen for this hardware.

View File

@ -52,14 +52,14 @@ OSystemUNIX::~OSystemUNIX()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 OSystemUNIX::getTicks() const
uInt64 OSystemUNIX::getTicks() const
{
#ifdef HAVE_GETTIMEOFDAY
timeval now;
gettimeofday(&now, 0);
return (uInt32) (now.tv_sec * 1000000 + now.tv_usec);
return uInt64(now.tv_sec) * 1000000 + now.tv_usec;
#else
return (uInt32) SDL_GetTicks() * 1000;
return uInt64(SDL_GetTicks()) * 1000;
#endif
}

View File

@ -45,7 +45,7 @@ class OSystemUNIX : public OSystem
@return Current time in microseconds.
*/
uInt32 getTicks() const;
uInt64 getTicks() const;
};
#endif

View File

@ -87,7 +87,7 @@ OSystemWin32::~OSystemWin32()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 OSystemWin32::getTicks() const
uInt64 OSystemWin32::getTicks() const
{
return (uInt32) SDL_GetTicks() * 1000;
return uInt64(SDL_GetTicks()) * 1000;
}

View File

@ -47,7 +47,7 @@ class OSystemWin32 : public OSystem
@return Current time in microseconds.
*/
virtual uInt32 getTicks() const;
virtual uInt64 getTicks() const;
};
#endif