Import upstream u-boot 1.1.4
[u-boot.git] / board / MAI / bios_emulator / scitech / src / common / gawin32.c
1 /****************************************************************************
2 *
3 *                   SciTech Nucleus Graphics Architecture
4 *
5 *               Copyright (C) 1991-1998 SciTech Software, Inc.
6 *                            All rights reserved.
7 *
8 *  ======================================================================
9 *  |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
10 *  |                                                                    |
11 *  |This copyrighted computer code contains proprietary technology      |
12 *  |owned by SciTech Software, Inc., located at 505 Wall Street,        |
13 *  |Chico, CA 95928 USA (http://www.scitechsoft.com).                   |
14 *  |                                                                    |
15 *  |The contents of this file are subject to the SciTech Nucleus        |
16 *  |License; you may *not* use this file or related software except in  |
17 *  |compliance with the License. You may obtain a copy of the License   |
18 *  |at http://www.scitechsoft.com/nucleus-license.txt                   |
19 *  |                                                                    |
20 *  |Software distributed under the License is distributed on an         |
21 *  |"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or      |
22 *  |implied. See the License for the specific language governing        |
23 *  |rights and limitations under the License.                           |
24 *  |                                                                    |
25 *  |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
26 *  ======================================================================
27 *
28 * Language:     ANSI C
29 * Environment:  Win32
30 *
31 * Description:  OS specific Nucleus Graphics Architecture services for
32 *               the Win32 operating system environments.
33 *
34 ****************************************************************************/
35
36 #include "pm_help.h"
37 #include "pmapi.h"
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #define STRICT
42 #define WIN32_LEAN_AND_MEAN
43 #include <windows.h>
44
45 /*------------------------- Global Variables ------------------------------*/
46
47 #define DLL_NAME        "nga_w32.dll"
48
49 extern HANDLE           _PM_hDevice;
50 static HMODULE          hModDLL = NULL;
51 static ibool            useRing0Driver = false;
52 static ibool            haveRDTSC;
53 static GA_largeInteger  countFreq;
54
55 /*-------------------------- Implementation -------------------------------*/
56
57 /****************************************************************************
58 REMARKS:
59 Loads the shared "nga_w32.dll" library from disk and connects to it. This
60 library is *always* located in the same directory as the Nucleus
61 graphics.bpd file.
62 ****************************************************************************/
63 static ibool LoadSharedDLL(void)
64 {
65     char                filename[PM_MAX_PATH];
66     char                bpdpath[PM_MAX_PATH];
67
68     /* Check if we have already loaded the DLL */
69     if (hModDLL)
70         return true;
71     PM_init();
72
73     /* Open the DLL file */
74     if (!PM_findBPD(DLL_NAME,bpdpath))
75         return false;
76     strcpy(filename,bpdpath);
77     strcat(filename,DLL_NAME);
78     if ((hModDLL = LoadLibrary(filename)) == NULL)
79         return false;
80     return true;
81 }
82
83 /****************************************************************************
84 PARAMETERS:
85 path    - Local path to the Nucleus driver files.
86
87 REMARKS:
88 This function is used by the application program to override the location
89 of the Nucleus driver files that are loaded. Normally the loader code
90 will look in the system Nucleus directories first, then in the 'drivers'
91 directory relative to the current working directory, and finally relative
92 to the MGL_ROOT environment variable.
93
94 Note that for Win32 we also call into the loaded PMHELP device driver
95 as necessary to change the local Nucleus path for system wide Nucleus
96 drivers.
97 ****************************************************************************/
98 void NAPI GA_setLocalPath(
99     const char *path)
100 {
101     DWORD   inBuf[1];
102     DWORD   outBuf[1],outCnt;
103
104     PM_setLocalBPDPath(path);
105     if (_PM_hDevice != INVALID_HANDLE_VALUE) {
106         inBuf[0] = (DWORD)path;
107         DeviceIoControl(_PM_hDevice, PMHELP_GASETLOCALPATH32,
108             inBuf, sizeof(inBuf), outBuf, sizeof(outBuf), &outCnt, NULL);
109         }
110 }
111
112 /****************************************************************************
113 RETURNS:
114 Pointer to the system wide PM library imports, or the internal version if none
115
116 REMARKS:
117 In order to support deploying new Nucleus drivers that may require updated
118 PM library functions, we check here to see if there is a system wide version
119 of the PM functions available. If so we return those functions for use with
120 the system wide Nucleus drivers, otherwise the compiled in version of the PM
121 library is used with the application local version of Nucleus.
122 ****************************************************************************/
123 PM_imports * NAPI GA_getSystemPMImports(void)
124 {
125     PM_imports * pmImp;
126     PM_imports * (NAPIP _GA_getSystemPMImports)(void);
127
128     if (LoadSharedDLL()) {
129         /* Note that Visual C++ build DLL's with only a single underscore in front
130          * of the exported name while Watcom C provides two of them. We check for
131          * both to allow working with either compiled DLL.
132          */
133         if ((_GA_getSystemPMImports = (void*)GetProcAddress(hModDLL,"_GA_getSystemPMImports")) != NULL) {
134             if ((_GA_getSystemPMImports = (void*)GetProcAddress(hModDLL,"__GA_getSystemPMImports")) != NULL) {
135                 pmImp = _GA_getSystemPMImports();
136                 memcpy(&_PM_imports,pmImp,MIN(_PM_imports.dwSize,pmImp->dwSize));
137                 return pmImp;
138                 }
139             }
140         }
141     return &_PM_imports;
142 }
143
144 /****************************************************************************
145 PARAMETERS:
146 gaExp   - Place to store the exported functions
147 shared  - True if connecting to the shared, global Nucleus driver
148
149 REMARKS:
150 For Win32 if we are connecting to the shared, global Nucleus driver (loaded
151 at ring 0) then we need to load a special nga_w32.dll library which contains
152 thunks to call down into the Ring 0 device driver as necessary. If we are
153 connecting to the application local Nucleus drivers (ie: Nucleus on DirectDraw
154 emulation layer) then we do nothing here.
155 ****************************************************************************/
156 ibool NAPI GA_getSharedExports(
157     GA_exports *gaExp,
158     ibool shared)
159 {
160     GA_exports * exp;
161     GA_exports * (NAPIP _GA_getSystemGAExports)(void);
162
163     useRing0Driver = false;
164     if (shared) {
165         if (!LoadSharedDLL())
166             PM_fatalError("Unable to load " DLL_NAME "!");
167         if ((_GA_getSystemGAExports = (void*)GetProcAddress(hModDLL,"_GA_getSystemGAExports")) == NULL)
168             if ((_GA_getSystemGAExports = (void*)GetProcAddress(hModDLL,"__GA_getSystemGAExports")) == NULL)
169                 PM_fatalError("Unable to load " DLL_NAME "!");
170         exp = _GA_getSystemGAExports();
171         memcpy(gaExp,exp,MIN(gaExp->dwSize,exp->dwSize));
172         useRing0Driver = true;
173         return true;
174         }
175     return false;
176 }
177
178 #ifndef TEST_HARNESS
179 /****************************************************************************
180 REMARKS:
181 Nothing special for this OS
182 ****************************************************************************/
183 ibool NAPI GA_queryFunctions(
184     GA_devCtx *dc,
185     N_uint32 id,
186     void _FAR_ *funcs)
187 {
188     static ibool (NAPIP _GA_queryFunctions)(GA_devCtx *dc,N_uint32 id,void _FAR_ *funcs) = NULL;
189
190     if (useRing0Driver) {
191         /* Call the version in nga_w32.dll if it is loaded */
192         if (!_GA_queryFunctions) {
193             if ((_GA_queryFunctions = (void*)GetProcAddress(hModDLL,"_GA_queryFunctions")) == NULL)
194                 if ((_GA_queryFunctions = (void*)GetProcAddress(hModDLL,"__GA_queryFunctions")) == NULL)
195                     PM_fatalError("Unable to get exports from " DLL_NAME "!");
196             }
197         return _GA_queryFunctions(dc,id,funcs);
198         }
199     return __GA_exports.GA_queryFunctions(dc,id,funcs);
200 }
201
202 /****************************************************************************
203 REMARKS:
204 Nothing special for this OS
205 ****************************************************************************/
206 ibool NAPI REF2D_queryFunctions(
207     REF2D_driver *ref2d,
208     N_uint32 id,
209     void _FAR_ *funcs)
210 {
211     static ibool (NAPIP _REF2D_queryFunctions)(REF2D_driver *ref2d,N_uint32 id,void _FAR_ *funcs) = NULL;
212
213     if (useRing0Driver) {
214         /* Call the version in nga_w32.dll if it is loaded */
215         if (!_REF2D_queryFunctions) {
216             if ((_REF2D_queryFunctions = (void*)GetProcAddress(hModDLL,"_REF2D_queryFunctions")) == NULL)
217                 if ((_REF2D_queryFunctions = (void*)GetProcAddress(hModDLL,"__REF2D_queryFunctions")) == NULL)
218                     PM_fatalError("Unable to get exports from " DLL_NAME "!");
219             }
220         return _REF2D_queryFunctions(ref2d,id,funcs);
221         }
222     return __GA_exports.REF2D_queryFunctions(ref2d,id,funcs);
223 }
224 #endif
225
226 /****************************************************************************
227 REMARKS:
228 This function initialises the high precision timing functions for the
229 Nucleus loader library.
230 ****************************************************************************/
231 ibool NAPI GA_TimerInit(void)
232 {
233     if (_GA_haveCPUID() && (_GA_getCPUIDFeatures() & CPU_HaveRDTSC) != 0) {
234         haveRDTSC = true;
235         return true;
236         }
237     else if (QueryPerformanceFrequency((LARGE_INTEGER*)&countFreq)) {
238         haveRDTSC = false;
239         return true;
240         }
241     return false;
242 }
243
244 /****************************************************************************
245 REMARKS:
246 This function reads the high resolution timer.
247 ****************************************************************************/
248 void NAPI GA_TimerRead(
249     GA_largeInteger *value)
250 {
251     if (haveRDTSC)
252         _GA_readTimeStamp(value);
253     else
254         QueryPerformanceCounter((LARGE_INTEGER*)value);
255 }