+\r
+/* File: Memory.c\r
+ * Module: All Modules\r
+ * Author(s): Chris Somers\r
+ * Date: December 1, 1992\r
+ * Version: V.1.1\r
+\r
+ minor mods by Alex Russell to simplify\r
+\r
+ Must use memory model with FAR code\r
+\r
+ */\r
+\r
+\r
+\r
+#if !defined(__LARGE__) && !defined(__COMPACT__) && !defined(__HUGE__)\r
+#error Invalid memory model for compiling MEMORY.C\r
+#endif\r
+\r
+#include <stdio.h>\r
+#include <dos.h>\r
+#include <mem.h>\r
+\r
+#include "memory.h"\r
+\r
+// static globals --------------------------------\r
+\r
+static int ActiveEMList[MAXEMHANDLES];\r
+static unsigned int EMMSeg;\r
+\r
+// forward declarations ---------------------------------\r
+\r
+static int EMPresent(void);\r
+static int EMReady(void);\r
+static unsigned int GetEMMSeg(void);\r
+static int GetEMHandle(int NumPages);\r
+static int EMMap(int Handle, int LogPg, int PhyPg);\r
+static int FreeEMHandle(int Handle);\r
+static int GetNumPages(int Handle);\r
+static int EMStateSave(int Handle);\r
+static void EMStateRestore(int Handle);\r
+\r
+\r
+/********************************************************************/\r
+int\r
+OpenEMM(void)\r
+{\r
+ if (!EMPresent() || !EMReady()) return(NOTREADY);\r
+ if (!(EMMSeg = GetEMMSeg())) return(NOTREADY); /*lint !e720 */\r
+ return(SUCCESS);\r
+} /* End of OpenEMM() */\r
+\r
+/********************************************************************/\r
+\r
+void\r
+CloseEMM(void)\r
+{\r
+ int i;\r
+\r
+ if (!EMMSeg) return;\r
+ for (i = 0; i < MAXEMHANDLES; i++) {\r
+ if (ActiveEMList[i]) {\r
+ FreeEMHandle(ActiveEMList[i]);\r
+ ActiveEMList[i] = 0;\r
+ }\r
+ }\r
+ EMMSeg = 0;\r
+} /* End of CloseEMM() */\r
+\r
+/********************************************************************/\r
+\r
+int\r
+EMMInstalled(void)\r
+{\r
+ return((EMMSeg) ? TRUE : FALSE); /* successfully opened? */\r
+} /* End of EMMInstalled() */\r
+\r
+/********************************************************************/\r
+\r
+unsigned long\r
+EMMCoreLeft(void)\r
+{\r
+ unsigned Pages;\r
+ unsigned long RtnVal = 0UL;\r
+\r
+ _asm {\r
+ mov ah,0x42 /* get EMM free page count */\r
+ int 0x67\r
+ or ah,ah\r
+ //js InternalError /* returns 80, 81, or 84 hex on error */\r
+ mov Pages,bx /* number of unallocated 16K pages */\r
+ }\r
+ RtnVal = ((unsigned long)Pages << 14); /* Pages * 16K rtns bytes*/\r
+\r
+//InternalError:\r
+\r
+ return(RtnVal);\r
+} /* End of EMMCoreLeft() */\r
+\r
+/********************************************************************/\r
+\r
+void far *\r
+EMMalloc(int *Handle, int Pages)\r
+{\r
+ int i;\r
+ char *RtnPtr = NULL;\r
+\r
+ if (!EMMSeg) {\r
+ *Handle = NOTREADY;\r
+ return(NULL);\r
+ }\r
+ if ((Pages < 1) || (Pages > 1020)) {\r
+ *Handle = VALUE_OUTF_RANGE;\r
+ return (NULL);\r
+ }\r
+ for (i = 0; (i < MAXEMHANDLES) && (ActiveEMList[i]); i++) ;\r
+ if (i == MAXEMHANDLES) {\r
+ *Handle = NOFREEITEMS;\r
+ return (NULL);\r
+ }\r
+ if ((ActiveEMList[i] = GetEMHandle(Pages)) > 0) {\r
+ RtnPtr = MK_FP(EMMSeg, 0);\r
+ }\r
+ *Handle = ActiveEMList[i];\r
+ return((void far *)RtnPtr);\r
+} /* End of EMMalloc() */\r
+\r
+/********************************************************************/\r
+\r
+int\r
+EMMRealloc(int Handle, int Pages)\r
+{\r
+ int RtnCode = FALSE;\r
+\r
+ if (!EMMSeg || (Pages < 0) || (Pages > 1020)) {\r
+ return (FALSE);\r
+ }\r
+ _asm {\r
+ mov ah,0x51 /* change # of pages */\r
+ mov bx,Pages\r
+ mov dx,Handle\r
+ int 0x67\r
+ or ah,ah\r
+ //js NoGo /* returns 80 to 88 hex on error */\r
+ }\r
+ RtnCode = TRUE;\r
+\r
+//NoGo:\r
+\r
+ return(RtnCode);\r
+} /* End of EMMRealloc() */\r
+\r
+/********************************************************************/\r
+\r
+void\r
+EMMFree(int Handle)\r
+{\r
+ int i, j;\r
+\r
+ if (!EMMSeg) return;\r
+ for (i = 0; (i < MAXEMHANDLES) && (ActiveEMList[i] != Handle); i++) ;\r
+ if (i >= MAXEMHANDLES) return;\r
+ j = 16;\r
+ while (j--) {\r
+ if (FreeEMHandle(ActiveEMList[i])) break;\r
+ }\r
+ ActiveEMList[i] = 0;\r
+} /* End of EMMFree() */\r
+\r
+/********************************************************************/\r
+\r
+int /* EMM map for application */\r
+MapEMM(int Handle, int Start, int Pages)\r
+{\r
+ int i;\r
+\r
+ if (!EMMSeg) return(NOTREADY);\r
+ for (i = 0; (i < MAXEMHANDLES) && (ActiveEMList[i] != Handle); i++) ;\r
+ if (i == MAXEMHANDLES) return (NO_DATA);\r
+ if ((GetNumPages(Handle) < Pages) || (Pages < 1) || (Pages > 4)) {\r
+ return (VALUE_OUTF_RANGE);\r
+ }\r
+ for (i = Start; i < Start + Pages; i++) {\r
+ if (!EMMap(Handle, i, i - Start)) return(NO_DATA);\r
+ }\r
+ return(SUCCESS);\r
+} /* End of MapEMM() */\r
+\r
+/********************************************************************/\r
+\r
+void /* EMM unmap for application */\r
+UnmapEMM(int Handle, int Start, int Pages)\r
+{\r
+ int i, j;\r
+\r
+ if (!EMMSeg) return;\r
+ for (i = 0; (i < MAXEMHANDLES) && (ActiveEMList[i] != Handle); i++) ;\r
+ if (i == MAXEMHANDLES) return;\r
+ j = Start + Pages;\r
+ if ((Pages < 1) || (j > 4)) return;\r
+\r
+ for (i = Start; i < j; i++) {\r
+ EMMap(Handle, NONE, i);\r
+ }\r
+} /* End of UnmapEMM() */\r
+\r
+/********************************************************************/\r
+\r
+int /* EMM map for devices - saves EMM state */\r
+UseEMM(int Handle, int Start, int Pages)\r
+{\r
+ EMStateSave(Handle);\r
+ return(MapEMM(Handle, Start, Pages));\r
+} /* End of UseEMM() */\r
+\r
+/********************************************************************/\r
+\r
+void /* EMM unmap for devices - restores EMM state */\r
+SaveEMM(int Handle, int Start, int Pages)\r
+{\r
+ UnmapEMM(Handle, Start, Pages);\r
+ EMStateRestore(Handle);\r
+} /* End of SaveEMM() */\r
+\r
+/********************************************************************/\r
+\r
+static int\r
+EMPresent(void)\r
+{\r
+ int i, Segment;\r
+ char EMName[] = "EMMXXXX0";\r
+ char *s, *t;\r
+\r
+ _asm { /* can be replaced with getvect() */\r
+ push es\r
+ mov ax,0x3567 /* get vector for int 67h */\r
+ int 0x21\r
+ mov ax,es\r
+ mov Segment,ax\r
+ pop es\r
+ }\r
+ t = MK_FP(Segment, 0x0A); /* point to driver name */\r
+ s = EMName;\r
+ for (i = 0; (i < 8) && (*s++ == *t++); i++) ; /* strncmp equivalent */\r
+\r
+ if (i == 8) return(TRUE);\r
+ return(FALSE);\r
+} /*End of EMPresent() */\r
+\r
+/********************************************************************/\r
+\r
+static int\r
+EMReady(void)\r
+{\r
+ _asm {\r
+ mov ah,0x40 /* get EM Manager Status */\r
+ int 0x67\r
+ or ah,ah\r
+ //jns Ready /* returns 80, 81, or 84 hex on error */\r
+ }\r
+ return(FALSE);\r
+\r
+//Ready:\r
+ return(TRUE);\r
+} /* End of EMReady() */\r
+\r
+/********************************************************************/\r
+\r
+static unsigned int\r
+GetEMMSeg(void)\r
+{\r
+ unsigned int EMSegment;\r
+\r
+ _asm {\r
+ mov ah,0x41 /* get EMM page frame segment */\r
+ int 0x67\r
+ or ah,ah\r
+ //js NotReady /* returns 80, 81, or 84 hex on error */\r
+ mov EMSegment,bx\r
+ }\r
+ return(EMSegment); /*lint !e530 */\r
+\r
+//NotReady:\r
+ return(NOTREADY);\r
+} /* End of GetEMMSeg() */\r
+\r
+/********************************************************************/\r
+\r
+static int\r
+GetEMHandle(int NumPages)\r
+{\r
+ int NewHandle;\r
+\r
+ _asm {\r
+ mov ah,0x43 /* get handle and allocate EM */\r
+ mov bx,NumPages /* number of 16K pages to allocate */\r
+ int 0x67\r
+ or ah,ah /* returns 80 to 89 hex on error */\r
+ //js NoHandle\r
+ mov NewHandle,dx /* retrieve handle */\r
+ }\r
+ return(NewHandle);\r
+\r
+//NoHandle:\r
+ return(NO_DATA);\r
+} /* End of GetEMHandle() */\r
+\r
+/********************************************************************/\r
+\r
+static int\r
+EMMap(int Handle, int LogPg, int PhyPg)\r
+{\r
+ int RtnCode = NO_DATA;\r
+\r
+ _asm {\r
+ mov ax,PhyPg /* physical page: 0 - 3 in AL only */\r
+ mov ah,0x44 /* map logical to physical page */\r
+ mov bx,LogPg /* logical page: 0 - 1020 */\r
+ mov dx,Handle\r
+ int 0x67\r
+ or ah,ah /* returns 80 to 8B hex on error */\r
+ //js NoMapping\r
+ }\r
+ RtnCode = SUCCESS;\r
+\r
+//NoMapping:\r
+ return(RtnCode);\r
+} /* End of EMMap() */\r
+\r
+/********************************************************************/\r
+\r
+static int\r
+FreeEMHandle(int Handle)\r
+{\r
+ _asm {\r
+ mov ah,0x45 /* free handle and deallocate EM */\r
+ mov dx,Handle\r
+ int 0x67\r
+ or ah,ah /* returns 80 to 86 hex on error */\r
+ //js NotFreed\r
+ }\r
+ return(SUCCESS);\r
+\r
+//NotFreed: /* must retry if unsuccessful */\r
+ return(NO_DATA);\r
+} /* End of FreeEMHandle() */\r
+\r
+/********************************************************************/\r
+\r
+static int\r
+GetNumPages(int Handle)\r
+{\r
+ int NumPages = 0;\r
+\r
+ _asm {\r
+ mov ah,0x4C /* get allocated pages for Handle */\r
+ mov dx,Handle\r
+ int 0x67\r
+ or ah,ah /* returns 80 to 84 hex on error */\r
+ //js BadHandle\r
+ mov NumPages,bx\r
+ }\r
+//BadHandle:\r
+\r
+ return(NumPages);\r
+} /* End of GetNumPages() */\r
+\r
+/********************************************************************/\r
+\r
+static int\r
+EMStateSave(int Handle)\r
+{\r
+ int RtnCode = NO_MEMORY;\r
+ _asm {\r
+ mov ah,0x47 /* save page map under Handle */\r
+ mov dx,Handle\r
+ int 0x67\r
+ or ah,ah\r
+ //js Unsaved /* out of save space error */\r
+ }\r
+ RtnCode = SUCCESS;\r
+\r
+//Unsaved:\r
+ return(RtnCode);\r
+} /* End of EMStateSave() */\r
+\r
+/********************************************************************/\r
+\r
+static void\r
+EMStateRestore(int Handle)\r
+{\r
+ _asm {\r
+ mov ah,0x48 /* restore page map for Handle */\r
+ mov dx,Handle\r
+ int 0x67 /* ignore error */\r
+ }\r
+} /* End of EMStateRestore() */\r