Mercurial > sdl-ios-xcode
comparison src/timer/macos/FastTimes.c @ 1668:4da1ee79c9af SDL-1.3
more tweaking indent options
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 29 May 2006 04:04:35 +0000 |
parents | 782fd950bd46 |
children |
comparison
equal
deleted
inserted
replaced
1667:1fddae038bc8 | 1668:4da1ee79c9af |
---|---|
76 anything before MacOS 9) -- regardless whether we are in Carbon or not! */ | 76 anything before MacOS 9) -- regardless whether we are in Carbon or not! */ |
77 #define MyLMGetTicks() (*(volatile UInt32 *) 0x16A) | 77 #define MyLMGetTicks() (*(volatile UInt32 *) 0x16A) |
78 | 78 |
79 #if GENERATINGPOWERPC | 79 #if GENERATINGPOWERPC |
80 | 80 |
81 static asm UnsignedWide PollRTC (void); | 81 static asm UnsignedWide PollRTC(void); |
82 static asm UnsignedWide PollTBR (void); | 82 static asm UnsignedWide PollTBR(void); |
83 static Ptr FindFunctionInSharedLib (StringPtr libName, StringPtr funcName); | 83 static Ptr FindFunctionInSharedLib(StringPtr libName, StringPtr funcName); |
84 | 84 |
85 static Boolean gInited = false; | 85 static Boolean gInited = false; |
86 static Boolean gNative = false; | 86 static Boolean gNative = false; |
87 static Boolean gUseRTC = false; | 87 static Boolean gUseRTC = false; |
88 static Boolean gUseTBR = false; | 88 static Boolean gUseTBR = false; |
89 static double gScaleUSec = 1.0 / 1000.0; /* 1 / ( nsec / usec) */ | 89 static double gScaleUSec = 1.0 / 1000.0; /* 1 / ( nsec / usec) */ |
90 static double gScaleMSec = 1.0 / 1000000.0; /* 1 / ( nsec / msec) */ | 90 static double gScaleMSec = 1.0 / 1000000.0; /* 1 / ( nsec / msec) */ |
91 | 91 |
92 /* Functions loaded from DriverServicesLib */ | 92 /* Functions loaded from DriverServicesLib */ |
93 typedef AbsoluteTime (*UpTimeProcPtr) (void); | 93 typedef AbsoluteTime(*UpTimeProcPtr) (void); |
94 typedef Nanoseconds (*A2NSProcPtr) (AbsoluteTime); | 94 typedef Nanoseconds(*A2NSProcPtr) (AbsoluteTime); |
95 static UpTimeProcPtr gUpTime = NULL; | 95 static UpTimeProcPtr gUpTime = NULL; |
96 static A2NSProcPtr gA2NS = NULL; | 96 static A2NSProcPtr gA2NS = NULL; |
97 | 97 |
98 #endif /* GENERATINGPOWERPC */ | 98 #endif /* GENERATINGPOWERPC */ |
99 | 99 |
100 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 100 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
101 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 101 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
102 | 102 |
103 void | 103 void |
104 FastInitialize () | 104 FastInitialize() |
105 { | 105 { |
106 SInt32 result; | 106 SInt32 result; |
107 | 107 |
108 if (!gInited) { | 108 if (!gInited) { |
109 | 109 |
113 gNative = gUseRTC = gUseTBR = false; | 113 gNative = gUseRTC = gUseTBR = false; |
114 | 114 |
115 /* We use CFM to find and load needed symbols from shared libraries, so | 115 /* We use CFM to find and load needed symbols from shared libraries, so |
116 the application doesn't have to weak-link them, for convenience. */ | 116 the application doesn't have to weak-link them, for convenience. */ |
117 gUpTime = | 117 gUpTime = |
118 (UpTimeProcPtr) FindFunctionInSharedLib ("\pDriverServicesLib", | 118 (UpTimeProcPtr) FindFunctionInSharedLib("\pDriverServicesLib", |
119 "\pUpTime"); | 119 "\pUpTime"); |
120 if (gUpTime) | 120 if (gUpTime) |
121 gA2NS = (A2NSProcPtr) | 121 gA2NS = (A2NSProcPtr) |
122 FindFunctionInSharedLib ("\pDriverServicesLib", | 122 FindFunctionInSharedLib("\pDriverServicesLib", |
123 "\pAbsoluteToNanoseconds"); | 123 "\pAbsoluteToNanoseconds"); |
124 if (!gA2NS) | 124 if (!gA2NS) |
125 gUpTime = nil; /* Pedantic but necessary */ | 125 gUpTime = nil; /* Pedantic but necessary */ |
126 | 126 |
127 if (gUpTime) { | 127 if (gUpTime) { |
128 /* If we loaded UpTime(), then we need to know if the system has | 128 /* If we loaded UpTime(), then we need to know if the system has |
129 a native implementation of the Time Manager. If so, then it's | 129 a native implementation of the Time Manager. If so, then it's |
130 pointless to calculate a scale factor against the missing VIA */ | 130 pointless to calculate a scale factor against the missing VIA */ |
131 | 131 |
132 /* gestaltNativeTimeMgr = 4 in some future version of the headers */ | 132 /* gestaltNativeTimeMgr = 4 in some future version of the headers */ |
133 if (!Gestalt (gestaltTimeMgrVersion, &result) && | 133 if (!Gestalt(gestaltTimeMgrVersion, &result) && |
134 (result > gestaltExtendedTimeMgr)) | 134 (result > gestaltExtendedTimeMgr)) |
135 gNative = true; | 135 gNative = true; |
136 } else { | 136 } else { |
137 /* If no DriverServicesLib, use Gestalt() to get the processor type. | 137 /* If no DriverServicesLib, use Gestalt() to get the processor type. |
138 Only NuBus PowerMacs with old System Software won't have DSL, so | 138 Only NuBus PowerMacs with old System Software won't have DSL, so |
139 we know it should either be a 601 or 603. */ | 139 we know it should either be a 601 or 603. */ |
140 | 140 |
141 /* Use the processor gestalt to determine which register to use */ | 141 /* Use the processor gestalt to determine which register to use */ |
142 if (!Gestalt (gestaltNativeCPUtype, &result)) { | 142 if (!Gestalt(gestaltNativeCPUtype, &result)) { |
143 if (result == gestaltCPU601) | 143 if (result == gestaltCPU601) |
144 gUseRTC = true; | 144 gUseRTC = true; |
145 else if (result > gestaltCPU601) | 145 else if (result > gestaltCPU601) |
146 gUseTBR = true; | 146 gUseTBR = true; |
147 } | 147 } |
151 if ((gUpTime && !gNative) || gUseRTC || gUseTBR) { | 151 if ((gUpTime && !gNative) || gUseRTC || gUseTBR) { |
152 UInt64 tick, usec1, usec2; | 152 UInt64 tick, usec1, usec2; |
153 UnsignedWide wide; | 153 UnsignedWide wide; |
154 | 154 |
155 /* Wait for the beginning of the very next tick */ | 155 /* Wait for the beginning of the very next tick */ |
156 for (tick = MyLMGetTicks () + 1; tick > MyLMGetTicks ();); | 156 for (tick = MyLMGetTicks() + 1; tick > MyLMGetTicks();); |
157 | 157 |
158 /* Poll the selected timer and prepare it (since we have time) */ | 158 /* Poll the selected timer and prepare it (since we have time) */ |
159 wide = (gUpTime) ? (*gA2NS) ((*gUpTime) ()) : | 159 wide = (gUpTime) ? (*gA2NS) ((*gUpTime) ()) : |
160 ((gUseRTC) ? PollRTC () : PollTBR ()); | 160 ((gUseRTC) ? PollRTC() : PollTBR()); |
161 usec1 = (gUseRTC) ? RTCToNano (wide) : WideTo64bit (wide); | 161 usec1 = (gUseRTC) ? RTCToNano(wide) : WideTo64bit(wide); |
162 | 162 |
163 /* Wait for the exact 60th tick to roll over */ | 163 /* Wait for the exact 60th tick to roll over */ |
164 while (tick + 60 > MyLMGetTicks ()); | 164 while (tick + 60 > MyLMGetTicks()); |
165 | 165 |
166 /* Poll the selected timer again and prepare it */ | 166 /* Poll the selected timer again and prepare it */ |
167 wide = (gUpTime) ? (*gA2NS) ((*gUpTime) ()) : | 167 wide = (gUpTime) ? (*gA2NS) ((*gUpTime) ()) : |
168 ((gUseRTC) ? PollRTC () : PollTBR ()); | 168 ((gUseRTC) ? PollRTC() : PollTBR()); |
169 usec2 = (gUseRTC) ? RTCToNano (wide) : WideTo64bit (wide); | 169 usec2 = (gUseRTC) ? RTCToNano(wide) : WideTo64bit(wide); |
170 | 170 |
171 /* Calculate a scale value that will give microseconds per second. | 171 /* Calculate a scale value that will give microseconds per second. |
172 Remember, there are actually 60.15 ticks in a second, not 60. */ | 172 Remember, there are actually 60.15 ticks in a second, not 60. */ |
173 gScaleUSec = (60.0 * 1000000.0) / ((usec2 - usec1) * 60.15); | 173 gScaleUSec = (60.0 * 1000000.0) / ((usec2 - usec1) * 60.15); |
174 gScaleMSec = gScaleUSec / 1000.0; | 174 gScaleMSec = gScaleUSec / 1000.0; |
182 | 182 |
183 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 183 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
184 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 184 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
185 | 185 |
186 UInt64 | 186 UInt64 |
187 FastMicroseconds () | 187 FastMicroseconds() |
188 { | 188 { |
189 UnsignedWide wide; | 189 UnsignedWide wide; |
190 UInt64 usec; | 190 UInt64 usec; |
191 | 191 |
192 #if GENERATINGPOWERPC | 192 #if GENERATINGPOWERPC |
193 /* Initialize globals the first time we are called */ | 193 /* Initialize globals the first time we are called */ |
194 if (!gInited) | 194 if (!gInited) |
195 FastInitialize (); | 195 FastInitialize(); |
196 | 196 |
197 if (gNative) { | 197 if (gNative) { |
198 /* Use DriverServices if it's available -- it's fast and compatible */ | 198 /* Use DriverServices if it's available -- it's fast and compatible */ |
199 wide = (*gA2NS) ((*gUpTime) ()); | 199 wide = (*gA2NS) ((*gUpTime) ()); |
200 usec = (double) WideTo64bit (wide) * gScaleUSec + 0.5; | 200 usec = (double) WideTo64bit(wide) * gScaleUSec + 0.5; |
201 } else if (gUpTime) { | 201 } else if (gUpTime) { |
202 /* Use DriverServices if it's available -- it's fast and compatible */ | 202 /* Use DriverServices if it's available -- it's fast and compatible */ |
203 wide = (*gA2NS) ((*gUpTime) ()); | 203 wide = (*gA2NS) ((*gUpTime) ()); |
204 usec = (double) WideTo64bit (wide) * gScaleUSec + 0.5; | 204 usec = (double) WideTo64bit(wide) * gScaleUSec + 0.5; |
205 } else if (gUseTBR) { | 205 } else if (gUseTBR) { |
206 /* On a recent PowerPC, we poll the TBR directly */ | 206 /* On a recent PowerPC, we poll the TBR directly */ |
207 wide = PollTBR (); | 207 wide = PollTBR(); |
208 usec = (double) WideTo64bit (wide) * gScaleUSec + 0.5; | 208 usec = (double) WideTo64bit(wide) * gScaleUSec + 0.5; |
209 } else if (gUseRTC) { | 209 } else if (gUseRTC) { |
210 /* On a 601, we can poll the RTC instead */ | 210 /* On a 601, we can poll the RTC instead */ |
211 wide = PollRTC (); | 211 wide = PollRTC(); |
212 usec = (double) RTCToNano (wide) * gScaleUSec + 0.5; | 212 usec = (double) RTCToNano(wide) * gScaleUSec + 0.5; |
213 } else | 213 } else |
214 #endif /* GENERATINGPOWERPC */ | 214 #endif /* GENERATINGPOWERPC */ |
215 { | 215 { |
216 /* If all else fails, suffer the mixed mode overhead */ | 216 /* If all else fails, suffer the mixed mode overhead */ |
217 Microseconds (&wide); | 217 Microseconds(&wide); |
218 usec = WideTo64bit (wide); | 218 usec = WideTo64bit(wide); |
219 } | 219 } |
220 | 220 |
221 return (usec); | 221 return (usec); |
222 } | 222 } |
223 | 223 |
224 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 224 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
225 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 225 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
226 | 226 |
227 UInt64 | 227 UInt64 |
228 FastMilliseconds () | 228 FastMilliseconds() |
229 { | 229 { |
230 UnsignedWide wide; | 230 UnsignedWide wide; |
231 UInt64 msec; | 231 UInt64 msec; |
232 | 232 |
233 #if GENERATINGPOWERPC | 233 #if GENERATINGPOWERPC |
234 /* Initialize globals the first time we are called */ | 234 /* Initialize globals the first time we are called */ |
235 if (!gInited) | 235 if (!gInited) |
236 FastInitialize (); | 236 FastInitialize(); |
237 | 237 |
238 if (gNative) { | 238 if (gNative) { |
239 /* Use DriverServices if it's available -- it's fast and compatible */ | 239 /* Use DriverServices if it's available -- it's fast and compatible */ |
240 wide = (*gA2NS) ((*gUpTime) ()); | 240 wide = (*gA2NS) ((*gUpTime) ()); |
241 msec = (double) WideTo64bit (wide) * gScaleMSec + 0.5; | 241 msec = (double) WideTo64bit(wide) * gScaleMSec + 0.5; |
242 } else if (gUpTime) { | 242 } else if (gUpTime) { |
243 /* Use DriverServices if it's available -- it's fast and compatible */ | 243 /* Use DriverServices if it's available -- it's fast and compatible */ |
244 wide = (*gA2NS) ((*gUpTime) ()); | 244 wide = (*gA2NS) ((*gUpTime) ()); |
245 msec = (double) WideTo64bit (wide) * gScaleMSec + 0.5; | 245 msec = (double) WideTo64bit(wide) * gScaleMSec + 0.5; |
246 } else if (gUseTBR) { | 246 } else if (gUseTBR) { |
247 /* On a recent PowerPC, we poll the TBR directly */ | 247 /* On a recent PowerPC, we poll the TBR directly */ |
248 wide = PollTBR (); | 248 wide = PollTBR(); |
249 msec = (double) WideTo64bit (wide) * gScaleMSec + 0.5; | 249 msec = (double) WideTo64bit(wide) * gScaleMSec + 0.5; |
250 } else if (gUseRTC) { | 250 } else if (gUseRTC) { |
251 /* On a 601, we can poll the RTC instead */ | 251 /* On a 601, we can poll the RTC instead */ |
252 wide = PollRTC (); | 252 wide = PollRTC(); |
253 msec = (double) RTCToNano (wide) * gScaleMSec + 0.5; | 253 msec = (double) RTCToNano(wide) * gScaleMSec + 0.5; |
254 } else | 254 } else |
255 #endif /* GENERATINGPOWERPC */ | 255 #endif /* GENERATINGPOWERPC */ |
256 { | 256 { |
257 /* If all else fails, suffer the mixed mode overhead */ | 257 /* If all else fails, suffer the mixed mode overhead */ |
258 Microseconds (&wide); | 258 Microseconds(&wide); |
259 msec = ((double) WideTo64bit (wide) + 500.0) / 1000.0; | 259 msec = ((double) WideTo64bit(wide) + 500.0) / 1000.0; |
260 } | 260 } |
261 | 261 |
262 return (msec); | 262 return (msec); |
263 } | 263 } |
264 | 264 |
265 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 265 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
266 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 266 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
267 | 267 |
268 StringPtr | 268 StringPtr |
269 FastMethod () | 269 FastMethod() |
270 { | 270 { |
271 StringPtr method = "\p<Unknown>"; | 271 StringPtr method = "\p<Unknown>"; |
272 | 272 |
273 #if GENERATINGPOWERPC | 273 #if GENERATINGPOWERPC |
274 /* Initialize globals the first time we are called */ | 274 /* Initialize globals the first time we are called */ |
275 if (!gInited) | 275 if (!gInited) |
276 FastInitialize (); | 276 FastInitialize(); |
277 | 277 |
278 if (gNative) { | 278 if (gNative) { |
279 /* The Time Manager and UpTime() are entirely native on this machine */ | 279 /* The Time Manager and UpTime() are entirely native on this machine */ |
280 method = "\pNative UpTime()"; | 280 method = "\pNative UpTime()"; |
281 } else if (gUpTime) { | 281 } else if (gUpTime) { |
301 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 301 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
302 #pragma mark - | 302 #pragma mark - |
303 | 303 |
304 #if GENERATINGPOWERPC | 304 #if GENERATINGPOWERPC |
305 asm static UnsignedWide | 305 asm static UnsignedWide |
306 PollRTC_ () | 306 PollRTC_() |
307 { | 307 { |
308 entry PollRTC /* Avoid CodeWarrior glue */ | 308 entry PollRTC /* Avoid CodeWarrior glue */ |
309 machine 601 @ AGAIN:mfrtcu r4 /* RTCU = SPR 4 */ | 309 machine 601 @ AGAIN:mfrtcu r4 /* RTCU = SPR 4 */ |
310 mfrtcl r5 /* RTCL = SPR 5 */ | 310 mfrtcl r5 /* RTCL = SPR 5 */ |
311 mfrtcu r6 cmpw r4, r6 bne @ AGAIN stw r4, 0 (r3) stw r5, 4 (r3) blr} | 311 mfrtcu r6 cmpw r4, r6 bne @ AGAIN stw r4, 0(r3) stw r5, 4(r3) blr} |
312 | 312 |
313 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 313 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
314 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 314 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
315 | 315 |
316 asm static UnsignedWide | 316 asm static UnsignedWide |
317 PollTBR_ () | 317 PollTBR_() |
318 { | 318 { |
319 entry PollTBR /* Avoid CodeWarrior glue */ | 319 entry PollTBR /* Avoid CodeWarrior glue */ |
320 machine 604 @ AGAIN:mftbu r4 /* TBRU = SPR 268 */ | 320 machine 604 @ AGAIN:mftbu r4 /* TBRU = SPR 268 */ |
321 mftb r5 /* TBRL = SPR 269 */ | 321 mftb r5 /* TBRL = SPR 269 */ |
322 mftbu r6 cmpw r4, r6 bne @ AGAIN stw r4, 0 (r3) stw r5, 4 (r3) blr} | 322 mftbu r6 cmpw r4, r6 bne @ AGAIN stw r4, 0(r3) stw r5, 4(r3) blr} |
323 | 323 |
324 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 324 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
325 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ | 325 /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ |
326 | 326 |
327 static Ptr | 327 static Ptr |
328 FindFunctionInSharedLib (StringPtr libName, StringPtr funcName) | 328 FindFunctionInSharedLib(StringPtr libName, StringPtr funcName) |
329 { | 329 { |
330 OSErr error = noErr; | 330 OSErr error = noErr; |
331 Str255 errorStr; | 331 Str255 errorStr; |
332 Ptr func = NULL; | 332 Ptr func = NULL; |
333 Ptr entry = NULL; | 333 Ptr entry = NULL; |
334 CFragSymbolClass symClass; | 334 CFragSymbolClass symClass; |
335 CFragConnectionID connID; | 335 CFragConnectionID connID; |
336 | 336 |
337 /* Find CFM containers for the current archecture -- CFM-PPC or CFM-68K */ | 337 /* Find CFM containers for the current archecture -- CFM-PPC or CFM-68K */ |
338 if ( /* error = */ GetSharedLibrary (libName, kCompiledCFragArch, | 338 if ( /* error = */ GetSharedLibrary(libName, kCompiledCFragArch, |
339 kLoadCFrag, &connID, &entry, | 339 kLoadCFrag, &connID, &entry, |
340 errorStr)) | 340 errorStr)) |
341 return (NULL); | 341 return (NULL); |
342 if ( /* error = */ FindSymbol (connID, funcName, &func, &symClass)) | 342 if ( /* error = */ FindSymbol(connID, funcName, &func, &symClass)) |
343 return (NULL); | 343 return (NULL); |
344 | 344 |
345 return (func); | 345 return (func); |
346 } | 346 } |
347 #endif /* GENERATINGPOWERPC */ | 347 #endif /* GENERATINGPOWERPC */ |