]> 4ch.mooo.com Git - 16.git/commitdiff
16_mm.c added!
authorsparky4 <sparky4@cock.li>
Sat, 27 Jun 2015 17:15:50 +0000 (12:15 -0500)
committersparky4 <sparky4@cock.li>
Sat, 27 Jun 2015 17:15:50 +0000 (12:15 -0500)
Signed-off-by: sparky4 <sparky4@cock.li>
20 files changed:
16.LIB
16.exe
16/cawat/lib_head.h
GFX.LIB
emmtest.exe
emsdump.exe
fmemtest.exe
fonttest.exe
inputest.exe
makefile
maptest.exe
maptest0.exe
palettec.exe
pcxtest.exe
scroll.exe
src/exmmtest.c [new file with mode: 0644]
src/lib/16_mm.c [moved from 16/cawat/16_mm.c with 85% similarity]
src/lib/16_mm.h [moved from 16/cawat/16_mm.h with 91% similarity]
test.exe
test2.exe

diff --git a/16.LIB b/16.LIB
index d273cb59f7a2bc5a7f15f6bb82c48a506257b27f..e78e27b08f3f1d7c6370b2ddecffbdc094a1e93c 100644 (file)
Binary files a/16.LIB and b/16.LIB differ
diff --git a/16.exe b/16.exe
index 43d3b6dd4bc13e3d58370bf747be460b8e17fef8..7c2c48b7a654ee486b506760b8c7cd2a130c8416 100644 (file)
Binary files a/16.exe and b/16.exe differ
index e20e1bdb3f608d0a9a26722e28ca3c46823b102d..0887d0c240a15fc34f27be20922a0dca7c9e41a8 100644 (file)
 \r
 #ifndef _LIB_HEAD_H_\r
 #define _LIB_HEAD_H_\r
-#include <i86.h>
+#include <i86.h>\r
 #include <dos.h>\r
-#include <conio.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <malloc.h>
-//#include <time.h>
-#include "types.h"\r
-
-dword far* clockdw= (dword far*) 0x046C; /* 18.2hz clock */
-
+#include <conio.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <malloc.h>\r
+#include <strings.h>\r
+//#include <time.h>\r
+#include "../../src/lib/types.h"\r
+\r
+dword far* clockdw= (dword far*) 0x046C; /* 18.2hz clock */\r
+\r
 #define peekb(segm,ofs) (*(byte far*)MK_FP((segm),(ofs)))\r
 #define peekw(segm,ofs) (*(word far*)MK_FP((segm),(ofs)))\r
 #define pokeb(segm,ofs,value) (peekb((segm),(ofs)) = (byte)(value))\r
diff --git a/GFX.LIB b/GFX.LIB
index a23acc9817ff3b12f62bb95e4e7e14a0d9a101c0..8a1b04b40875e21ffddfd344c85bd24648345219 100644 (file)
Binary files a/GFX.LIB and b/GFX.LIB differ
index 1afe9df7ab0f53fa981d5d4e8988f04372d9ba45..fb51561fba2318cd5e9c911d768dcabbfcce7c56 100644 (file)
Binary files a/emmtest.exe and b/emmtest.exe differ
index e19947ac5a5e6184e767a84144a91290af1f0874..9dac2237052d4c64943dd884961a976d3fd17ac3 100644 (file)
Binary files a/emsdump.exe and b/emsdump.exe differ
index 7904c7d68723ec8cab90dcb366ae7f50c3d64091..951d244027f6f6ae31868851c8f7a59e8a254534 100644 (file)
Binary files a/fmemtest.exe and b/fmemtest.exe differ
index ac1cda24eccc76b367c40f952b9ff1be71e60801..9fd9ea35b94dc4d9a31c02e6221c5f8e3ad02b35 100644 (file)
Binary files a/fonttest.exe and b/fonttest.exe differ
index c7826587bc31c554e0b79664f54f0f5b3717e5b3..97ba47cdcff5aa05fbb004dc476011f5d49832a9 100644 (file)
Binary files a/inputest.exe and b/inputest.exe differ
index 9c6738c1711e673bcc8350aea5a14fe8bd83ef69..d42e4085db5ea75564f491c8416b9b7bd1614586 100644 (file)
--- a/makefile
+++ b/makefile
@@ -16,7 +16,7 @@ EXMMLIB=$(SRCLIB)exmm$(DIRSEP)
 WCPULIB=$(SRCLIB)wcpu$(DIRSEP)\r
 \r
 16LIBOBJS = 16_in.$(OBJ) wcpu.$(OBJ) lib_head.$(OBJ) scroll16.$(OBJ) 16text.$(OBJ)\r
-GFXLIBOBJS = modex16.$(OBJ) bitmap.$(OBJ) planar.$(OBJ)
+GFXLIBOBJS = modex16.$(OBJ) bitmap.$(OBJ) planar.$(OBJ)\r
 \r
 all: 16.exe test.exe pcxtest.exe test2.exe scroll.exe palettec.exe maptest.exe maptest0.exe emsdump.exe emmtest.exe fmemtest.exe fonttest.exe inputest.exe\r
 \r
@@ -37,16 +37,13 @@ test2.exe: test2.$(OBJ) 16.lib
        wcl $(FLAGS) test2.$(OBJ) 16.lib\r
 \r
 fonttest.exe: fonttest.$(OBJ) 16.lib\r
-       wcl $(FLAGS) fonttest.$(OBJ) 16.lib
-
+       wcl $(FLAGS) fonttest.$(OBJ) 16.lib\r
+\r
 inputest.exe: inputest.$(OBJ) 16.lib\r
        wcl $(FLAGS) inputest.$(OBJ) 16.lib\r
 \r
-16text.$(OBJ): $(SRCLIB)16text.c\r
-       wcl -c $(SRCLIB)16text.c\r
-\r
-fonttest.$(OBJ): $(SRC)fonttest.c\r
-       wcl -c $(SRC)fonttest.c\r
+exmmtest.exe: exmmtest.$(OBJ) 16.lib\r
+       wcl $(FLAGS) $(MFLAGS) exmmtest.$(OBJ) 16.lib\r
 \r
 pcxtest.exe: pcxtest.$(OBJ) 16.lib\r
        wcl $(FLAGS) pcxtest.$(OBJ) 16.lib\r
@@ -100,17 +97,23 @@ emsdump.$(OBJ): $(SRC)emsdump.c
        wcl $(FLAGS) $(MFLAGS) -c $(SRC)emsdump.c\r
 \r
 fmemtest.$(OBJ): $(SRC)fmemtest.c\r
-       wcl $(FLAGS) $(MFLAGS) -c $(SRC)fmemtest.c
-
+       wcl $(FLAGS) $(MFLAGS) -c $(SRC)fmemtest.c\r
+\r
+fonttest.$(OBJ): $(SRC)fonttest.c\r
+       wcl -c $(SRC)fonttest.c\r
+\r
 inputest.$(OBJ): $(SRC)inputest.c\r
        wcl $(FLAGS) -c $(SRC)inputest.c\r
 \r
+exmmtest.$(OBJ): $(SRC)exmmtest.c\r
+       wcl $(FLAGS) $(MFLAGS) -c $(SRC)exmmtest.c\r
+\r
 #\r
 #non executable objects libraries\r
 #\r
 16.lib: $(16LIBOBJS) gfx.lib\r
-       wlib -b 16.lib $(16LIBOBJS) gfx.lib
-
+       wlib -b 16.lib $(16LIBOBJS) gfx.lib\r
+\r
 gfx.lib: $(GFXLIBOBJS)\r
        wlib -b gfx.lib $(GFXLIBOBJS)\r
 \r
@@ -132,15 +135,21 @@ scroll16.$(OBJ): $(SRCLIB)scroll16.h $(SRCLIB)scroll16.c
 wcpu.$(OBJ): $(WCPULIB)wcpu.h $(WCPULIB)wcpu.c\r
        wcl $(FLAGS) -c $(WCPULIB)wcpu.c\r
 \r
+16text.$(OBJ): $(SRCLIB)16text.c\r
+       wcl -c $(SRCLIB)16text.c\r
+\r
 mapread.$(OBJ): $(SRCLIB)mapread.h $(SRCLIB)mapread.c 16.lib\r
        wcl $(FLAGS) -c $(SRCLIB)mapread.c 16.lib\r
 \r
 fmapread.$(OBJ): $(SRCLIB)fmapread.h $(SRCLIB)fmapread.c 16.lib\r
-       wcl $(FLAGS) $(MFLAGS) -c $(SRCLIB)fmapread.c 16.lib
-
-16_in.$(OBJ): $(SRCLIB)16_in.h $(SRCLIB)16_in.c
+       wcl $(FLAGS) $(MFLAGS) -c $(SRCLIB)fmapread.c 16.lib\r
+\r
+16_in.$(OBJ): $(SRCLIB)16_in.h $(SRCLIB)16_in.c\r
        wcl $(FLAGS) -c $(SRCLIB)16_in.c\r
 \r
+16_mm.$(OBJ): $(SRCLIB)16_mm.h $(SRCLIB)16_mm.c\r
+       wcl $(FLAGS) $(MFLAGS) -c $(SRCLIB)16_mm.c\r
+\r
 lib_head.$(OBJ): $(SRCLIB)lib_head.h $(SRCLIB)lib_head.c\r
        wcl $(FLAGS) -c $(SRCLIB)lib_head.c\r
 \r
