|
@@ -25,7 +25,7 @@ |
|
|
|
|
|
/* |
|
|
* TOS/MiNT timer driver |
|
|
* based on vbl vector |
|
|
* based on RISCOS backend |
|
|
* |
|
|
* Patrice Mandin |
|
|
*/ |
|
@@ -44,106 +44,119 @@ |
|
|
|
|
|
#include "SDL_timer.h" |
|
|
#include "../SDL_timer_c.h" |
|
|
#include "SDL_thread.h" |
|
|
|
|
|
#include "../../video/ataricommon/SDL_atarisuper.h" |
|
|
|
|
|
#include "SDL_vbltimer_s.h" |
|
|
/* from src/video/ataricommon/SDL_atarievents.c */ |
|
|
void SDL_AtariMint_BackgroundTasks(void); |
|
|
|
|
|
/* from audio/mint */ |
|
|
void SDL_MintAudio_CheckFpu(void); |
|
|
static Uint32 readHz200Timer(void); |
|
|
|
|
|
/* The first ticks value of the application */ |
|
|
static Uint32 start; |
|
|
static SDL_bool read_hz200_from_vbl = SDL_FALSE; |
|
|
|
|
|
static int mint_present; /* can we use Syield() ? */ |
|
|
|
|
|
/* Timer SDL_arraysize(Timer ),start/reset time */ |
|
|
static Uint32 timerStart; |
|
|
|
|
|
void SDL_StartTicks(void) |
|
|
{ |
|
|
void *old_stack; |
|
|
long dummy; |
|
|
|
|
|
/* Set first ticks value */ |
|
|
old_stack = (void *)Super(0); |
|
|
start = *((volatile long *)_hz_200); |
|
|
SuperToUser(old_stack); |
|
|
|
|
|
start *= 5; /* One _hz_200 tic is 5ms */ |
|
|
/* Set first ticks value, one _hz_200 tic is 5ms */ |
|
|
start = readHz200Timer() * 5; |
|
|
|
|
|
mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); |
|
|
} |
|
|
|
|
|
Uint32 SDL_GetTicks (void) |
|
|
{ |
|
|
Uint32 now = start; |
|
|
|
|
|
if (read_hz200_from_vbl) { |
|
|
now = SDL_Atari_hz200; |
|
|
} else { |
|
|
void *old_stack = (void *)Super(0); |
|
|
now = *((volatile long *)_hz_200); |
|
|
SuperToUser(old_stack); |
|
|
} |
|
|
Uint32 now = readHz200Timer() * 5; |
|
|
|
|
|
return((now*5)-start); |
|
|
return(now-start); |
|
|
} |
|
|
|
|
|
void SDL_Delay (Uint32 ms) |
|
|
{ |
|
|
Uint32 now; |
|
|
|
|
|
/* No need to loop for delay below resolution */ |
|
|
if (ms<5) { |
|
|
SDL_AtariMint_BackgroundTasks(); |
|
|
if (mint_present) { |
|
|
Syield(); |
|
|
} |
|
|
return; |
|
|
} |
|
|
|
|
|
now = SDL_GetTicks(); |
|
|
while ((SDL_GetTicks()-now)<ms){ |
|
|
SDL_AtariMint_BackgroundTasks(); |
|
|
if (mint_present) { |
|
|
Syield(); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
/* Data to handle a single periodic alarm */ |
|
|
static SDL_bool timer_installed=SDL_FALSE; |
|
|
|
|
|
/* This is only called if the event thread is not running */ |
|
|
int SDL_SYS_TimerInit(void) |
|
|
static Uint32 readHz200Timer(void) |
|
|
{ |
|
|
void *old_stack; |
|
|
Uint32 now; |
|
|
|
|
|
SDL_MintAudio_CheckFpu(); |
|
|
|
|
|
/* Install RunTimer in vbl vector */ |
|
|
old_stack = (void *)Super(0); |
|
|
timer_installed = !SDL_AtariVblInstall(SDL_ThreadedTimerCheck); |
|
|
now = *((volatile long *)_hz_200); |
|
|
SuperToUser(old_stack); |
|
|
|
|
|
if (!timer_installed) { |
|
|
return(-1); |
|
|
} |
|
|
return now; |
|
|
} |
|
|
|
|
|
/* Non-threaded version of timer */ |
|
|
|
|
|
read_hz200_from_vbl = SDL_TRUE; |
|
|
return(SDL_SetTimerThreaded(0)); |
|
|
int SDL_SYS_TimerInit(void) |
|
|
{ |
|
|
return(0); |
|
|
} |
|
|
|
|
|
void SDL_SYS_TimerQuit(void) |
|
|
{ |
|
|
/* Uninstall RunTimer vbl vector */ |
|
|
if (timer_installed) { |
|
|
void *old_stack = (void *)Super(0); |
|
|
SDL_AtariVblUninstall(SDL_ThreadedTimerCheck); |
|
|
SuperToUser(old_stack); |
|
|
timer_installed = SDL_FALSE; |
|
|
} |
|
|
read_hz200_from_vbl = SDL_FALSE; |
|
|
SDL_SetTimer(0, NULL); |
|
|
} |
|
|
|
|
|
int SDL_SYS_StartTimer(void) |
|
|
{ |
|
|
SDL_SetError("Internal logic error: MiNT uses vbl timer"); |
|
|
return(-1); |
|
|
timerStart = SDL_GetTicks(); |
|
|
|
|
|
return(0); |
|
|
} |
|
|
|
|
|
void SDL_SYS_StopTimer(void) |
|
|
{ |
|
|
return; |
|
|
/* Don't need to do anything as we use SDL_timer_running |
|
|
to detect if we need to check the timer */ |
|
|
} |
|
|
|
|
|
|
|
|
void SDL_AtariMint_CheckTimer(void) |
|
|
{ |
|
|
if (SDL_timer_running && SDL_GetTicks() - timerStart >= SDL_alarm_interval) |
|
|
{ |
|
|
Uint32 ms; |
|
|
|
|
|
ms = SDL_alarm_callback(SDL_alarm_interval); |
|
|
if ( ms != SDL_alarm_interval ) |
|
|
{ |
|
|
if ( ms ) |
|
|
{ |
|
|
SDL_alarm_interval = ROUND_RESOLUTION(ms); |
|
|
} else |
|
|
{ |
|
|
SDL_alarm_interval = 0; |
|
|
SDL_timer_running = 0; |
|
|
} |
|
|
} |
|
|
if (SDL_alarm_interval) timerStart = SDL_GetTicks(); |
|
|
} |
|
|
} |
|
|
|
|
|
#endif /* SDL_TIMER_MINT */ |