Home | History | Annotate | Download | only in mint
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2006 Sam Lantinga
      4 
      5     This library is free software; you can redistribute it and/or
      6     modify it under the terms of the GNU Lesser General Public
      7     License as published by the Free Software Foundation; either
      8     version 2.1 of the License, or (at your option) any later version.
      9 
     10     This library is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13     Lesser General Public License for more details.
     14 
     15     You should have received a copy of the GNU Lesser General Public
     16     License along with this library; if not, write to the Free Software
     17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     18 
     19     Sam Lantinga
     20     slouken (at) libsdl.org
     21 */
     22 #include "SDL_config.h"
     23 
     24 #ifdef SDL_TIMER_MINT
     25 
     26 /*
     27  *	TOS/MiNT timer driver
     28  *	based on vbl vector
     29  *
     30  *	Patrice Mandin
     31  */
     32 
     33 #include <stdio.h>
     34 #include <sys/time.h>
     35 #include <signal.h>
     36 #include <unistd.h>
     37 #include <string.h>
     38 #include <errno.h>
     39 
     40 #include <mint/cookie.h>
     41 #include <mint/sysvars.h>
     42 #include <mint/osbind.h>
     43 #include <mint/mintbind.h>
     44 
     45 #include "SDL_timer.h"
     46 #include "../SDL_timer_c.h"
     47 #include "SDL_thread.h"
     48 
     49 #include "SDL_vbltimer_s.h"
     50 
     51 /* from audio/mint */
     52 void SDL_MintAudio_CheckFpu(void);
     53 
     54 /* The first ticks value of the application */
     55 static Uint32 start;
     56 static SDL_bool read_hz200_from_vbl = SDL_FALSE;
     57 static int mint_present; /* can we use Syield() ? */
     58 
     59 void SDL_StartTicks(void)
     60 {
     61 	void *old_stack;
     62 	unsigned long dummy;
     63 
     64 	/* Set first ticks value */
     65 	old_stack = (void *)Super(0);
     66 	start = *((volatile long *)_hz_200);
     67 	Super(old_stack);
     68 
     69 	start *= 5;	/* One _hz_200 tic is 5ms */
     70 
     71 	mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);
     72 }
     73 
     74 Uint32 SDL_GetTicks (void)
     75 {
     76 	Uint32 now = start;
     77 
     78 	if (read_hz200_from_vbl) {
     79 		now = SDL_Atari_hz200;
     80 	} else {
     81 		void *old_stack = (void *)Super(0);
     82 		now = *((volatile long *)_hz_200);
     83 		Super(old_stack);
     84 	}
     85 
     86 	return((now*5)-start);
     87 }
     88 
     89 void SDL_Delay (Uint32 ms)
     90 {
     91 	Uint32 now;
     92 
     93 	now = SDL_GetTicks();
     94 	while ((SDL_GetTicks()-now)<ms){
     95 		if (mint_present) {
     96 			Syield();
     97 		}
     98 	}
     99 }
    100 
    101 /* Data to handle a single periodic alarm */
    102 static SDL_bool timer_installed=SDL_FALSE;
    103 
    104 /* This is only called if the event thread is not running */
    105 int SDL_SYS_TimerInit(void)
    106 {
    107 	void *old_stack;
    108 
    109 	SDL_MintAudio_CheckFpu();
    110 
    111 	/* Install RunTimer in vbl vector */
    112 	old_stack = (void *)Super(0);
    113 	timer_installed = !SDL_AtariVblInstall(SDL_ThreadedTimerCheck);
    114 	Super(old_stack);
    115 
    116 	if (!timer_installed) {
    117 		return(-1);
    118 	}
    119 
    120 	read_hz200_from_vbl = SDL_TRUE;
    121 	return(SDL_SetTimerThreaded(0));
    122 }
    123 
    124 void SDL_SYS_TimerQuit(void)
    125 {
    126 	/* Uninstall RunTimer vbl vector */
    127 	if (timer_installed) {
    128 		void *old_stack = (void *)Super(0);
    129 		SDL_AtariVblUninstall(SDL_ThreadedTimerCheck);
    130 		Super(old_stack);
    131 		timer_installed = SDL_FALSE;
    132 	}
    133 	read_hz200_from_vbl = SDL_FALSE;
    134 }
    135 
    136 int SDL_SYS_StartTimer(void)
    137 {
    138 	SDL_SetError("Internal logic error: MiNT uses vbl timer");
    139 	return(-1);
    140 }
    141 
    142 void SDL_SYS_StopTimer(void)
    143 {
    144 	return;
    145 }
    146 
    147 #endif /* SDL_TIMER_MINT */
    148