Home | History | Annotate | Download | only in mint
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2012 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 "../../video/ataricommon/SDL_atarisuper.h"
     50 
     51 #include "SDL_vbltimer_s.h"
     52 
     53 /* from audio/mint */
     54 void SDL_MintAudio_CheckFpu(void);
     55 
     56 /* The first ticks value of the application */
     57 static Uint32 start;
     58 static SDL_bool read_hz200_from_vbl = SDL_FALSE;
     59 static int mint_present; /* can we use Syield() ? */
     60 
     61 void SDL_StartTicks(void)
     62 {
     63 	void *old_stack;
     64 	long dummy;
     65 
     66 	/* Set first ticks value */
     67 	old_stack = (void *)Super(0);
     68 	start = *((volatile long *)_hz_200);
     69 	SuperToUser(old_stack);
     70 
     71 	start *= 5;	/* One _hz_200 tic is 5ms */
     72 
     73 	mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);
     74 }
     75 
     76 Uint32 SDL_GetTicks (void)
     77 {
     78 	Uint32 now = start;
     79 
     80 	if (read_hz200_from_vbl) {
     81 		now = SDL_Atari_hz200;
     82 	} else {
     83 		void *old_stack = (void *)Super(0);
     84 		now = *((volatile long *)_hz_200);
     85 		SuperToUser(old_stack);
     86 	}
     87 
     88 	return((now*5)-start);
     89 }
     90 
     91 void SDL_Delay (Uint32 ms)
     92 {
     93 	Uint32 now;
     94 
     95 	now = SDL_GetTicks();
     96 	while ((SDL_GetTicks()-now)<ms){
     97 		if (mint_present) {
     98 			Syield();
     99 		}
    100 	}
    101 }
    102 
    103 /* Data to handle a single periodic alarm */
    104 static SDL_bool timer_installed=SDL_FALSE;
    105 
    106 /* This is only called if the event thread is not running */
    107 int SDL_SYS_TimerInit(void)
    108 {
    109 	void *old_stack;
    110 
    111 	SDL_MintAudio_CheckFpu();
    112 
    113 	/* Install RunTimer in vbl vector */
    114 	old_stack = (void *)Super(0);
    115 	timer_installed = !SDL_AtariVblInstall(SDL_ThreadedTimerCheck);
    116 	SuperToUser(old_stack);
    117 
    118 	if (!timer_installed) {
    119 		return(-1);
    120 	}
    121 
    122 	read_hz200_from_vbl = SDL_TRUE;
    123 	return(SDL_SetTimerThreaded(0));
    124 }
    125 
    126 void SDL_SYS_TimerQuit(void)
    127 {
    128 	/* Uninstall RunTimer vbl vector */
    129 	if (timer_installed) {
    130 		void *old_stack = (void *)Super(0);
    131 		SDL_AtariVblUninstall(SDL_ThreadedTimerCheck);
    132 		SuperToUser(old_stack);
    133 		timer_installed = SDL_FALSE;
    134 	}
    135 	read_hz200_from_vbl = SDL_FALSE;
    136 }
    137 
    138 int SDL_SYS_StartTimer(void)
    139 {
    140 	SDL_SetError("Internal logic error: MiNT uses vbl timer");
    141 	return(-1);
    142 }
    143 
    144 void SDL_SYS_StopTimer(void)
    145 {
    146 	return;
    147 }
    148 
    149 #endif /* SDL_TIMER_MINT */
    150