Skip to content
Permalink
Browse files

atari: Do not use system interrupt for handling timer. Do it from use…

…rspace, like RISCOS backend.
  • Loading branch information
pmandin committed Jul 28, 2014
1 parent f666cbb commit d9769b053283738048c5b63dc1454eaf0d6bad81
@@ -2865,7 +2865,6 @@ case "$host" in
else
AC_DEFINE(SDL_TIMER_MINT)
SOURCES="$SOURCES $srcdir/src/timer/mint/*.c"
SOURCES="$SOURCES $srcdir/src/timer/mint/*.S"
fi
have_timers=yes
fi
@@ -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 */

0 comments on commit d9769b0

Please sign in to comment.