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