]> 4ch.mooo.com Git - 16.git/blob - src/lib/exmm/memory.c
added a EMS & XMS library
[16.git] / src / lib / exmm / memory.c
1 \r
2 /*      File:       Memory.c\r
3  *      Module:     All Modules\r
4  *      Author(s):  Chris Somers\r
5  *      Date:       December 1, 1992\r
6  *      Version:    V.1.1\r
7 \r
8         minor mods by Alex Russell to simplify\r
9 \r
10         Must use memory model with FAR code\r
11 \r
12  */\r
13 \r
14 \r
15 \r
16 #if !defined(__LARGE__) && !defined(__COMPACT__) && !defined(__HUGE__)\r
17 #error Invalid memory model for compiling MEMORY.C\r
18 #endif\r
19 \r
20 #include <stdio.h>\r
21 #include <dos.h>\r
22 #include <mem.h>\r
23 \r
24 #include "memory.h"\r
25 \r
26 // static globals --------------------------------\r
27 \r
28 static int  ActiveEMList[MAXEMHANDLES];\r
29 static unsigned int  EMMSeg;\r
30 \r
31 // forward declarations ---------------------------------\r
32 \r
33 static int  EMPresent(void);\r
34 static int  EMReady(void);\r
35 static unsigned int  GetEMMSeg(void);\r
36 static int  GetEMHandle(int NumPages);\r
37 static int  EMMap(int Handle, int LogPg, int PhyPg);\r
38 static int  FreeEMHandle(int Handle);\r
39 static int  GetNumPages(int Handle);\r
40 static int  EMStateSave(int Handle);\r
41 static void EMStateRestore(int Handle);\r
42 \r
43 \r
44 /********************************************************************/\r
45 int\r
46 OpenEMM(void)\r
47 {\r
48     if (!EMPresent() || !EMReady()) return(NOTREADY);\r
49     if (!(EMMSeg = GetEMMSeg())) return(NOTREADY);  /*lint !e720 */\r
50     return(SUCCESS);\r
51 }               /* End of OpenEMM() */\r
52 \r
53 /********************************************************************/\r
54 \r
55 void\r
56 CloseEMM(void)\r
57 {\r
58     int     i;\r
59 \r
60     if (!EMMSeg) return;\r
61     for (i = 0; i < MAXEMHANDLES; i++) {\r
62         if (ActiveEMList[i]) {\r
63             FreeEMHandle(ActiveEMList[i]);\r
64             ActiveEMList[i] = 0;\r
65         }\r
66     }\r
67     EMMSeg = 0;\r
68 }               /* End of CloseEMM() */\r
69 \r
70 /********************************************************************/\r
71 \r
72 int\r
73 EMMInstalled(void)\r
74 {\r
75     return((EMMSeg) ? TRUE : FALSE);        /* successfully opened? */\r
76 }               /* End of EMMInstalled() */\r
77 \r
78 /********************************************************************/\r
79 \r
80 unsigned long\r
81 EMMCoreLeft(void)\r
82 {\r
83     unsigned      Pages;\r
84     unsigned long RtnVal = 0UL;\r
85 \r
86     _asm {\r
87         mov     ah,0x42             /* get EMM free page count */\r
88         int     0x67\r
89         or      ah,ah\r
90         //js      InternalError       /* returns 80, 81, or 84 hex on error */\r
91         mov     Pages,bx            /* number of unallocated 16K pages */\r
92     }\r
93     RtnVal = ((unsigned long)Pages << 14);  /* Pages * 16K rtns bytes*/\r
94 \r
95 //InternalError:\r
96 \r
97     return(RtnVal);\r
98 }               /* End of EMMCoreLeft() */\r
99 \r
100 /********************************************************************/\r
101 \r
102 void far *\r
103 EMMalloc(int *Handle, int Pages)\r
104 {\r
105     int     i;\r
106     char    *RtnPtr = NULL;\r
107 \r
108     if (!EMMSeg) {\r
109         *Handle = NOTREADY;\r
110         return(NULL);\r
111     }\r
112     if ((Pages < 1) || (Pages > 1020)) {\r
113         *Handle = VALUE_OUTF_RANGE;\r
114         return (NULL);\r
115     }\r
116     for (i = 0; (i < MAXEMHANDLES) && (ActiveEMList[i]); i++) ;\r
117     if (i == MAXEMHANDLES) {\r
118         *Handle = NOFREEITEMS;\r
119         return (NULL);\r
120     }\r
121     if ((ActiveEMList[i] = GetEMHandle(Pages)) > 0) {\r
122         RtnPtr = MK_FP(EMMSeg, 0);\r
123     }\r
124     *Handle = ActiveEMList[i];\r
125     return((void far *)RtnPtr);\r
126 }               /* End of EMMalloc() */\r
127 \r
128 /********************************************************************/\r
129 \r
130 int\r
131 EMMRealloc(int Handle, int Pages)\r
132 {\r
133     int     RtnCode = FALSE;\r
134 \r
135     if (!EMMSeg || (Pages < 0) || (Pages > 1020)) {\r
136         return (FALSE);\r
137     }\r
138     _asm {\r
139         mov     ah,0x51             /* change # of pages */\r
140         mov     bx,Pages\r
141         mov     dx,Handle\r
142         int     0x67\r
143         or      ah,ah\r
144         //js      NoGo                /* returns 80 to 88 hex on error */\r
145     }\r
146     RtnCode = TRUE;\r
147 \r
148 //NoGo:\r
149 \r
150     return(RtnCode);\r
151 }               /* End of EMMRealloc() */\r
152 \r
153 /********************************************************************/\r
154 \r
155 void\r
156 EMMFree(int Handle)\r
157 {\r
158     int     i, j;\r
159 \r
160     if (!EMMSeg) return;\r
161     for (i = 0; (i < MAXEMHANDLES) && (ActiveEMList[i] != Handle); i++) ;\r
162     if (i >= MAXEMHANDLES) return;\r
163     j = 16;\r
164     while (j--) {\r
165         if (FreeEMHandle(ActiveEMList[i])) break;\r
166     }\r
167     ActiveEMList[i] = 0;\r
168 }               /* End of EMMFree() */\r
169 \r
170 /********************************************************************/\r
171 \r
172 int                                         /* EMM map for application */\r
173 MapEMM(int Handle, int Start, int Pages)\r
174 {\r
175     int     i;\r
176 \r
177     if (!EMMSeg) return(NOTREADY);\r
178     for (i = 0; (i < MAXEMHANDLES) && (ActiveEMList[i] != Handle); i++) ;\r
179     if (i == MAXEMHANDLES) return (NO_DATA);\r
180     if ((GetNumPages(Handle) < Pages) || (Pages < 1) || (Pages > 4)) {\r
181         return (VALUE_OUTF_RANGE);\r
182     }\r
183     for (i = Start; i < Start + Pages; i++) {\r
184         if (!EMMap(Handle, i, i - Start)) return(NO_DATA);\r
185     }\r
186     return(SUCCESS);\r
187 }               /* End of MapEMM() */\r
188 \r
189 /********************************************************************/\r
190 \r
191 void                                        /* EMM unmap for application */\r
192 UnmapEMM(int Handle, int Start, int Pages)\r
193 {\r
194     int     i, j;\r
195 \r
196     if (!EMMSeg) return;\r
197     for (i = 0; (i < MAXEMHANDLES) && (ActiveEMList[i] != Handle); i++) ;\r
198     if (i == MAXEMHANDLES) return;\r
199     j = Start + Pages;\r
200     if ((Pages < 1) || (j > 4)) return;\r
201 \r
202     for (i = Start; i < j; i++) {\r
203         EMMap(Handle, NONE, i);\r
204     }\r
205 }               /* End of UnmapEMM() */\r
206 \r
207 /********************************************************************/\r
208 \r
209 int                     /* EMM map for devices - saves EMM state */\r
210 UseEMM(int Handle, int Start, int Pages)\r
211 {\r
212     EMStateSave(Handle);\r
213     return(MapEMM(Handle, Start, Pages));\r
214 }               /* End of UseEMM() */\r
215 \r
216 /********************************************************************/\r
217 \r
218 void                    /* EMM unmap for devices - restores EMM state */\r
219 SaveEMM(int Handle, int Start, int Pages)\r
220 {\r
221     UnmapEMM(Handle, Start, Pages);\r
222     EMStateRestore(Handle);\r
223 }               /* End of SaveEMM() */\r
224 \r
225 /********************************************************************/\r
226 \r
227 static int\r
228 EMPresent(void)\r
229 {\r
230     int     i, Segment;\r
231     char    EMName[] = "EMMXXXX0";\r
232     char    *s, *t;\r
233 \r
234     _asm {                      /* can be replaced with getvect() */\r
235         push    es\r
236         mov     ax,0x3567       /* get vector for int 67h */\r
237         int     0x21\r
238         mov     ax,es\r
239         mov     Segment,ax\r
240         pop     es\r
241     }\r
242     t = MK_FP(Segment, 0x0A);   /* point to driver name */\r
243     s = EMName;\r
244     for (i = 0; (i < 8) && (*s++ == *t++); i++) ;   /* strncmp equivalent */\r
245 \r
246     if (i == 8) return(TRUE);\r
247     return(FALSE);\r
248 }               /*End of EMPresent() */\r
249 \r
250 /********************************************************************/\r
251 \r
252 static int\r
253 EMReady(void)\r
254 {\r
255     _asm {\r
256         mov     ah,0x40             /* get EM Manager Status */\r
257         int     0x67\r
258         or      ah,ah\r
259         //jns     Ready               /* returns 80, 81, or 84 hex on error */\r
260     }\r
261     return(FALSE);\r
262 \r
263 //Ready:\r
264     return(TRUE);\r
265 }               /* End of EMReady() */\r
266 \r
267 /********************************************************************/\r
268 \r
269 static unsigned int\r
270 GetEMMSeg(void)\r
271 {\r
272     unsigned int     EMSegment;\r
273 \r
274     _asm {\r
275         mov     ah,0x41             /* get EMM page frame segment */\r
276         int     0x67\r
277         or      ah,ah\r
278         //js      NotReady            /* returns 80, 81, or 84 hex on error */\r
279         mov     EMSegment,bx\r
280     }\r
281     return(EMSegment);              /*lint !e530 */\r
282 \r
283 //NotReady:\r
284     return(NOTREADY);\r
285 }               /* End of GetEMMSeg() */\r
286 \r
287 /********************************************************************/\r
288 \r
289 static int\r
290 GetEMHandle(int NumPages)\r
291 {\r
292     int     NewHandle;\r
293 \r
294     _asm {\r
295         mov     ah,0x43             /* get handle and allocate EM */\r
296         mov     bx,NumPages         /* number of 16K pages to allocate */\r
297         int     0x67\r
298         or      ah,ah               /* returns 80 to 89 hex on error */\r
299         //js      NoHandle\r
300         mov     NewHandle,dx        /* retrieve handle */\r
301     }\r
302     return(NewHandle);\r
303 \r
304 //NoHandle:\r
305     return(NO_DATA);\r
306 }               /* End of GetEMHandle() */\r
307 \r
308 /********************************************************************/\r
309 \r
310 static int\r
311 EMMap(int Handle, int LogPg, int PhyPg)\r
312 {\r
313     int     RtnCode = NO_DATA;\r
314 \r
315     _asm {\r
316         mov     ax,PhyPg            /* physical page: 0 - 3 in AL only */\r
317         mov     ah,0x44             /* map logical to physical page */\r
318         mov     bx,LogPg            /* logical page: 0 - 1020 */\r
319         mov     dx,Handle\r
320         int     0x67\r
321         or      ah,ah               /* returns 80 to 8B hex on error */\r
322         //js      NoMapping\r
323     }\r
324     RtnCode = SUCCESS;\r
325 \r
326 //NoMapping:\r
327     return(RtnCode);\r
328 }               /* End of EMMap() */\r
329 \r
330 /********************************************************************/\r
331 \r
332 static int\r
333 FreeEMHandle(int Handle)\r
334 {\r
335     _asm {\r
336         mov     ah,0x45             /* free handle and deallocate EM */\r
337         mov     dx,Handle\r
338         int     0x67\r
339         or      ah,ah               /* returns 80 to 86 hex on error */\r
340         //js      NotFreed\r
341     }\r
342     return(SUCCESS);\r
343 \r
344 //NotFreed:                           /* must retry if unsuccessful */\r
345     return(NO_DATA);\r
346 }               /* End of FreeEMHandle() */\r
347 \r
348 /********************************************************************/\r
349 \r
350 static int\r
351 GetNumPages(int Handle)\r
352 {\r
353     int     NumPages = 0;\r
354 \r
355     _asm {\r
356         mov     ah,0x4C             /* get allocated pages for Handle */\r
357         mov     dx,Handle\r
358         int     0x67\r
359         or      ah,ah               /* returns 80 to 84 hex on error */\r
360         //js      BadHandle\r
361         mov     NumPages,bx\r
362     }\r
363 //BadHandle:\r
364 \r
365     return(NumPages);\r
366 }               /* End of GetNumPages() */\r
367 \r
368 /********************************************************************/\r
369 \r
370 static int\r
371 EMStateSave(int Handle)\r
372 {\r
373     int     RtnCode = NO_MEMORY;\r
374     _asm {\r
375         mov     ah,0x47             /* save page map under Handle */\r
376         mov     dx,Handle\r
377         int     0x67\r
378         or      ah,ah\r
379         //js      Unsaved             /* out of save space error */\r
380     }\r
381     RtnCode = SUCCESS;\r
382 \r
383 //Unsaved:\r
384     return(RtnCode);\r
385 }               /* End of EMStateSave() */\r
386 \r
387 /********************************************************************/\r
388 \r
389 static void\r
390 EMStateRestore(int Handle)\r
391 {\r
392     _asm {\r
393         mov     ah,0x48             /* restore page map for Handle */\r
394         mov     dx,Handle\r
395         int     0x67                /* ignore error */\r
396     }\r
397 }               /* End of EMStateRestore() */\r