Avoid switch to supervisor mode in SDL_GetTicks, by updating system counter from vbl interrupt SDL-1.2
authorPatrice Mandin <patmandin@gmail.com>
Sat, 09 Jun 2007 19:52:05 +0000
branchSDL-1.2
changeset 3955 40b6b5744e05
parent 3954 649fba69eccd
child 3956 3868bebb9f5b
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:40 2007 +0000
+++ b/src/timer/mint/SDL_systimer.c	Sat Jun 09 19:52:05 2007 +0000
@@ -53,18 +53,18 @@
 
 /* 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 SDL_StartTicks(void)
 {
-	void *oldpile;
+	void *old_stack;
 	unsigned long dummy;
 
 	/* Set first ticks value */
-	oldpile=(void *)Super(0);
-	start=*((volatile long *)_hz_200);
-	Super(oldpile);
+	old_stack = (void *)Super(0);
+	start = *((volatile long *)_hz_200);
+	Super(old_stack);
 
 	start *= 5;	/* One _hz_200 tic is 5ms */
 
@@ -73,21 +73,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);
@@ -108,44 +101,36 @@
 /* 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;
-
+	/* Uninstall RunTimer vbl vector */
 	if (timer_installed) {
-		/* Uninstall RunTimer vbl vector */
-		oldpile=(void *)Super(0);
-		SDL_AtariVblUninstall(RunTimer);
-		Super(oldpile);
+		void *old_stack = (void *)Super(0);
+		SDL_AtariVblUninstall(SDL_ThreadedTimerCheck);
+		Super(old_stack);
 		timer_installed = SDL_FALSE;
 	}
+	read_hz200_from_vbl = SDL_FALSE;
 }
 
 int SDL_SYS_StartTimer(void)
--- a/src/timer/mint/SDL_vbltimer.S	Fri Jun 08 21:44:40 2007 +0000
+++ b/src/timer/mint/SDL_vbltimer.S	Sat Jun 09 19:52:05 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:40 2007 +0000
+++ b/src/timer/mint/SDL_vbltimer_s.h	Sat Jun 09 19:52:05 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);