]> 4ch.mooo.com Git - 16.git/commitdiff
ok i need to remove heap walk from the borland c stuff and the allocation of things! ww
authorsparky4 <sparky4@cock.li>
Wed, 5 Aug 2015 02:21:57 +0000 (21:21 -0500)
committersparky4 <sparky4@cock.li>
Wed, 5 Aug 2015 02:21:57 +0000 (21:21 -0500)
deleted:    16/exmmtest/16_ca.c
deleted:    16/exmmtest/16_ca.h
deleted:    16/exmmtest/16_head.c
deleted:    16/exmmtest/16_head.h
deleted:    16/exmmtest/16_mm.c
deleted:    16/exmmtest/16_mm.h
modified:   16/exmmtest/EXMMTEST.DSK
modified:   16/exmmtest/EXMMTEST.PRJ
deleted:    16/exmmtest/ID_CA.C
deleted:    16/exmmtest/ID_CA.H
deleted:    16/exmmtest/ID_MM.C
deleted:    16/exmmtest/ID_MM.H
deleted:    16/exmmtest/exmmtest.c
modified:   16/exmmtest/src/exmmtest.c
new file:   16/exmmtest/src/lib/16_hc.c
new file:   16/exmmtest/src/lib/16_hc.h
modified:   16/exmmtest/src/lib/16_head.h
modified:   16/exmmtest/src/lib/16_mm.h
new file:   16/exmmtest/src/lib/types.h
deleted:    HEAP.16
deleted:    PROFILE.16
modified:   exmmtest.exe
modified:   makefile
modified:   src/exmmtest.c
modified:   src/lib/16_head.h
modified:   src/lib/16_mm.h

26 files changed:
16/exmmtest/16_ca.c [deleted file]
16/exmmtest/16_ca.h [deleted file]
16/exmmtest/16_head.c [deleted file]
16/exmmtest/16_head.h [deleted file]
16/exmmtest/16_mm.c [deleted file]
16/exmmtest/16_mm.h [deleted file]
16/exmmtest/EXMMTEST.DSK
16/exmmtest/EXMMTEST.PRJ
16/exmmtest/ID_CA.C [deleted file]
16/exmmtest/ID_CA.H [deleted file]
16/exmmtest/ID_MM.C [deleted file]
16/exmmtest/ID_MM.H [deleted file]
16/exmmtest/exmmtest.c [deleted file]
16/exmmtest/src/exmmtest.c
16/exmmtest/src/lib/16_hc.c [new file with mode: 0644]
16/exmmtest/src/lib/16_hc.h [new file with mode: 0644]
16/exmmtest/src/lib/16_head.h
16/exmmtest/src/lib/16_mm.h
16/exmmtest/src/lib/types.h [new file with mode: 0644]
HEAP.16 [deleted file]
PROFILE.16 [deleted file]
exmmtest.exe
makefile
src/exmmtest.c
src/lib/16_head.h
src/lib/16_mm.h

