Mercurial > sdl-ios-xcode
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"); |