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 */