diff --git a/16/exmmtest/16_ca.c b/16/exmmtest/16_ca.c
deleted file mode 100644 (file)
index 1783f87..0000000
+++ /dev/null
@@ -1,2238 +0,0 @@
-/* Catacomb Apocalypse 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
-// ID_CA.C\r
-\r
-/*\r
-=============================================================================\r
-\r
-Id Software Caching Manager\r
----------------------------\r
-\r
-Must be started BEFORE the memory manager, because it needs to get the headers\r
-loaded into the data segment\r
-\r
-=============================================================================\r
-*/\r
-\r
-#include "16_ca.h"\r
-//#include "ID_STRS.H"\r
-\r
-//#define THREEBYTEGRSTARTS\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                LOCAL CONSTANTS\r
-\r
-=============================================================================\r
-*/\r
-\r
-typedef struct\r
-{\r
-  unsigned bit0,bit1;  // 0-255 is a character, > is a pointer to a node\r
-} huffnode;\r
-\r
-\r
-/*typedef struct\r
-{\r
-       unsigned        RLEWtag;\r
-       long            headeroffsets[100];\r
-       byte            tileinfo[];\r
-} mapfiletype;*/\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                GLOBAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-/*byte                 _seg    *tinf;\r
-int                    mapon;\r
-\r
-unsigned       _seg    *mapsegs[3];\r
-maptype                _seg    *mapheaderseg[NUMMAPS];\r
-byte           _seg    *audiosegs[NUMSNDCHUNKS];\r
-void           _seg    *grsegs[NUMCHUNKS];\r
-\r
-byte           far     grneeded[NUMCHUNKS];\r
-byte           ca_levelbit,ca_levelnum;*/\r
-\r
-int                    profilehandle,debughandle;\r
-\r
-void   (*drawcachebox)         (char *title, unsigned numcache);\r
-void   (*updatecachebox)       (void);\r
-void   (*finishcachebox)       (void);\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                LOCAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-/*extern       long    far     CGAhead;\r
-extern long    far     EGAhead;\r
-extern byte    CGAdict;\r
-extern byte    EGAdict;\r
-extern byte    far     maphead;\r
-extern byte    mapdict;\r
-extern byte    far     audiohead;\r
-extern byte    audiodict;\r
-\r
-\r
-long           _seg *grstarts; // array of offsets in egagraph, -1 for sparse\r
-long           _seg *audiostarts;      // array of offsets in audio / audiot\r
-\r
-#ifdef GRHEADERLINKED\r
-huffnode       *grhuffman;\r
-#else\r
-huffnode       grhuffman[255];\r
-#endif\r
-\r
-#ifdef AUDIOHEADERLINKED\r
-huffnode       *audiohuffman;\r
-#else\r
-huffnode       audiohuffman[255];\r
-#endif\r
-\r
-\r
-int                    grhandle;               // handle to EGAGRAPH\r
-int                    maphandle;              // handle to MAPTEMP / GAMEMAPS\r
-int                    audiohandle;    // handle to AUDIOT / AUDIO\r
-\r
-long           chunkcomplen,chunkexplen;\r
-\r
-SDMode         oldsoundmode;\r
-\r
-\r
-\r
-void   CAL_DialogDraw (char *title,unsigned numcache);\r
-void   CAL_DialogUpdate (void);\r
-void   CAL_DialogFinish (void);*/\r
-//void CAL_CarmackExpand (unsigned far *source, unsigned far *dest,unsigned length);\r
-\r
-\r
-/*++++#ifdef THREEBYTEGRSTARTS\r
-#define FILEPOSSIZE    3\r
-//#define      GRFILEPOS(c) (*(long far *)(((byte far *)grstarts)+(c)*3)&0xffffff)\r
-long GRFILEPOS(int c)\r
-{\r
-       long value;\r
-       int     offset;\r
-\r
-       offset = c*3;\r
-\r
-       value = *(long far *)(((byte far *)grstarts)+offset);\r
-\r
-       value &= 0x00ffffffl;\r
-\r
-       if (value == 0xffffffl)\r
-               value = -1;\r
-\r
-       return value;\r
-};\r
-#else\r
-#define FILEPOSSIZE    4\r
-#define        GRFILEPOS(c) (grstarts[c])\r
-#endif*/\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                          LOW LEVEL ROUTINES\r
-\r
-=============================================================================\r
-*/\r
-\r
-/*\r
-============================\r
-=\r
-= CA_OpenDebug / CA_CloseDebug\r
-=\r
-= Opens a binary file with the handle "debughandle"\r
-=\r
-============================\r
-*/\r
-void CA_OpenDebug(void)\r
-{\r
-       unlink("debug.16");\r
-       debughandle = open("debug.16", O_CREAT | O_WRONLY | O_TEXT);\r
-}\r
-\r
-void CA_CloseDebug(void)\r
-{\r
-       close(debughandle);\r
-}\r
-\r
-\r
-\r
-/*\r
-============================\r
-=\r
-= CAL_GetGrChunkLength\r
-=\r
-= Gets the length of an explicit length chunk (not tiles)\r
-= The file pointer is positioned so the compressed data can be read in next.\r
-=\r
-============================\r
-*/\r
-/*++++\r
-void CAL_GetGrChunkLength (int chunk)\r
-{\r
-       lseek(grhandle,GRFILEPOS(chunk),SEEK_SET);\r
-       read(grhandle,&chunkexplen,sizeof(chunkexplen));\r
-       chunkcomplen = GRFILEPOS(chunk+1)-GRFILEPOS(chunk)-4;\r
-}*/\r
-\r
-\r
-/*\r
-==========================\r
-=\r
-= CA_FarRead\r
-=\r
-= Read from a file to a far pointer\r
-=\r
-==========================\r
-*/\r
-\r
-boolean CA_FarRead(int handle, byte huge *dest, dword length, mminfo_t *mm)\r
-{\r
-       boolean flag;\r
-       /*dword fat=0;
-       word segm=0;
-       //if(mm->EMSVer<0x40)\r
-       if(length>0xfffflu)
-       {
-               printf("File is a fat bakapee\n");
-               segm=(length%0xfffflu)-1;
-               fat=segm*0xfffflu;
-               length-=fat;\r
-//             printf("CA_FarRead doesn't support 64K reads yet!\n");\r
-       }
-
-       if(!fat&&!segm)
-       {*/\r
-               __asm {\r
-                       push    ds\r
-                       mov     bx,[handle]\r
-                       mov     cx,[WORD PTR length]\r
-                       mov     dx,[WORD PTR dest]\r
-                       mov     ds,[WORD PTR dest+2]\r
-                       mov     ah,0x3f                         // READ w/handle\r
-                       int     21h\r
-                       pop     ds\r
-                       jnc     good\r
-                       mov     errno,ax\r
-                       mov     flag,0\r
-                       jmp End
-               }\r
-good:
-               __asm {\r
-                       cmp     ax,[WORD PTR length]\r
-                       je      done\r
-//                     errno = EINVFMT;                        // user manager knows this is bad read\r
-                       mov     flag,0\r
-                       jmp End
-               }\r
-done:
-               __asm {\r
-                       mov     flag,1
-               }\r
-End:\r
-       return flag;
-       //}else return 0;//todo: EXPAND!!!\r
-}\r
-\r
-\r
-/*\r
-==========================\r
-=\r
-= CA_SegWrite\r
-=\r
-= Write from a file to a far pointer\r
-=\r
-==========================\r
-*/\r
-\r
-boolean CA_FarWrite(int handle, byte huge *source, dword length, mminfo_t *mm)\r
-{\r
-       boolean flag;\r
-       /*dword fat=0;
-       word segm=0;
-       //if(mm->EMSVer<0x40)\r
-       if(length>0xfffflu)
-       {
-               printf("File is a fat bakapee\n");
-               segm=(length%0xfffflu)-1;
-               fat=segm*0xfffflu;
-               length-=fat;\r
-//             printf("CA_FarRead doesn't support 64K reads yet!\n");\r
-       }\r
-
-       if(!fat&&!segm)
-       {*/\r
-               __asm {\r
-                       push    ds\r
-                       mov     bx,[handle]\r
-                       mov     cx,[WORD PTR length]\r
-                       mov     dx,[WORD PTR source]\r
-                       mov     ds,[WORD PTR source+2]\r
-                       mov     ah,0x40                 // WRITE w/handle\r
-                       int     21h\r
-                       pop     ds\r
-                       jnc     good\r
-                       mov     errno,ax\r
-                       mov flag,0\r
-                       jmp End
-               }\r
-good:
-               __asm {\r
-                       cmp     ax,[WORD PTR length]\r
-                       je      done\r
-                       //errno = ENOMEM;                               // user manager knows this is bad write\r
-                       mov     flag,0\r
-                       jmp End
-               }\r
-done:
-               __asm {\r
-                       mov     flag,1
-               }\r
-End:\r
-       return flag;
-       //}else return 0;\r
-}\r
-\r
-\r
-/*\r
-==========================\r
-=\r
-= CA_ReadFile\r
-=\r
-= Reads a file into an allready allocated buffer\r
-=\r
-==========================\r
-*/\r
-\r
-boolean CA_ReadFile(char *filename, memptr *ptr, mminfo_t *mm)\r
-{\r
-       int handle;\r
-       dword size;
-       //long size;\r
-\r
-       if((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               return false;\r
-\r
-       size = filelength(handle);\r
-       if(!CA_FarRead(handle,*ptr,size, mm))\r
-       {\r
-               close(handle);\r
-               return false;\r
-       }\r
-       close(handle);\r
-       return true;\r
-}\r
-\r
-\r
-\r
-/*\r
-==========================\r
-=\r
-= CA_LoadFile\r
-=\r
-= Allocate space for and load a file\r
-=\r
-==========================\r
-*/\r
-\r
-boolean CA_LoadFile(char *filename, memptr *ptr, mminfo_t *mm, mminfotype *mmi)\r
-{\r
-       int handle;\r
-       dword size;
-       //long size;\r
-\r
-       if((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               return false;\r
-\r
-       size = filelength (handle);\r
-       MM_GetPtr(ptr,size, mm, mmi);\r
-       if(!CA_FarRead(handle,*ptr,size, mm))\r
-       {\r
-               close(handle);\r
-               return false;\r
-       }\r
-       close(handle);\r
-       return true;\r
-}\r
-\r
-/*\r
-============================================================================\r
-\r
-               COMPRESSION routines, see JHUFF.C for more\r
-\r
-============================================================================\r
-*/\r
-\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= CAL_OptimizeNodes\r
-=\r
-= Goes through a huffman table and changes the 256-511 node numbers to the\r
-= actular address of the node.  Must be called before CAL_HuffExpand\r
-=\r
-===============\r
-*/\r
-\r
-void CAL_OptimizeNodes(huffnode *table)\r
-{\r
-  huffnode *node;\r
-  int i;\r
-\r
-  node = table;\r
-\r
-  for (i=0;i<255;i++)\r
-  {\r
-       if (node->bit0 >= 256)\r
-         node->bit0 = (unsigned)(table+(node->bit0-256));\r
-       if (node->bit1 >= 256)\r
-         node->bit1 = (unsigned)(table+(node->bit1-256));\r
-       node++;\r
-  }\r
-}\r
-\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_HuffExpand\r
-=\r
-= Length is the length of the EXPANDED data\r
-=\r
-======================\r
-*/\r
-\r
-/*++++void CAL_HuffExpand (byte huge *source, byte huge *dest,\r
-  long length,huffnode *hufftable)\r
-{\r
-//  unsigned bit,byte,node,code;\r
-  unsigned sourceseg,sourceoff,destseg,destoff,endoff;\r
-  huffnode *headptr;\r
-//  huffnode *nodeon;\r
-\r
-  headptr = hufftable+254;     // head node is allways node 254\r
-\r
-  source++;    // normalize\r
-  source--;\r
-  dest++;\r
-  dest--;\r
-\r
-  sourceseg = FP_SEG(source);\r
-  sourceoff = FP_OFF(source);\r
-  destseg = FP_SEG(dest);\r
-  destoff = FP_OFF(dest);\r
-  endoff = destoff+length;\r
-\r
-//\r
-// ds:si source\r
-// es:di dest\r
-// ss:bx node pointer\r
-//\r
-\r
-       if (length <0xfff0)\r
-       {\r
-\r
-//--------------------------\r
-// expand less than 64k of data\r
-//--------------------------\r
-\r
-       __asm\r
-       {\r
-               mov     bx,[headptr]\r
-\r
-               mov     si,[sourceoff]\r
-               mov     di,[destoff]\r
-               mov     es,[destseg]\r
-               mov     ds,[sourceseg]\r
-               mov     ax,[endoff]\r
-\r
-               mov     ch,[si]                         // load first byte\r
-               inc     si\r
-               mov     cl,1\r
-\r
-expandshort:\r
-               test    ch,cl                   // bit set?\r
-               jnz     bit1short\r
-               mov     dx,[ss:bx]                      // take bit0 path from node\r
-               shl     cl,1                            // advance to next bit position\r
-               jc      newbyteshort\r
-               jnc     sourceupshort\r
-\r
-bit1short:\r
-asm    mov     dx,[ss:bx+2]            // take bit1 path\r
-asm    shl     cl,1                            // advance to next bit position\r
-asm    jnc     sourceupshort\r
-\r
-newbyteshort:\r
-asm    mov     ch,[si]                         // load next byte\r
-asm    inc     si\r
-asm    mov     cl,1                            // back to first bit\r
-\r
-sourceupshort:\r
-asm    or      dh,dh                           // if dx<256 its a byte, else move node\r
-asm    jz      storebyteshort\r
-asm    mov     bx,dx                           // next node = (huffnode *)code\r
-asm    jmp     expandshort\r
-\r
-storebyteshort:\r
-asm    mov     [es:di],dl\r
-asm    inc     di                                      // write a decopmpressed byte out\r
-asm    mov     bx,[headptr]            // back to the head node for next bit\r
-\r
-asm    cmp     di,ax                           // done?\r
-asm    jne     expandshort\r
-       }\r
-       }\r
-       else\r
-       {\r
-\r
-//--------------------------\r
-// expand more than 64k of data\r
-//--------------------------\r
-\r
-  length--;\r
-\r
-       __asm\r
-       {\r
-asm mov        bx,[headptr]\r
-asm    mov     cl,1\r
-\r
-asm    mov     si,[sourceoff]\r
-asm    mov     di,[destoff]\r
-asm    mov     es,[destseg]\r
-asm    mov     ds,[sourceseg]\r
-\r
-asm    lodsb                   // load first byte\r
-\r
-expand:\r
-asm    test    al,cl           // bit set?\r
-asm    jnz     bit1\r
-asm    mov     dx,[ss:bx]      // take bit0 path from node\r
-asm    jmp     gotcode\r
-bit1:\r
-asm    mov     dx,[ss:bx+2]    // take bit1 path\r
-\r
-gotcode:\r
-asm    shl     cl,1            // advance to next bit position\r
-asm    jnc     sourceup\r
-asm    lodsb\r
-asm    cmp     si,0x10         // normalize ds:si\r
-asm    jb      sinorm\r
-asm    mov     cx,ds\r
-asm    inc     cx\r
-asm    mov     ds,cx\r
-asm    xor     si,si\r
-sinorm:\r
-asm    mov     cl,1            // back to first bit\r
-\r
-sourceup:\r
-asm    or      dh,dh           // if dx<256 its a byte, else move node\r
-asm    jz      storebyte\r
-asm    mov     bx,dx           // next node = (huffnode *)code\r
-asm    jmp     expand\r
-\r
-storebyte:\r
-asm    mov     [es:di],dl\r
-asm    inc     di              // write a decopmpressed byte out\r
-asm    mov     bx,[headptr]    // back to the head node for next bit\r
-\r
-asm    cmp     di,0x10         // normalize es:di\r
-asm    jb      dinorm\r
-asm    mov     dx,es\r
-asm    inc     dx\r
-asm    mov     es,dx\r
-asm    xor     di,di\r
-dinorm:\r
-\r
-asm    sub     [WORD PTR ss:length],1\r
-asm    jnc     expand\r
-asm    dec     [WORD PTR ss:length+2]\r
-asm    jns     expand          // when length = ffff ffff, done\r
-       }\r
-       }\r
-\r
-       __asm\r
-       {\r
-               mov     ax,ss\r
-               mov     ds,ax\r
-       }\r
-\r
-}*/\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_CarmackExpand\r
-=\r
-= Length is the length of the EXPANDED data\r
-=\r
-======================\r
-*/\r
-/*++++\r
-#define NEARTAG        0xa7\r
-#define FARTAG 0xa8\r
-\r
-void CAL_CarmackExpand (unsigned far *source, unsigned far *dest, unsigned length)\r
-{\r
-       unsigned        ch,chhigh,count,offset;\r
-       unsigned        far *copyptr, far *inptr, far *outptr;\r
-\r
-       length/=2;\r
-\r
-       inptr = source;\r
-       outptr = dest;\r
-\r
-       while (length)\r
-       {\r
-               ch = *inptr++;\r
-               chhigh = ch>>8;\r
-               if (chhigh == NEARTAG)\r
-               {\r
-                       count = ch&0xff;\r
-                       if (!count)\r
-                       {                               // have to insert a word containing the tag byte\r
-                               ch |= *((unsigned char far *)inptr)++;\r
-                               *outptr++ = ch;\r
-                               length--;\r
-                       }\r
-                       else\r
-                       {\r
-                               offset = *((unsigned char far *)inptr)++;\r
-                               copyptr = outptr - offset;\r
-                               length -= count;\r
-                               while (count--)\r
-                                       *outptr++ = *copyptr++;\r
-                       }\r
-               }\r
-               else if (chhigh == FARTAG)\r
-               {\r
-                       count = ch&0xff;\r
-                       if (!count)\r
-                       {                               // have to insert a word containing the tag byte\r
-                               ch |= *((unsigned char far *)inptr)++;\r
-                               *outptr++ = ch;\r
-                               length --;\r
-                       }\r
-                       else\r
-                       {\r
-                               offset = *inptr++;\r
-                               copyptr = dest + offset;\r
-                               length -= count;\r
-                               while (count--)\r
-                                       *outptr++ = *copyptr++;\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       *outptr++ = ch;\r
-                       length --;\r
-               }\r
-       }\r
-}\r
-*/\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CA_RLEWcompress\r
-=\r
-======================\r
-*/\r
-/*++++\r
-long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest,\r
-  unsigned rlewtag)\r
-{\r
-  long complength;\r
-  unsigned value,count,i;\r
-  unsigned huge *start,huge *end;\r
-\r
-  start = dest;\r
-\r
-  end = source + (length+1)/2;\r
-\r
-//\r
-// compress it\r
-//\r
-  do\r
-  {\r
-       count = 1;\r
-       value = *source++;\r
-       while (*source == value && source<end)\r
-       {\r
-         count++;\r
-         source++;\r
-       }\r
-       if (count>3 || value == rlewtag)\r
-       {\r
-    //\r
-    // send a tag / count / value string\r
-    //\r
-      *dest++ = rlewtag;\r
-      *dest++ = count;\r
-      *dest++ = value;\r
-    }\r
-    else\r
-    {\r
-    //\r
-    // send word without compressing\r
-    //\r
-      for (i=1;i<=count;i++)\r
-       *dest++ = value;\r
-       }\r
-\r
-  } while (source<end);\r
-\r
-  complength = 2*(dest-start);\r
-  return complength;\r
-}\r
-*/\r
-\r
-/*\r
-======================\r
-=\r
-= CA_RLEWexpand\r
-= length is EXPANDED length\r
-=\r
-======================\r
-*/\r
-/*++++\r
-void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length,\r
-  unsigned rlewtag)\r
-{\r
-//  unsigned value,count,i;\r
-  unsigned huge *end;\r
-  unsigned sourceseg,sourceoff,destseg,destoff,endseg,endoff;\r
-\r
-\r
-//\r
-// expand it\r
-//\r
-#if 0\r
-  do\r
-  {\r
-       value = *source++;\r
-       if (value != rlewtag)\r
-       //\r
-       // uncompressed\r
-       //\r
-         *dest++=value;\r
-       else\r
-       {\r
-       //\r
-       // compressed string\r
-       //\r
-         count = *source++;\r
-         value = *source++;\r
-         for (i=1;i<=count;i++)\r
-       *dest++ = value;\r
-       }\r
-  } while (dest<end);\r
-#endif\r
-\r
-  end = dest + (length)/2;\r
-  sourceseg = FP_SEG(source);\r
-  sourceoff = FP_OFF(source);\r
-  destseg = FP_SEG(dest);\r
-  destoff = FP_OFF(dest);\r
-  endseg = FP_SEG(end);\r
-  endoff = FP_OFF(end);\r
-\r
-\r
-//\r
-// ax = source value\r
-// bx = tag value\r
-// cx = repeat counts\r
-// dx = scratch\r
-//\r
-// NOTE: A repeat count that produces 0xfff0 bytes can blow this!\r
-//\r
-\r
-asm    mov     bx,rlewtag\r
-asm    mov     si,sourceoff\r
-asm    mov     di,destoff\r
-asm    mov     es,destseg\r
-asm    mov     ds,sourceseg\r
-\r
-expand:\r
-asm    lodsw\r
-asm    cmp     ax,bx\r
-asm    je      repeat\r
-asm    stosw\r
-asm    jmp     next\r
-\r
-repeat:\r
-asm    lodsw\r
-asm    mov     cx,ax           // repeat count\r
-asm    lodsw                   // repeat value\r
-asm    rep stosw\r
-\r
-next:\r
-\r
-asm    cmp     si,0x10         // normalize ds:si\r
-asm    jb      sinorm\r
-asm    mov     ax,si\r
-asm    shr     ax,1\r
-asm    shr     ax,1\r
-asm    shr     ax,1\r
-asm    shr     ax,1\r
-asm    mov     dx,ds\r
-asm    add     dx,ax\r
-asm    mov     ds,dx\r
-asm    and     si,0xf\r
-sinorm:\r
-asm    cmp     di,0x10         // normalize es:di\r
-asm    jb      dinorm\r
-asm    mov     ax,di\r
-asm    shr     ax,1\r
-asm    shr     ax,1\r
-asm    shr     ax,1\r
-asm    shr     ax,1\r
-asm    mov     dx,es\r
-asm    add     dx,ax\r
-asm    mov     es,dx\r
-asm    and     di,0xf\r
-dinorm:\r
-\r
-asm    cmp     di,ss:endoff\r
-asm    jne     expand\r
-asm    mov     ax,es\r
-asm    cmp     ax,ss:endseg\r
-asm    jb      expand\r
-\r
-asm    mov     ax,ss\r
-asm    mov     ds,ax\r
-\r
-}\r
-*/\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                        CACHE MANAGER ROUTINES\r
-\r
-=============================================================================\r
-*/\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_SetupGrFile\r
-=\r
-======================\r
-*/\r
-\r
-/*void CAL_SetupGrFile (void)\r
-{\r
-       int handle;\r
-       memptr compseg;\r
-\r
-#ifdef GRHEADERLINKED\r
-\r
-#if GRMODE == EGAGR\r
-       grhuffman = (huffnode *)&EGAdict;\r
-       grstarts = (long _seg *)FP_SEG(&EGAhead);\r
-#endif\r
-#if GRMODE == CGAGR\r
-       grhuffman = (huffnode *)&CGAdict;\r
-       grstarts = (long _seg *)FP_SEG(&CGAhead);\r
-#endif\r
-\r
-       CAL_OptimizeNodes (grhuffman);\r
-\r
-#else\r
-\r
-//\r
-// load ???dict.ext (huffman dictionary for graphics files)\r
-//\r
-\r
-       if ((handle = open(GREXT"DICT."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open "GREXT"DICT."EXT"!");\r
-\r
-       read(handle, &grhuffman, sizeof(grhuffman));\r
-       close(handle);\r
-       CAL_OptimizeNodes (grhuffman);\r
-//\r
-// load the data offsets from ???head.ext\r
-//\r
-       MM_GetPtr (&(memptr)grstarts,(NUMCHUNKS+1)*FILEPOSSIZE);\r
-\r
-       if ((handle = open(GREXT"HEAD."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open "GREXT"HEAD."EXT"!");\r
-\r
-       CA_FarRead(handle, (memptr)grstarts, (NUMCHUNKS+1)*FILEPOSSIZE);\r
-\r
-       close(handle);\r
-\r
-\r
-#endif\r
-\r
-//\r
-// Open the graphics file, leaving it open until the game is finished\r
-//\r
-       grhandle = open(GREXT"GRAPH."EXT, O_RDONLY | O_BINARY);\r
-       if (grhandle == -1)\r
-               Quit ("Cannot open "GREXT"GRAPH."EXT"!");\r
-\r
-\r
-//\r
-// load the pic and sprite headers into the arrays in the data segment\r
-//\r
-#if NUMPICS>0\r
-       MM_GetPtr(&(memptr)pictable,NUMPICS*sizeof(pictabletype));\r
-       CAL_GetGrChunkLength(STRUCTPIC);                // position file pointer\r
-       MM_GetPtr(&compseg,chunkcomplen);\r
-       CA_FarRead (grhandle,compseg,chunkcomplen);\r
-       CAL_HuffExpand (compseg, (byte huge *)pictable,NUMPICS*sizeof(pictabletype),grhuffman);\r
-       MM_FreePtr(&compseg);\r
-#endif\r
-\r
-#if NUMPICM>0\r
-       MM_GetPtr(&(memptr)picmtable,NUMPICM*sizeof(pictabletype));\r
-       CAL_GetGrChunkLength(STRUCTPICM);               // position file pointer\r
-       MM_GetPtr(&compseg,chunkcomplen);\r
-       CA_FarRead (grhandle,compseg,chunkcomplen);\r
-       CAL_HuffExpand (compseg, (byte huge *)picmtable,NUMPICS*sizeof(pictabletype),grhuffman);\r
-       MM_FreePtr(&compseg);\r
-#endif\r
-\r
-#if NUMSPRITES>0\r
-       MM_GetPtr(&(memptr)spritetable,NUMSPRITES*sizeof(spritetabletype));\r
-       CAL_GetGrChunkLength(STRUCTSPRITE);     // position file pointer\r
-       MM_GetPtr(&compseg,chunkcomplen);\r
-       CA_FarRead (grhandle,compseg,chunkcomplen);\r
-       CAL_HuffExpand (compseg, (byte huge *)spritetable,NUMSPRITES*sizeof(spritetabletype),grhuffman);\r
-       MM_FreePtr(&compseg);\r
-#endif\r
-\r
-}*/\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_SetupMapFile\r
-=\r
-======================\r
-*/\r
-\r
-/*void CAL_SetupMapFile (void)\r
-{\r
-       int handle;\r
-       long length;\r
-\r
-//\r
-// load maphead.ext (offsets and tileinfo for map file)\r
-//\r
-#ifndef MAPHEADERLINKED\r
-       if ((handle = open("MAPHEAD."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open MAPHEAD."EXT"!");\r
-       length = filelength(handle);\r
-       MM_GetPtr (&(memptr)tinf,length);\r
-       CA_FarRead(handle, tinf, length);\r
-       close(handle);\r
-#else\r
-\r
-       tinf = (byte _seg *)FP_SEG(&maphead);\r
-\r
-#endif\r
-\r
-//\r
-// open the data file\r
-//\r
-#ifdef MAPHEADERLINKED\r
-       if ((maphandle = open("GAMEMAPS."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open GAMEMAPS."EXT"!");\r
-#else\r
-       if ((maphandle = open("MAPTEMP."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open MAPTEMP."EXT"!");\r
-#endif\r
-}*/\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_SetupAudioFile\r
-=\r
-======================\r
-*/\r
-\r
-/*void CAL_SetupAudioFile (void)\r
-{\r
-       int handle;\r
-       long length;\r
-\r
-//\r
-// load maphead.ext (offsets and tileinfo for map file)\r
-//\r
-#ifndef AUDIOHEADERLINKED\r
-       if ((handle = open("AUDIOHED."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open AUDIOHED."EXT"!");\r
-       length = filelength(handle);\r
-       MM_GetPtr (&(memptr)audiostarts,length);\r
-       CA_FarRead(handle, (byte far *)audiostarts, length);\r
-       close(handle);\r
-#else\r
-       audiohuffman = (huffnode *)&audiodict;\r
-       CAL_OptimizeNodes (audiohuffman);\r
-       audiostarts = (long _seg *)FP_SEG(&audiohead);\r
-#endif\r
-\r
-//\r
-// open the data file\r
-//\r
-#ifndef AUDIOHEADERLINKED\r
-       if ((audiohandle = open("AUDIOT."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open AUDIOT."EXT"!");\r
-#else\r
-       if ((audiohandle = open("AUDIO."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open AUDIO."EXT"!");\r
-#endif\r
-}*/\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CA_Startup\r
-=\r
-= Open all files and load in headers\r
-=\r
-======================\r
-*/\r
-\r
-void CA_Startup(void)\r
-{\r
-#ifdef PROFILE\r
-       unlink("profile.16");\r
-       profilehandle = open("profile.16", O_CREAT | O_WRONLY | O_TEXT);\r
-#endif\r
-/*++++\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if(!FindFile("AUDIO."EXT,NULL,2))\r
-               Quit("CA_Startup(): Can't find audio files.");\r
-//\r
-// MDM end\r
-\r
-#ifndef NOAUDIO\r
-       CAL_SetupAudioFile();\r
-#endif\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("GAMEMAPS."EXT,NULL,1))\r
-               Quit("CA_Startup(): Can't find level files.");\r
-//\r
-// MDM end\r
-\r
-#ifndef NOMAPS\r
-       CAL_SetupMapFile ();\r
-#endif\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
-               Quit("CA_Startup(): Can't find graphics files.");\r
-//\r
-// MDM end\r
-\r
-#ifndef NOGRAPHICS\r
-       CAL_SetupGrFile ();\r
-#endif\r
-\r
-       mapon = -1;\r
-       ca_levelbit = 1;\r
-       ca_levelnum = 0;\r
-\r
-       drawcachebox    = CAL_DialogDraw;\r
-       updatecachebox  = CAL_DialogUpdate;\r
-       finishcachebox  = CAL_DialogFinish;*/\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CA_Shutdown\r
-=\r
-= Closes all files\r
-=\r
-======================\r
-*/\r
-\r
-void CA_Shutdown(void)\r
-{\r
-#ifdef PROFILE\r
-       close(profilehandle);\r
-#endif\r
-/*++++\r
-       close(maphandle);\r
-       close(grhandle);\r
-       close(audiohandle);*/\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_CacheAudioChunk\r
-=\r
-======================\r
-*/\r
-/*++++\r
-void CA_CacheAudioChunk (int chunk)\r
-{\r
-       long    pos,compressed;\r
-#ifdef AUDIOHEADERLINKED\r
-       long    expanded;\r
-       memptr  bigbufferseg;\r
-       byte    far *source;\r
-#endif\r
-\r
-       if (audiosegs[chunk])\r
-       {\r
-               MM_SetPurge (&(memptr)audiosegs[chunk],0);\r
-               return;                                                 // allready in memory\r
-       }\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("AUDIO."EXT,NULL,2))\r
-               Quit("CA_CacheAudioChunk(): Can't find audio files.");\r
-//\r
-// MDM end\r
-\r
-//\r
-// load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
-// a larger buffer\r
-//\r
-       pos = audiostarts[chunk];\r
-       compressed = audiostarts[chunk+1]-pos;\r
-\r
-       lseek(audiohandle,pos,SEEK_SET);\r
-\r
-#ifndef AUDIOHEADERLINKED\r
-\r
-       MM_GetPtr (&(memptr)audiosegs[chunk],compressed);\r
-       if (mmerror)\r
-               return;\r
-\r
-       CA_FarRead(audiohandle,audiosegs[chunk],compressed);\r
-\r
-#else\r
-\r
-       if (compressed<=BUFFERSIZE)\r
-       {\r
-               CA_FarRead(audiohandle,bufferseg,compressed);\r
-               source = bufferseg;\r
-       }\r
-       else\r
-       {\r
-               MM_GetPtr(&bigbufferseg,compressed);\r
-               if (mmerror)\r
-                       return;\r
-               MM_SetLock (&bigbufferseg,true);\r
-               CA_FarRead(audiohandle,bigbufferseg,compressed);\r
-               source = bigbufferseg;\r
-       }\r
-\r
-       expanded = *(long far *)source;\r
-       source += 4;                    // skip over length\r
-       MM_GetPtr (&(memptr)audiosegs[chunk],expanded);\r
-       if (mmerror)\r
-               goto done;\r
-       CAL_HuffExpand (source,audiosegs[chunk],expanded,audiohuffman);\r
-\r
-done:\r
-       if (compressed>BUFFERSIZE)\r
-               MM_FreePtr(&bigbufferseg);\r
-#endif\r
-}*/\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_LoadAllSounds\r
-=\r
-= Purges all sounds, then loads all new ones (mode switch)\r
-=\r
-======================\r
-*/\r
-/*++++\r
-void CA_LoadAllSounds (void)\r
-{\r
-       unsigned        start,i;\r
-\r
-       switch (oldsoundmode)\r
-       {\r
-       case sdm_Off:\r
-               goto cachein;\r
-       case sdm_PC:\r
-               start = STARTPCSOUNDS;\r
-               break;\r
-       case sdm_AdLib:\r
-               start = STARTADLIBSOUNDS;\r
-               break;\r
-       }\r
-\r
-       for (i=0;i<NUMSOUNDS;i++,start++)\r
-               if (audiosegs[start])\r
-                       MM_SetPurge (&(memptr)audiosegs[start],3);              // make purgable\r
-\r
-cachein:\r
-\r
-       switch (SoundMode)\r
-       {\r
-       case sdm_Off:\r
-               return;\r
-       case sdm_PC:\r
-               start = STARTPCSOUNDS;\r
-               break;\r
-       case sdm_AdLib:\r
-               start = STARTADLIBSOUNDS;\r
-               break;\r
-       }\r
-\r
-       for (i=0;i<NUMSOUNDS;i++,start++)\r
-               CA_CacheAudioChunk (start);\r
-\r
-       oldsoundmode = SoundMode;\r
-}*/\r
-\r
-//===========================================================================\r
-\r
-//++++#if GRMODE == EGAGR\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_ShiftSprite\r
-=\r
-= Make a shifted (one byte wider) copy of a sprite into another area\r
-=\r
-======================\r
-*/\r
-/*++++\r
-unsigned       static  sheight,swidth;\r
-boolean static dothemask;\r
-\r
-void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,\r
-       unsigned width, unsigned height, unsigned pixshift, boolean domask)\r
-{\r
-\r
-       sheight = height;               // because we are going to reassign bp\r
-       swidth = width;\r
-       dothemask = domask;\r
-\r
-asm    mov     ax,[segment]\r
-asm    mov     ds,ax           // source and dest are in same segment, and all local\r
-\r
-asm    mov     bx,[source]\r
-asm    mov     di,[dest]\r
-\r
-asm    mov     bp,[pixshift]\r
-asm    shl     bp,1\r
-asm    mov     bp,WORD PTR [shifttabletable+bp]        // bp holds pointer to shift table\r
-\r
-asm    cmp     [ss:dothemask],0\r
-asm    je              skipmask\r
-\r
-//\r
-// table shift the mask\r
-//\r
-asm    mov     dx,[ss:sheight]\r
-\r
-domaskrow:\r
-\r
-asm    mov     BYTE PTR [di],255       // 0xff first byte\r
-asm    mov     cx,ss:[swidth]\r
-\r
-domaskbyte:\r
-\r
-asm    mov     al,[bx]                         // source\r
-asm    not     al\r
-asm    inc     bx                                      // next source byte\r
-asm    xor     ah,ah\r
-asm    shl     ax,1\r
-asm    mov     si,ax\r
-asm    mov     ax,[bp+si]                      // table shift into two bytes\r
-asm    not     ax\r
-asm    and     [di],al                         // and with first byte\r
-asm    inc     di\r
-asm    mov     [di],ah                         // replace next byte\r
-\r
-asm    loop    domaskbyte\r
-\r
-asm    inc     di                                      // the last shifted byte has 1s in it\r
-asm    dec     dx\r
-asm    jnz     domaskrow\r
-\r
-skipmask:\r
-\r
-//\r
-// table shift the data\r
-//\r
-asm    mov     dx,ss:[sheight]\r
-asm    shl     dx,1\r
-asm    shl     dx,1                            // four planes of data\r
-\r
-dodatarow:\r
-\r
-asm    mov     BYTE PTR [di],0         // 0 first byte\r
-asm    mov     cx,ss:[swidth]\r
-\r
-dodatabyte:\r
-\r
-asm    mov     al,[bx]                         // source\r
-asm    inc     bx                                      // next source byte\r
-asm    xor     ah,ah\r
-asm    shl     ax,1\r
-asm    mov     si,ax\r
-asm    mov     ax,[bp+si]                      // table shift into two bytes\r
-asm    or      [di],al                         // or with first byte\r
-asm    inc     di\r
-asm    mov     [di],ah                         // replace next byte\r
-\r
-asm    loop    dodatabyte\r
-\r
-asm    inc     di                                      // the last shifted byte has 0s in it\r
-asm    dec     dx\r
-asm    jnz     dodatarow\r
-\r
-//\r
-// done\r
-//\r
-\r
-asm    mov     ax,ss                           // restore data segment\r
-asm    mov     ds,ax\r
-\r
-}\r
-\r
-#endif\r
-*/\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_CacheSprite\r
-=\r
-= Generate shifts and set up sprite structure for a given sprite\r
-=\r
-======================\r
-*/\r
-/*++++\r
-void CAL_CacheSprite (int chunk, byte far *compressed)\r
-{\r
-       int i;\r
-       unsigned shiftstarts[5];\r
-       unsigned smallplane,bigplane,expanded;\r
-       spritetabletype far *spr;\r
-       spritetype _seg *dest;\r
-\r
-#if GRMODE == CGAGR\r
-//\r
-// CGA has no pel panning, so shifts are never needed\r
-//\r
-       spr = &spritetable[chunk-STARTSPRITES];\r
-       smallplane = spr->width*spr->height;\r
-       MM_GetPtr (&grsegs[chunk],smallplane*2+MAXSHIFTS*6);\r
-       if (mmerror)\r
-               return;\r
-       dest = (spritetype _seg *)grsegs[chunk];\r
-       dest->sourceoffset[0] = MAXSHIFTS*6;    // start data after 3 unsigned tables\r
-       dest->planesize[0] = smallplane;\r
-       dest->width[0] = spr->width;\r
-\r
-//\r
-// expand the unshifted shape\r
-//\r
-       CAL_HuffExpand (compressed, &dest->data[0],smallplane*2,grhuffman);\r
-\r
-#endif\r
-\r
-\r
-#if GRMODE == EGAGR\r
-\r
-//\r
-// calculate sizes\r
-//\r
-       spr = &spritetable[chunk-STARTSPRITES];\r
-       smallplane = spr->width*spr->height;\r
-       bigplane = (spr->width+1)*spr->height;\r
-\r
-       shiftstarts[0] = MAXSHIFTS*6;   // start data after 3 unsigned tables\r
-       shiftstarts[1] = shiftstarts[0] + smallplane*5; // 5 planes in a sprite\r
-       shiftstarts[2] = shiftstarts[1] + bigplane*5;\r
-       shiftstarts[3] = shiftstarts[2] + bigplane*5;\r
-       shiftstarts[4] = shiftstarts[3] + bigplane*5;   // nothing ever put here\r
-\r
-       expanded = shiftstarts[spr->shifts];\r
-       MM_GetPtr (&grsegs[chunk],expanded);\r
-       if (mmerror)\r
-               return;\r
-       dest = (spritetype _seg *)grsegs[chunk];\r
-\r
-//\r
-// expand the unshifted shape\r
-//\r
-       CAL_HuffExpand (compressed, &dest->data[0],smallplane*5,grhuffman);\r
-\r
-//\r
-// make the shifts!\r
-//\r
-       switch (spr->shifts)\r
-       {\r
-       case    1:\r
-               for (i=0;i<4;i++)\r
-               {\r
-                       dest->sourceoffset[i] = shiftstarts[0];\r
-                       dest->planesize[i] = smallplane;\r
-                       dest->width[i] = spr->width;\r
-               }\r
-               break;\r
-\r
-       case    2:\r
-               for (i=0;i<2;i++)\r
-               {\r
-                       dest->sourceoffset[i] = shiftstarts[0];\r
-                       dest->planesize[i] = smallplane;\r
-                       dest->width[i] = spr->width;\r
-               }\r
-               for (i=2;i<4;i++)\r
-               {\r
-                       dest->sourceoffset[i] = shiftstarts[1];\r
-                       dest->planesize[i] = bigplane;\r
-                       dest->width[i] = spr->width+1;\r
-               }\r
-               CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
-                       dest->sourceoffset[2],spr->width,spr->height,4,true);\r
-               break;\r
-\r
-       case    4:\r
-               dest->sourceoffset[0] = shiftstarts[0];\r
-               dest->planesize[0] = smallplane;\r
-               dest->width[0] = spr->width;\r
-\r
-               dest->sourceoffset[1] = shiftstarts[1];\r
-               dest->planesize[1] = bigplane;\r
-               dest->width[1] = spr->width+1;\r
-               CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
-                       dest->sourceoffset[1],spr->width,spr->height,2,true);\r
-\r
-               dest->sourceoffset[2] = shiftstarts[2];\r
-               dest->planesize[2] = bigplane;\r
-               dest->width[2] = spr->width+1;\r
-               CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
-                       dest->sourceoffset[2],spr->width,spr->height,4,true);\r
-\r
-               dest->sourceoffset[3] = shiftstarts[3];\r
-               dest->planesize[3] = bigplane;\r
-               dest->width[3] = spr->width+1;\r
-               CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
-                       dest->sourceoffset[3],spr->width,spr->height,6,true);\r
-\r
-               break;\r
-\r
-       default:\r
-               Quit ("CAL_CacheSprite: Bad shifts number!");\r
-       }\r
-\r
-#endif\r
-}*/\r
-\r
-//===========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_ExpandGrChunk\r
-=\r
-= Does whatever is needed with a pointer to a compressed chunk\r
-=\r
-======================\r
-*/\r
-/*++++\r
-void CAL_ExpandGrChunk (int chunk, byte far *source)\r
-{\r
-       long    expanded;\r
-\r
-\r
-       if (chunk >= STARTTILE8 && chunk < STARTEXTERNS)\r
-       {\r
-       //\r
-       // expanded sizes of tile8/16/32 are implicit\r
-       //\r
-\r
-#if GRMODE == EGAGR\r
-#define BLOCK          32\r
-#define MASKBLOCK      40\r
-#endif\r
-\r
-#if GRMODE == CGAGR\r
-#define BLOCK          16\r
-#define MASKBLOCK      32\r
-#endif\r
-\r
-               if (chunk<STARTTILE8M)                  // tile 8s are all in one chunk!\r
-                       expanded = BLOCK*NUMTILE8;\r
-               else if (chunk<STARTTILE16)\r
-                       expanded = MASKBLOCK*NUMTILE8M;\r
-               else if (chunk<STARTTILE16M)    // all other tiles are one/chunk\r
-                       expanded = BLOCK*4;\r
-               else if (chunk<STARTTILE32)\r
-                       expanded = MASKBLOCK*4;\r
-               else if (chunk<STARTTILE32M)\r
-                       expanded = BLOCK*16;\r
-               else\r
-                       expanded = MASKBLOCK*16;\r
-       }\r
-       else\r
-       {\r
-       //\r
-       // everything else has an explicit size longword\r
-       //\r
-               expanded = *(long far *)source;\r
-               source += 4;                    // skip over length\r
-       }\r
-\r
-//\r
-// allocate final space, decompress it, and free bigbuffer\r
-// Sprites need to have shifts made and various other junk\r
-//\r
-       if (chunk>=STARTSPRITES && chunk< STARTTILE8)\r
-               CAL_CacheSprite(chunk,source);\r
-       else\r
-       {\r
-               MM_GetPtr (&grsegs[chunk],expanded);\r
-               if (mmerror)\r
-                       return;\r
-               CAL_HuffExpand (source,grsegs[chunk],expanded,grhuffman);\r
-       }\r
-}\r
-*/\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_ReadGrChunk\r
-=\r
-= Gets a chunk off disk, optimizing reads to general buffer\r
-=\r
-======================\r
-*/\r
-/*++++\r
-void CAL_ReadGrChunk (int chunk)\r
-{\r
-       long    pos,compressed;\r
-       memptr  bigbufferseg;\r
-       byte    far *source;\r
-       int             next;\r
-\r
-//\r
-// load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
-// a larger buffer\r
-//\r
-       pos = GRFILEPOS(chunk);\r
-       if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
-         return;\r
-\r
-       next = chunk +1;\r
-       while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
-               next++;\r
-\r
-       compressed = GRFILEPOS(next)-pos;\r
-\r
-       lseek(grhandle,pos,SEEK_SET);\r
-\r
-       if (compressed<=BUFFERSIZE)\r
-       {\r
-               CA_FarRead(grhandle,bufferseg,compressed);\r
-               source = bufferseg;\r
-       }\r
-       else\r
-       {\r
-               MM_GetPtr(&bigbufferseg,compressed);\r
-               if (mmerror)\r
-                       return;\r
-               MM_SetLock (&bigbufferseg,true);\r
-               CA_FarRead(grhandle,bigbufferseg,compressed);\r
-               source = bigbufferseg;\r
-       }\r
-\r
-       CAL_ExpandGrChunk (chunk,source);\r
-\r
-       if (compressed>BUFFERSIZE)\r
-               MM_FreePtr(&bigbufferseg);\r
-}\r
-*/\r
-/*\r
-======================\r
-=\r
-= CA_CacheGrChunk\r
-=\r
-= Makes sure a given chunk is in memory, loadiing it if needed\r
-=\r
-======================\r
-*/\r
-/*++++\r
-void CA_CacheGrChunk (int chunk)\r
-{\r
-       long    pos,compressed;\r
-       memptr  bigbufferseg;\r
-       byte    far *source;\r
-       int             next;\r
-\r
-       grneeded[chunk] |= ca_levelbit;         // make sure it doesn't get removed\r
-       if (grsegs[chunk])\r
-       {\r
-               MM_SetPurge (&grsegs[chunk],0);\r
-               return;                                                 // allready in memory\r
-       }\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
-               Quit("CA_CacheGrChunk(): Can't find graphics files.");\r
-//\r
-// MDM end\r
-\r
-//\r
-// load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
-// a larger buffer\r
-//\r
-       pos = GRFILEPOS(chunk);\r
-       if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
-         return;\r
-\r
-       next = chunk +1;\r
-       while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
-               next++;\r
-\r
-       compressed = GRFILEPOS(next)-pos;\r
-\r
-       lseek(grhandle,pos,SEEK_SET);\r
-\r
-       if (compressed<=BUFFERSIZE)\r
-       {\r
-               CA_FarRead(grhandle,bufferseg,compressed);\r
-               source = bufferseg;\r
-       }\r
-       else\r
-       {\r
-               MM_GetPtr(&bigbufferseg,compressed);\r
-               MM_SetLock (&bigbufferseg,true);\r
-               CA_FarRead(grhandle,bigbufferseg,compressed);\r
-               source = bigbufferseg;\r
-       }\r
-\r
-       CAL_ExpandGrChunk (chunk,source);\r
-\r
-       if (compressed>BUFFERSIZE)\r
-               MM_FreePtr(&bigbufferseg);\r
-}\r
-*/\r
-\r
-\r
-//==========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_CacheMap\r
-=\r
-======================\r
-*/\r
-/*++++\r
-void CA_CacheMap (int mapnum)\r
-{\r
-       long    pos,compressed;\r
-       int             plane;\r
-       memptr  *dest,bigbufferseg;\r
-       unsigned        size;\r
-       unsigned        far     *source;\r
-#ifdef MAPHEADERLINKED\r
-       memptr  buffer2seg;\r
-       long    expanded;\r
-#endif\r
-\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("GAMEMAPS."EXT,NULL,1))\r
-               Quit("CA_CacheMap(): Can't find level files.");\r
-//\r
-// MDM end\r
-\r
-\r
-//\r
-// free up memory from last map\r
-//\r
-       if (mapon>-1 && mapheaderseg[mapon])\r
-               MM_SetPurge (&(memptr)mapheaderseg[mapon],3);\r
-       for (plane=0;plane<MAPPLANES;plane++)\r
-               if (mapsegs[plane])\r
-                       MM_FreePtr (&(memptr)mapsegs[plane]);\r
-\r
-       mapon = mapnum;\r
-\r
-\r
-//\r
-// load map header\r
-// The header will be cached if it is still around\r
-//\r
-       if (!mapheaderseg[mapnum])\r
-       {\r
-               pos = ((mapfiletype     _seg *)tinf)->headeroffsets[mapnum];\r
-               if (pos<0)                                              // $FFFFFFFF start is a sparse map\r
-                 Quit ("CA_CacheMap: Tried to load a non existent map!");\r
-\r
-               MM_GetPtr(&(memptr)mapheaderseg[mapnum],sizeof(maptype));\r
-               lseek(maphandle,pos,SEEK_SET);\r
-               CA_FarRead (maphandle,(memptr)mapheaderseg[mapnum],sizeof(maptype));\r
-       }\r
-       else\r
-               MM_SetPurge (&(memptr)mapheaderseg[mapnum],0);\r
-\r
-//\r
-// load the planes in\r
-// If a plane's pointer still exists it will be overwritten (levels are\r
-// allways reloaded, never cached)\r
-//\r
-\r
-       size = mapheaderseg[mapnum]->width * mapheaderseg[mapnum]->height * 2;\r
-\r
-       for (plane = 0; plane<MAPPLANES; plane++)\r
-       {\r
-               pos = mapheaderseg[mapnum]->planestart[plane];\r
-               compressed = mapheaderseg[mapnum]->planelength[plane];\r
-\r
-               if (!compressed)\r
-                       continue;               // the plane is not used in this game\r
-\r
-               dest = &(memptr)mapsegs[plane];\r
-               MM_GetPtr(dest,size);\r
-\r
-               lseek(maphandle,pos,SEEK_SET);\r
-               if (compressed<=BUFFERSIZE)\r
-                       source = bufferseg;\r
-               else\r
-               {\r
-                       MM_GetPtr(&bigbufferseg,compressed);\r
-                       MM_SetLock (&bigbufferseg,true);\r
-                       source = bigbufferseg;\r
-               }\r
-\r
-               CA_FarRead(maphandle,(byte far *)source,compressed);\r
-#ifdef MAPHEADERLINKED\r
-               //\r
-               // unhuffman, then unRLEW\r
-               // The huffman'd chunk has a two byte expanded length first\r
-               // The resulting RLEW chunk also does, even though it's not really\r
-               // needed\r
-               //\r
-               expanded = *source;\r
-               source++;\r
-               MM_GetPtr (&buffer2seg,expanded);\r
-               CAL_CarmackExpand (source, (unsigned far *)buffer2seg,expanded);\r
-               CA_RLEWexpand (((unsigned far *)buffer2seg)+1,*dest,size,\r
-               ((mapfiletype _seg *)tinf)->RLEWtag);\r
-               MM_FreePtr (&buffer2seg);\r
-\r
-#else\r
-               //\r
-               // unRLEW, skipping expanded length\r
-               //\r
-               CA_RLEWexpand (source+1, *dest,size,\r
-               ((mapfiletype _seg *)tinf)->RLEWtag);\r
-#endif\r
-\r
-               if (compressed>BUFFERSIZE)\r
-                       MM_FreePtr(&bigbufferseg);\r
-       }\r
-}*/\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_UpLevel\r
-=\r
-= Goes up a bit level in the needed lists and clears it out.\r
-= Everything is made purgable\r
-=\r
-======================\r
-*/\r
-/*++++\r
-void CA_UpLevel (void)\r
-{\r
-       if (ca_levelnum==7)\r
-               Quit ("CA_UpLevel: Up past level 7!");\r
-\r
-       ca_levelbit<<=1;\r
-       ca_levelnum++;\r
-}*/\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_DownLevel\r
-=\r
-= Goes down a bit level in the needed lists and recaches\r
-= everything from the lower level\r
-=\r
-======================\r
-*/\r
-/*++\r
-void CA_DownLevel (void)\r
-{\r
-       if (!ca_levelnum)\r
-               Quit ("CA_DownLevel: Down past level 0!");\r
-       ca_levelbit>>=1;\r
-       ca_levelnum--;\r
-       CA_CacheMarks(NULL);\r
-}*/\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_ClearMarks\r
-=\r
-= Clears out all the marks at the current level\r
-=\r
-======================\r
-*/\r
-/*\r
-void CA_ClearMarks (void)\r
-{\r
-       int i;\r
-\r
-       for (i=0;i<NUMCHUNKS;i++)\r
-               grneeded[i]&=~ca_levelbit;\r
-}\r
-*/\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_ClearAllMarks\r
-=\r
-= Clears out all the marks on all the levels\r
-=\r
-======================\r
-*/\r
-/*\r
-void CA_ClearAllMarks (void)\r
-{\r
-       _fmemset (grneeded,0,sizeof(grneeded));\r
-       ca_levelbit = 1;\r
-       ca_levelnum = 0;\r
-}\r
-*/\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_FreeGraphics\r
-=\r
-======================\r
-*/\r
-/*++++\r
-void CA_FreeGraphics (void)\r
-{\r
-       int     i;\r
-\r
-       for (i=0;i<NUMCHUNKS;i++)\r
-               if (grsegs[i])\r
-                       MM_SetPurge (&(memptr)grsegs[i],3);\r
-}\r
-*/\r
-\r
-/*\r
-======================\r
-=\r
-= CA_SetAllPurge\r
-=\r
-= Make everything possible purgable\r
-=\r
-======================\r
-*/\r
-/*++++++++\r
-void CA_SetAllPurge (void)\r
-{\r
-       int i;\r
-\r
-       CA_ClearMarks ();\r
-\r
-//\r
-// free cursor sprite and background save\r
-//\r
-       VW_FreeCursor ();\r
-\r
-//\r
-// free map headers and map planes\r
-//\r
-       for (i=0;i<NUMMAPS;i++)\r
-               if (mapheaderseg[i])\r
-                       MM_SetPurge (&(memptr)mapheaderseg[i],3);\r
-\r
-       for (i=0;i<3;i++)\r
-               if (mapsegs[i])\r
-                       MM_FreePtr (&(memptr)mapsegs[i]);\r
-\r
-//\r
-// free sounds\r
-//\r
-       for (i=0;i<NUMSNDCHUNKS;i++)\r
-               if (audiosegs[i])\r
-                       MM_SetPurge (&(memptr)audiosegs[i],3);\r
-\r
-//\r
-// free graphics\r
-//\r
-       CA_FreeGraphics ();\r
-}\r
-\r
-\r
-void CA_SetGrPurge (void)\r
-{\r
-       int i;\r
-\r
-//\r
-// free graphics\r
-//\r
-       for (i=0;i<NUMCHUNKS;i++)\r
-               if (grsegs[i])\r
-                       MM_SetPurge (&(memptr)grsegs[i],3);\r
-}*/\r
-\r
-\r
-//===========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_DialogDraw\r
-=\r
-======================\r
-*/\r
-/*\r
-#define NUMBARS        (17l*8)\r
-#define BARSTEP        8\r
-\r
-unsigned       thx,thy,lastx;\r
-long           barx,barstep;\r
-\r
-void   CAL_DialogDraw (char *title,unsigned numcache)\r
-{\r
-       unsigned        homex,homey,x;\r
-\r
-       barstep = (NUMBARS<<16)/numcache;\r
-\r
-//\r
-// draw dialog window (masked tiles 12 - 20 are window borders)\r
-//\r
-       US_CenterWindow (20,8);\r
-       homex = PrintX;\r
-       homey = PrintY;\r
-\r
-       US_CPrint ("Loading");\r
-       fontcolor = F_SECONDCOLOR;\r
-       US_CPrint (title);\r
-       fontcolor = F_BLACK;\r
-\r
-//\r
-// draw thermometer bar\r
-//\r
-       thx = homex + 8;\r
-       thy = homey + 32;\r
-       VWB_DrawTile8(thx,thy,0);               // CAT3D numbers\r
-       VWB_DrawTile8(thx,thy+8,3);\r
-       VWB_DrawTile8(thx,thy+16,6);\r
-       VWB_DrawTile8(thx+17*8,thy,2);\r
-       VWB_DrawTile8(thx+17*8,thy+8,5);\r
-       VWB_DrawTile8(thx+17*8,thy+16,8);\r
-       for (x=thx+8;x<thx+17*8;x+=8)\r
-       {\r
-               VWB_DrawTile8(x,thy,1);\r
-               VWB_DrawTile8(x,thy+8,4);\r
-               VWB_DrawTile8(x,thy+16,7);\r
-       }\r
-\r
-       thx += 4;               // first line location\r
-       thy += 5;\r
-       barx = (long)thx<<16;\r
-       lastx = thx;\r
-\r
-       VW_UpdateScreen();\r
-}\r
-*/\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_DialogUpdate\r
-=\r
-======================\r
-*/\r
-/*\r
-void   CAL_DialogUpdate (void)\r
-{\r
-       unsigned        x,xh;\r
-\r
-       barx+=barstep;\r
-       xh = barx>>16;\r
-       if (xh - lastx > BARSTEP)\r
-       {\r
-               for (x=lastx;x<=xh;x++)\r
-#if GRMODE == EGAGR\r
-                       VWB_Vlin (thy,thy+13,x,14);\r
-#endif\r
-#if GRMODE == CGAGR\r
-                       VWB_Vlin (thy,thy+13,x,SECONDCOLOR);\r
-#endif\r
-               lastx = xh;\r
-               VW_UpdateScreen();\r
-       }\r
-}*/\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_DialogFinish\r
-=\r
-======================\r
-*/\r
-/*\r
-void   CAL_DialogFinish (void)\r
-{\r
-       unsigned        x,xh;\r
-\r
-       xh = thx + NUMBARS;\r
-       for (x=lastx;x<=xh;x++)\r
-#if GRMODE == EGAGR\r
-               VWB_Vlin (thy,thy+13,x,14);\r
-#endif\r
-#if GRMODE == CGAGR\r
-               VWB_Vlin (thy,thy+13,x,SECONDCOLOR);\r
-#endif\r
-       VW_UpdateScreen();\r
-\r
-}*/\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_CacheMarks\r
-=\r
-======================\r
-*//*\r
-#define MAXEMPTYREAD   1024\r
-\r
-void CA_CacheMarks (char *title)\r
-{\r
-       boolean dialog;\r
-       int     i,next,numcache;\r
-       long    pos,endpos,nextpos,nextendpos,compressed;\r
-       long    bufferstart,bufferend;  // file position of general buffer\r
-       byte    far *source;\r
-       memptr  bigbufferseg;\r
-\r
-       dialog = (title!=NULL);\r
-\r
-       numcache = 0;\r
-//\r
-// go through and make everything not needed purgable\r
-//\r
-       for (i=0;i<NUMCHUNKS;i++)\r
-               if (grneeded[i]&ca_levelbit)\r
-               {\r
-                       if (grsegs[i])                                  // its allready in memory, make\r
-                               MM_SetPurge(&grsegs[i],0);      // sure it stays there!\r
-                       else\r
-                               numcache++;\r
-               }\r
-               else\r
-               {\r
-                       if (grsegs[i])                                  // not needed, so make it purgeable\r
-                               MM_SetPurge(&grsegs[i],3);\r
-               }\r
-\r
-       if (!numcache)                  // nothing to cache!\r
-               return;\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
-               Quit("CA_CacheMarks(): Can't find graphics files.");\r
-//\r
-// MDM end\r
-\r
-       if (dialog)\r
-       {\r
-#ifdef PROFILE\r
-               write(profilehandle,title,strlen(title));\r
-               write(profilehandle,"\n",1);\r
-#endif\r
-               if (drawcachebox)\r
-                       drawcachebox(title,numcache);\r
-       }\r
-\r
-//\r
-// go through and load in anything still needed\r
-//\r
-       bufferstart = bufferend = 0;            // nothing good in buffer now\r
-\r
-       for (i=0;i<NUMCHUNKS;i++)\r
-               if ( (grneeded[i]&ca_levelbit) && !grsegs[i])\r
-               {\r
-//\r
-// update thermometer\r
-//\r
-                       if (dialog && updatecachebox)\r
-                               updatecachebox ();\r
-\r
-                       pos = GRFILEPOS(i);\r
-                       if (pos<0)\r
-                               continue;\r
-\r
-                       next = i +1;\r
-                       while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
-                               next++;\r
-\r
-                       compressed = GRFILEPOS(next)-pos;\r
-                       endpos = pos+compressed;\r
-\r
-                       if (compressed<=BUFFERSIZE)\r
-                       {\r
-                               if (bufferstart<=pos\r
-                               && bufferend>= endpos)\r
-                               {\r
-                               // data is allready in buffer\r
-                                       source = (byte _seg *)bufferseg+(pos-bufferstart);\r
-                               }\r
-                               else\r
-                               {\r
-                               // load buffer with a new block from disk\r
-                               // try to get as many of the needed blocks in as possible\r
-                                       while ( next < NUMCHUNKS )\r
-                                       {\r
-                                               while (next < NUMCHUNKS &&\r
-                                               !(grneeded[next]&ca_levelbit && !grsegs[next]))\r
-                                                       next++;\r
-                                               if (next == NUMCHUNKS)\r
-                                                       continue;\r
-\r
-                                               nextpos = GRFILEPOS(next);\r
-                                               while (GRFILEPOS(++next) == -1) // skip past any sparse tiles\r
-                                                       ;\r
-                                               nextendpos = GRFILEPOS(next);\r
-                                               if (nextpos - endpos <= MAXEMPTYREAD\r
-                                               && nextendpos-pos <= BUFFERSIZE)\r
-                                                       endpos = nextendpos;\r
-                                               else\r
-                                                       next = NUMCHUNKS;                       // read pos to posend\r
-                                       }\r
-\r
-                                       lseek(grhandle,pos,SEEK_SET);\r
-                                       CA_FarRead(grhandle,bufferseg,endpos-pos);\r
-                                       bufferstart = pos;\r
-                                       bufferend = endpos;\r
-                                       source = bufferseg;\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                       // big chunk, allocate temporary buffer\r
-                               MM_GetPtr(&bigbufferseg,compressed);\r
-                               if (mmerror)\r
-                                       return;\r
-                               MM_SetLock (&bigbufferseg,true);\r
-                               lseek(grhandle,pos,SEEK_SET);\r
-                               CA_FarRead(grhandle,bigbufferseg,compressed);\r
-                               source = bigbufferseg;\r
-                       }\r
-\r
-                       CAL_ExpandGrChunk (i,source);\r
-                       if (mmerror)\r
-                               return;\r
-\r
-                       if (compressed>BUFFERSIZE)\r
-                               MM_FreePtr(&bigbufferseg);\r
-\r
-               }\r
-\r
-//\r
-// finish up any thermometer remnants\r
-//\r
-               if (dialog && finishcachebox)\r
-                       finishcachebox();\r
-}*/\r
diff --git a/16/exmmtest/16_ca.h b/16/exmmtest/16_ca.h
deleted file mode 100644 (file)
index 9fbbd2d..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Catacomb Apocalypse 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
-// ID_CA.H\r
-#ifndef __16_CA__\r
-#define __16_CA__\r
-\r
-#ifndef __16_MM__\r
-#include "16_head.h"\r
-#include "16_mm.h"\r
-#endif\r
-\r
-//===========================================================================\r
-\r
-//#define NOMAPS\r
-//#define NOGRAPHICS\r
-//#define NOAUDIO\r
-\r
-//#define MAPHEADERLINKED\r
-//#define GRHEADERLINKED\r
-//#define AUDIOHEADERLINKED\r
-\r
-//#define NUMMAPS              39\r
-//#define MAPPLANES            3
-#define PROFILE\r
-\r
-//===========================================================================\r
-\r
-/*typedef      struct\r
-{\r
-       long            planestart[3];\r
-       unsigned        planelength[3];\r
-       unsigned        width,height;\r
-       char            name[16];\r
-} maptype;*/\r
-\r
-//===========================================================================\r
-\r
-/*extern       byte            _seg    *tinf;\r
-extern int                     mapon;\r
-\r
-extern unsigned        _seg    *mapsegs[3];\r
-extern maptype         _seg    *mapheaderseg[NUMMAPS];\r
-extern byte            _seg    *audiosegs[NUMSNDCHUNKS];\r
-extern void            _seg    *grsegs[NUMCHUNKS];\r
-\r
-extern byte            far     grneeded[NUMCHUNKS];\r
-extern byte            ca_levelbit,ca_levelnum;\r
-\r
-extern char            *titleptr[8];*/\r
-\r
-extern int                     profilehandle,debughandle;\r
-\r
-//\r
-// hooks for custom cache dialogs\r
-//\r
-extern void    (*drawcachebox)         (char *title, unsigned numcache);\r
-extern void    (*updatecachebox)       (void);\r
-extern void    (*finishcachebox)       (void);\r
-\r
-//===========================================================================\r
-\r
-// just for the score box reshifting\r
-\r
-//void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,unsigned width, unsigned height, unsigned pixshift, boolean domask);\r
-\r
-//===========================================================================\r
-
-void CA_OpenDebug (void);\r
-void CA_CloseDebug (void);
-boolean CA_FarRead (int handle, byte huge *dest, dword length, mminfo_t *mm);\r
-boolean CA_FarWrite (int handle, byte huge *source, dword length, mminfo_t *mm);
-\r
-boolean CA_ReadFile (char *filename, memptr *ptr, mminfo_t *mm);\r
-boolean CA_LoadFile (char *filename, memptr *ptr, mminfo_t *mm, mminfotype *mmi);
-\r
-//long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest,unsigned rlewtag);\r
-\r
-//void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length,unsigned rlewtag);\r
-\r
-void CA_Startup (void);\r
-void CA_Shutdown (void);\r
-\r
-//void CA_CacheAudioChunk (int chunk);\r
-//void CA_LoadAllSounds (void);\r
-\r
-/*void CA_UpLevel (void);\r
-void CA_DownLevel (void);\r
-\r
-void CA_SetAllPurge (void);\r
-\r
-void CA_ClearMarks (void);\r
-void CA_ClearAllMarks (void);\r
-\r
-#define CA_MarkGrChunk(chunk)  grneeded[chunk]|=ca_levelbit\r
-\r
-void CA_CacheGrChunk (int chunk);\r
-void CA_CacheMap (int mapnum);\r
-\r
-void CA_CacheMarks (char *title);*/\r
-#endif\r
diff --git a/16/exmmtest/16_head.c b/16/exmmtest/16_head.c
deleted file mode 100644 (file)
index dc14ac6..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/* 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.
- *
- */
-
-#include "16_head.h"
-
-/* Function: Wait **********************************************************\r
-*\r
-*     Parameters:    wait - time in microseconds\r
-*\r
-*     Description:    pauses for a specified number of microseconds.\r
-*\r
-*/\r
-void wait(clock_t wait){\r
-       clock_t goal;\r
-\r
-       if(!wait) return;\r
-\r
-       goal = wait + clock();\r
-       while((goal > clock()) && !kbhit()) ;\r
-} /* End of wait */
-
-void* AllocateLargestFreeBlock(size_t* Size)
-{
-  size_t s0, s1;
-  void* p;
-
-  s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
-
-  while (s0 && (p = malloc(s0)) == NULL)
-    s0 >>= 1;
-
-  if (p)
-    free(p);
-
-  s1 = s0 >> 1;
-
-  while (s1)
-  {
-    if ((p = malloc(s0 + s1)) != NULL)
-    {
-      s0 += s1;
-      free(p);
-    }
-    s1 >>= 1;
-  }
-
-  while (s0 && (p = malloc(s0)) == NULL)
-    s0 ^= s0 & -s0;
-
-  *Size = s0;
-  return p;
-}
-
-size_t GetFreeSize(void)
-{
-  size_t total = 0;
-  void* pFirst = NULL;
-  void* pLast = NULL;
-
-  for (;;)
-  {
-    size_t largest;
-    void* p = AllocateLargestFreeBlock(&largest);
-
-    if (largest < sizeof(void*))
-    {
-      if (p != NULL)
-        free(p);
-      break;
-    }
-
-    *(void**)p = NULL;
-
-    total += largest;
-
-    if (pFirst == NULL)
-      pFirst = p;
-
-    if (pLast != NULL)
-      *(void**)pLast = p;
-
-    pLast = p;
-  }
-
-  while (pFirst != NULL)
-  {
-    void* p = *(void**)pFirst;
-    free(pFirst);
-    pFirst = p;
-  }
-
-  return total;
-}
-
-void far* AllocateLargestFarFreeBlock(size_t* Size)
-{
-       size_t s0, s1;
-       void far* p;
-
-       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
-       while (s0 && (p = _fmalloc(s0)) == NULL)
-               s0 >>= 1;
-
-       if (p)
-               _ffree(p);
-
-       s1 = s0 >> 1;
-       while (s1)
-       {
-               if ((p = _fmalloc(s0 + s1)) != NULL)
-               {
-                       s0 += s1;
-                       _ffree(p);
-               }
-       s1 >>= 1;
-       }
-       while (s0 && (p = _fmalloc(s0)) == NULL)
-               s0 ^= s0 & -s0;
-
-       *Size = s0;
-       return p;
-}
-
-size_t GetFarFreeSize(void)
-{
-       size_t total = 0;
-       void far* pFirst = NULL;
-       void far* pLast = NULL;
-       for(;;)
-       {
-               size_t largest;
-               void far* p = AllocateLargestFarFreeBlock(&largest);
-               if (largest < sizeof(void far*))
-               {
-                       if (p != NULL)
-                       _ffree(p);
-                       break;
-               }
-               *(void far* far*)p = NULL;
-               total += largest;
-               if (pFirst == NULL)
-                       pFirst = p;
-
-               if (pLast != NULL)
-                       *(void far* far*)pLast = p;
-               pLast = p;
-       }
-
-       while (pFirst != NULL)
-       {
-               void far* p = *(void far* far*)pFirst;
-               _ffree(pFirst);
-               pFirst = p;
-       }
-       return total;
-}
-
-long int
-filesize(FILE *fp)\r
-{\r
-       long int save_pos, size_of_file;\r
-\r
-       save_pos = ftell(fp);\r
-       fseek(fp, 0L, SEEK_END);\r
-       size_of_file = ftell(fp);\r
-       fseek(fp, save_pos, SEEK_SET);\r
-       return(size_of_file);\r
-}
-
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//      US_CheckParm() - checks to see if a string matches one of a set of\r
-//              strings. The check is case insensitive. The routine returns the\r
-//              index of the string that matched, or -1 if no matches were found\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-int\r
-US_CheckParm(char *parm,char **strings)\r
-{\r
-       char    cp,cs,\r
-                       *p,*s;\r
-       int             i;\r
-\r
-       while (!isalpha(*parm)) // Skip non-alphas\r
-               parm++;\r
-\r
-       for (i = 0;*strings && **strings;i++)\r
-       {\r
-               for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)\r
-               {\r
-                       cs = *s++;\r
-                       if (!cs)\r
-                               return(i);\r
-                       cp = *p++;\r
-\r
-                       if (isupper(cs))\r
-                               cs = tolower(cs);\r
-                       if (isupper(cp))\r
-                               cp = tolower(cp);\r
-               }\r
-       }\r
-       return(-1);\r
-}
-
-/*\r
-==========================\r
-=\r
-= Quit\r
-=\r
-==========================\r
-*/\r
-\r
-/*void Quit(char *error, ...)\r
-{\r
-       short exit_code=0;\r
-       unsigned        finscreen;\r
-\r
-       va_list ap;\r
-\r
-       va_start(ap,error);\r
-\r
-#ifndef CATALOG\r
-       if (!error)\r
-       {\r
-               CA_SetAllPurge ();\r
-               CA_CacheGrChunk (PIRACY);\r
-               finscreen = (unsigned)grsegs[PIRACY];\r
-       }\r
-#endif\r
-\r
-       //ShutdownId ();\r
-\r
-       if (error && *error)\r
-       {\r
-               vprintf(error,ap);\r
-               exit_code = 1;\r
-       }\r
-#ifndef CATALOG\r
-       else\r
-       if (!NoWait)\r
-       {\r
-               movedata (finscreen,0,0xb800,0,4000);\r
-               bioskey (0);\r
-       }\r
-#endif\r
-\r
-       va_end(ap);\r
-\r
-#ifndef CATALOG\r
-       if (!error)\r
-       {\r
-               _argc = 2;\r
-               _argv[1] = "LAST.SHL";\r
-               _argv[2] = "ENDSCN.SCN";\r
-               _argv[3] = NULL;\r
-               if (execv("LOADSCN.EXE", _argv) == -1)\r
-               {\r
-                       clrscr();\r
-                       puts("Couldn't find executable LOADSCN.EXE.\n");\r
-                       exit(1);\r
-               }\r
-       }\r
-#endif\r
-\r
-       exit(exit_code);\r
-}*/
diff --git a/16/exmmtest/16_head.h b/16/exmmtest/16_head.h
deleted file mode 100644 (file)
index 1a2c748..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/* 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.
- *
- */
-
-/*
-#if !defined(__LARGE__) && !defined(__COMPACT__) && !defined(__HUGE__)
-#error Invalid memory model for compiling project 16
-#endif
-*/
-
-#if !defined(__i86__) && defined(__i386__)
-#error i8088 only
-#endif
-
-#ifndef _LIBHEAD_H_
-#define _LIBHEAD_H_
-#include <io.h>
-#include <dos.h>
-#include <stdio.h>
-#include <conio.h> // just for wait
-#include <time.h> // just for wait
-#include <stdlib.h>
-#include <malloc.h>
-#include <ctype.h>
-//#include <unistd.h>
-#include <fcntl.h>\r
-#include <sys/stat.h>
-#include <mem.h>
-#include "../../src/lib/types.h"
-
-/* Control codes for all keys on the keyboard */
-//here temperarly
-/*
-#define KEY_A          (0x1E)
-#define KEY_B          (0x30)
-#define KEY_C          (0x2E)
-#define KEY_D          (0x20)
-#define KEY_E          (0x12)
-#define KEY_F          (0x21)
-#define KEY_G          (0x22)
-#define KEY_H          (0x23)
-#define KEY_I          (0x17)
-#define KEY_J          (0x24)
-#define KEY_K          (0x25)
-#define KEY_L          (0x26)
-#define KEY_M          (0x32)
-#define KEY_N          (0x31)
-#define KEY_O          (0x18)
-#define KEY_P          (0x19)
-#define KEY_Q          (0x10)
-#define KEY_R          (0x13)
-#define KEY_S          (0x1F)
-#define KEY_T          (0x14)
-#define KEY_U          (0x16)
-#define KEY_V          (0x2F)
-#define KEY_W          (0x11)
-#define KEY_X          (0x2D)
-#define KEY_Y          (0x15)
-#define KEY_Z          (0x2C)
-#define KEY_1          (0x02)
-#define KEY_2          (0x03)
-#define KEY_3          (0x04)
-#define KEY_4          (0x05)
-#define KEY_5          (0x06)
-#define KEY_6          (0x07)
-#define KEY_7          (0x08)
-#define KEY_8          (0x09)
-#define KEY_9          (0x0A)
-#define KEY_0          (0x0B)
-#define KEY_DASH               (0x0C)  // -_
-#define KEY_EQUAL              (0x0D)  // =+
-#define KEY_LBRACKET   (0x1A)  // [{
-#define KEY_RBRACKET   (0x1B)  // ]}
-#define KEY_SEMICOLON  (0x27)  // ;:
-#define KEY_RQUOTE     (0x28)  // '"
-#define KEY_LQUOTE     (0x29)  // `~
-#define KEY_PERIOD     (0x33)  // .>
-#define KEY_COMMA              (0x34)  // ,<
-#define KEY_SLASH              (0x35)  // /?
-#define KEY_BACKSLASH  (0x2B)  // \|
-#define KEY_F1         (0x3B)
-#define KEY_F2         (0x3C)
-#define KEY_F3         (0x3D)
-#define KEY_F4         (0x3E)
-#define KEY_F5         (0x3F)
-#define KEY_F6         (0x40)
-#define KEY_F7         (0x41)
-#define KEY_F8         (0x42)
-#define KEY_F9         (0x43)
-#define KEY_F10                (0x44)
-#define KEY_ESC                (0x01)
-#define KEY_BACKSPACE   (0x0E)
-#define KEY_TAB                (0x0F)
-#define KEY_ENTER              (0x1C)
-#define KEY_CONTROL    (0x1D)
-#define KEY_LSHIFT     (0x2A)
-#define KEY_RSHIFT     (0x36)
-#define KEY_PRTSC              (0x37)
-#define KEY_ALT                (0x38)
-#define KEY_SPACE              (0x39)
-#define KEY_CAPSLOCK   (0x3A)
-#define KEY_NUMLOCK    (0x45)
-#define KEY_SCROLLLOCK (0x46)
-#define KEY_HOME               (0x47)
-#define KEY_UP         (0x48)
-#define KEY_PGUP               (0x49)
-#define KEY_MINUS              (0x4A)
-#define KEY_LEFT               (0x4B)
-#define KEY_CENTER     (0x4C)
-#define KEY_RIGHT              (0x4D)
-#define KEY_PLUS               (0x4E)
-#define KEY_END                (0x4F)
-#define KEY_DOWN               (0x50)
-#define KEY_PGDOWN     (0x51)
-#define KEY_INS                (0x52)
-#define KEY_DEL                (0x53)
-
-#define KEY_LWIN               (0x73)
-#define KEY_RWIN               (0x74)
-#define KEY_MENU               (0x75)
-*/
-
-static dword far* clockdw= (dword far*) 0x046C; /* 18.2hz clock */
-//static dword clockdw=0;
-extern int                     profilehandle,debughandle;      //make it into game global
-
-#define        nil     ((void *)0)
-
-#define __DEBUG__
-
-//#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
-//#define pokew(segm,ofs,value) (peekw((segm),(ofs)) = (word)(value))\r
-
-//typedef union REGPACK        regs_t;
-typedef        enum    {false,true}    boolean;
-//I hope this is correct!
-//__self
-typedef void _seg * memptr;
-//typedef void __based(__self) * memptr;
-//typedef __segment * memptr;
-typedef struct
-{\r
-       int old_mode;   //old video mode before game!
-} global_game_variables_t;
-
-/* local function */\r
-void wait(clock_t wait);
-void* AllocateLargestFreeBlock(size_t* Size);
-size_t GetFreeSize(void);
-void far *AllocateLargestFarFreeBlock(size_t* Size);
-size_t GetFarFreeSize(void);
-long int filesize(FILE *fp);
-int US_CheckParm(char *parm,char **strings);
-
-extern void CA_OpenDebug (void);\r
-extern void CA_CloseDebug (void);
-
-#endif/*_LIBHEAD_H_*/
diff --git a/16/exmmtest/16_mm.c b/16/exmmtest/16_mm.c
deleted file mode 100644 (file)
index e422371..0000000
+++ /dev/null
@@ -1,1603 +0,0 @@
-/* Catacomb Apocalypse 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
-
-=============================================================================
-*/
-/*
-
-Open Watcom port by sparky4
-
-*/
-#include "16_mm.h"
-#pragma hdrstop
-
-#pragma warn -pro
-#pragma warn -use
-
-/*#define GETNEWBLOCK {if(!(mmnew=mmfree))Quit("MM_GETNEWBLOCK: No free blocks!")\\r
-       ;mmfree=mmfree->next;}\r
-\r
-//#define GETNEWBLOCK {if(!mmfree)MML_ClearBlock();mmnew=mmfree;mmfree=mmfree->next;}\r
-\r
-#define FREEBLOCK(x) {*x->useptr=NULL;x->next=mmfree;mmfree=x;}*/
-
-/*
-=============================================================================
-
-                                                GLOBAL VARIABLES
-
-=============================================================================
-*/
-
-void           (* beforesort) (void);
-void           (* aftersort) (void);
-void           (* XMSaddr) (void);             // far pointer to XMS driver
-
-/*
-=============================================================================
-
-                                                LOCAL VARIABLES
-
-=============================================================================
-*/
-
-static char *ParmStringsexmm[] = {"noems","noxms",""};
-
-/*
-======================
-=
-= MML_CheckForEMS
-=
-= Routine from p36 of Extending DOS
-=
-=======================
-*/
-
-boolean MML_CheckForEMS(void)
-{
-       boolean emmcfems;
-       static char     emmname[] = "EMMXXXX0"; //fix by andrius4669
-//             mov     dx,OFFSET emmname
-       __asm {
-               //LEA   DX, emmname     //fix by andrius4669
-               mov     dx,OFFSET 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:
-       __asm {
-               //
-               // EMS is bad
-               //
-               mov     emmcfems,0
-       }
-               End:
-       return(emmcfems);
-}
-
-
-/*
-======================
-=
-= MML_SetupEMS
-=
-=======================
-*/
-
-byte MML_SetupEMS(mminfo_t *mm)
-{
-       byte    str[160];
-       byte    err;
-       boolean errorflag=false;
-
-       unsigned int EMSVer = 0;
-       //byte  EMS_status;
-       unsigned        totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle;
-       totalEMSpages = freeEMSpages = EMSpageframe = EMSpagesmapped = 0;
-
-       __asm {
-               mov     ah,EMS_STATUS
-               int     EMS_INT                                         // make sure EMS hardware is present
-               or      ah,ah
-               //mov   [EMS_status],ah
-               jnz     error
-
-               mov     ah,EMS_VERSION
-               int     EMS_INT
-               or      ah,ah
-               jnz     error
-               mov     [EMSVer],ax                             //      set EMSVer
-               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
-                                                                                       //EXPAND DONG!!!!
-               cmp     [EMSVer],0x40
-               jb      low
-               cmp     bx,[freeEMSpages]
-               jle     getpages
-               mov     bx,[freeEMSpages]
-               jmp     getpages
-       }
-
-low:
-       __asm {
-               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:
-       __asm {
-               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:
-       __asm {
-               mov     err,ah
-               mov     errorflag,1
-               jmp End
-       }
-noEMS:
-End:
-       if(errorflag==true)
-       {
-               //err = CPURegs.h.ah;
-               strcpy(str,"MM_SetupEMS: EMS error ");
-               //itoa(err,str2,16);
-               MM_EMSerr(str, err);
-               printf("%s\n",str);
-               return err;
-       }
-       mm->totalEMSpages=totalEMSpages;
-       mm->freeEMSpages=freeEMSpages;
-       mm->EMSpageframe=EMSpageframe;
-       mm->EMSpagesmapped=EMSpagesmapped;
-       mm->EMShandle=EMShandle;
-       mm->EMSVer=EMSVer;
-       return 0;
-}
-
-
-/*
-======================
-=
-= MML_ShutdownEMS
-=
-=======================
-*/
-
-void MML_ShutdownEMS(mminfo_t *mm)
-{
-       boolean errorflag=false;
-       unsigned EMShandle=mm->EMShandle;
-
-       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!\n");    //++++ 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.
-=
-====================
-*/
-
-byte MM_MapEMS(mminfo_t *mm, mminfotype *mmi)
-{
-       byte    str[160];
-       unsigned        EMShandle;
-       byte err;
-       boolean errorflag=false;
-       int     i;
-       EMShandle=mm->EMShandle;
-
-       for (i=0;i<4/*MAPPAGES*/;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:
-               __asm {
-                       mov     err,ah
-                       mov     errorflag,1
-               }
-                       End:
-               if(errorflag==true)
-               {
-                       //err = CPURegs.h.ah;
-                       strcpy(str,"MM_MapEMS: EMS error ");
-                       //itoa(err,str2,16);
-                       MM_EMSerr(str, err);
-                       printf("%s\n",str);
-                       //printf("FACK! %x\n", err);
-                       return err;
-               }
-       }
-       mmi->EMSmem = (i)*0x4000lu;
-       return 0;
-}
-
-byte MM_MapXEMS(mminfo_t *mm, mminfotype *mmi)
-{
-//SUB EMS.MapXPages (PhysicalStart, LogicalStart, NumPages, Handle)
-
-       //Maps up to 4 logical EMS pages to physical pages in the page frame, where:
-       //PhysicalStart = Physical page first logical page is mapped to
-       //LogicalStart  = First logical page to map
-       //NumPages      = Number of pages to map (1 to 4)
-       //Handle        = EMS handle logical pages are allocated to
-
-  /*//Create a buffer containing the page information
-//  FOR x = 0 TO NumPages - 1
-//    MapInfo$ = MapInfo$ + MKI$(LogicalStart + x) + MKI$(PhysicalStart + x)
-//  NEXT*/
-
-//  Regs.ax = 0x5000                           //Map the pages in the buffer
-//  Regs.cx = NumPages                         //to the pageframe
-//  Regs.dx = Handle
-//  Regs.ds = VARSEG(MapInfo$)
-//  Regs.si = SADD(MapInfo$)
-//  InterruptX 0x67, Regs, Regs
-//     EMS.Error = (Regs.ax AND 0xFF00&) \ 0x100  //Store the status code
-
-//END SUB
-       byte    str[160];
-       byte err;
-       word    EMShandle;
-       boolean errorflag=false;
-       int     i;
-       EMShandle=mm->EMShandle;
-
-       if(mm->EMSVer<0x40)
-               return 5;
-
-       for (i=0;i<MAPPAGES;i++)
-       {
-               __asm {
-                       mov     ah,EMS_MAPXPAGE
-                       mov     cx,[i]                  // logical page
-                       mov     al,bl                   // physical page
-                       mov     dx,[EMShandle]  // handle
-                       int     EMS_INT
-                       or      ah,ah
-                       jnz     error
-                       jmp End
-               }
-                       error:
-               __asm {
-                       mov     err,ah
-                       mov     errorflag,1
-               }
-                       End:
-               if(errorflag==true)
-               {
-                       //err = CPURegs.h.ah;
-                       //strcpy(str,"MM_MapXEMS: EMS error 0x");
-                       strcpy(str,"MM_MapXEMS: EMS error ");
-                       //itoa(err,str2,16);
-                       MM_EMSerr(str, err);
-                       printf("%s\n",str);
-                       //printf("%s%x\n",str, err);
-                       //printf("FACK! %x\n", err);
-                       return err;
-               }
-       }
-       mmi->EMSmem = (i)*0x4000lu;
-       return 0;
-}
-
-//==========================================================================
-
-/*
-======================
-=
-= MML_CheckForXMS
-=
-= Check for XMM driver
-=
-=======================
-*/
-
-boolean MML_CheckForXMS(mminfo_t *mm)
-{
-       boolean errorflag=false;
-       mm->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(mminfo_t *mm, mminfotype *mmi)
-{
-       unsigned        base,size;
-
-getmemory:
-       __asm {
-               mov     ax,0x4310
-               int     0x2f
-               mov     [WORD PTR XMSaddr],bx
-               mov     [WORD PTR XMSaddr+2],es         // function pointer to XMS driver
-
-               mov     ah,XMS_ALLOCUMB
-               mov     dx,0xffff                                       // try for largest block possible
-               //mov     ax,dx                                         // Set available Kbytes.
-               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:
-       __asm {
-               mov     [base],bx
-               mov     [size],dx
-       }
-done:
-       printf("base=%u ", base); printf("size=%u\n", size);
-       MML_UseSpace(base,size, mm);
-       mmi->XMSmem += size*16;
-       mm->UMBbase[mm->numUMBs] = base;
-       mm->numUMBs++;
-       if(mm->numUMBs < MAXUMBS)
-               goto getmemory;
-}
-
-
-/*
-======================
-=
-= MML_ShutdownXMS
-=
-======================
-*/
-
-void MML_ShutdownXMS(mminfo_t *mm)
-{
-       int     i;
-       unsigned        base;
-
-       for (i=0;i<mm->numUMBs;i++)
-       {
-               base = mm->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(/*d*/word segstart, dword seglength, mminfo_t *mm)
-{
-       mmblocktype huge *scan,huge *last;
-       word            segm;
-       dword   oldend;
-       dword           extra;
-
-       scan = last = mm->mmhead;
-       mm->mmrover = mm->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;
-       }
-
-       //find out how many blocks it spans!
-       if(seglength>0xffffu)
-       {
-//             segm=seglength/0x4000u;
-               segm=seglength/0xffffu;
-       }
-       else segm=1;
-
-       //++++emsver stuff!
-       if(segm>1/*extra>0xfffflu*/)
-       {
-               /*__asm
-               {
-                       push    ds
-                       mov     ax,ds
-                       inc             ax
-                       mov     ds,ax
-               }*/
-
-
-//MML_UseSpace(?segstart?, ?length?, mm);
-
-               /*__asm
-               {
-                       pop ds
-               }*/
-               //printf("MML_UseSpace: Segment spans two blocks!\n");
-       }
-
-//
-// take the given range out of the block
-//
-       oldend = scan->start + scan->length;
-       extra = oldend - (segstart+seglength);
-/*
-printf("segm=%u        ", segm);
-printf("ex=%lu ", extra);
-printf("start+seglen=%lu       ", segstart+seglength);
-printf("len=%u ", scan->length);
-printf("segsta=%x      ", segstart);
-printf("seglen=%lu\n", seglength);
-*/
-//segu:
-//++++todo: linked list of segment!
-//printf("segm=%lu\n", segm);
-       if(segstart == scan->start)
-       {
-               last->next = scan->next;                        // unlink block
-               MM_FreeBlock(scan, mm);
-               scan = last;
-       }
-       else
-               scan->length = segstart-scan->start;    // shorten block
-
-//     segm--;
-
-       if(extra > 0)
-       {
-               MM_GetNewBlock(mm);
-               mm->mmnew->next = scan->next;
-               scan->next = mm->mmnew;
-               mm->mmnew->start = segstart+seglength;
-               mm->mmnew->length = extra;
-               mm->mmnew->attributes = LOCKBIT;
-       }//else if(segm>0) goto segu;
-
-}
-
-//==========================================================================
-
-/*
-====================
-=
-= MML_ClearBlock
-=
-= We are out of blocks, so free a purgable block
-=
-====================
-*/
-
-void MML_ClearBlock(mminfo_t *mm)
-{
-       mmblocktype huge *scan,huge *last;
-
-       scan = mm->mmhead->next;
-
-       while(scan)
-       {
-               if(!(scan->attributes&LOCKBIT) && (scan->attributes&PURGEBITS))
-               {
-                       MM_FreePtr(scan->useptr, mm);
-                       return;
-               }
-               scan = scan->next;
-       }
-
-       printf("MM_ClearBlock: No purgable blocks!\n");
-}
-
-
-//==========================================================================
-
-/*
-===================
-=
-= MM_Startup
-=
-= Grabs all space from turbo with malloc/farmalloc
-= Allocates bufferseg misc buffer
-=
-===================
-*/
-
-void MM_Startup(mminfo_t *mm, mminfotype *mmi)
-{
-       int i;
-       dword length,seglength;
-       //dword length; word seglength;
-       void huge       *start;
-       word    segstart;//,endfree;
-
-       if(mm->mmstarted)
-               MM_Shutdown(mm);
-
-       mm->mmstarted = true;
-       mm->bombonerror = true;
-
-//
-// set up the linked list (everything in the free list;
-//
-       //printf("              linked list making!\n");
-       mm->mmhead = NULL;
-       mm->mmfree = &(mm->mmblocks[0]);
-       for(i=0;i<MAXBLOCKS-1;i++)
-       {
-               mm->mmblocks[i].next = &(mm->mmblocks[i+1]);
-       }
-       mm->mmblocks[i].next = NULL;
-
-//
-// locked block of all memory until we punch out free space
-//
-       //printf("              newblock making!\n");
-       MM_GetNewBlock(mm);
-       mm->mmhead = mm->mmnew;                         // this will allways be the first node
-       mm->mmnew->start = 0;
-       mm->mmnew->length = 0xffff;
-       mm->mmnew->attributes = LOCKBIT;
-       mm->mmnew->next = NULL;
-       mm->mmrover = mm->mmhead;
-
-//
-// get all available near conventional memory segments
-//
-       length=coreleft();
-       printf("                nearheap making!\n");
-       //_heapgrow();
-       //length=_memmax();//(dword)GetFreeSize();
-       start = (void huge *)(mm->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, mm);
-       mmi->nearheap = length;
-       printf("start=%Fp       segstart=%x     seglen=%l       len=%l\n", start, segstart, seglength, length);
-       printf("                near heap ok!\n");
-
-//
-// get all available far conventional memory segments
-//
-       length=farcoreleft();
-       //printf("              farheap making!\n");
-       //_fheapgrow();
-       //length=(dword)GetFarFreeSize();//0xffffUL*4UL;
-       //start = mm->farheap = halloc(length, 1);
-       start = mm->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, mm);
-       mmi->farheap = length;
-       printf("start=%Fp       segstart=%x     seglen=%l       len=%l\n", start, segstart, seglength, length);
-       printf("                far heap ok!\n");
-
-       mmi->mainmem = mmi->nearheap + mmi->farheap;
-
-       getch();
-
-//
-// detect EMS and allocate up to 64K at page frame
-//
-printf("               EMS1\n");
-printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");    //bug!
-       mmi->EMSmem = 0;
-       for(i = 1;i < _argc;i++)
-       {
-               if(US_CheckParm(_argv[i],ParmStringsexmm) == 0)
-                       goto emsskip;                           // param NOEMS
-       }
-printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");    //bug!
-       if(MML_CheckForEMS())
-       {
-printf("               EMS2\n");
-printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");    //bug!
-               MML_SetupEMS(mm);                                       // allocate space
-printf("               EMS3\n");
-printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");    //bug!
-               //TODO: EMS4! AND EMS 3.2 MASSIVE DATA HANDLMENT!
-               MML_UseSpace(mm->EMSpageframe,(MAPPAGES)*0x4000lu, mm);
-printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");    //bug!
-printf("               EMS4\n");
-               //if(mm->EMSVer<0x40)
-                       MM_MapEMS(mm, mmi);                                     // map in used pages
-               //else
-                       //MM_MapXEMS(mm, mmi);                                  // map in used pages
-       }
-
-//
-// detect XMS and get upper memory blocks
-//
-emsskip:
-       mmi->XMSmem = 0;
-       for(i = 1;i < _argc;i++)
-       {
-               if(US_CheckParm(_argv[i],ParmStringsexmm) == 0)
-                       goto xmsskip;                           // param NOXMS
-       }
-printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");    //bug!
-       if(MML_CheckForXMS(mm))
-       {
-printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");    //bug!
-printf("               XMS!\n");
-               MML_SetupXMS(mm, mmi);                                  // allocate as many UMBs as possible
-       }
-
-//
-// allocate the misc buffer
-//
-xmsskip:
-       mm->mmrover = mm->mmhead;               // start looking for space after low block
-
-       MM_GetPtr(&(mm->bufferseg),BUFFERSIZE, mm, mmi);
-}
-
-//==========================================================================
-
-/*
-====================
-=
-= MM_Shutdown
-=
-= Frees all conventional, EMS, and XMS allocated
-=
-====================
-*/
-
-void MM_Shutdown(mminfo_t *mm)
-{
-       if(!(mm->mmstarted))
-               return;
-
-       _ffree(mm->farheap);    printf("                far freed\n");
-       free(mm->nearheap);     printf("                near freed\n");
-       if(MML_CheckForEMS()){ MML_ShutdownEMS(mm); printf("            EMS freed\n"); }
-       if(MML_CheckForXMS(mm)){ MML_ShutdownXMS(mm); printf("          XMS freed\n"); }
-}
-
-//==========================================================================
-
-/*
-====================
-=
-= MM_GetPtr
-=
-= Allocates an unlocked, unpurgable block
-=
-====================
-*/
-
-void MM_GetPtr(memptr *baseptr,dword size, mminfo_t *mm, mminfotype *mmi)
-{
-       mmblocktype huge *scan,huge *lastscan,huge *endscan,huge *purge,huge *next;
-       int                     search;
-       unsigned        needed,startseg;
-
-       needed = (size+15)/16;          // convert size from bytes to paragraphs
-
-       MM_GetNewBlock(mm);                             // fill in start and next after a spot is found
-       mm->mmnew->length = needed;
-       mm->mmnew->useptr = baseptr;
-       mm->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 && mm->mmrover == mm->mmhead)
-                       search++;
-
-               switch(search)
-               {
-               case 0:
-                       lastscan = mm->mmrover;
-                       scan = mm->mmrover->next;
-                       endscan = NULL;
-                       break;
-               case 1:
-                       lastscan = mm->mmhead;
-                       scan = mm->mmhead->next;
-                       endscan = mm->mmrover;
-                       break;
-               case 2:
-                       MM_SortMem(mm);
-                       lastscan = mm->mmhead;
-                       scan = mm->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 = mm->mmnew;
-                               mm->mmnew->start = *(unsigned *)baseptr = startseg;
-                               mm->mmnew->next = scan;
-                               while(purge != scan)
-                               {       // free the purgable block
-                                       next = purge->next;
-                                       MM_FreeBlock(purge, mm);
-                                       purge = next;           // purge another if not at scan
-                               }
-                               mm->mmrover = mm->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 (mm->bombonerror)
-       {
-               printf(OUT_OF_MEM_MSG,(size-mmi->nearheap));
-               exit(-5);
-       }
-       else
-               mm->mmerror = true;
-}
-
-//==========================================================================
-
-/*
-====================
-=
-= MM_FreePtr
-=
-= Allocates an unlocked, unpurgable block
-=
-====================
-*/
-
-void MM_FreePtr(memptr *baseptr, mminfo_t *mm)
-{
-       mmblocktype huge *scan,huge *last;
-
-       last = mm->mmhead;
-       scan = last->next;
-
-       if(baseptr == mm->mmrover->useptr)      // removed the last allocated block
-               mm->mmrover = mm->mmhead;
-
-       while(scan->useptr != baseptr && scan)
-       {
-               last = scan;
-               scan = scan->next;
-       }
-
-       if(!scan)
-       {
-               printf("MM_FreePtr: Block not found!\n");
-               return;
-       }
-
-       last->next = scan->next;
-
-       MM_FreeBlock(scan, mm);
-}
-//==========================================================================
-
-/*
-=====================
-=
-= MM_SetPurge
-=
-= Sets the purge level for a block (locked blocks cannot be made purgable)
-=
-=====================
-*/
-
-void MM_SetPurge(memptr *baseptr, int purge, mminfo_t *mm)
-{
-       mmblocktype huge *start;
-
-       start = mm->mmrover;
-
-       do
-       {
-               if(mm->mmrover->useptr == baseptr)
-                       break;
-
-               mm->mmrover = mm->mmrover->next;
-
-               if(!mm->mmrover)
-                       mm->mmrover = mm->mmhead;
-               else if(mm->mmrover == start)
-               {
-                       printf("MM_SetPurge: Block not found!");
-                       return;
-               }
-
-       } while(1);
-
-       mm->mmrover->attributes &= ~PURGEBITS;
-       mm->mmrover->attributes |= purge;
-}
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_SetLock
-=
-= Locks / unlocks the block
-=
-=====================
-*/
-
-void MM_SetLock(memptr *baseptr, boolean locked, mminfo_t *mm)
-{
-       mmblocktype huge *start;
-
-       start = mm->mmrover;
-
-       do
-       {
-               if(mm->mmrover->useptr == baseptr)
-                       break;
-
-               mm->mmrover = mm->mmrover->next;
-
-               if(!mm->mmrover)
-                       mm->mmrover = mm->mmhead;
-               else if(mm->mmrover == start)
-               {
-                       printf("MM_SetLock: Block not found!");
-                       return;
-               }
-
-       } while(1);
-
-       mm->mmrover->attributes &= ~LOCKBIT;
-       mm->mmrover->attributes |= locked*LOCKBIT;
-}
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_SortMem
-=
-= Throws out all purgable stuff and compresses movable blocks
-=
-=====================
-*/
-
-void MM_SortMem(mminfo_t *mm)
-{
-       mmblocktype huge *scan,huge *last,huge *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 = mm->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;
-                               MM_FreeBlock(scan, mm);
-                               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
-       }
-
-       mm->mmrover = mm->mmhead;
-
-       if(aftersort)
-               aftersort();
-
-//     VW_ColorBorder (oldborder);
-
-/*++++ if(playing)
-               MM_SetLock(&(memptr)audiosegs[playing],false);*/
-}
-
-
-//==========================================================================
-
-//****#if 0
-/*
-=====================
-=
-= MM_ShowMemory
-=
-=====================
-*/
-
-void MM_ShowMemory(/*page_t *page, */mminfo_t *mm)
-{
-       mmblocktype huge *scan;
-       word color,temp;
-       long    end,owner;
-       word chx,chy;
-       byte    scratch[160],str[16];
-
-//**** VW_SetDefaultColors();
-//**** VW_SetLineWidth(40);
-//++++mh       temp = bufferofs;
-//++++mh       bufferofs = 0;
-//**** VW_SetScreen (0,0);
-
-       scan = mm->mmhead;
-
-       end = -1;
-
-CA_OpenDebug ();
-
-       chx=0;
-       chy=0;
-
-       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(");
-                       write(debughandle,"\nMM_ShowMemory: Memory block order currupted!\n",strlen("\nMM_ShowMemory: Memory block order currupted!\n"));
-                       //modexprint(&page, chx, chy, 1, 0, 24, "\nMM_ShowMemory: Memory block order currupted!\n");
-                       return;
-               }
-               end = scan->start+scan->length-1;
-               chy = scan->start/320;
-               chx = scan->start%320;
-                               //modexhlin(page, scan->start, (unsigned)end, chy, color);
-                               //for(chx=scan->start;chx+4>=(word)end;chx+=4)
-                               //{
-//++++                                 modexClearRegion(page, chx, chy, 4, 4, color);
-                               //}
-
-//++++         VW_Hlin(scan->start,(unsigned)end,0,color);
-
-//++++         VW_Plot(scan->start,0,15);
-//++++                         modexClearRegion(page, chx, chy, 4, 4, 15);
-               if(scan->next->start > end+1)
-//++++                 VW_Hlin(end+1,scan->next->start,0,0);   // black = free
-                       //for(chx=scan->next->start;chx+4>=(word)end+1;chx+=4)
-                       //{
-//++++                         chx+=scan->next->start;
-//++++                         modexClearRegion(page, chx, chy, 4, 4, 2);
-                       //}
-                                       //modexhlin(page, end+1,scan->next->start, chy, 0);
-
-/*
-               end = scan->length-1;
-               y = scan->start/320;
-               x = scan->start%320;
-               VW_Hlin(x,x+end,y,color);
-               VW_Plot(x,y,15);
-               if (scan->next && scan->next->start > end+1)
-                       VW_Hlin(x+end+1,x+(scan->next->start-scan->start),y,0); // black = free
-*/
-
-//****#if 0
-printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");    //bug!
-strcpy(scratch,"Seg:");
-ultoa (scan->start,str,16);
-strcat (scratch,str);
-strcat (scratch,"\tSize:");
-ultoa ((dword)scan->length,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));
-//modexprint(page, chx, chy, 1, 0, 24, &scratch);
-//++++chy+=4;
-//fprintf(stdout, "%s", scratch);
-//****#endif
-
-               scan = scan->next;
-       }
-
-CA_CloseDebug ();
-
-//++++mh       IN_Ack();
-//**** VW_SetLineWidth(64);
-//++++mh       bufferofs = temp;
-}
-//****#endif
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_DumpData
-=
-=====================
-*/
-
-void MM_DumpData(mminfo_t *mm)
-{
-       mmblocktype far *scan,far *best;
-       long    lowest,oldlowest;
-       word    owner;
-       byte    lock,purge;
-       FILE    *dumpfile;
-
-
-       //++++free(mm->nearheap);
-       dumpfile = fopen ("mmdump.16","w");
-       if (!dumpfile){
-               printf("MM_DumpData: Couldn't open MMDUMP.16!\n");
-               return;
-       }
-
-       lowest = -1;
-       do
-       {
-               oldlowest = lowest;
-               lowest = 0xffff;
-
-               scan = mm->mmhead;
-               while (scan)
-               {
-                       owner = (word)scan->useptr;
-
-                       if (owner && owner<lowest && owner > oldlowest)
-                       {
-                               best = scan;
-                               lowest = owner;
-                       }
-
-                       scan = scan->next;
-               }
-
-               if (lowest != 0xffff)
-               {
-                       if (best->attributes & PURGEBITS)
-                               purge = 'P';
-                       else
-                               purge = '-';
-                       if (best->attributes & LOCKBIT)
-                               lock = 'L';
-                       else
-                               lock = '-';
-                       fprintf (dumpfile,"0x%p (%c%c) = %u\n"
-                       ,(word)lowest,lock,purge,best->length);
-               }
-
-       } while (lowest != 0xffff);
-
-       fclose(dumpfile);
-       printf("MMDUMP.16 created.\n");
-}
-
-//==========================================================================
-
-
-/*
-======================
-=
-= MM_UnusedMemory
-=
-= Returns the total free space without purging
-=
-======================
-*/
-
-dword MM_UnusedMemory(mminfo_t *mm)
-{
-       dword free;
-       mmblocktype huge *scan;
-
-       free = 0;
-       scan = mm->mmhead;
-
-       while(scan->next)
-       {
-               free += scan->next->start - (scan->start + scan->length);
-               scan = scan->next;
-       }
-
-//     return free*16l;
-       return free;
-}
-
-//==========================================================================
-
-
-/*
-======================
-=
-= MM_TotalFree
-=
-= Returns the total free space with purging
-=
-======================
-*/
-
-dword MM_TotalFree(mminfo_t *mm)
-{
-       dword free;
-       mmblocktype huge *scan;
-
-       free = 0;
-       scan = mm->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;
-       return free;
-}
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_Report
-=
-=====================
-*/
-
-void MM_Report(/*page_t *page, */mminfo_t *mm, mminfotype *mmi)
-{
-       if(MML_CheckForEMS())
-       {
-               printf("EMM v%x.%x available\n", mm->EMSVer>>4,mm->EMSVer&0x0F);
-               printf("totalEMSpages=%u\n", mm->totalEMSpages);
-               printf("freeEMSpages=%u\n", mm->freeEMSpages);
-               printf("EMSpageframe=%x\n", mm->EMSpageframe);
-       }
-       if(MML_CheckForXMS(mm)) printf("XMSaddr=%X\n", *XMSaddr);
-       printf("near=%lu\n", mmi->nearheap);
-       printf("far=%lu\n", mmi->farheap);
-       printf("EMSmem=%lu\n", mmi->EMSmem);
-       printf("XMSmem=%lu\n", mmi->XMSmem);
-       printf("mainmem=%lu\n", mmi->mainmem);
-       printf("UnusedMemory=%lu\n", MM_UnusedMemory(mm));
-       printf("TotalFree=%lu\n", MM_TotalFree(mm));
-       //mmi->nearheap+mmi->farheap+
-       printf("TotalUsed=%lu\n", mmi->mainmem+mmi->EMSmem+mmi->XMSmem);//+);
-//     printf("\n");
-//     printf("UnusedMemory=%lu kb\n", MM_UnusedMemory()/10248);
-//     printf("TotalFree=%lu kb\n", MM_TotalFree()/10248);
-}
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_EMSerr
-=
-=====================
-*/
-
-void MM_EMSerr(byte *stri, byte err)
-{
-       //Returns a text string describing the error code in EMS.Error.
-       switch(err)
-       {
-               case 0x0:
-                       strcat(stri, "successful");
-               break;
-               case 0x80:
-                       strcat(stri, "internal error");
-               break;
-               case 0x81:
-                       strcat(stri, "hardware malfunction");
-               break;
-               case 0x82:
-                       strcat(stri, "busy .. retry later");
-               break;
-               case 0x83:
-                       strcat(stri, "invalid handle");
-               break;
-               case 0x84:
-                       strcat(stri, "undefined function requested by application");
-               break;
-               case 0x85:
-                       strcat(stri, "no more handles available");
-               break;
-               case 0x86:
-                       strcat(stri, "error in save or restore of mapping context");
-               break;
-               case 0x87:
-                       strcat(stri, "insufficient memory pages in system");
-               break;
-               case 0x88:
-                       strcat(stri, "insufficient memory pages available");
-               break;
-               case 0x89:
-                       strcat(stri, "zero pages requested");
-               break;
-               case 0x8A:
-                       strcat(stri, "invalid logical page number encountered");
-               break;
-               case 0x8B:
-                       strcat(stri, "invalid physical page number encountered");
-               break;
-               case 0x8C:
-                       strcat(stri, "page-mapping hardware state save area is full");
-               break;
-               case 0x8D:
-                       strcat(stri, "save of mapping context failed");
-               break;
-               case 0x8E:
-                       strcat(stri, "restore of mapping context failed");
-               break;
-               case 0x8F:
-                       strcat(stri, "undefined subfunction");
-               break;
-               case 0x90:
-                       strcat(stri, "undefined attribute type");
-               break;
-               case 0x91:
-                       strcat(stri, "feature not supported");
-               break;
-               case 0x92:
-                       strcat(stri, "successful, but a portion of the source region has been overwritten");
-               break;
-               case 0x93:
-                       strcat(stri, "length of source or destination region exceeds length of region allocated to either source or destination handle");
-               break;
-               case 0x94:
-                       strcat(stri, "conventional and expanded memory regions overlap");
-               break;
-               case 0x95:
-                       strcat(stri, "offset within logical page exceeds size of logical page");
-               break;
-               case 0x96:
-                       strcat(stri, "region length exceeds 1 MB");
-               break;
-               case 0x97:
-                       strcat(stri, "source and destination EMS regions have same handle and overlap");
-               break;
-               case 0x98:
-                       strcat(stri, "memory source or destination type undefined");
-               break;
-               case 0x9A:
-                       strcat(stri, "specified alternate map register or DMA register set not supported");
-               break;
-               case 0x9B:
-                       strcat(stri, "all alternate map register or DMA register sets currently allocated");
-               break;
-               case 0x9C:
-                       strcat(stri, "alternate map register or DMA register sets not supported");
-               break;
-               case 0x9D:
-                       strcat(stri, "undefined or unallocated alternate map register or DMA register set");
-               break;
-               case 0x9E:
-                       strcat(stri, "dedicated DMA channels not supported");
-               break;
-               case 0x9F:
-                       strcat(stri, "specified dedicated DMA channel not supported");
-               break;
-               case 0xA0:
-                       strcat(stri, "no such handle name");
-               break;
-               case 0xA1:
-                       strcat(stri, "a handle found had no name, or duplicate handle name");
-               break;
-               case 0xA2:
-                       strcat(stri, "attempted to wrap around 1M conventional address space");
-               break;
-               case 0xA3:
-                       strcat(stri, "source array corrupted");
-               break;
-               case 0xA4:
-                       strcat(stri, "operating system denied access");
-               break;
-               default:
-                       strcat(stri, "undefined error");
-       }
-}
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_BombOnError
-=
-=====================
-*/
-
-void MM_BombOnError(boolean bomb, mminfo_t *mm)
-{
-       mm->bombonerror = bomb;
-}
-
-void MM_GetNewBlock(mminfo_t *mm)
-{
-       if(!mm->mmfree)
-               MML_ClearBlock(mm);
-       mm->mmnew=mm->mmfree;
-       mm->mmfree=mm->mmfree->next;
-       //if(!(mm->mmnew=mm->mmfree))
-       //{
-               //printf("MM_GETNEWBLOCK: No free blocks!");
-//             return;
-       //}
-       //mm->mmfree=mm->mmfree->next;
-}
-
-void MM_FreeBlock(mmblocktype *x, mminfo_t *mm)
-{
-       x->useptr=NULL;
-       x->next=mm->mmfree;
-       mm->mmfree=x;
-}
-
-/*void MM_seguin(void)
-{
-       __asm
-       {
-               push    ds
-               mov     ax,ds
-               inc             ax
-               mov     ds,ax
-       }
-}
-
-void MM_segude(void)
-{
-       __asm
-       {
-               pop ds
-       }
-}*/
-
-/*
-pull data from far and put it into ds var
-mov ax,es:si
-mov x,ax
-*/
-/*
-ss stack segment
-sp top of stack
-bp bottem of stack
-*/
diff --git a/16/exmmtest/16_mm.h b/16/exmmtest/16_mm.h
deleted file mode 100644 (file)
index a431bf7..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Catacomb Apocalypse 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 __16_EXMM__
-#define __16_EXMM__
-
-#include <string.h>
-#include <malloc.h>
-//#include <bios.h>
-#include "16_head.h"
-//#include "modex16.h"
-//#include "src/lib/16_ca.h"
-//++++mh       #include "src/lib/16_in.h"
-
-#ifdef __DEBUG__               // 1 == Debug/Dev  ;  0 == Production/final
-#define OUT_OF_MEM_MSG "MM_GetPtr: Out of memory!\nYou were short :%lu bytes"
-#else
-#define OUT_OF_MEM_MSG "\npee\n"
-#endif
-
-
-#define SAVENEARHEAP   0x200           // space to leave in data segment
-#define SAVEFARHEAP    0x400                   // space to leave in far heap
-
-#define        BUFFERSIZE              0x1000          // miscelanious, allways available buffer
-
-#define MAXBLOCKS              720
-
-
-
-//--------
-
-#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_MAPXPAGE            0x50
-#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 struct
-{
-       dword   nearheap,farheap,EMSmem,XMSmem,mainmem;
-       //__segment segu;
-} mminfotype;
-
-//==========================================================================
-
-extern void            (* beforesort) (void);
-extern void            (* aftersort) (void);
-extern void            (* XMSaddr) (void);             // far pointer to XMS driver
-
-//==========================================================================
-
-/*
-=============================================================================
-
-                                                       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                12
-#define MAPPAGES               4//mm->EMSpagesmapped
-
-typedef struct mmblockstruct
-{
-       //word  start,length;
-       word    start;  dword length;
-       unsigned        attributes;
-       memptr          *useptr;        // pointer to the segment start
-       struct mmblockstruct huge *next;
-} mmblocktype;
-
-
-typedef struct
-{
-       memptr bufferseg;
-       boolean         mmstarted, bombonerror, mmerror;
-       void huge       *farheap;
-       void    *nearheap;
-       //byte          EMS_status;
-       unsigned        totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle;
-       unsigned int EMSVer;
-       word numUMBs,UMBbase[MAXUMBS];
-       //dword numUMBs,UMBbase[MAXUMBS];
-       mmblocktype     huge mmblocks[MAXBLOCKS],huge *mmhead,huge *mmfree,huge *mmrover,huge *mmnew;
-} mminfo_t;
-
-/*
-=============================================================================
-
-                                                GLOBAL VARIABLES
-
-=============================================================================
-*/
-
-
-/*
-=============================================================================
-
-                                                LOCAL VARIABLES
-
-=============================================================================
-*/
-
-//==========================================================================
-
-boolean MML_CheckForEMS(void);
-byte MML_SetupEMS(mminfo_t *mm);
-void MML_ShutdownEMS(mminfo_t *mm);
-byte MM_MapEMS(mminfo_t *mm, mminfotype *mmi);
-byte MM_MapXEMS(mminfo_t *mm, mminfotype *mmi);
-boolean MML_CheckForXMS(mminfo_t *mm);
-void MML_SetupXMS(mminfo_t *mm, mminfotype *mmi);
-void MML_ShutdownXMS(mminfo_t *mm);
-void MML_UseSpace(/*d*/word segstart, dword seglength, mminfo_t *mm);
-void MML_ClearBlock(mminfo_t *mm);
-
-void MM_Startup(mminfo_t *mm, mminfotype *mmi);
-void MM_Shutdown(mminfo_t *mm);
-
-void MM_GetPtr(memptr *baseptr,dword size, mminfo_t *mm, mminfotype *mmi);
-void MM_FreePtr(memptr *baseptr, mminfo_t *mm);
-void MM_SetPurge(memptr *baseptr, int purge, mminfo_t *mm);
-void MM_SetLock(memptr *baseptr, boolean locked, mminfo_t *mm);
-void MM_SortMem(mminfo_t *mm);
-void MM_ShowMemory(/*page_t *page, */mminfo_t *mm);
-void MM_DumpData(mminfo_t *mm);
-dword MM_UnusedMemory(mminfo_t *mm);
-dword MM_TotalFree(mminfo_t *mm);
-void MM_Report(/*page_t *page, */mminfo_t *mm, mminfotype *mmi);
-static void MM_EMSerr(byte *stri, byte err);
-void MM_BombOnError(boolean bomb, mminfo_t *mm);
-void MM_GetNewBlock(mminfo_t *mm);
-void MM_FreeBlock(mmblocktype *x, mminfo_t *mm);
-
-//==========================================================================
-
-#endif
index 449303dcdcaa9f9fdc18e75068d34bfa3f3b7a12..af8fa1879c190579c053002d3eb0f90c800666b2 100644 (file)
Binary files a/16/exmmtest/EXMMTEST.DSK and b/16/exmmtest/EXMMTEST.DSK differ
index 26edd1f1cb068b614754bfd7f07ac8b287e10f09..13a00527053641a20e6501f9b8a3a231b7b2c284 100644 (file)
Binary files a/16/exmmtest/EXMMTEST.PRJ and b/16/exmmtest/EXMMTEST.PRJ differ
diff --git a/16/exmmtest/ID_CA.C b/16/exmmtest/ID_CA.C
deleted file mode 100644 (file)
index bacb718..0000000
+++ /dev/null
@@ -1,2190 +0,0 @@
-/* Catacomb Apocalypse 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
-// ID_CA.C\r
-\r
-/*\r
-=============================================================================\r
-\r
-Id Software Caching Manager\r
----------------------------\r
-\r
-Must be started BEFORE the memory manager, because it needs to get the headers\r
-loaded into the data segment\r
-\r
-=============================================================================\r
-*/\r
-\r
-#include "ID_HEADS.H"\r
-#pragma hdrstop\r
-#include "ID_STRS.H"\r
-\r
-#pragma warn -pro\r
-#pragma warn -use\r
-\r
-#define THREEBYTEGRSTARTS\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                LOCAL CONSTANTS\r
-\r
-=============================================================================\r
-*/\r
-\r
-typedef struct\r
-{\r
-  unsigned bit0,bit1;  // 0-255 is a character, > is a pointer to a node\r
-} huffnode;\r
-\r
-\r
-typedef struct\r
-{\r
-       unsigned        RLEWtag;\r
-       long            headeroffsets[100];\r
-       byte            tileinfo[];\r
-} mapfiletype;\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                GLOBAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-byte           _seg    *tinf;\r
-int                    mapon;\r
-\r
-unsigned       _seg    *mapsegs[3];\r
-maptype                _seg    *mapheaderseg[NUMMAPS];\r
-byte           _seg    *audiosegs[NUMSNDCHUNKS];\r
-void           _seg    *grsegs[NUMCHUNKS];\r
-\r
-byte           far     grneeded[NUMCHUNKS];\r
-byte           ca_levelbit,ca_levelnum;\r
-\r
-int                    profilehandle,debughandle;\r
-\r
-void   (*drawcachebox)         (char *title, unsigned numcache);\r
-void   (*updatecachebox)       (void);\r
-void   (*finishcachebox)       (void);\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                LOCAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-extern long    far     CGAhead;\r
-extern long    far     EGAhead;\r
-extern byte    CGAdict;\r
-extern byte    EGAdict;\r
-extern byte    far     maphead;\r
-extern byte    mapdict;\r
-extern byte    far     audiohead;\r
-extern byte    audiodict;\r
-\r
-\r
-long           _seg *grstarts; // array of offsets in egagraph, -1 for sparse\r
-long           _seg *audiostarts;      // array of offsets in audio / audiot\r
-\r
-#ifdef GRHEADERLINKED\r
-huffnode       *grhuffman;\r
-#else\r
-huffnode       grhuffman[255];\r
-#endif\r
-\r
-#ifdef AUDIOHEADERLINKED\r
-huffnode       *audiohuffman;\r
-#else\r
-huffnode       audiohuffman[255];\r
-#endif\r
-\r
-\r
-int                    grhandle;               // handle to EGAGRAPH\r
-int                    maphandle;              // handle to MAPTEMP / GAMEMAPS\r
-int                    audiohandle;    // handle to AUDIOT / AUDIO\r
-\r
-long           chunkcomplen,chunkexplen;\r
-\r
-SDMode         oldsoundmode;\r
-\r
-\r
-\r
-void   CAL_DialogDraw (char *title,unsigned numcache);\r
-void   CAL_DialogUpdate (void);\r
-void   CAL_DialogFinish (void);\r
-void   CAL_CarmackExpand (unsigned far *source, unsigned far *dest,\r
-               unsigned length);\r
-\r
-\r
-#ifdef THREEBYTEGRSTARTS\r
-#define FILEPOSSIZE    3\r
-//#define      GRFILEPOS(c) (*(long far *)(((byte far *)grstarts)+(c)*3)&0xffffff)\r
-long GRFILEPOS(int c)\r
-{\r
-       long value;\r
-       int     offset;\r
-\r
-       offset = c*3;\r
-\r
-       value = *(long far *)(((byte far *)grstarts)+offset);\r
-\r
-       value &= 0x00ffffffl;\r
-\r
-       if (value == 0xffffffl)\r
-               value = -1;\r
-\r
-       return value;\r
-};\r
-#else\r
-#define FILEPOSSIZE    4\r
-#define        GRFILEPOS(c) (grstarts[c])\r
-#endif\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                          LOW LEVEL ROUTINES\r
-\r
-=============================================================================\r
-*/\r
-\r
-/*\r
-============================\r
-=\r
-= CA_OpenDebug / CA_CloseDebug\r
-=\r
-= Opens a binary file with the handle "debughandle"\r
-=\r
-============================\r
-*/\r
-\r
-void CA_OpenDebug (void)\r
-{\r
-       unlink ("DEBUG.TXT");\r
-       debughandle = open("DEBUG.TXT", O_CREAT | O_WRONLY | O_TEXT);\r
-}\r
-\r
-void CA_CloseDebug (void)\r
-{\r
-       close (debughandle);\r
-}\r
-\r
-\r
-\r
-/*\r
-============================\r
-=\r
-= CAL_GetGrChunkLength\r
-=\r
-= Gets the length of an explicit length chunk (not tiles)\r
-= The file pointer is positioned so the compressed data can be read in next.\r
-=\r
-============================\r
-*/\r
-\r
-void CAL_GetGrChunkLength (int chunk)\r
-{\r
-       lseek(grhandle,GRFILEPOS(chunk),SEEK_SET);\r
-       read(grhandle,&chunkexplen,sizeof(chunkexplen));\r
-       chunkcomplen = GRFILEPOS(chunk+1)-GRFILEPOS(chunk)-4;\r
-}\r
-\r
-\r
-/*\r
-==========================\r
-=\r
-= CA_FarRead\r
-=\r
-= Read from a file to a far pointer\r
-=\r
-==========================\r
-*/\r
-\r
-boolean CA_FarRead (int handle, byte far *dest, long length)\r
-{\r
-       if (length>0xffffl)\r
-               Quit ("CA_FarRead doesn't support 64K reads yet!");\r
-\r
-asm            push    ds\r
-asm            mov     bx,[handle]\r
-asm            mov     cx,[WORD PTR length]\r
-asm            mov     dx,[WORD PTR dest]\r
-asm            mov     ds,[WORD PTR dest+2]\r
-asm            mov     ah,0x3f                         // READ w/handle\r
-asm            int     21h\r
-asm            pop     ds\r
-asm            jnc     good\r
-       errno = _AX;\r
-       return  false;\r
-good:\r
-asm            cmp     ax,[WORD PTR length]\r
-asm            je      done\r
-       errno = EINVFMT;                        // user manager knows this is bad read\r
-       return  false;\r
-done:\r
-       return  true;\r
-}\r
-\r
-\r
-/*\r
-==========================\r
-=\r
-= CA_SegWrite\r
-=\r
-= Write from a file to a far pointer\r
-=\r
-==========================\r
-*/\r
-\r
-boolean CA_FarWrite (int handle, byte far *source, long length)\r
-{\r
-       if (length>0xffffl)\r
-               Quit ("CA_FarWrite doesn't support 64K reads yet!");\r
-\r
-asm            push    ds\r
-asm            mov     bx,[handle]\r
-asm            mov     cx,[WORD PTR length]\r
-asm            mov     dx,[WORD PTR source]\r
-asm            mov     ds,[WORD PTR source+2]\r
-asm            mov     ah,0x40                 // WRITE w/handle\r
-asm            int     21h\r
-asm            pop     ds\r
-asm            jnc     good\r
-       errno = _AX;\r
-       return  false;\r
-good:\r
-asm            cmp     ax,[WORD PTR length]\r
-asm            je      done\r
-       errno = ENOMEM;                         // user manager knows this is bad write\r
-       return  false;\r
-\r
-done:\r
-       return  true;\r
-}\r
-\r
-\r
-/*\r
-==========================\r
-=\r
-= CA_ReadFile\r
-=\r
-= Reads a file into an allready allocated buffer\r
-=\r
-==========================\r
-*/\r
-\r
-boolean CA_ReadFile (char *filename, memptr *ptr)\r
-{\r
-       int handle;\r
-       long size;\r
-\r
-       if ((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               return false;\r
-\r
-       size = filelength (handle);\r
-       if (!CA_FarRead (handle,*ptr,size))\r
-       {\r
-               close (handle);\r
-               return false;\r
-       }\r
-       close (handle);\r
-       return true;\r
-}\r
-\r
-\r
-\r
-/*\r
-==========================\r
-=\r
-= CA_LoadFile\r
-=\r
-= Allocate space for and load a file\r
-=\r
-==========================\r
-*/\r
-\r
-boolean CA_LoadFile (char *filename, memptr *ptr)\r
-{\r
-       int handle;\r
-       long size;\r
-\r
-       if ((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               return false;\r
-\r
-       size = filelength (handle);\r
-       MM_GetPtr (ptr,size);\r
-       if (!CA_FarRead (handle,*ptr,size))\r
-       {\r
-               close (handle);\r
-               return false;\r
-       }\r
-       close (handle);\r
-       return true;\r
-}\r
-\r
-/*\r
-============================================================================\r
-\r
-               COMPRESSION routines, see JHUFF.C for more\r
-\r
-============================================================================\r
-*/\r
-\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= CAL_OptimizeNodes\r
-=\r
-= Goes through a huffman table and changes the 256-511 node numbers to the\r
-= actular address of the node.  Must be called before CAL_HuffExpand\r
-=\r
-===============\r
-*/\r
-\r
-void CAL_OptimizeNodes (huffnode *table)\r
-{\r
-  huffnode *node;\r
-  int i;\r
-\r
-  node = table;\r
-\r
-  for (i=0;i<255;i++)\r
-  {\r
-       if (node->bit0 >= 256)\r
-         node->bit0 = (unsigned)(table+(node->bit0-256));\r
-       if (node->bit1 >= 256)\r
-         node->bit1 = (unsigned)(table+(node->bit1-256));\r
-       node++;\r
-  }\r
-}\r
-\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_HuffExpand\r
-=\r
-= Length is the length of the EXPANDED data\r
-=\r
-======================\r
-*/\r
-\r
-void CAL_HuffExpand (byte huge *source, byte huge *dest,\r
-  long length,huffnode *hufftable)\r
-{\r
-//  unsigned bit,byte,node,code;\r
-  unsigned sourceseg,sourceoff,destseg,destoff,endoff;\r
-  huffnode *headptr;\r
-//  huffnode *nodeon;\r
-\r
-  headptr = hufftable+254;     // head node is allways node 254\r
-\r
-  source++;    // normalize\r
-  source--;\r
-  dest++;\r
-  dest--;\r
-\r
-  sourceseg = FP_SEG(source);\r
-  sourceoff = FP_OFF(source);\r
-  destseg = FP_SEG(dest);\r
-  destoff = FP_OFF(dest);\r
-  endoff = destoff+length;\r
-\r
-//\r
-// ds:si source\r
-// es:di dest\r
-// ss:bx node pointer\r
-//\r
-\r
-       if (length <0xfff0)\r
-       {\r
-\r
-//--------------------------\r
-// expand less than 64k of data\r
-//--------------------------\r
-\r
-asm mov        bx,[headptr]\r
-\r
-asm    mov     si,[sourceoff]\r
-asm    mov     di,[destoff]\r
-asm    mov     es,[destseg]\r
-asm    mov     ds,[sourceseg]\r
-asm    mov     ax,[endoff]\r
-\r
-asm    mov     ch,[si]                         // load first byte\r
-asm    inc     si\r
-asm    mov     cl,1\r
-\r
-expandshort:\r
-asm    test    ch,cl                   // bit set?\r
-asm    jnz     bit1short\r
-asm    mov     dx,[ss:bx]                      // take bit0 path from node\r
-asm    shl     cl,1                            // advance to next bit position\r
-asm    jc      newbyteshort\r
-asm    jnc     sourceupshort\r
-\r
-bit1short:\r
-asm    mov     dx,[ss:bx+2]            // take bit1 path\r
-asm    shl     cl,1                            // advance to next bit position\r
-asm    jnc     sourceupshort\r
-\r
-newbyteshort:\r
-asm    mov     ch,[si]                         // load next byte\r
-asm    inc     si\r
-asm    mov     cl,1                            // back to first bit\r
-\r
-sourceupshort:\r
-asm    or      dh,dh                           // if dx<256 its a byte, else move node\r
-asm    jz      storebyteshort\r
-asm    mov     bx,dx                           // next node = (huffnode *)code\r
-asm    jmp     expandshort\r
-\r
-storebyteshort:\r
-asm    mov     [es:di],dl\r
-asm    inc     di                                      // write a decopmpressed byte out\r
-asm    mov     bx,[headptr]            // back to the head node for next bit\r
-\r
-asm    cmp     di,ax                           // done?\r
-asm    jne     expandshort\r
-       }\r
-       else\r
-       {\r
-\r
-//--------------------------\r
-// expand more than 64k of data\r
-//--------------------------\r
-\r
-  length--;\r
-\r
-asm mov        bx,[headptr]\r
-asm    mov     cl,1\r
-\r
-asm    mov     si,[sourceoff]\r
-asm    mov     di,[destoff]\r
-asm    mov     es,[destseg]\r
-asm    mov     ds,[sourceseg]\r
-\r
-asm    lodsb                   // load first byte\r
-\r
-expand:\r
-asm    test    al,cl           // bit set?\r
-asm    jnz     bit1\r
-asm    mov     dx,[ss:bx]      // take bit0 path from node\r
-asm    jmp     gotcode\r
-bit1:\r
-asm    mov     dx,[ss:bx+2]    // take bit1 path\r
-\r
-gotcode:\r
-asm    shl     cl,1            // advance to next bit position\r
-asm    jnc     sourceup\r
-asm    lodsb\r
-asm    cmp     si,0x10         // normalize ds:si\r
-asm    jb      sinorm\r
-asm    mov     cx,ds\r
-asm    inc     cx\r
-asm    mov     ds,cx\r
-asm    xor     si,si\r
-sinorm:\r
-asm    mov     cl,1            // back to first bit\r
-\r
-sourceup:\r
-asm    or      dh,dh           // if dx<256 its a byte, else move node\r
-asm    jz      storebyte\r
-asm    mov     bx,dx           // next node = (huffnode *)code\r
-asm    jmp     expand\r
-\r
-storebyte:\r
-asm    mov     [es:di],dl\r
-asm    inc     di              // write a decopmpressed byte out\r
-asm    mov     bx,[headptr]    // back to the head node for next bit\r
-\r
-asm    cmp     di,0x10         // normalize es:di\r
-asm    jb      dinorm\r
-asm    mov     dx,es\r
-asm    inc     dx\r
-asm    mov     es,dx\r
-asm    xor     di,di\r
-dinorm:\r
-\r
-asm    sub     [WORD PTR ss:length],1\r
-asm    jnc     expand\r
-asm    dec     [WORD PTR ss:length+2]\r
-asm    jns     expand          // when length = ffff ffff, done\r
-\r
-       }\r
-\r
-asm    mov     ax,ss\r
-asm    mov     ds,ax\r
-\r
-}\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_CarmackExpand\r
-=\r
-= Length is the length of the EXPANDED data\r
-=\r
-======================\r
-*/\r
-\r
-#define NEARTAG        0xa7\r
-#define FARTAG 0xa8\r
-\r
-void CAL_CarmackExpand (unsigned far *source, unsigned far *dest, unsigned length)\r
-{\r
-       unsigned        ch,chhigh,count,offset;\r
-       unsigned        far *copyptr, far *inptr, far *outptr;\r
-\r
-       length/=2;\r
-\r
-       inptr = source;\r
-       outptr = dest;\r
-\r
-       while (length)\r
-       {\r
-               ch = *inptr++;\r
-               chhigh = ch>>8;\r
-               if (chhigh == NEARTAG)\r
-               {\r
-                       count = ch&0xff;\r
-                       if (!count)\r
-                       {                               // have to insert a word containing the tag byte\r
-                               ch |= *((unsigned char far *)inptr)++;\r
-                               *outptr++ = ch;\r
-                               length--;\r
-                       }\r
-                       else\r
-                       {\r
-                               offset = *((unsigned char far *)inptr)++;\r
-                               copyptr = outptr - offset;\r
-                               length -= count;\r
-                               while (count--)\r
-                                       *outptr++ = *copyptr++;\r
-                       }\r
-               }\r
-               else if (chhigh == FARTAG)\r
-               {\r
-                       count = ch&0xff;\r
-                       if (!count)\r
-                       {                               // have to insert a word containing the tag byte\r
-                               ch |= *((unsigned char far *)inptr)++;\r
-                               *outptr++ = ch;\r
-                               length --;\r
-                       }\r
-                       else\r
-                       {\r
-                               offset = *inptr++;\r
-                               copyptr = dest + offset;\r
-                               length -= count;\r
-                               while (count--)\r
-                                       *outptr++ = *copyptr++;\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       *outptr++ = ch;\r
-                       length --;\r
-               }\r
-       }\r
-}\r
-\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CA_RLEWcompress\r
-=\r
-======================\r
-*/\r
-\r
-long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest,\r
-  unsigned rlewtag)\r
-{\r
-  long complength;\r
-  unsigned value,count,i;\r
-  unsigned huge *start,huge *end;\r
-\r
-  start = dest;\r
-\r
-  end = source + (length+1)/2;\r
-\r
-//\r
-// compress it\r
-//\r
-  do\r
-  {\r
-       count = 1;\r
-       value = *source++;\r
-       while (*source == value && source<end)\r
-       {\r
-         count++;\r
-         source++;\r
-       }\r
-       if (count>3 || value == rlewtag)\r
-       {\r
-    //\r
-    // send a tag / count / value string\r
-    //\r
-      *dest++ = rlewtag;\r
-      *dest++ = count;\r
-      *dest++ = value;\r
-    }\r
-    else\r
-    {\r
-    //\r
-    // send word without compressing\r
-    //\r
-      for (i=1;i<=count;i++)\r
-       *dest++ = value;\r
-       }\r
-\r
-  } while (source<end);\r
-\r
-  complength = 2*(dest-start);\r
-  return complength;\r
-}\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CA_RLEWexpand\r
-= length is EXPANDED length\r
-=\r
-======================\r
-*/\r
-\r
-void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length,\r
-  unsigned rlewtag)\r
-{\r
-//  unsigned value,count,i;\r
-  unsigned huge *end;\r
-  unsigned sourceseg,sourceoff,destseg,destoff,endseg,endoff;\r
-\r
-\r
-//\r
-// expand it\r
-//\r
-#if 0\r
-  do\r
-  {\r
-       value = *source++;\r
-       if (value != rlewtag)\r
-       //\r
-       // uncompressed\r
-       //\r
-         *dest++=value;\r
-       else\r
-       {\r
-       //\r
-       // compressed string\r
-       //\r
-         count = *source++;\r
-         value = *source++;\r
-         for (i=1;i<=count;i++)\r
-       *dest++ = value;\r
-       }\r
-  } while (dest<end);\r
-#endif\r
-\r
-  end = dest + (length)/2;\r
-  sourceseg = FP_SEG(source);\r
-  sourceoff = FP_OFF(source);\r
-  destseg = FP_SEG(dest);\r
-  destoff = FP_OFF(dest);\r
-  endseg = FP_SEG(end);\r
-  endoff = FP_OFF(end);\r
-\r
-\r
-//\r
-// ax = source value\r
-// bx = tag value\r
-// cx = repeat counts\r
-// dx = scratch\r
-//\r
-// NOTE: A repeat count that produces 0xfff0 bytes can blow this!\r
-//\r
-\r
-asm    mov     bx,rlewtag\r
-asm    mov     si,sourceoff\r
-asm    mov     di,destoff\r
-asm    mov     es,destseg\r
-asm    mov     ds,sourceseg\r
-\r
-expand:\r
-asm    lodsw\r
-asm    cmp     ax,bx\r
-asm    je      repeat\r
-asm    stosw\r
-asm    jmp     next\r
-\r
-repeat:\r
-asm    lodsw\r
-asm    mov     cx,ax           // repeat count\r
-asm    lodsw                   // repeat value\r
-asm    rep stosw\r
-\r
-next:\r
-\r
-asm    cmp     si,0x10         // normalize ds:si\r
-asm    jb      sinorm\r
-asm    mov     ax,si\r
-asm    shr     ax,1\r
-asm    shr     ax,1\r
-asm    shr     ax,1\r
-asm    shr     ax,1\r
-asm    mov     dx,ds\r
-asm    add     dx,ax\r
-asm    mov     ds,dx\r
-asm    and     si,0xf\r
-sinorm:\r
-asm    cmp     di,0x10         // normalize es:di\r
-asm    jb      dinorm\r
-asm    mov     ax,di\r
-asm    shr     ax,1\r
-asm    shr     ax,1\r
-asm    shr     ax,1\r
-asm    shr     ax,1\r
-asm    mov     dx,es\r
-asm    add     dx,ax\r
-asm    mov     es,dx\r
-asm    and     di,0xf\r
-dinorm:\r
-\r
-asm    cmp     di,ss:endoff\r
-asm    jne     expand\r
-asm    mov     ax,es\r
-asm    cmp     ax,ss:endseg\r
-asm    jb      expand\r
-\r
-asm    mov     ax,ss\r
-asm    mov     ds,ax\r
-\r
-}\r
-\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                        CACHE MANAGER ROUTINES\r
-\r
-=============================================================================\r
-*/\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_SetupGrFile\r
-=\r
-======================\r
-*/\r
-\r
-void CAL_SetupGrFile (void)\r
-{\r
-       int handle;\r
-       memptr compseg;\r
-\r
-#ifdef GRHEADERLINKED\r
-\r
-#if GRMODE == EGAGR\r
-       grhuffman = (huffnode *)&EGAdict;\r
-       grstarts = (long _seg *)FP_SEG(&EGAhead);\r
-#endif\r
-#if GRMODE == CGAGR\r
-       grhuffman = (huffnode *)&CGAdict;\r
-       grstarts = (long _seg *)FP_SEG(&CGAhead);\r
-#endif\r
-\r
-       CAL_OptimizeNodes (grhuffman);\r
-\r
-#else\r
-\r
-//\r
-// load ???dict.ext (huffman dictionary for graphics files)\r
-//\r
-\r
-       if ((handle = open(GREXT"DICT."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open "GREXT"DICT."EXT"!");\r
-\r
-       read(handle, &grhuffman, sizeof(grhuffman));\r
-       close(handle);\r
-       CAL_OptimizeNodes (grhuffman);\r
-//\r
-// load the data offsets from ???head.ext\r
-//\r
-       MM_GetPtr (&(memptr)grstarts,(NUMCHUNKS+1)*FILEPOSSIZE);\r
-\r
-       if ((handle = open(GREXT"HEAD."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open "GREXT"HEAD."EXT"!");\r
-\r
-       CA_FarRead(handle, (memptr)grstarts, (NUMCHUNKS+1)*FILEPOSSIZE);\r
-\r
-       close(handle);\r
-\r
-\r
-#endif\r
-\r
-//\r
-// Open the graphics file, leaving it open until the game is finished\r
-//\r
-       grhandle = open(GREXT"GRAPH."EXT, O_RDONLY | O_BINARY);\r
-       if (grhandle == -1)\r
-               Quit ("Cannot open "GREXT"GRAPH."EXT"!");\r
-\r
-\r
-//\r
-// load the pic and sprite headers into the arrays in the data segment\r
-//\r
-#if NUMPICS>0\r
-       MM_GetPtr(&(memptr)pictable,NUMPICS*sizeof(pictabletype));\r
-       CAL_GetGrChunkLength(STRUCTPIC);                // position file pointer\r
-       MM_GetPtr(&compseg,chunkcomplen);\r
-       CA_FarRead (grhandle,compseg,chunkcomplen);\r
-       CAL_HuffExpand (compseg, (byte huge *)pictable,NUMPICS*sizeof(pictabletype),grhuffman);\r
-       MM_FreePtr(&compseg);\r
-#endif\r
-\r
-#if NUMPICM>0\r
-       MM_GetPtr(&(memptr)picmtable,NUMPICM*sizeof(pictabletype));\r
-       CAL_GetGrChunkLength(STRUCTPICM);               // position file pointer\r
-       MM_GetPtr(&compseg,chunkcomplen);\r
-       CA_FarRead (grhandle,compseg,chunkcomplen);\r
-       CAL_HuffExpand (compseg, (byte huge *)picmtable,NUMPICS*sizeof(pictabletype),grhuffman);\r
-       MM_FreePtr(&compseg);\r
-#endif\r
-\r
-#if NUMSPRITES>0\r
-       MM_GetPtr(&(memptr)spritetable,NUMSPRITES*sizeof(spritetabletype));\r
-       CAL_GetGrChunkLength(STRUCTSPRITE);     // position file pointer\r
-       MM_GetPtr(&compseg,chunkcomplen);\r
-       CA_FarRead (grhandle,compseg,chunkcomplen);\r
-       CAL_HuffExpand (compseg, (byte huge *)spritetable,NUMSPRITES*sizeof(spritetabletype),grhuffman);\r
-       MM_FreePtr(&compseg);\r
-#endif\r
-\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_SetupMapFile\r
-=\r
-======================\r
-*/\r
-\r
-void CAL_SetupMapFile (void)\r
-{\r
-       int handle;\r
-       long length;\r
-\r
-//\r
-// load maphead.ext (offsets and tileinfo for map file)\r
-//\r
-#ifndef MAPHEADERLINKED\r
-       if ((handle = open("MAPHEAD."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open MAPHEAD."EXT"!");\r
-       length = filelength(handle);\r
-       MM_GetPtr (&(memptr)tinf,length);\r
-       CA_FarRead(handle, tinf, length);\r
-       close(handle);\r
-#else\r
-\r
-       tinf = (byte _seg *)FP_SEG(&maphead);\r
-\r
-#endif\r
-\r
-//\r
-// open the data file\r
-//\r
-#ifdef MAPHEADERLINKED\r
-       if ((maphandle = open("GAMEMAPS."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open GAMEMAPS."EXT"!");\r
-#else\r
-       if ((maphandle = open("MAPTEMP."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open MAPTEMP."EXT"!");\r
-#endif\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_SetupAudioFile\r
-=\r
-======================\r
-*/\r
-\r
-void CAL_SetupAudioFile (void)\r
-{\r
-       int handle;\r
-       long length;\r
-\r
-//\r
-// load maphead.ext (offsets and tileinfo for map file)\r
-//\r
-#ifndef AUDIOHEADERLINKED\r
-       if ((handle = open("AUDIOHED."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open AUDIOHED."EXT"!");\r
-       length = filelength(handle);\r
-       MM_GetPtr (&(memptr)audiostarts,length);\r
-       CA_FarRead(handle, (byte far *)audiostarts, length);\r
-       close(handle);\r
-#else\r
-       audiohuffman = (huffnode *)&audiodict;\r
-       CAL_OptimizeNodes (audiohuffman);\r
-       audiostarts = (long _seg *)FP_SEG(&audiohead);\r
-#endif\r
-\r
-//\r
-// open the data file\r
-//\r
-#ifndef AUDIOHEADERLINKED\r
-       if ((audiohandle = open("AUDIOT."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open AUDIOT."EXT"!");\r
-#else\r
-       if ((audiohandle = open("AUDIO."EXT,\r
-                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
-               Quit ("Can't open AUDIO."EXT"!");\r
-#endif\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CA_Startup\r
-=\r
-= Open all files and load in headers\r
-=\r
-======================\r
-*/\r
-\r
-void CA_Startup (void)\r
-{\r
-#ifdef PROFILE\r
-       unlink ("PROFILE.TXT");\r
-       profilehandle = open("PROFILE.TXT", O_CREAT | O_WRONLY | O_TEXT);\r
-#endif\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("AUDIO."EXT,NULL,2))\r
-               Quit("CA_Startup(): Can't find audio files.");\r
-//\r
-// MDM end\r
-\r
-#ifndef NOAUDIO\r
-       CAL_SetupAudioFile ();\r
-#endif\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("GAMEMAPS."EXT,NULL,1))\r
-               Quit("CA_Startup(): Can't find level files.");\r
-//\r
-// MDM end\r
-\r
-#ifndef NOMAPS\r
-       CAL_SetupMapFile ();\r
-#endif\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
-               Quit("CA_Startup(): Can't find graphics files.");\r
-//\r
-// MDM end\r
-\r
-#ifndef NOGRAPHICS\r
-       CAL_SetupGrFile ();\r
-#endif\r
-\r
-       mapon = -1;\r
-       ca_levelbit = 1;\r
-       ca_levelnum = 0;\r
-\r
-       drawcachebox    = CAL_DialogDraw;\r
-       updatecachebox  = CAL_DialogUpdate;\r
-       finishcachebox  = CAL_DialogFinish;\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CA_Shutdown\r
-=\r
-= Closes all files\r
-=\r
-======================\r
-*/\r
-\r
-void CA_Shutdown (void)\r
-{\r
-#ifdef PROFILE\r
-       close (profilehandle);\r
-#endif\r
-\r
-       close (maphandle);\r
-       close (grhandle);\r
-       close (audiohandle);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_CacheAudioChunk\r
-=\r
-======================\r
-*/\r
-\r
-void CA_CacheAudioChunk (int chunk)\r
-{\r
-       long    pos,compressed;\r
-#ifdef AUDIOHEADERLINKED\r
-       long    expanded;\r
-       memptr  bigbufferseg;\r
-       byte    far *source;\r
-#endif\r
-\r
-       if (audiosegs[chunk])\r
-       {\r
-               MM_SetPurge (&(memptr)audiosegs[chunk],0);\r
-               return;                                                 // allready in memory\r
-       }\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("AUDIO."EXT,NULL,2))\r
-               Quit("CA_CacheAudioChunk(): Can't find audio files.");\r
-//\r
-// MDM end\r
-\r
-//\r
-// load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
-// a larger buffer\r
-//\r
-       pos = audiostarts[chunk];\r
-       compressed = audiostarts[chunk+1]-pos;\r
-\r
-       lseek(audiohandle,pos,SEEK_SET);\r
-\r
-#ifndef AUDIOHEADERLINKED\r
-\r
-       MM_GetPtr (&(memptr)audiosegs[chunk],compressed);\r
-       if (mmerror)\r
-               return;\r
-\r
-       CA_FarRead(audiohandle,audiosegs[chunk],compressed);\r
-\r
-#else\r
-\r
-       if (compressed<=BUFFERSIZE)\r
-       {\r
-               CA_FarRead(audiohandle,bufferseg,compressed);\r
-               source = bufferseg;\r
-       }\r
-       else\r
-       {\r
-               MM_GetPtr(&bigbufferseg,compressed);\r
-               if (mmerror)\r
-                       return;\r
-               MM_SetLock (&bigbufferseg,true);\r
-               CA_FarRead(audiohandle,bigbufferseg,compressed);\r
-               source = bigbufferseg;\r
-       }\r
-\r
-       expanded = *(long far *)source;\r
-       source += 4;                    // skip over length\r
-       MM_GetPtr (&(memptr)audiosegs[chunk],expanded);\r
-       if (mmerror)\r
-               goto done;\r
-       CAL_HuffExpand (source,audiosegs[chunk],expanded,audiohuffman);\r
-\r
-done:\r
-       if (compressed>BUFFERSIZE)\r
-               MM_FreePtr(&bigbufferseg);\r
-#endif\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_LoadAllSounds\r
-=\r
-= Purges all sounds, then loads all new ones (mode switch)\r
-=\r
-======================\r
-*/\r
-\r
-void CA_LoadAllSounds (void)\r
-{\r
-       unsigned        start,i;\r
-\r
-       switch (oldsoundmode)\r
-       {\r
-       case sdm_Off:\r
-               goto cachein;\r
-       case sdm_PC:\r
-               start = STARTPCSOUNDS;\r
-               break;\r
-       case sdm_AdLib:\r
-               start = STARTADLIBSOUNDS;\r
-               break;\r
-       }\r
-\r
-       for (i=0;i<NUMSOUNDS;i++,start++)\r
-               if (audiosegs[start])\r
-                       MM_SetPurge (&(memptr)audiosegs[start],3);              // make purgable\r
-\r
-cachein:\r
-\r
-       switch (SoundMode)\r
-       {\r
-       case sdm_Off:\r
-               return;\r
-       case sdm_PC:\r
-               start = STARTPCSOUNDS;\r
-               break;\r
-       case sdm_AdLib:\r
-               start = STARTADLIBSOUNDS;\r
-               break;\r
-       }\r
-\r
-       for (i=0;i<NUMSOUNDS;i++,start++)\r
-               CA_CacheAudioChunk (start);\r
-\r
-       oldsoundmode = SoundMode;\r
-}\r
-\r
-//===========================================================================\r
-\r
-#if GRMODE == EGAGR\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_ShiftSprite\r
-=\r
-= Make a shifted (one byte wider) copy of a sprite into another area\r
-=\r
-======================\r
-*/\r
-\r
-unsigned       static  sheight,swidth;\r
-boolean static dothemask;\r
-\r
-void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,\r
-       unsigned width, unsigned height, unsigned pixshift, boolean domask)\r
-{\r
-\r
-       sheight = height;               // because we are going to reassign bp\r
-       swidth = width;\r
-       dothemask = domask;\r
-\r
-asm    mov     ax,[segment]\r
-asm    mov     ds,ax           // source and dest are in same segment, and all local\r
-\r
-asm    mov     bx,[source]\r
-asm    mov     di,[dest]\r
-\r
-asm    mov     bp,[pixshift]\r
-asm    shl     bp,1\r
-asm    mov     bp,WORD PTR [shifttabletable+bp]        // bp holds pointer to shift table\r
-\r
-asm    cmp     [ss:dothemask],0\r
-asm    je              skipmask\r
-\r
-//\r
-// table shift the mask\r
-//\r
-asm    mov     dx,[ss:sheight]\r
-\r
-domaskrow:\r
-\r
-asm    mov     BYTE PTR [di],255       // 0xff first byte\r
-asm    mov     cx,ss:[swidth]\r
-\r
-domaskbyte:\r
-\r
-asm    mov     al,[bx]                         // source\r
-asm    not     al\r
-asm    inc     bx                                      // next source byte\r
-asm    xor     ah,ah\r
-asm    shl     ax,1\r
-asm    mov     si,ax\r
-asm    mov     ax,[bp+si]                      // table shift into two bytes\r
-asm    not     ax\r
-asm    and     [di],al                         // and with first byte\r
-asm    inc     di\r
-asm    mov     [di],ah                         // replace next byte\r
-\r
-asm    loop    domaskbyte\r
-\r
-asm    inc     di                                      // the last shifted byte has 1s in it\r
-asm    dec     dx\r
-asm    jnz     domaskrow\r
-\r
-skipmask:\r
-\r
-//\r
-// table shift the data\r
-//\r
-asm    mov     dx,ss:[sheight]\r
-asm    shl     dx,1\r
-asm    shl     dx,1                            // four planes of data\r
-\r
-dodatarow:\r
-\r
-asm    mov     BYTE PTR [di],0         // 0 first byte\r
-asm    mov     cx,ss:[swidth]\r
-\r
-dodatabyte:\r
-\r
-asm    mov     al,[bx]                         // source\r
-asm    inc     bx                                      // next source byte\r
-asm    xor     ah,ah\r
-asm    shl     ax,1\r
-asm    mov     si,ax\r
-asm    mov     ax,[bp+si]                      // table shift into two bytes\r
-asm    or      [di],al                         // or with first byte\r
-asm    inc     di\r
-asm    mov     [di],ah                         // replace next byte\r
-\r
-asm    loop    dodatabyte\r
-\r
-asm    inc     di                                      // the last shifted byte has 0s in it\r
-asm    dec     dx\r
-asm    jnz     dodatarow\r
-\r
-//\r
-// done\r
-//\r
-\r
-asm    mov     ax,ss                           // restore data segment\r
-asm    mov     ds,ax\r
-\r
-}\r
-\r
-#endif\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_CacheSprite\r
-=\r
-= Generate shifts and set up sprite structure for a given sprite\r
-=\r
-======================\r
-*/\r
-\r
-void CAL_CacheSprite (int chunk, byte far *compressed)\r
-{\r
-       int i;\r
-       unsigned shiftstarts[5];\r
-       unsigned smallplane,bigplane,expanded;\r
-       spritetabletype far *spr;\r
-       spritetype _seg *dest;\r
-\r
-#if GRMODE == CGAGR\r
-//\r
-// CGA has no pel panning, so shifts are never needed\r
-//\r
-       spr = &spritetable[chunk-STARTSPRITES];\r
-       smallplane = spr->width*spr->height;\r
-       MM_GetPtr (&grsegs[chunk],smallplane*2+MAXSHIFTS*6);\r
-       if (mmerror)\r
-               return;\r
-       dest = (spritetype _seg *)grsegs[chunk];\r
-       dest->sourceoffset[0] = MAXSHIFTS*6;    // start data after 3 unsigned tables\r
-       dest->planesize[0] = smallplane;\r
-       dest->width[0] = spr->width;\r
-\r
-//\r
-// expand the unshifted shape\r
-//\r
-       CAL_HuffExpand (compressed, &dest->data[0],smallplane*2,grhuffman);\r
-\r
-#endif\r
-\r
-\r
-#if GRMODE == EGAGR\r
-\r
-//\r
-// calculate sizes\r
-//\r
-       spr = &spritetable[chunk-STARTSPRITES];\r
-       smallplane = spr->width*spr->height;\r
-       bigplane = (spr->width+1)*spr->height;\r
-\r
-       shiftstarts[0] = MAXSHIFTS*6;   // start data after 3 unsigned tables\r
-       shiftstarts[1] = shiftstarts[0] + smallplane*5; // 5 planes in a sprite\r
-       shiftstarts[2] = shiftstarts[1] + bigplane*5;\r
-       shiftstarts[3] = shiftstarts[2] + bigplane*5;\r
-       shiftstarts[4] = shiftstarts[3] + bigplane*5;   // nothing ever put here\r
-\r
-       expanded = shiftstarts[spr->shifts];\r
-       MM_GetPtr (&grsegs[chunk],expanded);\r
-       if (mmerror)\r
-               return;\r
-       dest = (spritetype _seg *)grsegs[chunk];\r
-\r
-//\r
-// expand the unshifted shape\r
-//\r
-       CAL_HuffExpand (compressed, &dest->data[0],smallplane*5,grhuffman);\r
-\r
-//\r
-// make the shifts!\r
-//\r
-       switch (spr->shifts)\r
-       {\r
-       case    1:\r
-               for (i=0;i<4;i++)\r
-               {\r
-                       dest->sourceoffset[i] = shiftstarts[0];\r
-                       dest->planesize[i] = smallplane;\r
-                       dest->width[i] = spr->width;\r
-               }\r
-               break;\r
-\r
-       case    2:\r
-               for (i=0;i<2;i++)\r
-               {\r
-                       dest->sourceoffset[i] = shiftstarts[0];\r
-                       dest->planesize[i] = smallplane;\r
-                       dest->width[i] = spr->width;\r
-               }\r
-               for (i=2;i<4;i++)\r
-               {\r
-                       dest->sourceoffset[i] = shiftstarts[1];\r
-                       dest->planesize[i] = bigplane;\r
-                       dest->width[i] = spr->width+1;\r
-               }\r
-               CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
-                       dest->sourceoffset[2],spr->width,spr->height,4,true);\r
-               break;\r
-\r
-       case    4:\r
-               dest->sourceoffset[0] = shiftstarts[0];\r
-               dest->planesize[0] = smallplane;\r
-               dest->width[0] = spr->width;\r
-\r
-               dest->sourceoffset[1] = shiftstarts[1];\r
-               dest->planesize[1] = bigplane;\r
-               dest->width[1] = spr->width+1;\r
-               CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
-                       dest->sourceoffset[1],spr->width,spr->height,2,true);\r
-\r
-               dest->sourceoffset[2] = shiftstarts[2];\r
-               dest->planesize[2] = bigplane;\r
-               dest->width[2] = spr->width+1;\r
-               CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
-                       dest->sourceoffset[2],spr->width,spr->height,4,true);\r
-\r
-               dest->sourceoffset[3] = shiftstarts[3];\r
-               dest->planesize[3] = bigplane;\r
-               dest->width[3] = spr->width+1;\r
-               CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
-                       dest->sourceoffset[3],spr->width,spr->height,6,true);\r
-\r
-               break;\r
-\r
-       default:\r
-               Quit ("CAL_CacheSprite: Bad shifts number!");\r
-       }\r
-\r
-#endif\r
-}\r
-\r
-//===========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_ExpandGrChunk\r
-=\r
-= Does whatever is needed with a pointer to a compressed chunk\r
-=\r
-======================\r
-*/\r
-\r
-void CAL_ExpandGrChunk (int chunk, byte far *source)\r
-{\r
-       long    expanded;\r
-\r
-\r
-       if (chunk >= STARTTILE8 && chunk < STARTEXTERNS)\r
-       {\r
-       //\r
-       // expanded sizes of tile8/16/32 are implicit\r
-       //\r
-\r
-#if GRMODE == EGAGR\r
-#define BLOCK          32\r
-#define MASKBLOCK      40\r
-#endif\r
-\r
-#if GRMODE == CGAGR\r
-#define BLOCK          16\r
-#define MASKBLOCK      32\r
-#endif\r
-\r
-               if (chunk<STARTTILE8M)                  // tile 8s are all in one chunk!\r
-                       expanded = BLOCK*NUMTILE8;\r
-               else if (chunk<STARTTILE16)\r
-                       expanded = MASKBLOCK*NUMTILE8M;\r
-               else if (chunk<STARTTILE16M)    // all other tiles are one/chunk\r
-                       expanded = BLOCK*4;\r
-               else if (chunk<STARTTILE32)\r
-                       expanded = MASKBLOCK*4;\r
-               else if (chunk<STARTTILE32M)\r
-                       expanded = BLOCK*16;\r
-               else\r
-                       expanded = MASKBLOCK*16;\r
-       }\r
-       else\r
-       {\r
-       //\r
-       // everything else has an explicit size longword\r
-       //\r
-               expanded = *(long far *)source;\r
-               source += 4;                    // skip over length\r
-       }\r
-\r
-//\r
-// allocate final space, decompress it, and free bigbuffer\r
-// Sprites need to have shifts made and various other junk\r
-//\r
-       if (chunk>=STARTSPRITES && chunk< STARTTILE8)\r
-               CAL_CacheSprite(chunk,source);\r
-       else\r
-       {\r
-               MM_GetPtr (&grsegs[chunk],expanded);\r
-               if (mmerror)\r
-                       return;\r
-               CAL_HuffExpand (source,grsegs[chunk],expanded,grhuffman);\r
-       }\r
-}\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_ReadGrChunk\r
-=\r
-= Gets a chunk off disk, optimizing reads to general buffer\r
-=\r
-======================\r
-*/\r
-\r
-void CAL_ReadGrChunk (int chunk)\r
-{\r
-       long    pos,compressed;\r
-       memptr  bigbufferseg;\r
-       byte    far *source;\r
-       int             next;\r
-\r
-//\r
-// load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
-// a larger buffer\r
-//\r
-       pos = GRFILEPOS(chunk);\r
-       if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
-         return;\r
-\r
-       next = chunk +1;\r
-       while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
-               next++;\r
-\r
-       compressed = GRFILEPOS(next)-pos;\r
-\r
-       lseek(grhandle,pos,SEEK_SET);\r
-\r
-       if (compressed<=BUFFERSIZE)\r
-       {\r
-               CA_FarRead(grhandle,bufferseg,compressed);\r
-               source = bufferseg;\r
-       }\r
-       else\r
-       {\r
-               MM_GetPtr(&bigbufferseg,compressed);\r
-               if (mmerror)\r
-                       return;\r
-               MM_SetLock (&bigbufferseg,true);\r
-               CA_FarRead(grhandle,bigbufferseg,compressed);\r
-               source = bigbufferseg;\r
-       }\r
-\r
-       CAL_ExpandGrChunk (chunk,source);\r
-\r
-       if (compressed>BUFFERSIZE)\r
-               MM_FreePtr(&bigbufferseg);\r
-}\r
-\r
-/*\r
-======================\r
-=\r
-= CA_CacheGrChunk\r
-=\r
-= Makes sure a given chunk is in memory, loadiing it if needed\r
-=\r
-======================\r
-*/\r
-\r
-void CA_CacheGrChunk (int chunk)\r
-{\r
-       long    pos,compressed;\r
-       memptr  bigbufferseg;\r
-       byte    far *source;\r
-       int             next;\r
-\r
-       grneeded[chunk] |= ca_levelbit;         // make sure it doesn't get removed\r
-       if (grsegs[chunk])\r
-       {\r
-               MM_SetPurge (&grsegs[chunk],0);\r
-               return;                                                 // allready in memory\r
-       }\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
-               Quit("CA_CacheGrChunk(): Can't find graphics files.");\r
-//\r
-// MDM end\r
-\r
-//\r
-// load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
-// a larger buffer\r
-//\r
-       pos = GRFILEPOS(chunk);\r
-       if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
-         return;\r
-\r
-       next = chunk +1;\r
-       while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
-               next++;\r
-\r
-       compressed = GRFILEPOS(next)-pos;\r
-\r
-       lseek(grhandle,pos,SEEK_SET);\r
-\r
-       if (compressed<=BUFFERSIZE)\r
-       {\r
-               CA_FarRead(grhandle,bufferseg,compressed);\r
-               source = bufferseg;\r
-       }\r
-       else\r
-       {\r
-               MM_GetPtr(&bigbufferseg,compressed);\r
-               MM_SetLock (&bigbufferseg,true);\r
-               CA_FarRead(grhandle,bigbufferseg,compressed);\r
-               source = bigbufferseg;\r
-       }\r
-\r
-       CAL_ExpandGrChunk (chunk,source);\r
-\r
-       if (compressed>BUFFERSIZE)\r
-               MM_FreePtr(&bigbufferseg);\r
-}\r
-\r
-\r
-\r
-//==========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_CacheMap\r
-=\r
-======================\r
-*/\r
-\r
-void CA_CacheMap (int mapnum)\r
-{\r
-       long    pos,compressed;\r
-       int             plane;\r
-       memptr  *dest,bigbufferseg;\r
-       unsigned        size;\r
-       unsigned        far     *source;\r
-#ifdef MAPHEADERLINKED\r
-       memptr  buffer2seg;\r
-       long    expanded;\r
-#endif\r
-\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("GAMEMAPS."EXT,NULL,1))\r
-               Quit("CA_CacheMap(): Can't find level files.");\r
-//\r
-// MDM end\r
-\r
-\r
-//\r
-// free up memory from last map\r
-//\r
-       if (mapon>-1 && mapheaderseg[mapon])\r
-               MM_SetPurge (&(memptr)mapheaderseg[mapon],3);\r
-       for (plane=0;plane<MAPPLANES;plane++)\r
-               if (mapsegs[plane])\r
-                       MM_FreePtr (&(memptr)mapsegs[plane]);\r
-\r
-       mapon = mapnum;\r
-\r
-\r
-//\r
-// load map header\r
-// The header will be cached if it is still around\r
-//\r
-       if (!mapheaderseg[mapnum])\r
-       {\r
-               pos = ((mapfiletype     _seg *)tinf)->headeroffsets[mapnum];\r
-               if (pos<0)                                              // $FFFFFFFF start is a sparse map\r
-                 Quit ("CA_CacheMap: Tried to load a non existent map!");\r
-\r
-               MM_GetPtr(&(memptr)mapheaderseg[mapnum],sizeof(maptype));\r
-               lseek(maphandle,pos,SEEK_SET);\r
-               CA_FarRead (maphandle,(memptr)mapheaderseg[mapnum],sizeof(maptype));\r
-       }\r
-       else\r
-               MM_SetPurge (&(memptr)mapheaderseg[mapnum],0);\r
-\r
-//\r
-// load the planes in\r
-// If a plane's pointer still exists it will be overwritten (levels are\r
-// allways reloaded, never cached)\r
-//\r
-\r
-       size = mapheaderseg[mapnum]->width * mapheaderseg[mapnum]->height * 2;\r
-\r
-       for (plane = 0; plane<MAPPLANES; plane++)\r
-       {\r
-               pos = mapheaderseg[mapnum]->planestart[plane];\r
-               compressed = mapheaderseg[mapnum]->planelength[plane];\r
-\r
-               if (!compressed)\r
-                       continue;               // the plane is not used in this game\r
-\r
-               dest = &(memptr)mapsegs[plane];\r
-               MM_GetPtr(dest,size);\r
-\r
-               lseek(maphandle,pos,SEEK_SET);\r
-               if (compressed<=BUFFERSIZE)\r
-                       source = bufferseg;\r
-               else\r
-               {\r
-                       MM_GetPtr(&bigbufferseg,compressed);\r
-                       MM_SetLock (&bigbufferseg,true);\r
-                       source = bigbufferseg;\r
-               }\r
-\r
-               CA_FarRead(maphandle,(byte far *)source,compressed);\r
-#ifdef MAPHEADERLINKED\r
-               //\r
-               // unhuffman, then unRLEW\r
-               // The huffman'd chunk has a two byte expanded length first\r
-               // The resulting RLEW chunk also does, even though it's not really\r
-               // needed\r
-               //\r
-               expanded = *source;\r
-               source++;\r
-               MM_GetPtr (&buffer2seg,expanded);\r
-               CAL_CarmackExpand (source, (unsigned far *)buffer2seg,expanded);\r
-               CA_RLEWexpand (((unsigned far *)buffer2seg)+1,*dest,size,\r
-               ((mapfiletype _seg *)tinf)->RLEWtag);\r
-               MM_FreePtr (&buffer2seg);\r
-\r
-#else\r
-               //\r
-               // unRLEW, skipping expanded length\r
-               //\r
-               CA_RLEWexpand (source+1, *dest,size,\r
-               ((mapfiletype _seg *)tinf)->RLEWtag);\r
-#endif\r
-\r
-               if (compressed>BUFFERSIZE)\r
-                       MM_FreePtr(&bigbufferseg);\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_UpLevel\r
-=\r
-= Goes up a bit level in the needed lists and clears it out.\r
-= Everything is made purgable\r
-=\r
-======================\r
-*/\r
-\r
-void CA_UpLevel (void)\r
-{\r
-       if (ca_levelnum==7)\r
-               Quit ("CA_UpLevel: Up past level 7!");\r
-\r
-       ca_levelbit<<=1;\r
-       ca_levelnum++;\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_DownLevel\r
-=\r
-= Goes down a bit level in the needed lists and recaches\r
-= everything from the lower level\r
-=\r
-======================\r
-*/\r
-\r
-void CA_DownLevel (void)\r
-{\r
-       if (!ca_levelnum)\r
-               Quit ("CA_DownLevel: Down past level 0!");\r
-       ca_levelbit>>=1;\r
-       ca_levelnum--;\r
-       CA_CacheMarks(NULL);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_ClearMarks\r
-=\r
-= Clears out all the marks at the current level\r
-=\r
-======================\r
-*/\r
-\r
-void CA_ClearMarks (void)\r
-{\r
-       int i;\r
-\r
-       for (i=0;i<NUMCHUNKS;i++)\r
-               grneeded[i]&=~ca_levelbit;\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_ClearAllMarks\r
-=\r
-= Clears out all the marks on all the levels\r
-=\r
-======================\r
-*/\r
-\r
-void CA_ClearAllMarks (void)\r
-{\r
-       _fmemset (grneeded,0,sizeof(grneeded));\r
-       ca_levelbit = 1;\r
-       ca_levelnum = 0;\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_FreeGraphics\r
-=\r
-======================\r
-*/\r
-\r
-void CA_FreeGraphics (void)\r
-{\r
-       int     i;\r
-\r
-       for (i=0;i<NUMCHUNKS;i++)\r
-               if (grsegs[i])\r
-                       MM_SetPurge (&(memptr)grsegs[i],3);\r
-}\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CA_SetAllPurge\r
-=\r
-= Make everything possible purgable\r
-=\r
-======================\r
-*/\r
-\r
-void CA_SetAllPurge (void)\r
-{\r
-       int i;\r
-\r
-       CA_ClearMarks ();\r
-\r
-//\r
-// free cursor sprite and background save\r
-//\r
-       VW_FreeCursor ();\r
-\r
-//\r
-// free map headers and map planes\r
-//\r
-       for (i=0;i<NUMMAPS;i++)\r
-               if (mapheaderseg[i])\r
-                       MM_SetPurge (&(memptr)mapheaderseg[i],3);\r
-\r
-       for (i=0;i<3;i++)\r
-               if (mapsegs[i])\r
-                       MM_FreePtr (&(memptr)mapsegs[i]);\r
-\r
-//\r
-// free sounds\r
-//\r
-       for (i=0;i<NUMSNDCHUNKS;i++)\r
-               if (audiosegs[i])\r
-                       MM_SetPurge (&(memptr)audiosegs[i],3);\r
-\r
-//\r
-// free graphics\r
-//\r
-       CA_FreeGraphics ();\r
-}\r
-\r
-\r
-void CA_SetGrPurge (void)\r
-{\r
-       int i;\r
-\r
-//\r
-// free graphics\r
-//\r
-       for (i=0;i<NUMCHUNKS;i++)\r
-               if (grsegs[i])\r
-                       MM_SetPurge (&(memptr)grsegs[i],3);\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_DialogDraw\r
-=\r
-======================\r
-*/\r
-\r
-#define NUMBARS        (17l*8)\r
-#define BARSTEP        8\r
-\r
-unsigned       thx,thy,lastx;\r
-long           barx,barstep;\r
-\r
-void   CAL_DialogDraw (char *title,unsigned numcache)\r
-{\r
-       unsigned        homex,homey,x;\r
-\r
-       barstep = (NUMBARS<<16)/numcache;\r
-\r
-//\r
-// draw dialog window (masked tiles 12 - 20 are window borders)\r
-//\r
-       US_CenterWindow (20,8);\r
-       homex = PrintX;\r
-       homey = PrintY;\r
-\r
-       US_CPrint ("Loading");\r
-       fontcolor = F_SECONDCOLOR;\r
-       US_CPrint (title);\r
-       fontcolor = F_BLACK;\r
-\r
-//\r
-// draw thermometer bar\r
-//\r
-       thx = homex + 8;\r
-       thy = homey + 32;\r
-       VWB_DrawTile8(thx,thy,0);               // CAT3D numbers\r
-       VWB_DrawTile8(thx,thy+8,3);\r
-       VWB_DrawTile8(thx,thy+16,6);\r
-       VWB_DrawTile8(thx+17*8,thy,2);\r
-       VWB_DrawTile8(thx+17*8,thy+8,5);\r
-       VWB_DrawTile8(thx+17*8,thy+16,8);\r
-       for (x=thx+8;x<thx+17*8;x+=8)\r
-       {\r
-               VWB_DrawTile8(x,thy,1);\r
-               VWB_DrawTile8(x,thy+8,4);\r
-               VWB_DrawTile8(x,thy+16,7);\r
-       }\r
-\r
-       thx += 4;               // first line location\r
-       thy += 5;\r
-       barx = (long)thx<<16;\r
-       lastx = thx;\r
-\r
-       VW_UpdateScreen();\r
-}\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_DialogUpdate\r
-=\r
-======================\r
-*/\r
-\r
-void   CAL_DialogUpdate (void)\r
-{\r
-       unsigned        x,xh;\r
-\r
-       barx+=barstep;\r
-       xh = barx>>16;\r
-       if (xh - lastx > BARSTEP)\r
-       {\r
-               for (x=lastx;x<=xh;x++)\r
-#if GRMODE == EGAGR\r
-                       VWB_Vlin (thy,thy+13,x,14);\r
-#endif\r
-#if GRMODE == CGAGR\r
-                       VWB_Vlin (thy,thy+13,x,SECONDCOLOR);\r
-#endif\r
-               lastx = xh;\r
-               VW_UpdateScreen();\r
-       }\r
-}\r
-\r
-/*\r
-======================\r
-=\r
-= CAL_DialogFinish\r
-=\r
-======================\r
-*/\r
-\r
-void   CAL_DialogFinish (void)\r
-{\r
-       unsigned        x,xh;\r
-\r
-       xh = thx + NUMBARS;\r
-       for (x=lastx;x<=xh;x++)\r
-#if GRMODE == EGAGR\r
-               VWB_Vlin (thy,thy+13,x,14);\r
-#endif\r
-#if GRMODE == CGAGR\r
-               VWB_Vlin (thy,thy+13,x,SECONDCOLOR);\r
-#endif\r
-       VW_UpdateScreen();\r
-\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CA_CacheMarks\r
-=\r
-======================\r
-*/\r
-#define MAXEMPTYREAD   1024\r
-\r
-void CA_CacheMarks (char *title)\r
-{\r
-       boolean dialog;\r
-       int     i,next,numcache;\r
-       long    pos,endpos,nextpos,nextendpos,compressed;\r
-       long    bufferstart,bufferend;  // file position of general buffer\r
-       byte    far *source;\r
-       memptr  bigbufferseg;\r
-\r
-       dialog = (title!=NULL);\r
-\r
-       numcache = 0;\r
-//\r
-// go through and make everything not needed purgable\r
-//\r
-       for (i=0;i<NUMCHUNKS;i++)\r
-               if (grneeded[i]&ca_levelbit)\r
-               {\r
-                       if (grsegs[i])                                  // its allready in memory, make\r
-                               MM_SetPurge(&grsegs[i],0);      // sure it stays there!\r
-                       else\r
-                               numcache++;\r
-               }\r
-               else\r
-               {\r
-                       if (grsegs[i])                                  // not needed, so make it purgeable\r
-                               MM_SetPurge(&grsegs[i],3);\r
-               }\r
-\r
-       if (!numcache)                  // nothing to cache!\r
-               return;\r
-\r
-// MDM begin - (GAMERS EDGE)\r
-//\r
-       if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
-               Quit("CA_CacheMarks(): Can't find graphics files.");\r
-//\r
-// MDM end\r
-\r
-       if (dialog)\r
-       {\r
-#ifdef PROFILE\r
-               write(profilehandle,title,strlen(title));\r
-               write(profilehandle,"\n",1);\r
-#endif\r
-               if (drawcachebox)\r
-                       drawcachebox(title,numcache);\r
-       }\r
-\r
-//\r
-// go through and load in anything still needed\r
-//\r
-       bufferstart = bufferend = 0;            // nothing good in buffer now\r
-\r
-       for (i=0;i<NUMCHUNKS;i++)\r
-               if ( (grneeded[i]&ca_levelbit) && !grsegs[i])\r
-               {\r
-//\r
-// update thermometer\r
-//\r
-                       if (dialog && updatecachebox)\r
-                               updatecachebox ();\r
-\r
-                       pos = GRFILEPOS(i);\r
-                       if (pos<0)\r
-                               continue;\r
-\r
-                       next = i +1;\r
-                       while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
-                               next++;\r
-\r
-                       compressed = GRFILEPOS(next)-pos;\r
-                       endpos = pos+compressed;\r
-\r
-                       if (compressed<=BUFFERSIZE)\r
-                       {\r
-                               if (bufferstart<=pos\r
-                               && bufferend>= endpos)\r
-                               {\r
-                               // data is allready in buffer\r
-                                       source = (byte _seg *)bufferseg+(pos-bufferstart);\r
-                               }\r
-                               else\r
-                               {\r
-                               // load buffer with a new block from disk\r
-                               // try to get as many of the needed blocks in as possible\r
-                                       while ( next < NUMCHUNKS )\r
-                                       {\r
-                                               while (next < NUMCHUNKS &&\r
-                                               !(grneeded[next]&ca_levelbit && !grsegs[next]))\r
-                                                       next++;\r
-                                               if (next == NUMCHUNKS)\r
-                                                       continue;\r
-\r
-                                               nextpos = GRFILEPOS(next);\r
-                                               while (GRFILEPOS(++next) == -1) // skip past any sparse tiles\r
-                                                       ;\r
-                                               nextendpos = GRFILEPOS(next);\r
-                                               if (nextpos - endpos <= MAXEMPTYREAD\r
-                                               && nextendpos-pos <= BUFFERSIZE)\r
-                                                       endpos = nextendpos;\r
-                                               else\r
-                                                       next = NUMCHUNKS;                       // read pos to posend\r
-                                       }\r
-\r
-                                       lseek(grhandle,pos,SEEK_SET);\r
-                                       CA_FarRead(grhandle,bufferseg,endpos-pos);\r
-                                       bufferstart = pos;\r
-                                       bufferend = endpos;\r
-                                       source = bufferseg;\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                       // big chunk, allocate temporary buffer\r
-                               MM_GetPtr(&bigbufferseg,compressed);\r
-                               if (mmerror)\r
-                                       return;\r
-                               MM_SetLock (&bigbufferseg,true);\r
-                               lseek(grhandle,pos,SEEK_SET);\r
-                               CA_FarRead(grhandle,bigbufferseg,compressed);\r
-                               source = bigbufferseg;\r
-                       }\r
-\r
-                       CAL_ExpandGrChunk (i,source);\r
-                       if (mmerror)\r
-                               return;\r
-\r
-                       if (compressed>BUFFERSIZE)\r
-                               MM_FreePtr(&bigbufferseg);\r
-\r
-               }\r
-\r
-//\r
-// finish up any thermometer remnants\r
-//\r
-               if (dialog && finishcachebox)\r
-                       finishcachebox();\r
-}\r
-\r
diff --git a/16/exmmtest/ID_CA.H b/16/exmmtest/ID_CA.H
deleted file mode 100644 (file)
index 380ae29..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Catacomb Apocalypse 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
-// ID_CA.H\r
-\r
-#ifndef __TYPES__\r
-#include "ID_TYPES.H"\r
-#endif\r
-\r
-#ifndef __ID_MM__\r
-#include "ID_MM.H"\r
-#endif\r
-\r
-#ifndef __ID_GLOB__\r
-#include "ID_GLOB.H"\r
-#endif\r
-\r
-#define __ID_CA__\r
-\r
-//===========================================================================\r
-\r
-//#define NOMAPS\r
-//#define NOGRAPHICS\r
-//#define NOAUDIO\r
-\r
-#define MAPHEADERLINKED\r
-#define GRHEADERLINKED\r
-#define AUDIOHEADERLINKED\r
-\r
-#define NUMMAPS                39\r
-#define MAPPLANES              3\r
-\r
-//===========================================================================\r
-\r
-typedef        struct\r
-{\r
-       long            planestart[3];\r
-       unsigned        planelength[3];\r
-       unsigned        width,height;\r
-       char            name[16];\r
-} maptype;\r
-\r
-//===========================================================================\r
-\r
-extern byte            _seg    *tinf;\r
-extern int                     mapon;\r
-\r
-extern unsigned        _seg    *mapsegs[3];\r
-extern maptype         _seg    *mapheaderseg[NUMMAPS];\r
-extern byte            _seg    *audiosegs[NUMSNDCHUNKS];\r
-extern void            _seg    *grsegs[NUMCHUNKS];\r
-\r
-extern byte            far     grneeded[NUMCHUNKS];\r
-extern byte            ca_levelbit,ca_levelnum;\r
-\r
-extern char            *titleptr[8];\r
-\r
-extern int                     profilehandle,debughandle;\r
-\r
-//\r
-// hooks for custom cache dialogs\r
-//\r
-extern void    (*drawcachebox)         (char *title, unsigned numcache);\r
-extern void    (*updatecachebox)       (void);\r
-extern void    (*finishcachebox)       (void);\r
-\r
-//===========================================================================\r
-\r
-// just for the score box reshifting\r
-\r
-void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,\r
-       unsigned width, unsigned height, unsigned pixshift, boolean domask);\r
-\r
-//===========================================================================\r
-\r
-void CA_OpenDebug (void);\r
-void CA_CloseDebug (void);\r
-boolean CA_FarRead (int handle, byte far *dest, long length);\r
-boolean CA_FarWrite (int handle, byte far *source, long length);\r
-boolean CA_ReadFile (char *filename, memptr *ptr);\r
-boolean CA_LoadFile (char *filename, memptr *ptr);\r
-\r
-long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest,\r
-  unsigned rlewtag);\r
-\r
-void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length,\r
-  unsigned rlewtag);\r
-\r
-void CA_Startup (void);\r
-void CA_Shutdown (void);\r
-\r
-void CA_CacheAudioChunk (int chunk);\r
-void CA_LoadAllSounds (void);\r
-\r
-void CA_UpLevel (void);\r
-void CA_DownLevel (void);\r
-\r
-void CA_SetAllPurge (void);\r
-\r
-void CA_ClearMarks (void);\r
-void CA_ClearAllMarks (void);\r
-\r
-#define CA_MarkGrChunk(chunk)  grneeded[chunk]|=ca_levelbit\r
-\r
-void CA_CacheGrChunk (int chunk);\r
-void CA_CacheMap (int mapnum);\r
-\r
-void CA_CacheMarks (char *title);\r
-\r
diff --git a/16/exmmtest/ID_MM.C b/16/exmmtest/ID_MM.C
deleted file mode 100644 (file)
index 4f01d8d..0000000
+++ /dev/null
@@ -1,1146 +0,0 @@
-/* Catacomb Apocalypse 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 "ID_HEADS.H"\r
-#pragma hdrstop\r
-\r
-#pragma warn -pro\r
-#pragma warn -use\r
-\r
-\r
-#if 0          // 1 == Debug/Dev  ;  0 == Production/final\r
-\r
-#define OUT_OF_MEM_MSG "MM_GetPtr: Out of memory!\nYou were short :%ld bytes"\r
-\r
-#else\r
-\r
-\r
-#define OUT_OF_MEM_MSG "\n"                                                                          \\r
-                                                               "You need more memory to run CATACOMB APOCALYPSE.  Read the INSTRUCTION\n"   \\r
-                                                               "section of the START program for tips on getting more memory.\n"\r
-#endif\r
-\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!")\\r
-//     ;mmfree=mmfree->next;}\r
-\r
-#define GETNEWBLOCK {if(!mmfree)MML_ClearBlock();mmnew=mmfree;mmfree=mmfree->next;}\r
-\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 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
-// 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
-//==========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= MML_CheckForEMS\r
-=\r
-= Routine from p36 of Extending DOS\r
-=\r
-=======================\r
-*/\r
-\r
-char   emmname[9] = "EMMXXXX0";\r
-\r
-boolean MML_CheckForEMS (void)\r
-{\r
-asm    mov     dx,OFFSET emmname[0]\r
-asm    mov     ax,0x3d00\r
-asm    int     0x21            // try to open EMMXXXX0 device\r
-asm    jc      error\r
-\r
-asm    mov     bx,ax\r
-asm    mov     ax,0x4400\r
-\r
-asm    int     0x21            // get device info\r
-asm    jc      error\r
-\r
-asm    and     dx,0x80\r
-asm    jz      error\r
-\r
-asm    mov     ax,0x4407\r
-\r
-asm    int     0x21            // get status\r
-asm    jc      error\r
-asm    or      al,al\r
-asm    jz      error\r
-\r
-asm    mov     ah,0x3e\r
-asm    int     0x21            // close handle\r
-asm    jc      error\r
-\r
-//\r
-// EMS is good\r
-//\r
-  return true;\r
-\r
-error:\r
-//\r
-// EMS is bad\r
-//\r
-  return false;\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        error;\r
-\r
-       totalEMSpages = freeEMSpages = EMSpageframe = EMSpagesmapped = 0;\r
-\r
-asm {\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
-\r
-getpages:\r
-asm {\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
-       }\r
-       return;\r
-\r
-error:\r
-       error = _AH;\r
-       strcpy (str,"MML_SetupEMS: EMS error 0x");\r
-       itoa(error,str2,16);\r
-       strcpy (str,str2);\r
-       Quit (str);\r
-\r
-noEMS:\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
-       mov     ah,EMS_FREEPAGES\r
-       mov     dx,[EMShandle]\r
-       int     EMS_INT\r
-       or      ah,ah\r
-       jz      ok\r
-       }\r
-\r
-       Quit ("MML_ShutdownEMS: Error freeing EMS!");\r
-\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
-               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
-               }\r
-       }\r
-\r
-       return;\r
-\r
-error:\r
-       error = _AH;\r
-       strcpy (str,"MM_MapEMS: EMS error 0x");\r
-       itoa(error,str2,16);\r
-       strcpy (str,str2);\r
-       Quit (str);\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
-       mov     ax,0x4300\r
-       int     0x2f                            // query status of installed diver\r
-       cmp     al,0x80\r
-       je      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
-       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
-\r
-getmemory:\r
-asm    {\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
-\r
-gotone:\r
-asm    {\r
-       mov     [base],bx\r
-       mov     [size],dx\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
-done:;\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
-\r
-asm    mov     ah,XMS_FREEUMB\r
-asm    mov     dx,[base]\r
-asm    call    [DWORD PTR XMSaddr]\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
diff --git a/16/exmmtest/ID_MM.H b/16/exmmtest/ID_MM.H
deleted file mode 100644 (file)
index d7a697e..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Catacomb Apocalypse 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
-// ID_MM.H\r
-\r
-#ifndef __ID_CA__\r
-\r
-#define __ID_CA__\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
-void MM_BombOnError (boolean bomb);\r
-\r
-#endif
\ No newline at end of file
diff --git a/16/exmmtest/exmmtest.c b/16/exmmtest/exmmtest.c
deleted file mode 100644 (file)
index bbbc32b..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/* 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.
- *
- */
-/*
-       exmm test borland c ver
-*/
-#include <stdio.h>
-#include <bios.h>
-
-/*#include "src/lib/16_head.h"
-#include "src/lib/16_ca.h"
-#include "src/lib/16_mm.h"*/
-#include "16_head.h"
-#include "16_ca.h"
-#include "16_mm.h"
-//#include "src/lib/modex16.h"
-/*#pragma hdrstop\r
-\r
-#pragma warn -pro\r
-#pragma warn -use*/
-
-//file load or read definition
-#define FILERL
-//#define FILEREAD
-
-void
-main(int argc, char *argv[])
-{
-       mminfo_t mm; mminfotype mmi;
-       memptr bigbuffer;
-#ifdef FILERL
-       char *bakapee;
-//     int bakapeehandle;
-       word baka;
-#endif
-       //static page_t screen;
-
-       //mmi.segu=FP_SEG(segu);
-
-       printf("&main()=        %Fp\n", *argv[0]);
-       //printf("segu= %Fp\n", segu);
-       printf("bigbuffer=      %Fp\n", bigbuffer);
-       printf("&bigbuffer=     %Fp\n", &bigbuffer);
-       printf("bigbuffer=      %04x\n", bigbuffer);
-       printf("&bigbuffer=     %04x\n", &bigbuffer);
-
-#ifdef FILERL
-       bakapee = malloc(64);
-//     memset(bakapee, 0, 64);
-#endif
-       mm.mmstarted=0;
-
-#ifdef FILERL
-       if(argv[1]) bakapee = argv[1];
-       else bakapee = "../../data/koishi~~.pcx";
-#endif
-
-       //textInit();\r
-
-       /* setup camera and screen~ */
-       //bug!!!\r
-       //screen = modexDefaultPage();\r
-       /*screen.width += (16*2);\r
-       screen.height += (16*2);*/
-
-       printf("main()=%Fp      start MM\n", *argv[0]);
-       MM_Startup(&mm, &mmi);
-       //PM_Startup();\r
-       //PM_UnlockMainMem();\r
-       CA_Startup();
-       printf("                done!\n");
-       /*if(FP_SEG(*argv[0])==0)
-       {
-               MM_Report(&screen, &mm, &mmi);
-               MM_Shutdown(&mm);
-               printf("&main()=%Fp\n", *argv[0]);
-               printf("&main() == %u\n", FP_SEG(*argv[0]));
-               exit(-5);
-       }*/
-       printf("&main()=        %Fp\n", *argv[0]);
-       //printf("segu= %Fp\n", segu);
-       printf("bigbuffer=      %Fp\n", bigbuffer);
-       printf("&bigbuffer=     %Fp\n", &bigbuffer);\r
-       printf("bigbuffer=      %04x\n", bigbuffer);
-       printf("&bigbuffer=     %04x\n", &bigbuffer);
-#ifdef FILERL
-//     bakapeehandle = open(bakapee,O_RDONLY | O_BINARY, S_IREAD);
-//wat  printf("size of big buffer~=%u\n", _bmsize(segu, bigbuffer));
-//     if(CA_FarRead(bakapeehandle,(void far *)&bigbuffer,sizeof(bigbuffer),&mm))
-#ifdef FILEREAD
-       printf("                read\n");
-       if(CA_ReadFile(bakapee, &bigbuffer, &mm))
-#else
-       printf("                load\n");
-       if(CA_LoadFile(bakapee, &bigbuffer, &mm, &mmi))
-#endif
-               baka=1;
-       else
-               baka=0;
-//     close(bakapeehandle);
-       //hmm functions in cache system use the buffered stuff
-//     printf("size of big buffer~=%u\n", _bmsize(segu, bigbuffer));
-#endif
-       printf("dark purple = purgable\n");
-       printf("medium blue = non purgable\n");
-       printf("red = locked\n");
-       getch();
-       //++++modexEnter();
-       //++++modexShowPage(&screen);
-       MM_ShowMemory(/*&screen, */&mm);
-       //getch();
-       MM_DumpData(&mm);
-       //++++modexLeave();
-       MM_Report(&mm, &mmi);
-       printf("                stop!\n");
-#ifdef FILERL
-       MM_FreePtr(&bigbuffer, &mm);
-#endif
-       //PM_Shutdown();
-       CA_Shutdown();
-       MM_Shutdown(&mm);
-       printf("                done!\n");
-#ifdef FILERL
-       free(bakapee);
-       if(baka) printf("\nyay!\n");
-       else printf("\npoo!\n");
-#endif
-       printf("bigbuffer=      %Fp\n", bigbuffer);
-       printf("&bigbuffer=     %Fp\n", &bigbuffer);
-       printf("bigbuffer=      %04x\n", bigbuffer);
-       printf("&bigbuffer=     %04x\n", &bigbuffer);
-       printf("\n\n");
-       printf("Total free:                     %lu\n", (dword)(GetFreeSize()));
-       //printf("Total near free:                      %zu\n", GetNearFreeSize());
-       printf("Total far free:                 %lu\n", (dword)(GetFarFreeSize()));
-       printf("\n");
-       printf("core left:                      %u\n", coreleft());
-       printf("far core left:                  %lu\n", farcoreleft());
-}
index bee5e1dcf697c4df2cdccd17329b25b2ccafd168..e4f56528c2c1ef3a58d1b7c66f82aa56b9998703 100644 (file)
@@ -43,8 +43,13 @@ void
 main(int argc, char *argv[])\r
 {\r
        mminfo_t mm; mminfotype mmi;\r
+#ifdef __WATCOMC__\r
        __segment sega;\r
        void __based(sega)* bigbuffer;\r
+#endif\r
+#ifdef __BORLANDC__\r
+       void memptr* bigbuffer;\r
+#endif\r
 #ifdef FILERL\r
        char *bakapee;\r
        word baka;\r
diff --git a/16/exmmtest/src/lib/16_hc.c b/16/exmmtest/src/lib/16_hc.c
new file mode 100644 (file)
index 0000000..f9f4948
--- /dev/null
@@ -0,0 +1,488 @@
+/* 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.
+ *
+ */
+/*
+       heap test stuff
+*/
+
+#include "src/lib/16_hc.h"
+
+int heaphandle;
+
+void __near* LargestFreeBlock(size_t* Size)
+{
+       size_t s0, s1;
+       void __near* p;
+
+       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
+       while (s0 && (p = _nmalloc(s0)) == NULL)
+               s0 >>= 1;
+
+       if (p)
+               _nfree(p);
+
+       s1 = s0 >> 1;
+       while (s1)
+       {
+               if ((p = _nmalloc(s0 + s1)) != NULL)
+               {
+                       s0 += s1;
+                       _nfree(p);
+               }
+       s1 >>= 1;
+       }
+       while (s0 && (p = _nmalloc(s0)) == NULL)
+               s0 ^= s0 & -s0;
+
+       *Size = s0;
+       return p;
+}
+
+size_t _coreleft(void)
+{
+       size_t total = 0;
+       void __near* pFirst = NULL;
+       void __near* pLast = NULL;
+       for(;;)
+       {
+               size_t largest;
+               void __near* p = LargestFreeBlock(&largest);
+               if (largest < sizeof(void __near*))
+               {
+                       if (p != NULL)
+                       _nfree(p);
+                       break;
+               }
+               *(void __near* __near*)p = NULL;
+               total += largest;
+               if (pFirst == NULL)
+                       pFirst = p;
+
+               if (pLast != NULL)
+                       *(void __near* __near*)pLast = p;
+               pLast = p;
+       }
+
+       while (pFirst != NULL)
+       {
+               void __near* p = *(void __near* __near*)pFirst;
+               _nfree(pFirst);
+               pFirst = p;
+       }
+       return total;
+}
+
+void far* LargestFarFreeBlock(size_t* Size)
+{
+       size_t s0, s1;
+       void far* p;
+
+       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
+       while (s0 && (p = _fmalloc(s0)) == NULL)
+               s0 >>= 1;
+
+       if (p)
+               _ffree(p);
+
+       s1 = s0 >> 1;
+       while (s1)
+       {
+               if ((p = _fmalloc(s0 + s1)) != NULL)
+               {
+                       s0 += s1;
+                       _ffree(p);
+               }
+       s1 >>= 1;
+       }
+       while (s0 && (p = _fmalloc(s0)) == NULL)
+               s0 ^= s0 & -s0;
+
+       *Size = s0;
+       return p;
+}
+
+size_t _farcoreleft(void)
+{
+       size_t total = 0;
+       void far* pFirst = NULL;
+       void far* pLast = NULL;
+       for(;;)
+       {
+               size_t largest;
+               void far* p = LargestFarFreeBlock(&largest);
+               if (largest < sizeof(void far*))
+               {
+                       if (p != NULL)
+                       _ffree(p);
+                       break;
+               }
+               *(void far* far*)p = NULL;
+               total += largest;
+               if (pFirst == NULL)
+                       pFirst = p;
+
+               if (pLast != NULL)
+                       *(void far* far*)pLast = p;
+               pLast = p;
+       }
+
+       while (pFirst != NULL)
+       {
+               void far* p = *(void far* far*)pFirst;
+               _ffree(pFirst);
+               pFirst = p;
+       }
+       return total;
+}
+
+void huge* LargestHugeFreeBlock(size_t* Size)
+{
+       size_t s0, s1;
+       void huge* p;
+
+       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
+       while (s0 && (p = halloc((dword)s0, 1)) == NULL)
+               s0 >>= 1;
+
+       if (p)
+               hfree(p);
+
+       s1 = s0 >> 1;
+       while (s1)
+       {
+               if ((p = halloc((dword)(s0 + s1), 1)) != NULL)
+               {
+                       s0 += s1;
+                       hfree(p);
+               }
+       s1 >>= 1;
+       }
+       while (s0 && (p = halloc((dword)s0, 1)) == NULL)
+               s0 ^= s0 & -s0;
+
+       *Size = s0;
+       return p;
+}
+
+size_t _hugecoreleft(void)
+{
+       size_t total = 0;
+       void huge* pFirst = NULL;
+       void huge* pLast = NULL;
+       for(;;)
+       {
+               size_t largest;
+               void huge* p = LargestHugeFreeBlock(&largest);
+               if (largest < sizeof(void huge*))
+               {
+                       if (p != NULL)
+                       hfree(p);
+                       break;
+               }
+               *(void huge* huge*)p = NULL;
+               total += largest;
+               if (pFirst == NULL)
+                       pFirst = p;
+
+               if (pLast != NULL)
+                       *(void huge* huge*)pLast = p;
+               pLast = p;
+       }
+
+       while (pFirst != NULL)
+       {
+               void huge* p = *(void huge* huge*)pFirst;
+               hfree(pFirst);
+               pFirst = p;
+       }
+       return total;
+}
+
+/*void __based(__self)* LargestBasedFreeBlock(size_t* Size)
+{
+       __segment segu;
+       size_t s0, s1;
+       void __based(__self)* p;
+
+       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
+       while (s0 && (p = _bmalloc(segu, s0)) == NULL)
+               s0 >>= 1;
+
+       if (p)
+               _ffree(p);
+
+       s1 = s0 >> 1;
+       while (s1)
+       {
+               if ((p = _bmalloc(segu, s0 + s1)) != NULL)
+               {
+                       s0 += s1;
+                       _ffree(p);
+               }
+       s1 >>= 1;
+       }
+       while (s0 && (p = _bmalloc(segu, s0)) == NULL)
+               s0 ^= s0 & -s0;
+
+       *Size = s0;
+       return p;
+}
+
+size_t _basedcoreleft(void)
+{
+       __segment segu;
+       size_t total = 0;
+       void __based(segu)* pFirst = NULL;
+       void __based(segu)* pLast = NULL;
+       // allocate based heap
+       segu = _bheapseg( 1024 );
+       if( segu == _NULLSEG ) {
+               printf( "Unable to allocate based heap\n" );
+               return 0;
+               //exit( 1 );
+       }
+       else
+
+       for(;;)
+       {
+               size_t largest;
+               void __based(segu)* p = LargestBasedFreeBlock(&largest);
+               if (largest < sizeof(void far*))
+               {
+                       if (p != NULL)
+                       _ffree(p);
+                       break;
+               }
+               *(void far* far*)p = NULL;
+               total += largest;
+               if (pFirst == NULL)
+                       pFirst = p;
+
+               if (pLast != NULL)
+                       *(void far* far*)pLast = p;
+               pLast = p;
+       }
+
+       while (pFirst != NULL)
+       {
+               void far* p = *(void far* far*)pFirst;
+               _ffree(pFirst);
+               pFirst = p;
+       }
+       return total;
+}*/
+
+size_t GetFreeSize(void)
+{
+       struct _heapinfo h_info;
+       int heap_status;
+       size_t h_free=0, h_total=0, h_used=0;
+
+       h_info._pentry = NULL;
+       for(;;) {
+               heap_status = _heapwalk( &h_info );
+               if( heap_status != _HEAPOK ) break;
+               if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") h_free += h_info._size;
+               if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") h_used += h_info._size;
+               h_total += h_info._size;
+       }
+       heapstat0(heap_status);
+       return h_free;
+}
+
+size_t GetFarFreeSize(void)
+{
+       struct _heapinfo fh_info;
+       int heap_status;
+       size_t fh_free=0, fh_total=0, fh_used=0;
+
+       fh_info._pentry = NULL;
+       for(;;) {
+               heap_status = _fheapwalk( &fh_info );
+               if( heap_status != _HEAPOK ) break;
+               if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") fh_free += fh_info._size;
+               if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") fh_used += fh_info._size;
+               fh_total += fh_info._size;
+       }
+       heapstat0(heap_status);
+       return fh_free;
+}
+
+size_t GetNearFreeSize(void)
+{
+       struct _heapinfo nh_info;
+       int heap_status;
+       size_t nh_free=0, nh_total=0, nh_used=0;
+
+       nh_info._pentry = NULL;
+       for(;;) {
+               heap_status = _nheapwalk( &nh_info );
+               if( heap_status != _HEAPOK ) break;
+               if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") nh_free += nh_info._size;
+               if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") nh_used += nh_info._size;
+               nh_total += nh_info._size;
+       }
+       heapstat0(heap_status);
+       return nh_free;
+}
+
+void heapdump(void)
+{
+       struct _heapinfo fh_info, nh_info, h_info;
+       int heap_status;
+       size_t h_free, nh_free, fh_free, h_total, nh_total, fh_total, h_used, nh_used, fh_used;
+       byte    scratch[1024],str[16];
+
+       HC_OpenDebug();
+
+       strcpy(scratch,"\n      == default ==\n\n");
+       write(heaphandle,scratch,strlen(scratch));
+       h_info._pentry = NULL;
+       h_free=0; h_total=0; h_used=0;
+       for(;;) {
+               heap_status = _heapwalk( &h_info );
+               if( heap_status != _HEAPOK ) break;
+               strcpy(scratch,"  "); strcat(scratch,(h_info._useflag == _USEDENTRY ? "USED" : "FREE")); strcat(scratch," block at "); ultoa((dword)h_info._pentry,str,16); strcat(scratch,str); strcat(scratch," of size "); ultoa(h_info._size,str,10); strcat(scratch,str); strcat(scratch,"\n");
+               if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") h_free += h_info._size;
+               if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") h_used += h_info._size;
+               h_total += h_info._size;
+               write(heaphandle,scratch,strlen(scratch));
+       }
+       heapstat(heap_status, &scratch);
+       
+       //near
+       strcpy(scratch,"\n      == near ==\n\n");
+       write(heaphandle,scratch,strlen(scratch));
+       nh_info._pentry = NULL;
+       nh_free=0; nh_total=0; nh_used=0;
+       for(;;) {
+               heap_status = _nheapwalk( &nh_info );
+               if( heap_status != _HEAPOK ) break;
+               strcpy(scratch,"  "); strcat(scratch,(h_info._useflag == _USEDENTRY ? "USED" : "FREE")); strcat(scratch," block at "); ultoa((dword)h_info._pentry,str,16); strcat(scratch,str); strcat(scratch," of size "); ultoa(h_info._size,str,10); strcat(scratch,str); strcat(scratch,"\n");
+/*             printf( "  %s block at %Fp of size %4.4X\n",
+(nh_info._useflag == _USEDENTRY ? "USED" : "FREE"),
+nh_info._pentry, nh_info._size );*/
+               if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") nh_free += nh_info._size;
+               if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") nh_used += nh_info._size;
+               nh_total += nh_info._size;
+               write(heaphandle,scratch,strlen(scratch));
+       }
+       heapstat(heap_status, &scratch);
+
+       //far
+       strcpy(scratch,"\n      == far ==\n\n");
+       write(heaphandle,scratch,strlen(scratch));
+       fh_info._pentry = NULL;
+       fh_free=0; fh_total=0; fh_used=0;
+       for(;;) {
+               heap_status = _fheapwalk( &fh_info );
+               if( heap_status != _HEAPOK ) break;
+               strcpy(scratch,"  "); strcat(scratch,(h_info._useflag == _USEDENTRY ? "USED" : "FREE")); strcat(scratch," block at "); ultoa((dword)h_info._pentry,str,16); strcat(scratch,str); strcat(scratch," of size "); ultoa(h_info._size,str,10); strcat(scratch,str); strcat(scratch,"\n");
+               /*printf( "  %s block at %Fp of size %4.4X\n",
+(fh_info._useflag == _USEDENTRY ? "USED" : "FREE"),
+fh_info._pentry, fh_info._size );*/
+               if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") fh_free += fh_info._size;
+               if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") fh_used += fh_info._size;
+               fh_total += fh_info._size;
+               write(heaphandle,scratch,strlen(scratch));
+       }
+       heapstat(heap_status, &scratch);
+
+       strcpy(scratch,"\n");
+       strcat(scratch,kittengets(2,0,"Memory Type         Total      Used       Free\n"));
+       strcat(scratch,"----------------  --------   --------   --------\n");
+       printmeminfoline(&scratch, "Default", h_total, h_used, h_free);
+       printmeminfoline(&scratch, "Near", nh_total, nh_used, nh_free);
+       printmeminfoline(&scratch, "Far", fh_total, fh_used, fh_free);
+       strcat(scratch,"----------------  --------   --------   --------\n");
+       strcat(scratch,"coreleft = ");                  ultoa((dword)_coreleft(),str,10);               strcat(scratch,str);    strcat(scratch,"\n");
+       strcat(scratch,"farcoreleft = ");               ultoa((dword)_farcoreleft(),str,10);    strcat(scratch,str);    strcat(scratch,"\n");
+       strcat(scratch,"GetFreeSize = ");               ultoa((dword)GetFreeSize(),str,10);             strcat(scratch,str);    strcat(scratch,"\n");
+       strcat(scratch,"GetNearFreeSize = ");   ultoa((dword)GetNearFreeSize(),str,10); strcat(scratch,str);    strcat(scratch,"\n");
+       strcat(scratch,"GetFarFreeSize = ");    ultoa((dword)GetFarFreeSize(),str,10);  strcat(scratch,str);    strcat(scratch,"\n");
+       strcat(scratch,"memavl = ");                    ultoa((dword)_memavl(),str,10);                 strcat(scratch,str);    strcat(scratch,"\n");
+       strcat(scratch,"stackavail = ");                ultoa((dword)stackavail(),str,10);              strcat(scratch,str);    strcat(scratch,"\n");
+       write(heaphandle,scratch,strlen(scratch));
+       HC_CloseDebug();
+}
+
+void heapstat(int heap_status, byte *str)
+{
+       switch( heap_status ) {
+               case _HEAPEND:
+                       strcpy((str),"OK - end of heap\n");
+               break;
+               case _HEAPEMPTY:
+                       strcpy((str),"OK - heap is empty\n");
+                       
+               break;
+               case _HEAPBADBEGIN:
+                       strcpy((str),"ERROR - heap is damaged\n");
+               break;
+               case _HEAPBADPTR:
+                       strcpy((str),"ERROR - bad pointer to heap\n");
+               break;
+               case _HEAPBADNODE:
+                       strcpy((str),"ERROR - bad node in heap\n");
+       }
+       write(heaphandle,(str),strlen((str)));
+}
+
+void heapstat0(int heap_status)
+{
+       switch( heap_status ) {
+               case _HEAPEND:
+                       //printf("OK - end of heap\n");
+               break;
+               case _HEAPEMPTY:
+                       //printf("OK - heap is empty\n");
+                       
+               break;
+               case _HEAPBADBEGIN:
+                       printf("ERROR - heap is damaged\n");
+               break;
+               case _HEAPBADPTR:
+                       printf("ERROR - bad pointer to heap\n");
+               break;
+               case _HEAPBADNODE:
+                       printf("ERROR - bad node in heap\n");
+       }
+}
+
+/*
+============================
+=
+= HC_OpenDebug / HC_CloseDebug
+=
+= Opens a binary file with the handle "heaphandle"
+=
+============================
+*/
+void HC_OpenDebug()
+{
+       unlink("heap.16");
+       heaphandle = open("heap.16", O_CREAT | O_WRONLY | O_TEXT);
+}
+
+void HC_CloseDebug()
+{
+       close(heaphandle);
+}
diff --git a/16/exmmtest/src/lib/16_hc.h b/16/exmmtest/src/lib/16_hc.h
new file mode 100644 (file)
index 0000000..d9677d1
--- /dev/null
@@ -0,0 +1,51 @@
+/* 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.
+ *
+ */
+/*
+       heap test stuff
+*/
+
+#ifndef __16HC__
+#define __16HC__
+
+#include "src/lib/16_head.h"
+
+extern int heaphandle;
+
+void __near* LargestFreeBlock(size_t* Size);
+size_t _coreleft(void);
+void far* LargestFarFreeBlock(size_t* Size);
+size_t _farcoreleft(void);
+void huge* LargestHugeFreeBlock(size_t* Size);
+size_t _hugecoreleft(void);
+//void __based(__self)* LargestBasedFreeBlock(size_t* Size);
+//size_t _basedcoreleft(void);
+size_t GetFreeSize(void);
+size_t GetFarFreeSize(void);
+size_t GetNearFreeSize(void);
+void heapdump(void);
+void heapstat(int heap_status, byte *str);
+void heapstat0(int heap_status);
+
+void HC_OpenDebug();
+void HC_CloseDebug();
+
+#endif /* __16HC__ */
index 73cc0bda2a1e389422ace24e34345ba51de58242..f74e8823435e9566d01110e52989de664cfd3c33 100644 (file)
@@ -30,7 +30,6 @@
 \r
 #ifndef _LIBHEAD_H_\r
 #define _LIBHEAD_H_\r
-#include <i86.h>\r
 #include <dos.h>\r
 #include <stdio.h>\r
 #include <conio.h> // just for wait\r
 #include <stdlib.h>\r
 #include <malloc.h>\r
 #include <ctype.h>\r
-#include <unistd.h>\r
 #include <fcntl.h>\r
 #include <sys/stat.h>\r
 #include <mem.h>\r
+#ifdef __WATCOMC__\r
+#include <i86.h>\r
+#include <unistd.h>\r
 #include <alloca.h>\r
 #include "src/lib/nyan/kitten.h"\r
+#endif\r
 #include "src/lib/types.h"\r
 \r
 //0000 test type def wwww\r
index 575685c3d01c9bc16c5db4d82e9e15fe66d3954f..8d3c09fe7e78587af2f0606690477874233ef3c7 100644 (file)
@@ -26,7 +26,7 @@
 //#include <bios.h>
 #include "src/lib/16_head.h"
 #include "src/lib/16_hc.h"
-#include "src/lib/modex16.h"
+//#include "src/lib/modex16.h"
 //#include "src/lib/16_ca.h"
 //++++mh       #include "src/lib/16_in.h"
 
diff --git a/16/exmmtest/src/lib/types.h b/16/exmmtest/src/lib/types.h
new file mode 100644 (file)
index 0000000..2055c20
--- /dev/null
@@ -0,0 +1,37 @@
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 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 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 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\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+/*\r
+ * Just some handy typedefs that make it easier to think about the low\r
+ * level code\r
+ */\r
+\r
+#ifndef _TYPE_H_\r
+#define _TYPE_H_\r
+\r
+typedef unsigned char byte;\r
+typedef unsigned short word;\r
+typedef unsigned long  dword;\r
+typedef signed char sbyte;\r
+typedef signed short sword;\r
+typedef signed long sdword;\r
+\r
+#endif/*_TYPE_H_*/\r
diff --git a/HEAP.16 b/HEAP.16
deleted file mode 100644 (file)
index d77c76b..0000000
--- a/HEAP.16
+++ /dev/null
@@ -1,43 +0,0 @@
-\r
-       == default ==\r
-\r
-  USED block at 1d470016 of size 136\r
-  USED block at 1d47009e of size 66\r
-  USED block at 1d4700e0 of size 7966\r
-  FREE block at 1d471ffe of size 8190\r
-OK - end of heap\r
-\r
-       == near ==\r
-\r
-  USED block at 0 of size 0\r
-  USED block at 0 of size 0\r
-  USED block at 0 of size 0\r
-  USED block at 0 of size 0\r
-  USED block at 0 of size 0\r
-  USED block at 0 of size 0\r
-  USED block at 0 of size 0\r
-  USED block at 0 of size 0\r
-  USED block at 0 of size 0\r
-OK - end of heap\r
-\r
-       == far ==\r
-\r
-  USED block at 0 of size 0\r
-  USED block at 0 of size 0\r
-  USED block at 0 of size 0\r
-  USED block at 0 of size 0\r
-OK - end of heap\r
-\r
-Memory Type         Total      Used       Free\r
-----------------  --------   --------   --------\r
-Default                   16358        8168    8190\r
-Near              31286        31286   0\r
-Far               16358        8168    8190\r
-----------------  --------   --------   --------\r
-coreleft = 0\r
-farcoreleft = 65340\r
-GetFreeSize = 65358\r
-GetNearFreeSize = 0\r
-GetFarFreeSize = 65358\r
-memavl = 0\r
-stackavail = 17041\r
diff --git a/PROFILE.16 b/PROFILE.16
deleted file mode 100644 (file)
index e69de29..0000000
index 651e72093eb7ffc561f183af4cf8f31412f8a936..f21d78761fc07db166173f1303ce113d36752a63 100644 (file)
Binary files a/exmmtest.exe and b/exmmtest.exe differ
index 76f8379650ff98d60528eac57e7f563ede4225bd..6cca691a1c375a0d7ede96ef5a5cfa35b1bb052f 100644 (file)
--- a/makefile
+++ b/makefile
@@ -302,9 +302,10 @@ clean: .symbolic
        @$(REMOVECOMMAND) __WCL__.LNK
 #      @$(REMOVECOMMAND) *.smp
        @$(REMOVECOMMAND) *.SMP
-       @$(REMOVECOMMAND) 16.hed
-       @$(REMOVECOMMAND) bakapi.hed
+       @$(REMOVECOMMAND) *.hed
        @$(COPYCOMMAND) $(SRC)exmmtest.c $(EXMMTESTDIR)$(SRC)
        @$(COPYCOMMAND) $(SRCLIB)16_mm.* $(EXMMTESTDIR)$(SRCLIB)
        @$(COPYCOMMAND) $(SRCLIB)16_head.* $(EXMMTESTDIR)$(SRCLIB)
        @$(COPYCOMMAND) $(SRCLIB)16_ca.* $(EXMMTESTDIR)$(SRCLIB)
+       @$(COPYCOMMAND) $(SRCLIB)16_hc.* $(EXMMTESTDIR)$(SRCLIB)
+       @$(COPYCOMMAND) $(SRCLIB)types.h* $(EXMMTESTDIR)$(SRCLIB)
index bee5e1dcf697c4df2cdccd17329b25b2ccafd168..e4f56528c2c1ef3a58d1b7c66f82aa56b9998703 100644 (file)
@@ -43,8 +43,13 @@ void
 main(int argc, char *argv[])\r
 {\r
        mminfo_t mm; mminfotype mmi;\r
+#ifdef __WATCOMC__\r
        __segment sega;\r
        void __based(sega)* bigbuffer;\r
+#endif\r
+#ifdef __BORLANDC__\r
+       void memptr* bigbuffer;\r
+#endif\r
 #ifdef FILERL\r
        char *bakapee;\r
        word baka;\r
index 73cc0bda2a1e389422ace24e34345ba51de58242..f74e8823435e9566d01110e52989de664cfd3c33 100644 (file)
@@ -30,7 +30,6 @@
 \r
 #ifndef _LIBHEAD_H_\r
 #define _LIBHEAD_H_\r
-#include <i86.h>\r
 #include <dos.h>\r
 #include <stdio.h>\r
 #include <conio.h> // just for wait\r
 #include <stdlib.h>\r
 #include <malloc.h>\r
 #include <ctype.h>\r
-#include <unistd.h>\r
 #include <fcntl.h>\r
 #include <sys/stat.h>\r
 #include <mem.h>\r
+#ifdef __WATCOMC__\r
+#include <i86.h>\r
+#include <unistd.h>\r
 #include <alloca.h>\r
 #include "src/lib/nyan/kitten.h"\r
+#endif\r
 #include "src/lib/types.h"\r
 \r
 //0000 test type def wwww\r
index 575685c3d01c9bc16c5db4d82e9e15fe66d3954f..8d3c09fe7e78587af2f0606690477874233ef3c7 100644 (file)
@@ -26,7 +26,7 @@
 //#include <bios.h>
 #include "src/lib/16_head.h"
 #include "src/lib/16_hc.h"
-#include "src/lib/modex16.h"
+//#include "src/lib/modex16.h"
 //#include "src/lib/16_ca.h"
 //++++mh       #include "src/lib/16_in.h"