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