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@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 */ 54void SDL_MintAudio_CheckFpu(void); 55 56/* The first ticks value of the application */ 57static Uint32 start; 58static SDL_bool read_hz200_from_vbl = SDL_FALSE; 59static int mint_present; /* can we use Syield() ? */ 60 61void 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 76Uint32 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 91void 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 */ 104static SDL_bool timer_installed=SDL_FALSE; 105 106/* This is only called if the event thread is not running */ 107int 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 126void 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 138int SDL_SYS_StartTimer(void) 139{ 140 SDL_SetError("Internal logic error: MiNT uses vbl timer"); 141 return(-1); 142} 143 144void SDL_SYS_StopTimer(void) 145{ 146 return; 147} 148 149#endif /* SDL_TIMER_MINT */ 150