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