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