]> git.ipfire.org Git - u-boot.git/blob - board/MAI/bios_emulator/scitech/src/pm/common.c
* Code cleanup:
[u-boot.git] / board / MAI / bios_emulator / scitech / src / pm / common.c
1 /****************************************************************************
2 *
3 * SciTech OS Portability Manager Library
4 *
5 * ========================================================================
6 *
7 * The contents of this file are subject to the SciTech MGL Public
8 * License Version 1.0 (the "License"); you may not use this file
9 * except in compliance with the License. You may obtain a copy of
10 * the License at http://www.scitechsoft.com/mgl-license.txt
11 *
12 * Software distributed under the License is distributed on an
13 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * rights and limitations under the License.
16 *
17 * The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
18 *
19 * The Initial Developer of the Original Code is SciTech Software, Inc.
20 * All Rights Reserved.
21 *
22 * ========================================================================
23 *
24 * Language: ANSI C
25 * Environment: Any
26 *
27 * Description: Module containing code common to all platforms.
28 *
29 ****************************************************************************/
30
31 #include "pmapi.h"
32 #include "drvlib/os/os.h"
33 #if defined(__WIN32_VXD__) || defined(__OS2_VDD__) || defined(__NT_DRIVER__)
34 #include "sdd/sddhelp.h"
35 #else
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #endif
40
41 /*---------------------------- Global variables ---------------------------*/
42
43 /* {secret} */
44 long _VARAPI ___drv_os_type = _OS_UNSUPPORTED;
45 static char localBPDPath[PM_MAX_PATH] = "";
46
47 /*----------------------------- Implementation ----------------------------*/
48
49 /****************************************************************************
50 PARAMETERS:
51 path - Local path to the Nucleus BPD driver files.
52
53 REMARKS:
54 This function is used by the application program to override the location
55 of the Nucleus driver files that are loaded. Normally the loader code
56 will look in the system Nucleus directories first, then in the 'drivers'
57 directory relative to the current working directory, and finally relative
58 to the MGL_ROOT environment variable. By default the local BPD path is
59 always set to the current directory if not initialised.
60 ****************************************************************************/
61 void PMAPI PM_setLocalBPDPath(
62 const char *path)
63 {
64 PM_init();
65 strncpy(localBPDPath,path,sizeof(localBPDPath));
66 localBPDPath[sizeof(localBPDPath)-1] = 0;
67 }
68
69 /****************************************************************************
70 PARAMETERS:
71 bpdpath - Place to store the actual path to the file
72 cachedpath - Place to store the cached BPD driver path
73 trypath - Path to try to find the BPD file in
74 subpath - Optional sub path to append to trypath
75 dllname - Name of the Binary Portable DLL to load
76
77 RETURNS:
78 True if found, false if not.
79
80 REMARKS:
81 Trys the specified path to see if the BPD file can be found or not. If so,
82 the path used is returned in bpdpath and cachedpath.
83 ****************************************************************************/
84 static ibool TryPath(
85 char *bpdpath,
86 char *cachedpath,
87 const char *trypath,
88 const char *subpath,
89 const char *dllname)
90 {
91 char filename[256];
92 FILE *f;
93
94 strcpy(bpdpath, trypath);
95 PM_backslash(bpdpath);
96 strcat(bpdpath,subpath);
97 PM_backslash(bpdpath);
98 strcpy(filename,bpdpath);
99 strcat(filename,dllname);
100 if ((f = fopen(filename,"rb")) == NULL)
101 return false;
102 if (cachedpath)
103 strcpy(cachedpath,bpdpath);
104 fclose(f);
105 return true;
106 }
107
108 /****************************************************************************
109 RETURNS:
110 True if local override enabled, false if not.
111
112 REMARKS:
113 Tests to see if the local override option is enabled, and if so it will
114 look for the Nucleus drivers in the local application directories in
115 preference to the Nucleus system directories.
116 ****************************************************************************/
117 static ibool GetLocalOverride(void)
118 {
119 char filename[256];
120 FILE *f;
121 static ibool local_override = -1;
122
123 if (local_override == -1) {
124 local_override = false;
125 strcpy(filename,PM_getNucleusPath());
126 PM_backslash(filename);
127 strcat(filename,"graphics.ini");
128 if ((f = fopen(filename,"r")) != NULL) {
129 while (!feof(f) && fgets(filename,sizeof(filename),f)) {
130 if (strnicmp(filename,"uselocal",8) == 0) {
131 local_override = ((*(filename+9) - '0') == 1);
132 break;
133 }
134 }
135 fclose(f);
136 }
137 }
138 return local_override;
139 }
140
141 /****************************************************************************
142 DESCRIPTION:
143 Sets the location of the debug log file.
144
145 HEADER:
146 pmapi.h
147
148 PARAMETERS:
149 dllname - Name of the Binary Portable DLL to load
150 bpdpath - Place to store the actual path to the file
151
152 RETURNS:
153 True if found, false if not.
154
155 REMARKS:
156 Finds the location of a specific Binary Portable DLL, by searching all
157 the standard SciTech Nucleus driver locations.
158 ****************************************************************************/
159 ibool PMAPI PM_findBPD(
160 const char *dllname,
161 char *bpdpath)
162 {
163 static char cachedpath[PM_MAX_PATH] = "";
164
165 /* On the first call determine the path to the Nucleus drivers */
166 if (cachedpath[0] == 0) {
167 /* First try in the global system Nucleus driver path if
168 * the local override setting is not enabled.
169 */
170 PM_init();
171 if (!GetLocalOverride()) {
172 if (TryPath(bpdpath,cachedpath,PM_getNucleusPath(),"",dllname))
173 return true;
174 }
175
176 /* Next try in the local application directory if available */
177 if (localBPDPath[0] != 0) {
178 if (TryPath(bpdpath,cachedpath,localBPDPath,"",dllname))
179 return true;
180 }
181 else {
182 #if !defined(__WIN32_VXD__) && !defined(__NT_DRIVER__)
183 char *mgl_root;
184 if ((mgl_root = getenv("MGL_ROOT")) != NULL) {
185 if (TryPath(bpdpath,cachedpath,mgl_root,"drivers",dllname))
186 return true;
187 }
188 #endif
189 PM_getCurrentPath(bpdpath,PM_MAX_PATH);
190 if (TryPath(bpdpath,cachedpath,bpdpath,"drivers",dllname))
191 return true;
192 }
193
194 /* Finally try in the global system path again so that we
195 * will still find the drivers in the global system path if
196 * the local override option is on, but the application does
197 * not have any local override drivers.
198 */
199 if (TryPath(bpdpath,cachedpath,PM_getNucleusPath(),"",dllname))
200 return true;
201
202 /* Whoops, we can't find the BPD file! */
203 return false;
204 }
205
206 /* Always try in the previously discovered path */
207 return TryPath(bpdpath,NULL,cachedpath,"",dllname);
208 }
209
210 /****************************************************************************
211 REMARKS:
212 Copies a string into another, and returns dest + strlen(src).
213 ****************************************************************************/
214 static char *_stpcpy(
215 char *_dest,
216 const char *_src)
217 {
218 if (!_dest || !_src)
219 return 0;
220 while ((*_dest++ = *_src++) != 0)
221 ;
222 return --_dest;
223 }
224
225 /****************************************************************************
226 REMARKS:
227 Copies a string into another, stopping at the maximum length. The string
228 is properly terminated (unlike strncpy).
229 ****************************************************************************/
230 static void safe_strncpy(
231 char *dst,
232 const char *src,
233 unsigned maxlen)
234 {
235 if (dst) {
236 if(strlen(src) >= maxlen) {
237 strncpy(dst, src, maxlen);
238 dst[maxlen] = 0;
239 }
240 else
241 strcpy(dst, src);
242 }
243 }
244
245 /****************************************************************************
246 REMARKS:
247 Determins if the dot separator is present in the string.
248 ****************************************************************************/
249 static int findDot(
250 char *p)
251 {
252 if (*(p-1) == '.')
253 p--;
254 switch (*--p) {
255 case ':':
256 if (*(p-2) != '\0')
257 break;
258 case '/':
259 case '\\':
260 case '\0':
261 return true;
262 }
263 return false;
264 }
265
266 /****************************************************************************
267 DESCRIPTION:
268 Make a full pathname from split components.
269
270 HEADER:
271 pmapi.h
272
273 PARAMETERS:
274 path - Place to store full path
275 drive - Drive component for path
276 dir - Directory component for path
277 name - Filename component for path
278 ext - Extension component for path
279
280 REMARKS:
281 Function to make a full pathname from split components. Under Unix the
282 drive component will usually be empty. If the drive, dir, name, or ext
283 parameters are null or empty, they are not inserted in the path string.
284 Otherwise, if the drive doesn't end with a colon, one is inserted in the
285 path. If the dir doesn't end in a slash, one is inserted in the path.
286 If the ext doesn't start with a dot, one is inserted in the path.
287
288 The maximum sizes for the path string is given by the constant PM_MAX_PATH,
289 which includes space for the null-terminator.
290
291 SEE ALSO:
292 PM_splitPath
293 ****************************************************************************/
294 void PMAPI PM_makepath(
295 char *path,
296 const char *drive,
297 const char *dir,
298 const char *name,
299 const char *ext)
300 {
301 if (drive && *drive) {
302 *path++ = *drive;
303 *path++ = ':';
304 }
305 if (dir && *dir) {
306 path = _stpcpy(path,dir);
307 if (*(path-1) != '\\' && *(path-1) != '/')
308 #ifdef __UNIX__
309 *path++ = '/';
310 #else
311 *path++ = '\\';
312 #endif
313 }
314 if (name)
315 path = _stpcpy(path,name);
316 if (ext && *ext) {
317 if (*ext != '.')
318 *path++ = '.';
319 path = _stpcpy(path,ext);
320 }
321 *path = 0;
322 }
323
324 /****************************************************************************
325 DESCRIPTION:
326 Split a full pathname into components.
327
328 HEADER:
329 pmapi.h
330
331 PARAMETERS:
332 path - Full path to split
333 drive - Drive component for path
334 dir - Directory component for path
335 name - Filename component for path
336 ext - Extension component for path
337
338 RETURNS:
339 Flags indicating what components were parsed.
340
341 REMARKS:
342 Function to split a full pathmame into separate components in the form
343
344 X:\DIR\SUBDIR\NAME.EXT
345
346 and splits path into its four components. It then stores those components
347 in the strings pointed to by drive, dir, name and ext. (Each component is
348 required but can be a NULL, which means the corresponding component will be
349 parsed but not stored).
350
351 The maximum sizes for these strings are given by the constants PM_MAX_DRIVE
352 and PM_MAX_PATH. PM_MAX_DRIVE is always 4, and PM_MAX_PATH is usually at
353 least 256 characters. Under Unix the dir, name and ext components may be
354 up to the full path in length.
355
356 SEE ALSO:
357 PM_makePath
358 ****************************************************************************/
359 int PMAPI PM_splitpath(
360 const char *path,
361 char *drive,
362 char *dir,
363 char *name,
364 char *ext)
365 {
366 char *p;
367 int temp,ret;
368 char buf[PM_MAX_PATH+2];
369
370 /* Set all string to default value zero */
371 ret = 0;
372 if (drive) *drive = 0;
373 if (dir) *dir = 0;
374 if (name) *name = 0;
375 if (ext) *ext = 0;
376
377 /* Copy filename into template up to PM_MAX_PATH characters */
378 p = buf;
379 if ((temp = strlen(path)) > PM_MAX_PATH)
380 temp = PM_MAX_PATH;
381 *p++ = 0;
382 strncpy(p, path, temp);
383 *(p += temp) = 0;
384
385 /* Split the filename and fill corresponding nonzero pointers */
386 temp = 0;
387 for (;;) {
388 switch (*--p) {
389 case '.':
390 if (!temp && (*(p+1) == '\0'))
391 temp = findDot(p);
392 if ((!temp) && ((ret & PM_HAS_EXTENSION) == 0)) {
393 ret |= PM_HAS_EXTENSION;
394 safe_strncpy(ext, p, PM_MAX_PATH - 1);
395 *p = 0;
396 }
397 continue;
398 case ':':
399 if (p != &buf[2])
400 continue;
401 case '\0':
402 if (temp) {
403 if (*++p)
404 ret |= PM_HAS_DIRECTORY;
405 safe_strncpy(dir, p, PM_MAX_PATH - 1);
406 *p-- = 0;
407 break;
408 }
409 case '/':
410 case '\\':
411 if (!temp) {
412 temp++;
413 if (*++p)
414 ret |= PM_HAS_FILENAME;
415 safe_strncpy(name, p, PM_MAX_PATH - 1);
416 *p-- = 0;
417 if (*p == 0 || (*p == ':' && p == &buf[2]))
418 break;
419 }
420 continue;
421 case '*':
422 case '?':
423 if (!temp)
424 ret |= PM_HAS_WILDCARDS;
425 default:
426 continue;
427 }
428 break;
429 }
430 if (*p == ':') {
431 if (buf[1])
432 ret |= PM_HAS_DRIVE;
433 safe_strncpy(drive, &buf[1], PM_MAX_DRIVE - 1);
434 }
435 return ret;
436 }
437
438 /****************************************************************************
439 DESCRIPTION:
440 Block until a specific time has elapsed since the last call
441
442 HEADER:
443 pmapi.h
444
445 PARAMETERS:
446 milliseconds - Number of milliseconds for delay
447
448 REMARKS:
449 This function will block the calling thread or process until the specified
450 number of milliseconds have passed since the /last/ call to this function.
451 The first time this function is called, it will return immediately. On
452 subsquent calls it will block until the specified time has elapsed, or it
453 will return immediately if the time has already elapsed.
454
455 This function is useful to provide constant time functionality in a
456 program, such as a frame rate limiter for graphics applications etc.
457
458 SEE ALSO:
459 PM_sleep
460 ****************************************************************************/
461 void PMAPI PM_blockUntilTimeout(
462 ulong milliseconds)
463 {
464 ulong microseconds = milliseconds * 1000L,msDelay;
465 static LZTimerObject tm;
466 static ibool firstTime = true;
467
468 if (firstTime) {
469 firstTime = false;
470 LZTimerOnExt(&tm);
471 }
472 else {
473 if ((msDelay = (microseconds - LZTimerLapExt(&tm)) / 1000L) > 0)
474 PM_sleep(msDelay);
475 while (LZTimerLapExt(&tm) < microseconds)
476 ;
477 LZTimerOffExt(&tm);
478 LZTimerOnExt(&tm);
479 }
480 }