@@ -151,8 +160,8 @@ farjsmn.$(OBJ): $(JSMNLIB)farjsmn.h $(JSMNLIB)farjsmn.c
        wcl $(FLAGS) $(MFLAGS) -c $(JSMNLIB)farjsmn.c\r
 \r
 memory.$(OBJ): $(EXMMLIB)memory.h $(EXMMLIB)memory.c\r
-       wcl $(FLAGS) $(MFLAGS) -c $(EXMMLIB)memory.c
-
+       wcl $(FLAGS) $(MFLAGS) -c $(EXMMLIB)memory.c\r
+\r
 #\r
 #other~\r
 #\r
index a846d026d0ebabe50ae22b7f328f0203b2abe9ae..2a6a6dd586b122fa01a6e73e6dc7518a1ae84076 100644 (file)
Binary files a/maptest.exe and b/maptest.exe differ
index 815756c681a1fa6b78dfce761fef435d8bb79a36..12dda10af0a71a06f5231f54b149f09a71ea8e76 100644 (file)
Binary files a/maptest0.exe and b/maptest0.exe differ
index fa4b8c085d9823bbf0c721965c46bf95f076d9a8..7801de41b4c071690224e0ea45f39d85f1030dff 100644 (file)
Binary files a/palettec.exe and b/palettec.exe differ
index 80badb00b632c1dd65e07c6b549e1af10c23c225..57294369fb8d0b5ca2bdecabd2374b6b01e80ab8 100644 (file)
Binary files a/pcxtest.exe and b/pcxtest.exe differ
index 9da91bdd00ee9a8585f985ca9f9b0898618fb7cb..4180b96fc72ba35d9bba12521956c9e26b649922 100644 (file)
Binary files a/scroll.exe and b/scroll.exe differ
diff --git a/src/exmmtest.c b/src/exmmtest.c
new file mode 100644 (file)
index 0000000..2124d3f
--- /dev/null
@@ -0,0 +1,31 @@
+/* Project 16 Source Code~
+ * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669
+ *
+ * This file is part of Project 16.
+ *
+ * Project 16 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Project 16 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+/*
+       input test
+*/
+#include "src/lib/16_mm.h"
+
+void
+main(int argc, char *argv[])
+{
+
+}
similarity index 85%
rename from 16/cawat/16_mm.c
rename to src/lib/16_mm.c
index 8c28277aff7580aa13504a9bf778e6bc3914e72a..570ec346b32cc937508075dfc09b89440394d867 100644 (file)
-/* Catacomb Armageddon Source Code\r
- * Copyright (C) 1993-2014 Flat Rock Software\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License along\r
- * with this program; if not, write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
- */\r
-\r
-// NEWMM.C\r
-\r
-/*\r
-=============================================================================\r
-\r
-                       ID software memory manager\r
-                       --------------------------\r
-\r
-Primary coder: John Carmack\r
-\r
-RELIES ON\r
----------\r
-Quit (char *error) function\r
-\r
-\r
-WORK TO DO\r
-----------\r
-MM_SizePtr to change the size of a given pointer\r
-\r
-Multiple purge levels utilized\r
-\r
-EMS / XMS unmanaged routines\r
-\r
-=============================================================================\r
-*/\r
-\r
-//#include "LIB_HEAD.H"\r
-#include "16_mm.h"\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                       LOCAL INFO\r
-\r
-=============================================================================\r
-*/\r
-\r
-#define LOCKBIT                0x80    // if set in attributes, block cannot be moved\r
-#define PURGEBITS      3               // 0-3 level, 0= unpurgable, 3= purge first\r
-#define PURGEMASK      0xfffc\r
-#define BASEATTRIBUTES 0       // unlocked, non purgable\r
-\r
-#define MAXUMBS                10\r
-\r
-typedef struct mmblockstruct\r
-{\r
-       unsigned        start,length;\r
-       unsigned        attributes;\r
-       memptr          *useptr;        // pointer to the segment start\r
-       struct mmblockstruct far *next;\r
-} mmblocktype;\r
-\r
-\r
-//#define GETNEWBLOCK {if(!(mmnew=mmfree))Quit("MM_GETNEWBLOCK: No free blocks!");mmfree=mmfree->next;}\r
-#define GETNEWBLOCK {if(!mmfree)MML_ClearBlock();mmnew=mmfree;mmfree=mmfree->next;}\r
-#define FREEBLOCK(x) {*x->useptr=NULL;x->next=mmfree;mmfree=x;}\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                GLOBAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-mminfotype     mminfo;\r
-memptr         bufferseg;\r
-boolean                mmerror;\r
-\r
-void           (* beforesort) (void);\r
-void           (* aftersort) (void);\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                LOCAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-boolean                mmstarted;\r
-\r
-void huge      *hugeheap;\r
-void far       *farheap;\r
-void           *nearheap;\r
-\r
-mmblocktype    far mmblocks[MAXBLOCKS]\r
-                       ,far *mmhead,far *mmfree,far *mmrover,far *mmnew;\r
-\r
-boolean                bombonerror;\r
-\r
-unsigned       totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle;\r
-\r
-void           (* XMSaddr) (void);             // far pointer to XMS driver\r
-\r
-unsigned       numUMBs,UMBbase[MAXUMBS];\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= MML_CheckForEMS\r
-=\r
-= Routine from p36 of Extending DOS\r
-=\r
-=======================\r
-*/\r
-\r
-boolean MML_CheckForEMS (void)\r
-{\r
-       boolean emmcfems;\r
-       char    emmname[] = "EMMXXXX0";\r
-//             mov     dx,OFFSET emmname\r
-       __asm {\r
-               LEA     DX, emmname     //fix by andrius4669\r
-               mov     ax,0x3d00\r
-               int     0x21            // try to open EMMXXXX0 device\r
-               jc      error\r
-\r
-               mov     bx,ax\r
-               mov     ax,0x4400\r
-\r
-               int     0x21            // get device info\r
-               jc      error\r
-\r
-               and     dx,0x80\r
-               jz      error\r
-\r
-               mov     ax,0x4407\r
-\r
-               int     0x21            // get status\r
-               jc      error\r
-               or      al,al\r
-               jz      error\r
-\r
-               mov     ah,0x3e\r
-               int     0x21            // close handle\r
-               jc      error\r
-               //\r
-               // EMS is good\r
-               //\r
-               mov     emmcfems,1\r
-               jmp End\r
-               error:\r
-               //\r
-               // EMS is bad\r
-               //\r
-               mov     emmcfems,0\r
-               End:\r
-       }\r
-       return(emmcfems);\r
-}\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= MML_SetupEMS\r
-=\r
-=======================\r
-*/\r
-\r
-void MML_SetupEMS (void)\r
-{\r
-       char    str[80],str2[10];\r
-       unsigned        err;\r
-       struct REGS CPURegs;\r
-\r
-       totalEMSpages = freeEMSpages = EMSpageframe = EMSpagesmapped = 0;\r
-\r
-       __asm\r
-               {\r
-               mov     ah,EMS_STATUS\r
-               int     EMS_INT                                         // make sure EMS hardware is present\r
-               or      ah,ah\r
-               jnz     error\r
-\r
-               mov     ah,EMS_VERSION\r
-               int     EMS_INT\r
-               or      ah,ah\r
-               jnz     error\r
-               cmp     al,0x32                                         // only work on ems 3.2 or greater\r
-               jb      error\r
-\r
-               mov     ah,EMS_GETFRAME\r
-               int     EMS_INT                                         // find the page frame address\r
-               or      ah,ah\r
-               jnz     error\r
-               mov     [EMSpageframe],bx\r
-\r
-               mov     ah,EMS_GETPAGES\r
-               int     EMS_INT                                         // find out how much EMS is there\r
-               or      ah,ah\r
-               jnz     error\r
-               mov     [totalEMSpages],dx\r
-               mov     [freeEMSpages],bx\r
-               or      bx,bx\r
-               jz      noEMS                                           // no EMS at all to allocate\r
-\r
-               cmp     bx,4\r
-               jle     getpages                                        // there is only 1,2,3,or 4 pages\r
-               mov     bx,4                                            // we can't use more than 4 pages\r
-\r
-getpages:\r
-               mov     [EMSpagesmapped],bx\r
-               mov     ah,EMS_ALLOCPAGES                       // allocate up to 64k of EMS\r
-               int     EMS_INT\r
-               or      ah,ah\r
-               jnz     error\r
-               mov     [EMShandle],dx\r
-               jmp End\r
-error:\r
-//             err = CPURegs.h.ah;\r
-//             strcpy (str,"MML_SetupEMS: EMS error 0x");\r
-//             itoa(err,str2,16);\r
-//             strcpy (str,str2);\r
-//             printf("%s\n",str);\r
-               jmp End\r
-noEMS:\r
-End:\r
-       }\r
-}\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= MML_ShutdownEMS\r
-=\r
-=======================\r
-*/\r
-\r
-void MML_ShutdownEMS (void)\r
-{\r
-       if (!EMShandle)\r
-               return;\r
-\r
-       __asm\r
-       {\r
-               mov     ah,EMS_FREEPAGES\r
-               mov     dx,[EMShandle]\r
-               int     EMS_INT\r
-               or      ah,ah\r
-               jz      ok\r
-               printf("MML_ShutdownEMS: Error freeing EMS!");\r
-               ok:\r
-       }\r
-}\r
-\r
-/*\r
-====================\r
-=\r
-= MM_MapEMS\r
-=\r
-= Maps the 64k of EMS used by memory manager into the page frame\r
-= for general use.  This only needs to be called if you are keeping\r
-= other things in EMS.\r
-=\r
-====================\r
-*/\r
-\r
-void MM_MapEMS (void)\r
-{\r
-       char    str[80],str2[10];\r
-       unsigned        error;\r
-       int     i;\r
-\r
-       for (i=0;i<EMSpagesmapped;i++)\r
-       {\r
-               __asm\r
-               {\r
-                       mov     ah,EMS_MAPPAGE\r
-                       mov     bx,[i]                  // logical page\r
-                       mov     al,bl                   // physical page\r
-                       mov     dx,[EMShandle]  // handle\r
-                       int     EMS_INT\r
-                       or      ah,ah\r
-                       jnz     error\r
-                       jmp End\r
-                       error:\r
-                       error = _AH;\r
-                       strcpy (str,"MM_MapEMS: EMS error 0x");\r
-                       itoa(error,str2,16);\r
-                       strcpy (str,str2);\r
-                       printf("%s\n",str);\r
-                       End:\r
-               }\r
-       }\r
-       return;\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= MML_CheckForXMS\r
-=\r
-= Check for XMM driver\r
-=\r
-=======================\r
-*/\r
-\r
-boolean MML_CheckForXMS (void)\r
-{\r
-       numUMBs = 0;\r
-\r
-       __asm\r
-       {\r
-               mov     ax,0x4300\r
-               int     0x2f                            // query status of installed diver\r
-               cmp     al,0x80\r
-               je      good\r
-               good:\r
-       }\r
-/*     return false;\r
-good:\r
-       return true;*/\r
-}\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= MML_SetupXMS\r
-=\r
-= Try to allocate all upper memory block\r
-=\r
-=======================\r
-*/\r
-\r
-void MML_SetupXMS (void)\r
-{\r
-       unsigned        base,size;\r
-\r
-       __asm\r
-       {\r
-               mov     ax,0x4310\r
-               int     0x2f\r
-               mov     [WORD PTR XMSaddr],bx\r
-               mov     [WORD PTR XMSaddr+2],es         // function pointer to XMS driver\r
-\r
-getmemory:\r
-       mov     ah,XMS_ALLOCUMB\r
-       mov     dx,0xffff                                       // try for largest block possible\r
-       call    [DWORD PTR XMSaddr]\r
-       or      ax,ax\r
-       jnz     gotone\r
-\r
-       cmp     bl,0xb0                                         // error: smaller UMB is available\r
-       jne     done;\r
-\r
-       mov     ah,XMS_ALLOCUMB\r
-       call    [DWORD PTR XMSaddr]             // DX holds largest available UMB\r
-       or      ax,ax\r
-       jz      done                                            // another error...\r
-\r
-gotone:\r
-       mov     [base],bx\r
-       mov     [size],dx\r
-       done:\r
-       }\r
-       MML_UseSpace (base,size);\r
-       mminfo.XMSmem += size*16;\r
-       UMBbase[numUMBs] = base;\r
-       numUMBs++;\r
-       if (numUMBs < MAXUMBS)\r
-               goto getmemory;\r
-}\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= MML_ShutdownXMS\r
-=\r
-======================\r
-*/\r
-\r
-void MML_ShutdownXMS (void)\r
-{\r
-       int     i;\r
-       unsigned        base;\r
-\r
-       for (i=0;i<numUMBs;i++)\r
-       {\r
-               base = UMBbase[i];\r
-               __asm\r
-               {\r
-                       mov     ah,XMS_FREEUMB\r
-                       mov     dx,[base]\r
-                       call    [DWORD PTR XMSaddr]\r
-               }\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= MML_UseSpace\r
-=\r
-= Marks a range of paragraphs as usable by the memory manager\r
-= This is used to mark space for the near heap, far heap, ems page frame,\r
-= and upper memory blocks\r
-=\r
-======================\r
-*/\r
-\r
-void MML_UseSpace (unsigned segstart, unsigned seglength)\r
-{\r
-       mmblocktype far *scan,far *last;\r
-       unsigned        oldend;\r
-       long            extra;\r
-\r
-       scan = last = mmhead;\r
-       mmrover = mmhead;               // reset rover to start of memory\r
-\r
-//\r
-// search for the block that contains the range of segments\r
-//\r
-       while (scan->start+scan->length < segstart)\r
-       {\r
-               last = scan;\r
-               scan = scan->next;\r
-       }\r
-\r
-//\r
-// take the given range out of the block\r
-//\r
-       oldend = scan->start + scan->length;\r
-       extra = oldend - (segstart+seglength);\r
-       if (extra < 0)\r
-               Quit ("MML_UseSpace: Segment spans two blocks!");\r
-\r
-       if (segstart == scan->start)\r
-       {\r
-               last->next = scan->next;                        // unlink block\r
-               FREEBLOCK(scan);\r
-               scan = last;\r
-       }\r
-       else\r
-               scan->length = segstart-scan->start;    // shorten block\r
-\r
-       if (extra > 0)\r
-       {\r
-               GETNEWBLOCK;\r
-               mmnew->next = scan->next;\r
-               scan->next = mmnew;\r
-               mmnew->start = segstart+seglength;\r
-               mmnew->length = extra;\r
-               mmnew->attributes = LOCKBIT;\r
-       }\r
-\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= MML_ClearBlock\r
-=\r
-= We are out of blocks, so free a purgable block\r
-=\r
-====================\r
-*/\r
-\r
-void MML_ClearBlock (void)\r
-{\r
-       mmblocktype far *scan,far *last;\r
-\r
-       scan = mmhead->next;\r
-\r
-       while (scan)\r
-       {\r
-               if (!(scan->attributes&LOCKBIT) && (scan->attributes&PURGEBITS) )\r
-               {\r
-                       MM_FreePtr(scan->useptr);\r
-                       return;\r
-               }\r
-               scan = scan->next;\r
-       }\r
-\r
-       Quit ("MM_ClearBlock: No purgable blocks!");\r
-}\r
-\r
-\r
-//==========================================================================\r
-\r
-/*\r
-===================\r
-=\r
-= MM_Startup\r
-=\r
-= Grabs all space from turbo with malloc/farmalloc\r
-= Allocates bufferseg misc buffer\r
-=\r
-===================\r
-*/\r
-\r
-static char *ParmStrings[] = {"noems","noxms",""};\r
-\r
-void MM_Startup (void)\r
-{\r
-       int i;\r
-       unsigned        long length;\r
-       void far        *start;\r
-       unsigned        segstart,seglength,endfree;\r
-\r
-       if (mmstarted)\r
-               MM_Shutdown ();\r
-\r
-\r
-       mmstarted = true;\r
-       bombonerror = true;\r
-//\r
-// set up the linked list (everything in the free list;\r
-//\r
-       mmhead = NULL;\r
-       mmfree = &mmblocks[0];\r
-       for (i=0;i<MAXBLOCKS-1;i++)\r
-               mmblocks[i].next = &mmblocks[i+1];\r
-       mmblocks[i].next = NULL;\r
-\r
-//\r
-// locked block of all memory until we punch out free space\r
-//\r
-       GETNEWBLOCK;\r
-       mmhead = mmnew;                         // this will allways be the first node\r
-       mmnew->start = 0;\r
-       mmnew->length = 0xffff;\r
-       mmnew->attributes = LOCKBIT;\r
-       mmnew->next = NULL;\r
-       mmrover = mmhead;\r
-\r
-\r
-//\r
-// get all available near conventional memory segments\r
-//\r
-       length=coreleft();\r
-       start = (void far *)(nearheap = malloc(length));\r
-\r
-       length -= 16-(FP_OFF(start)&15);\r
-       length -= SAVENEARHEAP;\r
-       seglength = length / 16;                        // now in paragraphs\r
-       segstart = FP_SEG(start)+(FP_OFF(start)+15)/16;\r
-       MML_UseSpace (segstart,seglength);\r
-       mminfo.nearheap = length;\r
-\r
-//\r
-// get all available far conventional memory segments\r
-//\r
-       length=farcoreleft();\r
-       start = farheap = farmalloc(length);\r
-       length -= 16-(FP_OFF(start)&15);\r
-       length -= SAVEFARHEAP;\r
-       seglength = length / 16;                        // now in paragraphs\r
-       segstart = FP_SEG(start)+(FP_OFF(start)+15)/16;\r
-       MML_UseSpace (segstart,seglength);\r
-       mminfo.farheap = length;\r
-       mminfo.mainmem = mminfo.nearheap + mminfo.farheap;\r
-\r
-\r
-//\r
-// detect EMS and allocate up to 64K at page frame\r
-//\r
-       mminfo.EMSmem = 0;\r
-       for (i = 1;i < _argc;i++)\r
-       {\r
-               if ( US_CheckParm(_argv[i],ParmStrings) == 0)\r
-                       goto emsskip;                           // param NOEMS\r
-       }\r
-\r
-       if (MML_CheckForEMS())\r
-       {\r
-               MML_SetupEMS();                                 // allocate space\r
-               MML_UseSpace (EMSpageframe,EMSpagesmapped*0x400);\r
-               MM_MapEMS();                                    // map in used pages\r
-               mminfo.EMSmem = EMSpagesmapped*0x4000l;\r
-       }\r
-\r
-//\r
-// detect XMS and get upper memory blocks\r
-//\r
-emsskip:\r
-       mminfo.XMSmem = 0;\r
-       for (i = 1;i < _argc;i++)\r
-       {\r
-               if ( US_CheckParm(_argv[i],ParmStrings) == 0)\r
-                       goto xmsskip;                           // param NOXMS\r
-       }\r
-\r
-       if (MML_CheckForXMS())\r
-               MML_SetupXMS();                                 // allocate as many UMBs as possible\r
-\r
-//\r
-// allocate the misc buffer\r
-//\r
-xmsskip:\r
-       mmrover = mmhead;               // start looking for space after low block\r
-\r
-       MM_GetPtr (&bufferseg,BUFFERSIZE);\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= MM_Shutdown\r
-=\r
-= Frees all conventional, EMS, and XMS allocated\r
-=\r
-====================\r
-*/\r
-\r
-void MM_Shutdown (void)\r
-{\r
-  if (!mmstarted)\r
-       return;\r
-\r
-  farfree (farheap);\r
-  free (nearheap);\r
-  MML_ShutdownEMS ();\r
-  MML_ShutdownXMS ();\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= MM_GetPtr\r
-=\r
-= Allocates an unlocked, unpurgable block\r
-=\r
-====================\r
-*/\r
-\r
-void MM_GetPtr (memptr *baseptr,unsigned long size)\r
-{\r
-       mmblocktype far *scan,far *lastscan,far *endscan\r
-                               ,far *purge,far *next;\r
-       int                     search;\r
-       unsigned        needed,startseg;\r
-\r
-       needed = (size+15)/16;          // convert size from bytes to paragraphs\r
-\r
-       GETNEWBLOCK;                            // fill in start and next after a spot is found\r
-       mmnew->length = needed;\r
-       mmnew->useptr = baseptr;\r
-       mmnew->attributes = BASEATTRIBUTES;\r
-\r
-       for (search = 0; search<3; search++)\r
-       {\r
-       //\r
-       // first search:        try to allocate right after the rover, then on up\r
-       // second search:       search from the head pointer up to the rover\r
-       // third search:        compress memory, then scan from start\r
-               if (search == 1 && mmrover == mmhead)\r
-                       search++;\r
-\r
-               switch (search)\r
-               {\r
-               case 0:\r
-                       lastscan = mmrover;\r
-                       scan = mmrover->next;\r
-                       endscan = NULL;\r
-                       break;\r
-               case 1:\r
-                       lastscan = mmhead;\r
-                       scan = mmhead->next;\r
-                       endscan = mmrover;\r
-                       break;\r
-               case 2:\r
-                       MM_SortMem ();\r
-                       lastscan = mmhead;\r
-                       scan = mmhead->next;\r
-                       endscan = NULL;\r
-                       break;\r
-               }\r
-\r
-               startseg = lastscan->start + lastscan->length;\r
-\r
-               while (scan != endscan)\r
-               {\r
-                       if (scan->start - startseg >= needed)\r
-                       {\r
-                       //\r
-                       // got enough space between the end of lastscan and\r
-                       // the start of scan, so throw out anything in the middle\r
-                       // and allocate the new block\r
-                       //\r
-                               purge = lastscan->next;\r
-                               lastscan->next = mmnew;\r
-                               mmnew->start = *(unsigned *)baseptr = startseg;\r
-                               mmnew->next = scan;\r
-                               while ( purge != scan)\r
-                               {       // free the purgable block\r
-                                       next = purge->next;\r
-                                       FREEBLOCK(purge);\r
-                                       purge = next;           // purge another if not at scan\r
-                               }\r
-                               mmrover = mmnew;\r
-                               return; // good allocation!\r
-                       }\r
-\r
-                       //\r
-                       // if this block is purge level zero or locked, skip past it\r
-                       //\r
-                       if ( (scan->attributes & LOCKBIT)\r
-                               || !(scan->attributes & PURGEBITS) )\r
-                       {\r
-                               lastscan = scan;\r
-                               startseg = lastscan->start + lastscan->length;\r
-                       }\r
-\r
-\r
-                       scan=scan->next;                // look at next line\r
-               }\r
-       }\r
-\r
-       if (bombonerror)\r
-               Quit (OUT_OF_MEM_MSG,(size-mminfo.nearheap));\r
-       else\r
-               mmerror = true;\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= MM_FreePtr\r
-=\r
-= Allocates an unlocked, unpurgable block\r
-=\r
-====================\r
-*/\r
-\r
-void MM_FreePtr (memptr *baseptr)\r
-{\r
-       mmblocktype far *scan,far *last;\r
-\r
-       last = mmhead;\r
-       scan = last->next;\r
-\r
-       if (baseptr == mmrover->useptr) // removed the last allocated block\r
-               mmrover = mmhead;\r
-\r
-       while (scan->useptr != baseptr && scan)\r
-       {\r
-               last = scan;\r
-               scan = scan->next;\r
-       }\r
-\r
-       if (!scan)\r
-               Quit ("MM_FreePtr: Block not found!");\r
-\r
-       last->next = scan->next;\r
-\r
-       FREEBLOCK(scan);\r
-}\r
-//==========================================================================\r
-\r
-/*\r
-=====================\r
-=\r
-= MM_SetPurge\r
-=\r
-= Sets the purge level for a block (locked blocks cannot be made purgable)\r
-=\r
-=====================\r
-*/\r
-\r
-void MM_SetPurge (memptr *baseptr, int purge)\r
-{\r
-       mmblocktype far *start;\r
-\r
-       start = mmrover;\r
-\r
-       do\r
-       {\r
-               if (mmrover->useptr == baseptr)\r
-                       break;\r
-\r
-               mmrover = mmrover->next;\r
-\r
-               if (!mmrover)\r
-                       mmrover = mmhead;\r
-               else if (mmrover == start)\r
-                       Quit ("MM_SetPurge: Block not found!");\r
-\r
-       } while (1);\r
-\r
-       mmrover->attributes &= ~PURGEBITS;\r
-       mmrover->attributes |= purge;\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-=====================\r
-=\r
-= MM_SetLock\r
-=\r
-= Locks / unlocks the block\r
-=\r
-=====================\r
-*/\r
-\r
-void MM_SetLock (memptr *baseptr, boolean locked)\r
-{\r
-       mmblocktype far *start;\r
-\r
-       start = mmrover;\r
-\r
-       do\r
-       {\r
-               if (mmrover->useptr == baseptr)\r
-                       break;\r
-\r
-               mmrover = mmrover->next;\r
-\r
-               if (!mmrover)\r
-                       mmrover = mmhead;\r
-               else if (mmrover == start)\r
-                       Quit ("MM_SetLock: Block not found!");\r
-\r
-       } while (1);\r
-\r
-       mmrover->attributes &= ~LOCKBIT;\r
-       mmrover->attributes |= locked*LOCKBIT;\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-=====================\r
-=\r
-= MM_SortMem\r
-=\r
-= Throws out all purgable stuff and compresses movable blocks\r
-=\r
-=====================\r
-*/\r
-\r
-void MM_SortMem (void)\r
-{\r
-       mmblocktype far *scan,far *last,far *next;\r
-       unsigned        start,length,source,dest,oldborder;\r
-       int                     playing;\r
-\r
-       //\r
-       // lock down a currently playing sound\r
-       //\r
-       playing = SD_SoundPlaying ();\r
-       if (playing)\r
-       {\r
-               switch (SoundMode)\r
-               {\r
-               case sdm_PC:\r
-                       playing += STARTPCSOUNDS;\r
-                       break;\r
-               case sdm_AdLib:\r
-                       playing += STARTADLIBSOUNDS;\r
-                       break;\r
-               }\r
-               MM_SetLock(&(memptr)audiosegs[playing],true);\r
-       }\r
-\r
-\r
-       SD_StopSound();\r
-//     oldborder = bordercolor;\r
-//     VW_ColorBorder (15);\r
-\r
-       if (beforesort)\r
-               beforesort();\r
-\r
-       scan = mmhead;\r
-\r
-       last = NULL;            // shut up compiler warning\r
-\r
-       while (scan)\r
-       {\r
-               if (scan->attributes & LOCKBIT)\r
-               {\r
-               //\r
-               // block is locked, so try to pile later blocks right after it\r
-               //\r
-                       start = scan->start + scan->length;\r
-               }\r
-               else\r
-               {\r
-                       if (scan->attributes & PURGEBITS)\r
-                       {\r
-                       //\r
-                       // throw out the purgable block\r
-                       //\r
-                               next = scan->next;\r
-                               FREEBLOCK(scan);\r
-                               last->next = next;\r
-                               scan = next;\r
-                               continue;\r
-                       }\r
-                       else\r
-                       {\r
-                       //\r
-                       // push the non purgable block on top of the last moved block\r
-                       //\r
-                               if (scan->start != start)\r
-                               {\r
-                                       length = scan->length;\r
-                                       source = scan->start;\r
-                                       dest = start;\r
-                                       while (length > 0xf00)\r
-                                       {\r
-                                               movedata(source,0,dest,0,0xf00*16);\r
-                                               length -= 0xf00;\r
-                                               source += 0xf00;\r
-                                               dest += 0xf00;\r
-                                       }\r
-                                       movedata(source,0,dest,0,length*16);\r
-\r
-                                       scan->start = start;\r
-                                       *(unsigned *)scan->useptr = start;\r
-                               }\r
-                               start = scan->start + scan->length;\r
-                       }\r
-               }\r
-\r
-               last = scan;\r
-               scan = scan->next;              // go to next block\r
-       }\r
-\r
-       mmrover = mmhead;\r
-\r
-       if (aftersort)\r
-               aftersort();\r
-\r
-//     VW_ColorBorder (oldborder);\r
-\r
-       if (playing)\r
-               MM_SetLock(&(memptr)audiosegs[playing],false);\r
-}\r
-\r
-\r
-//==========================================================================\r
-\r
-#if 0\r
-/*\r
-=====================\r
-=\r
-= MM_ShowMemory\r
-=\r
-=====================\r
-*/\r
-\r
-void MM_ShowMemory (void)\r
-{\r
-       mmblocktype far *scan;\r
-       unsigned color,temp;\r
-       long    end,owner;\r
-       char    scratch[80],str[10];\r
-\r
-       VW_SetDefaultColors();\r
-       VW_SetLineWidth(40);\r
-       temp = bufferofs;\r
-       bufferofs = 0;\r
-       VW_SetScreen (0,0);\r
-\r
-       scan = mmhead;\r
-\r
-       end = -1;\r
-\r
-//CA_OpenDebug ();\r
-\r
-       while (scan)\r
-       {\r
-               if (scan->attributes & PURGEBITS)\r
-                       color = 5;              // dark purple = purgable\r
-               else\r
-                       color = 9;              // medium blue = non purgable\r
-               if (scan->attributes & LOCKBIT)\r
-                       color = 12;             // red = locked\r
-               if (scan->start<=end)\r
-                       Quit ("MM_ShowMemory: Memory block order currupted!");\r
-               end = scan->start+scan->length-1;\r
-               VW_Hlin(scan->start,(unsigned)end,0,color);\r
-               VW_Plot(scan->start,0,15);\r
-               if (scan->next->start > end+1)\r
-                       VW_Hlin(end+1,scan->next->start,0,0);   // black = free\r
-\r
-#if 0\r
-strcpy (scratch,"Size:");\r
-ltoa ((long)scan->length*16,str,10);\r
-strcat (scratch,str);\r
-strcat (scratch,"\tOwner:0x");\r
-owner = (unsigned)scan->useptr;\r
-ultoa (owner,str,16);\r
-strcat (scratch,str);\r
-strcat (scratch,"\n");\r
-write (debughandle,scratch,strlen(scratch));\r
-#endif\r
-\r
-               scan = scan->next;\r
-       }\r
-\r
-//CA_CloseDebug ();\r
-\r
-       IN_Ack();\r
-       VW_SetLineWidth(64);\r
-       bufferofs = temp;\r
-}\r
-#endif\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= MM_UnusedMemory\r
-=\r
-= Returns the total free space without purging\r
-=\r
-======================\r
-*/\r
-\r
-long MM_UnusedMemory (void)\r
-{\r
-       unsigned free;\r
-       mmblocktype far *scan;\r
-\r
-       free = 0;\r
-       scan = mmhead;\r
-\r
-       while (scan->next)\r
-       {\r
-               free += scan->next->start - (scan->start + scan->length);\r
-               scan = scan->next;\r
-       }\r
-\r
-       return free*16l;\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= MM_TotalFree\r
-=\r
-= Returns the total free space with purging\r
-=\r
-======================\r
-*/\r
-\r
-long MM_TotalFree (void)\r
-{\r
-       unsigned free;\r
-       mmblocktype far *scan;\r
-\r
-       free = 0;\r
-       scan = mmhead;\r
-\r
-       while (scan->next)\r
-       {\r
-               if ((scan->attributes&PURGEBITS) && !(scan->attributes&LOCKBIT))\r
-                       free += scan->length;\r
-               free += scan->next->start - (scan->start + scan->length);\r
-               scan = scan->next;\r
-       }\r
-\r
-       return free*16l;\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-=====================\r
-=\r
-= MM_BombOnError\r
-=\r
-=====================\r
-*/\r
-\r
-void MM_BombOnError (boolean bomb)\r
-{\r
-       bombonerror = bomb;\r
-}\r
-\r
-\r
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+// NEWMM.C
+
+/*
+=============================================================================
+
+                       ID software memory manager
+                       --------------------------
+
+Primary coder: John Carmack
+
+RELIES ON
+---------
+Quit (char *error) function
+
+
+WORK TO DO
+----------
+MM_SizePtr to change the size of a given pointer
+
+Multiple purge levels utilized
+
+EMS / XMS unmanaged routines
+
+=============================================================================
+*/
+
+#include "src/lib/16_mm.h"
+
+/*
+=============================================================================
+
+                                                       LOCAL INFO
+
+=============================================================================
+*/
+
+#define LOCKBIT                0x80    // if set in attributes, block cannot be moved
+#define PURGEBITS      3               // 0-3 level, 0= unpurgable, 3= purge first
+#define PURGEMASK      0xfffc
+#define BASEATTRIBUTES 0       // unlocked, non purgable
+
+#define MAXUMBS                10
+
+typedef struct mmblockstruct
+{
+       unsigned        start,length;
+       unsigned        attributes;
+       memptr          *useptr;        // pointer to the segment start
+       struct mmblockstruct far *next;
+} mmblocktype;
+
+
+//#define GETNEWBLOCK {if(!(mmnew=mmfree))Quit("MM_GETNEWBLOCK: No free blocks!");mmfree=mmfree->next;}
+#define GETNEWBLOCK {if(!mmfree)MML_ClearBlock();mmnew=mmfree;mmfree=mmfree->next;}
+#define FREEBLOCK(x) {*x->useptr=NULL;x->next=mmfree;mmfree=x;}
+
+/*
+=============================================================================
+
+                                                GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+mminfotype     mminfo;
+memptr         bufferseg;
+boolean                mmerror;
+
+void           (* beforesort) (void);
+void           (* aftersort) (void);
+
+/*
+=============================================================================
+
+                                                LOCAL VARIABLES
+
+=============================================================================
+*/
+
+boolean                mmstarted;
+
+void huge      *hugeheap;
+void far       *farheap;
+void           *nearheap;
+
+mmblocktype    far mmblocks[MAXBLOCKS]
+                       ,far *mmhead,far *mmfree,far *mmrover,far *mmnew;
+
+boolean                bombonerror;
+
+unsigned       totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle;
+
+void           (* XMSaddr) (void);             // far pointer to XMS driver
+
+unsigned       numUMBs,UMBbase[MAXUMBS];
+
+
+/*
+======================
+=
+= MML_CheckForEMS
+=
+= Routine from p36 of Extending DOS
+=
+=======================
+*/
+
+boolean MML_CheckForEMS (void)
+{
+       boolean emmcfems;
+       char    emmname[] = "EMMXXXX0";
+//             mov     dx,OFFSET emmname
+       __asm {
+               LEA     DX, emmname     //fix by andrius4669
+               mov     ax,0x3d00
+               int     0x21            // try to open EMMXXXX0 device
+               jc      error
+
+               mov     bx,ax
+               mov     ax,0x4400
+
+               int     0x21            // get device info
+               jc      error
+
+               and     dx,0x80
+               jz      error
+
+               mov     ax,0x4407
+
+               int     0x21            // get status
+               jc      error
+               or      al,al
+               jz      error
+
+               mov     ah,0x3e
+               int     0x21            // close handle
+               jc      error
+               //
+               // EMS is good
+               //
+               mov     emmcfems,1
+               jmp End
+               error:
+               //
+               // EMS is bad
+               //
+               mov     emmcfems,0
+               End:
+       }
+       return(emmcfems);
+}
+
+
+/*
+======================
+=
+= MML_SetupEMS
+=
+=======================
+*/
+
+void MML_SetupEMS (void)
+{
+       char    str[80],str2[10];
+       unsigned        err;
+       boolean errorflag=false;
+       union REGS CPURegs;
+
+       totalEMSpages = freeEMSpages = EMSpageframe = EMSpagesmapped = 0;
+
+       __asm
+               {
+               mov     ah,EMS_STATUS
+               int     EMS_INT                                         // make sure EMS hardware is present
+               or      ah,ah
+               jnz     error
+
+               mov     ah,EMS_VERSION
+               int     EMS_INT
+               or      ah,ah
+               jnz     error
+               cmp     al,0x32                                         // only work on ems 3.2 or greater
+               jb      error
+
+               mov     ah,EMS_GETFRAME
+               int     EMS_INT                                         // find the page frame address
+               or      ah,ah
+               jnz     error
+               mov     [EMSpageframe],bx
+
+               mov     ah,EMS_GETPAGES
+               int     EMS_INT                                         // find out how much EMS is there
+               or      ah,ah
+               jnz     error
+               mov     [totalEMSpages],dx
+               mov     [freeEMSpages],bx
+               or      bx,bx
+               jz      noEMS                                           // no EMS at all to allocate
+
+               cmp     bx,4
+               jle     getpages                                        // there is only 1,2,3,or 4 pages
+               mov     bx,4                                            // we can't use more than 4 pages
+
+getpages:
+               mov     [EMSpagesmapped],bx
+               mov     ah,EMS_ALLOCPAGES                       // allocate up to 64k of EMS
+               int     EMS_INT
+               or      ah,ah
+               jnz     error
+               mov     [EMShandle],dx
+               jmp End
+error:
+               mov     errorflag,1
+               jmp End
+noEMS:
+End:
+       }
+       if(errorflag==true)
+       {
+               err = CPURegs.h.ah;
+               strcpy(str,"MML_SetupEMS: EMS error 0x");
+               itoa(err,str2,16);
+               strcpy(str,str2);
+               printf("%s\n",str);
+       }
+}
+
+
+/*
+======================
+=
+= MML_ShutdownEMS
+=
+=======================
+*/
+
+void MML_ShutdownEMS (void)
+{
+       boolean errorflag=false;
+       if (!EMShandle)
+               return;
+       __asm
+       {
+               mov     ah,EMS_FREEPAGES
+               mov     dx,[EMShandle]
+               int     EMS_INT
+               or      ah,ah
+               jz      ok
+               mov     errorflag,1
+               ok:
+       }
+       if(errorflag==true) printf("MML_ShutdownEMS: Error freeing EMS!");      //++++ add something
+}
+
+/*
+====================
+=
+= MM_MapEMS
+=
+= Maps the 64k of EMS used by memory manager into the page frame
+= for general use.  This only needs to be called if you are keeping
+= other things in EMS.
+=
+====================
+*/
+
+void MM_MapEMS (void)
+{
+       char    str[80],str2[10];
+       unsigned        err;
+       boolean errorflag=false;
+       int     i;
+       union REGS CPURegs;
+
+       for (i=0;i<EMSpagesmapped;i++)
+       {
+               __asm
+               {
+                       mov     ah,EMS_MAPPAGE
+                       mov     bx,[i]                  // logical page
+                       mov     al,bl                   // physical page
+                       mov     dx,[EMShandle]  // handle
+                       int     EMS_INT
+                       or      ah,ah
+                       jnz     error
+                       jmp End
+                       error:
+                       mov     errorflag,1
+                       End:
+               }
+               if(errorflag==true)
+               {
+                       err = CPURegs.h.ah;
+                       strcpy(str,"MM_MapEMS: EMS error 0x");
+                       itoa(err,str2,16);
+                       strcpy(str,str2);
+                       printf("%s\n",str);
+               }
+       }
+       return;
+}
+
+//==========================================================================
+
+/*
+======================
+=
+= MML_CheckForXMS
+=
+= Check for XMM driver
+=
+=======================
+*/
+
+boolean MML_CheckForXMS (void)
+{
+       boolean errorflag=false;
+       numUMBs = 0;
+
+       __asm
+       {
+               mov     ax,0x4300
+               int     0x2f                            // query status of installed diver
+               cmp     al,0x80
+               je      good
+               mov     errorflag,1
+               good:
+       }
+       if(errorflag==true) return false;
+       else return true;
+}
+
+
+/*
+======================
+=
+= MML_SetupXMS
+=
+= Try to allocate all upper memory block
+=
+=======================
+*/
+
+void MML_SetupXMS (void)
+{
+       unsigned        base,size;
+
+       __asm
+       {
+               mov     ax,0x4310
+               int     0x2f
+               mov     [WORD PTR XMSaddr],bx
+               mov     [WORD PTR XMSaddr+2],es         // function pointer to XMS driver
+       }
+getmemory:
+       __asm
+       {
+               mov     ah,XMS_ALLOCUMB
+               mov     dx,0xffff                                       // try for largest block possible
+               call    [DWORD PTR XMSaddr]
+               or      ax,ax
+               jnz     gotone
+
+               cmp     bl,0xb0                                         // error: smaller UMB is available
+               jne     done;
+
+               mov     ah,XMS_ALLOCUMB
+               call    [DWORD PTR XMSaddr]             // DX holds largest available UMB
+               or      ax,ax
+               jz      done                                            // another error...
+
+gotone:
+               mov     [base],bx
+               mov     [size],dx
+done:
+       }
+       MML_UseSpace (base,size);
+       mminfo.XMSmem += size*16;
+       UMBbase[numUMBs] = base;
+       numUMBs++;
+       if (numUMBs < MAXUMBS)
+               goto getmemory;
+}
+
+
+/*
+======================
+=
+= MML_ShutdownXMS
+=
+======================
+*/
+
+void MML_ShutdownXMS (void)
+{
+       int     i;
+       unsigned        base;
+
+       for (i=0;i<numUMBs;i++)
+       {
+               base = UMBbase[i];
+               __asm
+               {
+                       mov     ah,XMS_FREEUMB
+                       mov     dx,[base]
+                       call    [DWORD PTR XMSaddr]
+               }
+       }
+}
+
+//==========================================================================
+
+/*
+======================
+=
+= MML_UseSpace
+=
+= Marks a range of paragraphs as usable by the memory manager
+= This is used to mark space for the near heap, far heap, ems page frame,
+= and upper memory blocks
+=
+======================
+*/
+
+void MML_UseSpace (unsigned segstart, unsigned seglength)
+{
+       mmblocktype far *scan,far *last;
+       unsigned        oldend;
+       long            extra;
+
+       scan = last = mmhead;
+       mmrover = mmhead;               // reset rover to start of memory
+
+//
+// search for the block that contains the range of segments
+//
+       while (scan->start+scan->length < segstart)
+       {
+               last = scan;
+               scan = scan->next;
+       }
+
+//
+// take the given range out of the block
+//
+       oldend = scan->start + scan->length;
+       extra = oldend - (segstart+seglength);
+       if (extra < 0)
+       {
+               printf("MML_UseSpace: Segment spans two blocks!");
+               return;
+       }
+               
+
+       if (segstart == scan->start)
+       {
+               last->next = scan->next;                        // unlink block
+               FREEBLOCK(scan);
+               scan = last;
+       }
+       else
+               scan->length = segstart-scan->start;    // shorten block
+
+       if (extra > 0)
+       {
+               GETNEWBLOCK;
+               mmnew->next = scan->next;
+               scan->next = mmnew;
+               mmnew->start = segstart+seglength;
+               mmnew->length = extra;
+               mmnew->attributes = LOCKBIT;
+       }
+
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= MML_ClearBlock
+=
+= We are out of blocks, so free a purgable block
+=
+====================
+*/
+
+void MML_ClearBlock (void)
+{
+       mmblocktype far *scan,far *last;
+
+       scan = mmhead->next;
+
+       while (scan)
+       {
+               if (!(scan->attributes&LOCKBIT) && (scan->attributes&PURGEBITS) )
+               {
+                       MM_FreePtr(scan->useptr);
+                       return;
+               }
+               scan = scan->next;
+       }
+
+       printf("MM_ClearBlock: No purgable blocks!");
+}
+
+
+//==========================================================================
+
+/*
+===================
+=
+= MM_Startup
+=
+= Grabs all space from turbo with malloc/farmalloc
+= Allocates bufferseg misc buffer
+=
+===================
+*/
+
+static char *ParmStringsexmm[] = {"noems","noxms",""};
+
+void MM_Startup (void)
+{
+       int i;
+       dword length;
+       void far        *start;
+       unsigned        segstart,seglength,endfree;
+
+       if (mmstarted)
+               MM_Shutdown ();
+
+
+       mmstarted = true;
+       bombonerror = true;
+//
+// set up the linked list (everything in the free list;
+//
+       mmhead = NULL;
+       mmfree = &mmblocks[0];
+       for (i=0;i<MAXBLOCKS-1;i++)
+               mmblocks[i].next = &mmblocks[i+1];
+       mmblocks[i].next = NULL;
+
+//
+// locked block of all memory until we punch out free space
+//
+       GETNEWBLOCK;
+       mmhead = mmnew;                         // this will allways be the first node
+       mmnew->start = 0;
+       mmnew->length = 0xffff;
+       mmnew->attributes = LOCKBIT;
+       mmnew->next = NULL;
+       mmrover = mmhead;
+
+
+//
+// get all available near conventional memory segments
+//
+//---- length=coreleft();
+       length=_memavl();
+       start = (void far *)(nearheap = malloc(length));
+
+       length -= 16-(FP_OFF(start)&15);
+       length -= SAVENEARHEAP;
+       seglength = length / 16;                        // now in paragraphs
+       segstart = FP_SEG(start)+(FP_OFF(start)+15)/16;
+       MML_UseSpace (segstart,seglength);
+       mminfo.nearheap = length;
+
+//
+// get all available far conventional memory segments
+//
+//---- length=farcoreleft();
+       length=_memmax();
+       start = farheap = _fmalloc(length);
+       length -= 16-(FP_OFF(start)&15);
+       length -= SAVEFARHEAP;
+       seglength = length / 16;                        // now in paragraphs
+       segstart = FP_SEG(start)+(FP_OFF(start)+15)/16;
+       MML_UseSpace (segstart,seglength);
+       mminfo.farheap = length;
+       mminfo.mainmem = mminfo.nearheap + mminfo.farheap;
+
+
+//
+// detect EMS and allocate up to 64K at page frame
+//
+       mminfo.EMSmem = 0;
+       for (i = 1;i < __argc;i++)
+       {
+               if ( US_CheckParm(__argv[i],ParmStringsexmm) == 0)
+                       goto emsskip;                           // param NOEMS
+       }
+
+       if (MML_CheckForEMS())
+       {
+               MML_SetupEMS();                                 // allocate space
+               MML_UseSpace (EMSpageframe,EMSpagesmapped*0x400);
+               MM_MapEMS();                                    // map in used pages
+               mminfo.EMSmem = EMSpagesmapped*0x4000l;
+       }
+
+//
+// detect XMS and get upper memory blocks
+//
+emsskip:
+       mminfo.XMSmem = 0;
+       for (i = 1;i < __argc;i++)
+       {
+               if ( US_CheckParm(__argv[i],ParmStringsexmm) == 0)
+                       goto xmsskip;                           // param NOXMS
+       }
+
+       if (MML_CheckForXMS())
+               MML_SetupXMS();                                 // allocate as many UMBs as possible
+
+//
+// allocate the misc buffer
+//
+xmsskip:
+       mmrover = mmhead;               // start looking for space after low block
+
+       MM_GetPtr (&bufferseg,BUFFERSIZE);
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= MM_Shutdown
+=
+= Frees all conventional, EMS, and XMS allocated
+=
+====================
+*/
+
+void MM_Shutdown (void)
+{
+  if (!mmstarted)
+       return;
+
+  _ffree (farheap);
+  free (nearheap);
+  hfree(hugeheap);
+  MML_ShutdownEMS ();
+  MML_ShutdownXMS ();
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= MM_GetPtr
+=
+= Allocates an unlocked, unpurgable block
+=
+====================
+*/
+
+void MM_GetPtr (memptr *baseptr,dword size)
+{
+       mmblocktype far *scan,far *lastscan,far *endscan
+                               ,far *purge,far *next;
+       int                     search;
+       unsigned        needed,startseg;
+
+       needed = (size+15)/16;          // convert size from bytes to paragraphs
+
+       GETNEWBLOCK;                            // fill in start and next after a spot is found
+       mmnew->length = needed;
+       mmnew->useptr = baseptr;
+       mmnew->attributes = BASEATTRIBUTES;
+
+       for (search = 0; search<3; search++)
+       {
+       //
+       // first search:        try to allocate right after the rover, then on up
+       // second search:       search from the head pointer up to the rover
+       // third search:        compress memory, then scan from start
+               if (search == 1 && mmrover == mmhead)
+                       search++;
+
+               switch (search)
+               {
+               case 0:
+                       lastscan = mmrover;
+                       scan = mmrover->next;
+                       endscan = NULL;
+                       break;
+               case 1:
+                       lastscan = mmhead;
+                       scan = mmhead->next;
+                       endscan = mmrover;
+                       break;
+               case 2:
+                       MM_SortMem ();
+                       lastscan = mmhead;
+                       scan = mmhead->next;
+                       endscan = NULL;
+                       break;
+               }
+
+               startseg = lastscan->start + lastscan->length;
+
+               while (scan != endscan)
+               {
+                       if (scan->start - startseg >= needed)
+                       {
+                       //
+                       // got enough space between the end of lastscan and
+                       // the start of scan, so throw out anything in the middle
+                       // and allocate the new block
+                       //
+                               purge = lastscan->next;
+                               lastscan->next = mmnew;
+                               mmnew->start = *(unsigned *)baseptr = startseg;
+                               mmnew->next = scan;
+                               while ( purge != scan)
+                               {       // free the purgable block
+                                       next = purge->next;
+                                       FREEBLOCK(purge);
+                                       purge = next;           // purge another if not at scan
+                               }
+                               mmrover = mmnew;
+                               return; // good allocation!
+                       }
+
+                       //
+                       // if this block is purge level zero or locked, skip past it
+                       //
+                       if ( (scan->attributes & LOCKBIT)
+                               || !(scan->attributes & PURGEBITS) )
+                       {
+                               lastscan = scan;
+                               startseg = lastscan->start + lastscan->length;
+                       }
+
+
+                       scan=scan->next;                // look at next line
+               }
+       }
+
+       if (bombonerror)
+               printf(OUT_OF_MEM_MSG,(size-mminfo.nearheap));
+       else
+               mmerror = true;
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= MM_FreePtr
+=
+= Allocates an unlocked, unpurgable block
+=
+====================
+*/
+
+void MM_FreePtr (memptr *baseptr)
+{
+       mmblocktype far *scan,far *last;
+
+       last = mmhead;
+       scan = last->next;
+
+       if (baseptr == mmrover->useptr) // removed the last allocated block
+               mmrover = mmhead;
+
+       while (scan->useptr != baseptr && scan)
+       {
+               last = scan;
+               scan = scan->next;
+       }
+
+       if (!scan)
+       {
+               printf("MM_FreePtr: Block not found!");
+               return;
+       }
+
+       last->next = scan->next;
+
+       FREEBLOCK(scan);
+}
+//==========================================================================
+
+/*
+=====================
+=
+= MM_SetPurge
+=
+= Sets the purge level for a block (locked blocks cannot be made purgable)
+=
+=====================
+*/
+
+void MM_SetPurge (memptr *baseptr, int purge)
+{
+       mmblocktype far *start;
+
+       start = mmrover;
+
+       do
+       {
+               if (mmrover->useptr == baseptr)
+                       break;
+
+               mmrover = mmrover->next;
+
+               if (!mmrover)
+                       mmrover = mmhead;
+               else if (mmrover == start)
+               {
+                       printf("MM_SetPurge: Block not found!");
+                       return;
+               }
+
+       } while (1);
+
+       mmrover->attributes &= ~PURGEBITS;
+       mmrover->attributes |= purge;
+}
+
+//==========================================================================
+
+/*
+=====================
+=
+= MM_SetLock
+=
+= Locks / unlocks the block
+=
+=====================
+*/
+
+void MM_SetLock (memptr *baseptr, boolean locked)
+{
+       mmblocktype far *start;
+
+       start = mmrover;
+
+       do
+       {
+               if (mmrover->useptr == baseptr)
+                       break;
+
+               mmrover = mmrover->next;
+
+               if (!mmrover)
+                       mmrover = mmhead;
+               else if (mmrover == start)
+               {
+                       printf("MM_SetLock: Block not found!");
+                       return;
+               }
+
+       } while (1);
+
+       mmrover->attributes &= ~LOCKBIT;
+       mmrover->attributes |= locked*LOCKBIT;
+}
+
+//==========================================================================
+
+/*
+=====================
+=
+= MM_SortMem
+=
+= Throws out all purgable stuff and compresses movable blocks
+=
+=====================
+*/
+
+void MM_SortMem (void)
+{
+       mmblocktype far *scan,far *last,far *next;
+       unsigned        start,length,source,dest,oldborder;
+       int                     playing;
+
+       //
+       // lock down a currently playing sound
+       //
+/*++++ playing = SD_SoundPlaying ();
+       if (playing)
+       {
+               switch (SoundMode)
+               {
+               case sdm_PC:
+                       playing += STARTPCSOUNDS;
+                       break;
+               case sdm_AdLib:
+                       playing += STARTADLIBSOUNDS;
+                       break;
+               }
+               MM_SetLock(&(memptr)audiosegs[playing],true);
+       }
+
+
+       SD_StopSound();*/
+//     oldborder = bordercolor;
+//     VW_ColorBorder (15);
+
+       if (beforesort)
+               beforesort();
+
+       scan = mmhead;
+
+       last = NULL;            // shut up compiler warning
+
+       while (scan)
+       {
+               if (scan->attributes & LOCKBIT)
+               {
+               //
+               // block is locked, so try to pile later blocks right after it
+               //
+                       start = scan->start + scan->length;
+               }
+               else
+               {
+                       if (scan->attributes & PURGEBITS)
+                       {
+                       //
+                       // throw out the purgable block
+                       //
+                               next = scan->next;
+                               FREEBLOCK(scan);
+                               last->next = next;
+                               scan = next;
+                               continue;
+                       }
+                       else
+                       {
+                       //
+                       // push the non purgable block on top of the last moved block
+                       //
+                               if (scan->start != start)
+                               {
+                                       length = scan->length;
+                                       source = scan->start;
+                                       dest = start;
+                                       while (length > 0xf00)
+                                       {
+                                               movedata(source,0,dest,0,0xf00*16);
+                                               length -= 0xf00;
+                                               source += 0xf00;
+                                               dest += 0xf00;
+                                       }
+                                       movedata(source,0,dest,0,length*16);
+
+                                       scan->start = start;
+                                       *(unsigned *)scan->useptr = start;
+                               }
+                               start = scan->start + scan->length;
+                       }
+               }
+
+               last = scan;
+               scan = scan->next;              // go to next block
+       }
+
+       mmrover = mmhead;
+
+       if (aftersort)
+               aftersort();
+
+//     VW_ColorBorder (oldborder);
+
+/*++++ if (playing)
+               MM_SetLock(&(memptr)audiosegs[playing],false);*/
+}
+
+
+//==========================================================================
+
+//****
+#if 0
+/*
+=====================
+=
+= MM_ShowMemory
+=
+=====================
+*/
+
+void MM_ShowMemory (void)
+{
+       mmblocktype far *scan;
+       unsigned color,temp;
+       long    end,owner;
+       char    scratch[80],str[10];
+
+//**** VW_SetDefaultColors();
+//**** VW_SetLineWidth(40);
+       temp = bufferofs;
+       bufferofs = 0;
+//**** VW_SetScreen (0,0);
+
+       scan = mmhead;
+
+       end = -1;
+
+//CA_OpenDebug ();
+
+       while (scan)
+       {
+               if (scan->attributes & PURGEBITS)
+                       color = 5;              // dark purple = purgable
+               else
+                       color = 9;              // medium blue = non purgable
+               if (scan->attributes & LOCKBIT)
+                       color = 12;             // red = locked
+               if (scan->start<=end)
+               {
+                       printf("MM_ShowMemory: Memory block order currupted!");
+                       return;
+               }
+               end = scan->start+scan->length-1;
+//****         VW_Hlin(scan->start,(unsigned)end,0,color);
+//****         VW_Plot(scan->start,0,15);
+//****         if (scan->next->start > end+1)
+//****                 VW_Hlin(end+1,scan->next->start,0,0);   // black = free
+
+//****#if 0
+strcpy (scratch,"Size:");
+ltoa ((long)scan->length*16,str,10);
+strcat (scratch,str);
+strcat (scratch,"\tOwner:0x");
+owner = (unsigned)scan->useptr;
+ultoa (owner,str,16);
+strcat (scratch,str);
+strcat (scratch,"\n");
+//++++write (debughandle,scratch,strlen(scratch));
+//****#endif
+
+               scan = scan->next;
+       }
+
+//CA_CloseDebug ();
+
+       IN_Ack();
+//**** VW_SetLineWidth(64);
+       bufferofs = temp;
+}
+//****
+#endif
+
+//==========================================================================
+
+
+/*
+======================
+=
+= MM_UnusedMemory
+=
+= Returns the total free space without purging
+=
+======================
+*/
+
+long MM_UnusedMemory (void)
+{
+       unsigned free;
+       mmblocktype far *scan;
+
+       free = 0;
+       scan = mmhead;
+
+       while (scan->next)
+       {
+               free += scan->next->start - (scan->start + scan->length);
+               scan = scan->next;
+       }
+
+       return free*16l;
+}
+
+//==========================================================================
+
+
+/*
+======================
+=
+= MM_TotalFree
+=
+= Returns the total free space with purging
+=
+======================
+*/
+
+long MM_TotalFree (void)
+{
+       unsigned free;
+       mmblocktype far *scan;
+
+       free = 0;
+       scan = mmhead;
+
+       while (scan->next)
+       {
+               if ((scan->attributes&PURGEBITS) && !(scan->attributes&LOCKBIT))
+                       free += scan->length;
+               free += scan->next->start - (scan->start + scan->length);
+               scan = scan->next;
+       }
+
+       return free*16l;
+}
+
+//==========================================================================
+
+/*
+=====================
+=
+= MM_BombOnError
+=
+=====================
+*/
+
+void MM_BombOnError (boolean bomb)
+{
+       bombonerror = bomb;
+}
+
+
similarity index 91%
rename from 16/cawat/16_mm.h
rename to src/lib/16_mm.h
index 622a2b4d94f83bbd5bcc4ac773fd13eb746f7b6b..e864d042fb990d4916ac66346343224dcd2bfa5e 100644 (file)
-/* Catacomb Armageddon Source Code\r
- * Copyright (C) 1993-2014 Flat Rock Software\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License along\r
- * with this program; if not, write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
- */\r
-\r
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
 // ID_MM.H
 
-#ifndef __ID_EXMM__\r
-#define __ID_EXMM__
-
-#include "lib_head.h"
-//#pragma hdrstop\r
-\r
-//#pragma warn -pro\r
-//#pragma warn -use\r
-\r
-#if 1          // 1 == Debug/Dev  ;  0 == Production/final\r
-#define OUT_OF_MEM_MSG "MM_GetPtr: Out of memory!\nYou were short :%ld bytes"\r
-#else\r
+#ifndef __16_EXMM__
+#define __16_EXMM__
+
+#include <string.h>
+#include <malloc.h>
+#include "src/lib/lib_head.h"
+#include "src/lib/16_in.h"
+
+#if 1          // 1 == Debug/Dev  ;  0 == Production/final
+#define OUT_OF_MEM_MSG "MM_GetPtr: Out of memory!\nYou were short :%ld bytes"
+#else
 #define OUT_OF_MEM_MSG "\npee\n"
-#endif\r
-\r
-\r
-#define SAVENEARHEAP   0x400           // space to leave in data segment\r
-#define SAVEFARHEAP            0                       // space to leave in far heap\r
-\r
-#define        BUFFERSIZE              0x1000          // miscelanious, allways available buffer\r
-\r
-#define MAXBLOCKS              600\r
-\r
-\r
-//--------\r
-\r
-#define        EMS_INT                 0x67\r
-\r
-#define        EMS_STATUS              0x40\r
-#define        EMS_GETFRAME    0x41\r
-#define        EMS_GETPAGES    0x42\r
-#define        EMS_ALLOCPAGES  0x43\r
-#define        EMS_MAPPAGE             0x44\r
-#define        EMS_FREEPAGES   0x45\r
-#define        EMS_VERSION             0x46\r
-\r
-//--------\r
-\r
-#define        XMS_VERSION             0x00\r
-\r
-#define        XMS_ALLOCHMA    0x01\r
-#define        XMS_FREEHMA             0x02\r
-\r
-#define        XMS_GENABLEA20  0x03\r
-#define        XMS_GDISABLEA20 0x04\r
-#define        XMS_LENABLEA20  0x05\r
-#define        XMS_LDISABLEA20 0x06\r
-#define        XMS_QUERYA20    0x07\r
-\r
-#define        XMS_QUERYREE    0x08\r
-#define        XMS_ALLOC               0x09\r
-#define        XMS_FREE                0x0A\r
-#define        XMS_MOVE                0x0B\r
-#define        XMS_LOCK                0x0C\r
-#define        XMS_UNLOCK              0x0D\r
-#define        XMS_GETINFO             0x0E\r
-#define        XMS_RESIZE              0x0F\r
-\r
-#define        XMS_ALLOCUMB    0x10\r
-#define        XMS_FREEUMB             0x11\r
-\r
-//==========================================================================\r
-\r
-typedef void /*_seg*/ * memptr;\r
-\r
-typedef struct\r
-{\r
-       long    nearheap,farheap,EMSmem,XMSmem,mainmem;\r
-} mminfotype;\r
-\r
-//==========================================================================\r
-\r
-extern mminfotype      mminfo;\r
-extern memptr          bufferseg;\r
-extern boolean         mmerror;\r
-\r
-extern void            (* beforesort) (void);\r
-extern void            (* aftersort) (void);\r
-\r
-//==========================================================================\r
-\r
-void MM_Startup (void);\r
-void MM_Shutdown (void);\r
-void MM_MapEMS (void);\r
-\r
-void MM_GetPtr (memptr *baseptr,unsigned long size);\r
-void MM_FreePtr (memptr *baseptr);\r
-\r
-void MM_SetPurge (memptr *baseptr, int purge);\r
-void MM_SetLock (memptr *baseptr, boolean locked);\r
-void MM_SortMem (void);\r
-\r
-void MM_ShowMemory (void);\r
-\r
-long MM_UnusedMemory (void);\r
-long MM_TotalFree (void);\r
-\r
+#endif
+
+
+#define SAVENEARHEAP   0x400           // space to leave in data segment
+#define SAVEFARHEAP            0                       // space to leave in far heap
+
+#define        BUFFERSIZE              0x1000          // miscelanious, allways available buffer
+
+#define MAXBLOCKS              600
+
+
+//--------
+
+#define        EMS_INT                 0x67
+
+#define        EMS_STATUS              0x40
+#define        EMS_GETFRAME    0x41
+#define        EMS_GETPAGES    0x42
+#define        EMS_ALLOCPAGES  0x43
+#define        EMS_MAPPAGE             0x44
+#define        EMS_FREEPAGES   0x45
+#define        EMS_VERSION             0x46
+
+//--------
+
+#define        XMS_VERSION             0x00
+
+#define        XMS_ALLOCHMA    0x01
+#define        XMS_FREEHMA             0x02
+
+#define        XMS_GENABLEA20  0x03
+#define        XMS_GDISABLEA20 0x04
+#define        XMS_LENABLEA20  0x05
+#define        XMS_LDISABLEA20 0x06
+#define        XMS_QUERYA20    0x07
+
+#define        XMS_QUERYREE    0x08
+#define        XMS_ALLOC               0x09
+#define        XMS_FREE                0x0A
+#define        XMS_MOVE                0x0B
+#define        XMS_LOCK                0x0C
+#define        XMS_UNLOCK              0x0D
+#define        XMS_GETINFO             0x0E
+#define        XMS_RESIZE              0x0F
+
+#define        XMS_ALLOCUMB    0x10
+#define        XMS_FREEUMB             0x11
+
+//==========================================================================
+
+typedef void /*_seg*/ * memptr;
+
+typedef struct
+{
+       long    nearheap,farheap,EMSmem,XMSmem,mainmem;
+} mminfotype;
+
+//==========================================================================
+
+extern mminfotype      mminfo;
+extern memptr          bufferseg;
+extern boolean         mmerror;
+
+extern void            (* beforesort) (void);
+extern void            (* aftersort) (void);
+
+//==========================================================================
+
+void MM_Startup (void);
+void MM_Shutdown (void);
+void MM_MapEMS (void);
+
+void MM_GetPtr (memptr *baseptr,dword size);
+void MM_FreePtr (memptr *baseptr);
+
+void MM_SetPurge (memptr *baseptr, int purge);
+void MM_SetLock (memptr *baseptr, boolean locked);
+void MM_SortMem (void);
+
+void MM_ShowMemory (void);
+
+long MM_UnusedMemory (void);
+long MM_TotalFree (void);
+
 void MM_BombOnError (boolean bomb);
 
-//==========================================================================\r
-\r
-//\r
-// local prototypes\r
-//\r
-\r
-boolean                MML_CheckForEMS (void);\r
-void           MML_ShutdownEMS (void);\r
-void           MM_MapEMS (void);\r
-boolean        MML_CheckForXMS (void);\r
-void           MML_ShutdownXMS (void);\r
-void           MML_UseSpace (unsigned segstart, unsigned seglength);\r
-void           MML_ClearBlock (void);\r
-\r
+//==========================================================================
+
+//
+// local prototypes
+//
+
+boolean                MML_CheckForEMS (void);
+void           MML_ShutdownEMS (void);
+void           MM_MapEMS (void);
+boolean        MML_CheckForXMS (void);
+void           MML_ShutdownXMS (void);
+void           MML_UseSpace (unsigned segstart, unsigned seglength);
+void           MML_ClearBlock (void);
+
 //==========================================================================
 
 #endif
index c5c68fdb5e3edbfb2763e0acad280055ede3e296..262cd0229d6bdd75e63b36b5913fea8142c79a6b 100644 (file)
Binary files a/test.exe and b/test.exe differ
index 0b07453824bc80c9c9ff05a103753fc4015d38ec..c9f12fc11ae1ea3a9364ce46b0cffccc666afd37 100644 (file)
Binary files a/test2.exe and b/test2.exe differ