]> 4ch.mooo.com Git - 16.git/blob - src/lib/exmm/memory.c
experimenting! wwww
[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 */
92                 InternalError:
93                 ret\r
94     }\r
95     RtnVal = ((unsigned long)Pages << 14);  /* Pages * 16K rtns bytes*/\r
96 \r
97 //InternalError:\r
98     return(RtnVal);\r
99 }               /* End of EMMCoreLeft() */\r
100 \r
101 /********************************************************************/\r
102 \r
103 void far *\r
104 EMMalloc(int *Handle, int Pages)\r
105 {\r
106     int     i;\r
107     char    *RtnPtr = NULL;\r
108 \r
109     if (!EMMSeg) {\r
110         *Handle = NOTREADY;\r
111         return(NULL);\r
112     }\r
113     if ((Pages < 1) || (Pages > 1020)) {\r
114         *Handle = VALUE_OUTF_RANGE;\r
115         return (NULL);\r
116     }\r
117     for (i = 0; (i < MAXEMHANDLES) && (ActiveEMList[i]); i++) ;\r
118     if (i == MAXEMHANDLES) {\r
119         *Handle = NOFREEITEMS;\r
120         return (NULL);\r
121     }\r
122     if ((ActiveEMList[i] = GetEMHandle(Pages)) > 0) {\r
123         RtnPtr = MK_FP(EMMSeg, 0);\r
124     }\r
125     *Handle = ActiveEMList[i];\r
126     return((void far *)RtnPtr);\r
127 }               /* End of EMMalloc() */\r
128 \r
129 /********************************************************************/\r
130 \r
131 int\r
132 EMMRealloc(int Handle, int Pages)\r
133 {\r
134     int     RtnCode = FALSE;\r
135 \r
136     if (!EMMSeg || (Pages < 0) || (Pages > 1020)) {\r
137         return (FALSE);\r
138     }\r
139     _asm {\r
140         mov     ah,0x51             /* change # of pages */\r
141         mov     bx,Pages\r
142         mov     dx,Handle\r
143         int     0x67\r
144         or      ah,ah\r
145         js      NoGo                /* returns 80 to 88 hex on error */
146                 NoGo:
147                 ret\r
148     }\r
149     RtnCode = TRUE;\r
150 \r
151 //NoGo:\r
152     return(RtnCode);\r
153 }               /* End of EMMRealloc() */\r
154 \r
155 /********************************************************************/\r
156 \r
157 void\r
158 EMMFree(int Handle)\r
159 {\r
160     int     i, j;\r
161 \r
162     if (!EMMSeg) return;\r
163     for (i = 0; (i < MAXEMHANDLES) && (ActiveEMList[i] != Handle); i++) ;\r
164     if (i >= MAXEMHANDLES) return;\r
165     j = 16;\r
166     while (j--) {\r
167         if (FreeEMHandle(ActiveEMList[i])) break;\r
168     }\r
169     ActiveEMList[i] = 0;\r
170 }               /* End of EMMFree() */\r
171 \r
172 /********************************************************************/\r
173 \r
174 int                                         /* EMM map for application */\r
175 MapEMM(int Handle, int Start, int Pages)\r
176 {\r
177     int     i;\r
178 \r
179     if (!EMMSeg) return(NOTREADY);\r
180     for (i = 0; (i < MAXEMHANDLES) && (ActiveEMList[i] != Handle); i++) ;\r
181     if (i == MAXEMHANDLES) return (NO_DATA);\r
182     if ((GetNumPages(Handle) < Pages) || (Pages < 1) || (Pages > 4)) {\r
183         return (VALUE_OUTF_RANGE);\r
184     }\r
185     for (i = Start; i < Start + Pages; i++) {\r
186         if (!EMMap(Handle, i, i - Start)) return(NO_DATA);\r
187     }\r
188     return(SUCCESS);\r
189 }               /* End of MapEMM() */\r
190 \r
191 /********************************************************************/\r
192 \r
193 void                                        /* EMM unmap for application */\r
194 UnmapEMM(int Handle, int Start, int Pages)\r
195 {\r
196     int     i, j;\r
197 \r
198     if (!EMMSeg) return;\r
199     for (i = 0; (i < MAXEMHANDLES) && (ActiveEMList[i] != Handle); i++) ;\r
200     if (i == MAXEMHANDLES) return;\r
201     j = Start + Pages;\r
202     if ((Pages < 1) || (j > 4)) return;\r
203 \r
204     for (i = Start; i < j; i++) {\r
205         EMMap(Handle, NONE, i);\r
206     }\r
207 }               /* End of UnmapEMM() */\r
208 \r
209 /********************************************************************/\r
210 \r
211 int                     /* EMM map for devices - saves EMM state */\r
212 UseEMM(int Handle, int Start, int Pages)\r
213 {\r
214     EMStateSave(Handle);\r
215     return(MapEMM(Handle, Start, Pages));\r
216 }               /* End of UseEMM() */\r
217 \r
218 /********************************************************************/\r
219 \r
220 void                    /* EMM unmap for devices - restores EMM state */\r
221 SaveEMM(int Handle, int Start, int Pages)\r
222 {\r
223     UnmapEMM(Handle, Start, Pages);\r
224     EMStateRestore(Handle);\r
225 }               /* End of SaveEMM() */\r
226 \r
227 /********************************************************************/\r
228 \r
229 static int\r
230 EMPresent(void)\r
231 {\r
232     int     i, Segment;\r
233     char    EMName[] = "EMMXXXX0";\r
234     char    *s, *t;\r
235 \r
236     _asm {                      /* can be replaced with getvect() */\r
237         push    es\r
238         mov     ax,0x3567       /* get vector for int 67h */\r
239         int     0x21\r
240         mov     ax,es\r
241         mov     Segment,ax\r
242         pop     es\r
243     }\r
244     t = MK_FP(Segment, 0x0A);   /* point to driver name */\r
245     s = EMName;\r
246     for (i = 0; (i < 8) && (*s++ == *t++); i++) ;   /* strncmp equivalent */\r
247 \r
248     if (i == 8) return(TRUE);\r
249     return(FALSE);\r
250 }               /*End of EMPresent() */\r
251 \r
252 /********************************************************************/\r
253 \r
254 static int\r
255 EMReady(void)\r
256 {\r
257     _asm {\r
258         mov     ah,0x40             /* get EM Manager Status */\r
259         int     0x67\r
260         or      ah,ah\r
261         jns     Ready               /* returns 80, 81, or 84 hex on error */
262                 Ready:
263                 ret\r
264     }\r
265     return(FALSE);\r
266 \r
267 //Ready:\r
268 //    return(TRUE);\r
269 }               /* End of EMReady() */\r
270 \r
271 /********************************************************************/\r
272 \r
273 static unsigned int\r
274 GetEMMSeg(void)\r
275 {\r
276     unsigned int     EMSegment;\r
277 \r
278     _asm {\r
279         mov     ah,0x41             /* get EMM page frame segment */\r
280         int     0x67\r
281         or      ah,ah\r
282         js      NotReady            /* returns 80, 81, or 84 hex on error */\r
283         mov     EMSegment,bx
284                 NotReady:
285                 ret\r
286     }\r
287     return(EMSegment);              /*lint !e530 */\r
288 \r
289 //NotReady:\r
290 //    return(NOTREADY);\r
291 }               /* End of GetEMMSeg() */\r
292 \r
293 /********************************************************************/\r
294 \r
295 static int\r
296 GetEMHandle(int NumPages)\r
297 {\r
298     int     NewHandle;\r
299 \r
300     _asm {\r
301         mov     ah,0x43             /* get handle and allocate EM */\r
302         mov     bx,NumPages         /* number of 16K pages to allocate */\r
303         int     0x67\r
304         or      ah,ah               /* returns 80 to 89 hex on error */\r
305         js      NoHandle\r
306         mov     NewHandle,dx        /* retrieve handle */
307                 NoHandle:
308                 ret\r
309     }\r
310     return(NewHandle);\r
311 \r
312 //NoHandle:\r
313 //    return(NO_DATA);\r
314 }               /* End of GetEMHandle() */\r
315 \r
316 /********************************************************************/\r
317 \r
318 static int\r
319 EMMap(int Handle, int LogPg, int PhyPg)\r
320 {\r
321     int     RtnCode = NO_DATA;\r
322 \r
323     _asm {\r
324         mov     ax,PhyPg            /* physical page: 0 - 3 in AL only */\r
325         mov     ah,0x44             /* map logical to physical page */\r
326         mov     bx,LogPg            /* logical page: 0 - 1020 */\r
327         mov     dx,Handle\r
328         int     0x67\r
329         or      ah,ah               /* returns 80 to 8B hex on error */\r
330         js      NoMapping
331                 NoMapping:
332                 ret\r
333     }\r
334     RtnCode = SUCCESS;\r
335 \r
336 //NoMapping:\r
337     return(RtnCode);\r
338 }               /* End of EMMap() */\r
339 \r
340 /********************************************************************/\r
341 \r
342 static int\r
343 FreeEMHandle(int Handle)\r
344 {\r
345     _asm {\r
346         mov     ah,0x45             /* free handle and deallocate EM */\r
347         mov     dx,Handle\r
348         int     0x67\r
349         or      ah,ah               /* returns 80 to 86 hex on error */\r
350         js      NotFreed
351                 NotFreed:                           /* must retry if unsuccessful */
352                 ret\r
353     }\r
354     return(SUCCESS);\r
355 \r
356 //NotFreed:                           /* must retry if unsuccessful */\r
357 //    return(NO_DATA);\r
358 }               /* End of FreeEMHandle() */\r
359 \r
360 /********************************************************************/\r
361 \r
362 static int\r
363 GetNumPages(int Handle)\r
364 {\r
365     int     NumPages = 0;\r
366 \r
367     _asm {\r
368         mov     ah,0x4C             /* get allocated pages for Handle */\r
369         mov     dx,Handle\r
370         int     0x67\r
371         or      ah,ah               /* returns 80 to 84 hex on error */\r
372         js      BadHandle\r
373         mov     NumPages,bx
374                 BadHandle:
375                 ret\r
376     }
377 \r
378 //BadHandle:\r
379     return(NumPages);\r
380 }               /* End of GetNumPages() */\r
381 \r
382 /********************************************************************/\r
383 \r
384 static int\r
385 EMStateSave(int Handle)\r
386 {\r
387     int     RtnCode = NO_MEMORY;\r
388     _asm {\r
389         mov     ah,0x47             /* save page map under Handle */\r
390         mov     dx,Handle\r
391         int     0x67\r
392         or      ah,ah\r
393         js      Unsaved             /* out of save space error */
394                 Unsaved:
395                 ret\r
396     }\r
397     RtnCode = SUCCESS;\r
398 \r
399 //Unsaved:\r
400     return(RtnCode);\r
401 }               /* End of EMStateSave() */\r
402 \r
403 /********************************************************************/\r
404 \r
405 static void\r
406 EMStateRestore(int Handle)\r
407 {\r
408     _asm {\r
409         mov     ah,0x48             /* restore page map for Handle */\r
410         mov     dx,Handle\r
411         int     0x67                /* ignore error */\r
412     }\r
413 }               /* End of EMStateRestore() */\r