Avoid switch to supervisor mode in SDL_GetTicks, by updating system counter from vbl interrupt
authorPatrice Mandin <patmandin@gmail.com>
Sat, 09 Jun 2007 19:58:41 +0000
changeset 2116 b42abf0a50bc
parent 2115 502ae1f2a577
child 2117 40888832d785
Avoid switch to supervisor mode in SDL_GetTicks, by updating system counter from vbl interrupt
src/timer/mint/SDL_systimer.c
src/timer/mint/SDL_vbltimer.S
src/timer/mint/SDL_vbltimer_s.h
--- a/src/timer/mint/SDL_systimer.c	Fri Jun 08 21:44:55 2007 +0000
+++ b/src/timer/mint/SDL_systimer.c	Sat Jun 09 19:58:41 2007 +0000
@@ -53,7 +53,7 @@
 
 /* The first ticks value of the application */
 static Uint32 start;
-static volatile SDL_bool supervisor;
+static SDL_bool read_hz200_from_vbl = SDL_FALSE;
 static int mint_present;        /* can we use Syield() ? */
 
 void
@@ -75,21 +75,14 @@
 Uint32
 SDL_GetTicks(void)
 {
-    Uint32 now;
-    void *oldpile = NULL;
+    Uint32 now = start;
 
-    /* Check if we are in supervisor mode 
-       (this is the case when called from SDL_ThreadedTimerCheck,
-       which is called from RunTimer, running in the vbl vector)
-     */
-    if (!supervisor) {
-        oldpile = (void *) Super(0);
-    }
-
-    now = *((volatile long *) _hz_200);
-
-    if (!supervisor) {
-        Super(oldpile);
+    if (read_hz200_from_vbl) {
+        now = SDL_Atari_hz200;
+    } else {
+        void *old_stack = (void *)Super(0);
+        now = *((volatile long *)_hz_200);
+        Super(old_stack);
     }
 
     return ((now * 5) - start);
@@ -111,47 +104,38 @@
 /* Data to handle a single periodic alarm */
 static SDL_bool timer_installed = SDL_FALSE;
 
-static void
-RunTimer(void)
-{
-    supervisor = SDL_TRUE;
-    SDL_ThreadedTimerCheck();
-    supervisor = SDL_FALSE;
-}
-
 /* This is only called if the event thread is not running */
 int
 SDL_SYS_TimerInit(void)
 {
-    void *oldpile;
-
-    supervisor = SDL_FALSE;
+    void *old_stack;
 
     SDL_MintAudio_CheckFpu();
 
     /* Install RunTimer in vbl vector */
-    oldpile = (void *) Super(0);
-    timer_installed = !SDL_AtariVblInstall(RunTimer);
-    Super(oldpile);
+    old_stack = (void *) Super(0);
+    timer_installed = !SDL_AtariVblInstall(SDL_ThreadedTimerCheck);
+    Super(old_stack);
 
     if (!timer_installed) {
         return (-1);
     }
+
+    read_hz200_from_vbl = SDL_TRUE;
     return (SDL_SetTimerThreaded(0));
 }
 
 void
 SDL_SYS_TimerQuit(void)
 {
-    void *oldpile;
-
     if (timer_installed) {
         /* Uninstall RunTimer vbl vector */
-        oldpile = (void *) Super(0);
+        void *old_stack = (void *) Super(0);
         SDL_AtariVblUninstall(RunTimer);
-        Super(oldpile);
+        Super(old_stack);
         timer_installed = SDL_FALSE;
     }
+    read_hz200_from_vbl = SDL_FALSE;
 }
 
 int
--- a/src/timer/mint/SDL_vbltimer.S	Fri Jun 08 21:44:55 2007 +0000
+++ b/src/timer/mint/SDL_vbltimer.S	Sat Jun 09 19:58:41 2007 +0000
@@ -27,6 +27,7 @@
  */
 
 #define _vbl_queue 0x456
+#define _hz_200    0x4ba
 
 	.text
 
@@ -42,6 +43,7 @@
 	lea		_my_vbl,a0
 
 	clrw	vbl_mutex
+	movel	_hz_200.w, _SDL_Atari_hz200
 
 	/* Stop interrupts */
 
@@ -108,6 +110,9 @@
 /*--- Our vbl ---*/
 
 _my_vbl:
+	/* Update _hz_200 */
+	movel	_hz_200.w, _SDL_Atari_hz200
+
 	/* Verify if this is not already running */
 
 	tstw	vbl_mutex
@@ -147,6 +152,8 @@
 
 	.data
 	.even
+	.comm	_SDL_Atari_hz200,4*1
+	.even
 	.comm	vbl_mutex,2*1
 	.even
 	.comm	my_vector,4*1
--- a/src/timer/mint/SDL_vbltimer_s.h	Fri Jun 08 21:44:55 2007 +0000
+++ b/src/timer/mint/SDL_vbltimer_s.h	Sat Jun 09 19:58:41 2007 +0000
@@ -28,6 +28,8 @@
  *	Patrice Mandin
  */
 
+extern volatile long SDL_Atari_hz200;
+
 /* Functions prototypes */
 extern int SDL_AtariVblInstall(void *newvector);
 extern void SDL_AtariVblUninstall(void *newvector);