comparison src/timer/mint/SDL_systimer.c @ 3955:40b6b5744e05 SDL-1.2

Avoid switch to supervisor mode in SDL_GetTicks, by updating system counter from vbl interrupt
author Patrice Mandin <patmandin@gmail.com>
date Sat, 09 Jun 2007 19:52:05 +0000
parents 649fba69eccd
children a1b03ba2fcd0
comparison
equal deleted inserted replaced
3954:649fba69eccd 3955:40b6b5744e05
51 /* from audio/mint */ 51 /* from audio/mint */
52 void SDL_MintAudio_CheckFpu(void); 52 void SDL_MintAudio_CheckFpu(void);
53 53
54 /* The first ticks value of the application */ 54 /* The first ticks value of the application */
55 static Uint32 start; 55 static Uint32 start;
56 static volatile SDL_bool supervisor; 56 static SDL_bool read_hz200_from_vbl = SDL_FALSE;
57 static int mint_present; /* can we use Syield() ? */ 57 static int mint_present; /* can we use Syield() ? */
58 58
59 void SDL_StartTicks(void) 59 void SDL_StartTicks(void)
60 { 60 {
61 void *oldpile; 61 void *old_stack;
62 unsigned long dummy; 62 unsigned long dummy;
63 63
64 /* Set first ticks value */ 64 /* Set first ticks value */
65 oldpile=(void *)Super(0); 65 old_stack = (void *)Super(0);
66 start=*((volatile long *)_hz_200); 66 start = *((volatile long *)_hz_200);
67 Super(oldpile); 67 Super(old_stack);
68 68
69 start *= 5; /* One _hz_200 tic is 5ms */ 69 start *= 5; /* One _hz_200 tic is 5ms */
70 70
71 mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); 71 mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);
72 } 72 }
73 73
74 Uint32 SDL_GetTicks (void) 74 Uint32 SDL_GetTicks (void)
75 { 75 {
76 Uint32 now; 76 Uint32 now = start;
77 void *oldpile=NULL;
78 77
79 /* Check if we are in supervisor mode 78 if (read_hz200_from_vbl) {
80 (this is the case when called from SDL_ThreadedTimerCheck, 79 now = SDL_Atari_hz200;
81 which is called from RunTimer, running in the vbl vector) 80 } else {
82 */ 81 void *old_stack = (void *)Super(0);
83 if (!supervisor) { 82 now = *((volatile long *)_hz_200);
84 oldpile=(void *)Super(0); 83 Super(old_stack);
85 }
86
87 now=*((volatile long *)_hz_200);
88
89 if (!supervisor) {
90 Super(oldpile);
91 } 84 }
92 85
93 return((now*5)-start); 86 return((now*5)-start);
94 } 87 }
95 88
106 } 99 }
107 100
108 /* Data to handle a single periodic alarm */ 101 /* Data to handle a single periodic alarm */
109 static SDL_bool timer_installed=SDL_FALSE; 102 static SDL_bool timer_installed=SDL_FALSE;
110 103
111 static void RunTimer(void)
112 {
113 supervisor=SDL_TRUE;
114 SDL_ThreadedTimerCheck();
115 supervisor=SDL_FALSE;
116 }
117
118 /* This is only called if the event thread is not running */ 104 /* This is only called if the event thread is not running */
119 int SDL_SYS_TimerInit(void) 105 int SDL_SYS_TimerInit(void)
120 { 106 {
121 void *oldpile; 107 void *old_stack;
122
123 supervisor=SDL_FALSE;
124 108
125 SDL_MintAudio_CheckFpu(); 109 SDL_MintAudio_CheckFpu();
126 110
127 /* Install RunTimer in vbl vector */ 111 /* Install RunTimer in vbl vector */
128 oldpile=(void *)Super(0); 112 old_stack = (void *)Super(0);
129 timer_installed = !SDL_AtariVblInstall(RunTimer); 113 timer_installed = !SDL_AtariVblInstall(SDL_ThreadedTimerCheck);
130 Super(oldpile); 114 Super(old_stack);
131 115
132 if (!timer_installed) { 116 if (!timer_installed) {
133 return(-1); 117 return(-1);
134 } 118 }
119
120 read_hz200_from_vbl = SDL_TRUE;
135 return(SDL_SetTimerThreaded(0)); 121 return(SDL_SetTimerThreaded(0));
136 } 122 }
137 123
138 void SDL_SYS_TimerQuit(void) 124 void SDL_SYS_TimerQuit(void)
139 { 125 {
140 void *oldpile; 126 /* Uninstall RunTimer vbl vector */
141
142 if (timer_installed) { 127 if (timer_installed) {
143 /* Uninstall RunTimer vbl vector */ 128 void *old_stack = (void *)Super(0);
144 oldpile=(void *)Super(0); 129 SDL_AtariVblUninstall(SDL_ThreadedTimerCheck);
145 SDL_AtariVblUninstall(RunTimer); 130 Super(old_stack);
146 Super(oldpile);
147 timer_installed = SDL_FALSE; 131 timer_installed = SDL_FALSE;
148 } 132 }
133 read_hz200_from_vbl = SDL_FALSE;
149 } 134 }
150 135
151 int SDL_SYS_StartTimer(void) 136 int SDL_SYS_StartTimer(void)
152 { 137 {
153 SDL_SetError("Internal logic error: MiNT uses vbl timer"); 138 SDL_SetError("Internal logic error: MiNT uses vbl timer");