Import upstream u-boot 1.1.4
[u-boot.git] / board / MAI / bios_emulator / scitech / src / common / agplib.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:  Any 32-bit protected mode environment
30 *
31 * Description:  C module for the Graphics Accelerator Driver API. Uses
32 *               the SciTech PM library for interfacing with DOS
33 *               extender specific functions.
34 *
35 ****************************************************************************/
36
37 #include "nucleus/graphics.h"
38 #include "nucleus/agp.h"
39
40 /*---------------------------- Global Variables ---------------------------*/
41
42 #ifndef DEBUG_AGP_DRIVER
43 static AGP_exports  _AGP_exports;
44 static int          loaded = false;
45 static PE_MODULE    *hModBPD = NULL;
46
47 static N_imports _N_imports = {
48     sizeof(N_imports),
49     _OS_delay,
50     };
51
52 static AGP_imports _AGP_imports = {
53     sizeof(AGP_imports),
54     };
55 #endif
56
57 #include "pmimp.h"
58
59 /*----------------------------- Implementation ----------------------------*/
60
61 #define DLL_NAME        "agp.bpd"
62
63 #ifndef DEBUG_AGP_DRIVER
64 /****************************************************************************
65 REMARKS:
66 Fatal error handler for non-exported GA_exports.
67 ****************************************************************************/
68 static void _AGP_fatalErrorHandler(void)
69 {
70     PM_fatalError("Unsupported AGP export function called! Please upgrade your copy of AGP!\n");
71 }
72
73 /****************************************************************************
74 PARAMETERS:
75 shared  - True to load the driver into shared memory.
76
77 REMARKS:
78 Loads the Nucleus binary portable DLL into memory and initilises it.
79 ****************************************************************************/
80 static ibool LoadDriver(void)
81 {
82     AGP_initLibrary_t   AGP_initLibrary;
83     AGP_exports         *agpExp;
84     char                filename[PM_MAX_PATH];
85     char                bpdpath[PM_MAX_PATH];
86     int                 i,max;
87     ulong               *p;
88
89     /* Check if we have already loaded the driver */
90     if (loaded)
91         return true;
92     PM_init();
93
94     /* Open the BPD file */
95     if (!PM_findBPD(DLL_NAME,bpdpath))
96         return false;
97     strcpy(filename,bpdpath);
98     strcat(filename,DLL_NAME);
99     if ((hModBPD = PE_loadLibrary(filename,false)) == NULL)
100         return false;
101     if ((AGP_initLibrary = (AGP_initLibrary_t)PE_getProcAddress(hModBPD,"_AGP_initLibrary")) == NULL)
102         return false;
103     bpdpath[strlen(bpdpath)-1] = 0;
104     if (strcmp(bpdpath,PM_getNucleusPath()) == 0)
105         strcpy(bpdpath,PM_getNucleusConfigPath());
106     else {
107         PM_backslash(bpdpath);
108         strcat(bpdpath,"config");
109         }
110     if ((agpExp = AGP_initLibrary(bpdpath,filename,GA_getSystemPMImports(),&_N_imports,&_AGP_imports)) == NULL)
111         PM_fatalError("AGP_initLibrary failed!\n");
112     _AGP_exports.dwSize = sizeof(_AGP_exports);
113     max = sizeof(_AGP_exports)/sizeof(AGP_initLibrary_t);
114     for (i = 0,p = (ulong*)&_AGP_exports; i < max; i++)
115         *p++ = (ulong)_AGP_fatalErrorHandler;
116     memcpy(&_AGP_exports,agpExp,MIN(sizeof(_AGP_exports),agpExp->dwSize));
117     loaded = true;
118     return true;
119 }
120
121 /* The following are stub entry points that the application calls to
122  * initialise the Nucleus loader library, and we use this to load our
123  * driver DLL from disk and initialise the library using it.
124  */
125
126 /* {secret} */
127 int NAPI AGP_status(void)
128 {
129     if (!loaded)
130         return nDriverNotFound;
131     return _AGP_exports.AGP_status();
132 }
133
134 /* {secret} */
135 const char * NAPI AGP_errorMsg(
136     N_int32 status)
137 {
138     if (!loaded)
139         return "Unable to load Nucleus device driver!";
140     return _AGP_exports.AGP_errorMsg(status);
141 }
142
143 /* {secret} */
144 AGP_devCtx * NAPI AGP_loadDriver(N_int32 deviceIndex)
145 {
146     if (!LoadDriver())
147         return NULL;
148     return _AGP_exports.AGP_loadDriver(deviceIndex);
149 }
150
151 /* {secret} */
152 void NAPI AGP_unloadDriver(
153     AGP_devCtx *dc)
154 {
155     if (loaded)
156         _AGP_exports.AGP_unloadDriver(dc);
157 }
158
159 /* {secret} */
160 void NAPI AGP_getGlobalOptions(
161     AGP_globalOptions *options)
162 {
163     if (LoadDriver())
164         _AGP_exports.AGP_getGlobalOptions(options);
165 }
166
167 /* {secret} */
168 void NAPI AGP_setGlobalOptions(
169     AGP_globalOptions *options)
170 {
171     if (LoadDriver())
172         _AGP_exports.AGP_setGlobalOptions(options);
173 }
174
175 /* {secret} */
176 void NAPI AGP_saveGlobalOptions(
177     AGP_globalOptions *options)
178 {
179     if (loaded)
180         _AGP_exports.AGP_saveGlobalOptions(options);
181 }
182 #endif
183
184 /* {secret} */
185 void NAPI _OS_delay8253(N_uint32 microSeconds);
186
187 /****************************************************************************
188 REMARKS:
189 This function delays for the specified number of microseconds
190 ****************************************************************************/
191 void NAPI _OS_delay(
192     N_uint32 microSeconds)
193 {
194     static ibool    inited = false;
195     static ibool    haveRDTSC;
196     LZTimerObject   tm;
197
198     if (!inited) {
199 #ifndef __WIN32_VXD__
200         /* This has been causing problems in VxD's for some reason, so for now */
201         /* we avoid using it. */
202         if (_GA_haveCPUID() && (_GA_getCPUIDFeatures() & CPU_HaveRDTSC) != 0) {
203             ZTimerInit();
204             haveRDTSC = true;
205             }
206         else
207 #endif
208             haveRDTSC = false;
209         inited = true;
210         }
211     if (haveRDTSC) {
212         LZTimerOnExt(&tm);
213         while (LZTimerLapExt(&tm) < microSeconds)
214             ;
215         LZTimerOnExt(&tm);
216         }
217     else
218         _OS_delay8253(microSeconds);
219 }