OSDN Git Service

updated copyleft and need to test and fix newer version of open watcom
[proj16/16.git] / src / lib / 16_mm.c
index 75fc0d9..47fde07 100755 (executable)
@@ -1,19 +1,23 @@
-/* Catacomb Apocalypse Source Code\r
- * Copyright (C) 1993-2014 Flat Rock Software\r
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2022 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
  *\r
- * This program is free software; you can redistribute it and/or modify\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 2 of the License, or\r
+ * the Free Software Foundation; either version 3 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
+ * 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 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
+ * 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
 // NEWMM.C\r
@@ -57,14 +61,48 @@ Open Watcom port by sparky4
 /*\r
 =============================================================================\r
 \r
+                                                       LOCAL INFO\r
+\r
+=============================================================================\r
+*/\r
+\r
+#define LOCKBIT                0x80    // if set in attributes, block cannot be moved\r
+#define PURGEBITS      3               // 0-3 level, 0= unpurgable, 3= purge first\r
+#define PURGEMASK      0xfffc\r
+#define BASEATTRIBUTES 0       // unlocked, non purgable\r
+\r
+//#define MAXUMBS              10\r
+\r
+/*typedef struct mmblockstruct\r
+{\r
+       unsigned        start,length;\r
+       unsigned        attributes;\r
+       memptr          *useptr;        // pointer to the segment start\r
+       struct mmblockstruct far *next;\r
+} mmblocktype;*/\r
+\r
+\r
+//#define GETNEWBLOCK {if(!(mmnew=mmfree))Quit("MM_GETNEWBLOCK: No free blocks!") ;mmfree=mmfree->next;}\r
+//\r
+\r
+#define GETNEWBLOCK {if(!gvar->mm.mmfree)MML_ClearBlock(gvar);gvar->mm.mmnew=gvar->mm.mmfree;gvar->mm.mmfree=gvar->mm.mmfree->next;}\r
+\r
+#define FREEBLOCK(x) {*x->useptr=NULL;x->next=gvar->mm.mmfree;gvar->mm.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
-void           (* XMSaddr) (void);             // far pointer to XMS driver\r
 \r
 /*\r
 =============================================================================\r
@@ -73,6 +111,38 @@ void                (* XMSaddr) (void);             // far pointer to XMS driver
 \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
 #ifndef __16_PM__\r
 #if 0\r
 static char *ParmStringsexmm[] = {"noems","noxms",""};\r
@@ -624,10 +694,10 @@ void MML_ShutdownXMS(global_game_variables_t *gvar)
        }\r
 //++++todo: linked list of segment!\r
 */\r
-void MML_UseSpace(word segstart, dword seglength, global_game_variables_t *gvar)\r
+void MML_UseSpace (unsigned segstart, unsigned seglength, global_game_variables_t *gvar)\r
 {\r
        mmblocktype far *scan,far *last;\r
-       word    oldend;\r
+       unsigned        oldend;\r
        sdword          extra;\r
        //word segm=1;\r
 \r
@@ -656,8 +726,9 @@ void MML_UseSpace(word segstart, dword seglength, global_game_variables_t *gvar)
 // take the given range out of the block\r
 //\r
        oldend = scan->start + scan->length;\r
-       extra = oldend - (segstart+((unsigned)seglength));\r
+       extra = oldend - (segstart+seglength);\r
        if (extra < 0)\r
+#ifdef __DEBUG_MM__\r
        {\r
                printf("========================================\n");\r
                printf("start=%x        ", scan->start);\r
@@ -671,6 +742,9 @@ void MML_UseSpace(word segstart, dword seglength, global_game_variables_t *gvar)
                printf("========================================\n");\r
                //return;\r
        }\r
+#else\r
+               Quit (gvar, "MML_UseSpace: Segment spans two blocks!");\r
+#endif\r
 \r
        if (segstart == scan->start)\r
        {\r
@@ -707,7 +781,7 @@ void MML_UseSpace(word segstart, dword seglength, global_game_variables_t *gvar)
 ====================\r
 */\r
 \r
-void MML_ClearBlock(global_game_variables_t *gvar)\r
+void MML_ClearBlock (global_game_variables_t *gvar)\r
 {\r
        mmblocktype far *scan;//,far *last;\r
 \r
@@ -715,15 +789,47 @@ void MML_ClearBlock(global_game_variables_t *gvar)
 \r
        while(scan)\r
        {\r
-               if(!(scan->attributes&LOCKBIT) && (scan->attributes&PURGEBITS))\r
+               if(!(scan->attributes&LOCKBIT) && (scan->attributes&PURGEBITS) )\r
                {\r
-                       MM_FreePtr(scan->useptr, gvar);\r
+                       MM_FreePtr (scan->useptr, gvar);\r
                        return;\r
                }\r
                scan = scan->next;\r
        }\r
 \r
-       printf("MM_ClearBlock: No purgable blocks!\n");\r
+       Quit (gvar, "MM_ClearBlock: No purgable blocks!\n");\r
+}\r
+\r
+\r
+//==========================================================================\r
+\r
+/*\r
+===================\r
+=\r
+= MM_Reset\r
+=\r
+===================\r
+*/\r
+\r
+void MM_Reset (global_game_variables_t *gvar)\r
+{\r
+//     //has to be 16\r
+//     if(sizeof(mmblocktype)!=16)\r
+//             return;\r
+\r
+#ifdef __BORLANDC__\r
+       strcpy(gvar->handle.datadumpfilename, "mmdump.16b");\r
+#endif\r
+#ifdef __WATCOMC__\r
+       strcpy(gvar->handle.datadumpfilename, "mmdump.16w");\r
+#endif\r
+\r
+#ifdef __BORLANDC__\r
+       strcpy(gvar->handle.heapdumpfilename, "heap.16b");\r
+#endif\r
+#ifdef __WATCOMC__\r
+       strcpy(gvar->handle.heapdumpfilename, "heap.16w");\r
+#endif\r
 }\r
 \r
 \r
@@ -740,26 +846,25 @@ void MML_ClearBlock(global_game_variables_t *gvar)
 ===================\r
 */\r
 \r
-void MM_Startup(global_game_variables_t *gvar)\r
+void MM_Startup (global_game_variables_t *gvar)\r
 {\r
        int i;\r
-       //dword length,seglength;\r
-       dword length; word seglength;\r
+       unsigned        long length;\r
        void far        *start;\r
-       word    segstart;//,endfree;\r
+       unsigned        segstart,seglength;//,endfree;\r
 \r
        if(gvar->mm.mmstarted)\r
-               MM_Shutdown(gvar);\r
+               MM_Shutdown (gvar);\r
 \r
+       MM_Reset (gvar);\r
        gvar->mm.mmstarted = true;\r
        gvar->mm.bombonerror = true;\r
-\r
 //\r
 // set up the linked list (everything in the free list;\r
 //\r
        gvar->mm.mmhead = NULL;\r
        gvar->mm.mmfree = &(gvar->mm.mmblocks[0]);\r
-       for(i=0;i<MAXBLOCKS-1;i++)\r
+       for (i=0;i<MAXBLOCKS-1;i++)\r
                gvar->mm.mmblocks[i].next = &(gvar->mm.mmblocks[i+1]);\r
        gvar->mm.mmblocks[i].next = NULL;\r
 \r
@@ -774,52 +879,33 @@ void MM_Startup(global_game_variables_t *gvar)
        gvar->mm.mmnew->next = NULL;\r
        gvar->mm.mmrover = gvar->mm.mmhead;\r
 \r
+\r
 //\r
 // get all available near conventional memory segments\r
 //\r
-#ifdef __WATCOMC__\r
-       _nheapgrow();\r
-#endif\r
-       length=(word)_memavl();//(word)coreleft();\r
-       //start = gvar->mm.nearheap = _fmalloc(length);\r
-#ifdef __WATCOMC__\r
-       start = (void __far *)(gvar->mm.nearheap = _nmalloc(length));\r
-#endif\r
-#ifdef __BORLANDC__\r
-       start = (void far *)(gvar->mm.nearheap = malloc(length));\r
-#endif\r
+       length=(word)coreleft();\r
+       start = (void far *)(gvar->mm.nearheap = _nmalloc(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, gvar);\r
+       MML_UseSpace (segstart,seglength, gvar);\r
        gvar->mmi.nearheap = length;\r
        //0000printf("near:     start=%Fp       segstart=%x     seglen=%lu      len=%lu\n", start, segstart, (dword)seglength, length);\r
-\r
 //\r
 // get all available far conventional memory segments\r
 //\r
-#ifdef __WATCOMC__\r
-       _fheapgrow();\r
-#endif\r
-#ifdef __BORLANDC__\r
-//     printf("farcoreleft()                           %lu\n", farcoreleft());\r
-//     printf("(farcoreleft()+32)-_FCORELEFT   %d\n", (sword)((farcoreleft()+32)-_FCORELEFT));\r
-#endif\r
-       length=_FCORELEFT;\r
-       start = gvar->mm.farheap = _fmalloc(length);//start = gvar->mm.farheap = halloc(length, 1);\r
-\r
+       length=farcoreleft();\r
+       start = gvar->mm.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, gvar);\r
+       MML_UseSpace (segstart,seglength, gvar);\r
        gvar->mmi.farheap = length;\r
-       //0000printf("far:      start=%Fp       segstart=%x     seglen=%lu      len=%lu\n", start, segstart, (dword)seglength, length);\r
-\r
        gvar->mmi.mainmem = gvar->mmi.nearheap + gvar->mmi.farheap;\r
-\r
+       //0000printf("far:      start=%Fp       segstart=%x     seglen=%lu      len=%lu\n", start, segstart, (dword)seglength, length);\r
 #if !defined(__16_PM__)// && defined(__WATCOMC__)\r
 #if 0\r
        if(!dbg_debugpm) {\r
@@ -869,7 +955,7 @@ xmsskip:
 //\r
        gvar->mm.mmrover = gvar->mm.mmhead;             // start looking for space after low block\r
 \r
-       MM_GetPtr(&(gvar->mm.bufferseg),BUFFERSIZE, gvar);\r
+       MM_GetPtr (&(gvar->mm.bufferseg),BUFFERSIZE, gvar);\r
 }\r
 \r
 //==========================================================================\r
@@ -884,18 +970,13 @@ xmsskip:
 ====================\r
 */\r
 \r
-void MM_Shutdown(global_game_variables_t *gvar)\r
+void MM_Shutdown (global_game_variables_t *gvar)\r
 {\r
        if(!(gvar->mm.mmstarted))\r
                return;\r
 \r
        _ffree(gvar->mm.farheap);//     printf("                far freed\n");\r
-#ifdef __WATCOMC__\r
        _nfree(gvar->mm.nearheap);//    printf("                near freed\n");\r
-#endif\r
-#ifdef __BORLANDC__\r
-       free(gvar->mm.nearheap);//      printf("                near freed\n");\r
-#endif\r
 #ifndef __16_PM__\r
 #if 0\r
 #ifdef __DEBUG__\r
@@ -922,10 +1003,10 @@ void MM_Shutdown(global_game_variables_t *gvar)
 ====================\r
 */\r
 \r
-void MM_GetPtr (memptr *baseptr, dword size, global_game_variables_t *gvar)\r
+void MM_GetPtr (memptr *baseptr,dword size, global_game_variables_t *gvar)\r
 {\r
        mmblocktype far *scan,far *lastscan,far *endscan\r
-                                               ,far *purge,far *next;\r
+                               ,far *purge,far *next;\r
        int                     search;\r
        unsigned        needed,startseg;\r
 \r
@@ -934,18 +1015,26 @@ void MM_GetPtr (memptr *baseptr, dword size, global_game_variables_t *gvar)
        GETNEWBLOCK;                            // fill in start and next after a spot is found\r
        gvar->mm.mmnew->length = needed;\r
        gvar->mm.mmnew->useptr = baseptr;\r
+       gvar->mm.mmnew->attributes = BASEATTRIBUTES;\r
        //if(gvar->mm.mmnew->useptr==NULL){\r
 #ifdef __DEBUG_MM__\r
        if(dbg_debugmm>0){\r
-               printf("MM_GetPtr\n");\r
+       printf("===============================================================================\n");\r
+       printf("                MM_GetPtr\n");\r
+       printf("===============================================================================\n");\r
                //%04x\r
-               printf("        baseptr=%Fp     ", baseptr); printf("useptr=%Fp\n", gvar->mm.mmnew->useptr);\r
-               printf("        *baseptr=%Fp    ", *baseptr); printf("*useptr=%Fp\n", *(gvar->mm.mmnew->useptr));\r
-               printf("        &baseptr=%Fp    ", &baseptr); printf("&useptr=%Fp\n", &(gvar->mm.mmnew->useptr));\r
+//             printf("        baseptr=%Fp     ", baseptr); printf("useptr=%Fp\n", gvar->mm.mmnew->useptr);\r
+//             //printf("      *baseptr=%Fp    ", *baseptr); printf("*useptr=%Fp\n", *(gvar->mm.mmnew->useptr));\r
+//             printf("        &baseptr=%Fp    ", &baseptr); printf("&useptr=%Fp\n", &(gvar->mm.mmnew->useptr));\r
+\r
+               printf("        baseptr=%04x    ", baseptr); printf("useptr=%04x\n", gvar->mm.mmnew->useptr);\r
+               //printf("      *baseptr=%04x   ", *baseptr); printf("*useptr=%04x\n", *(gvar->mm.mmnew->useptr));\r
+               printf("        &baseptr=%04u   ", &baseptr); printf("&useptr=%04u\n", &(gvar->mm.mmnew->useptr));\r
+\r
+               printf("        size is %lu\n", size);\r
        }\r
 #endif\r
-       //Quit(gvar, "gvar->mm.mmnew->useptr==NULL"); }\r
-       gvar->mm.mmnew->attributes = BASEATTRIBUTES;\r
+       //Quit (gvar, "gvar->mm.mmnew->useptr==NULL"); }\r
 \r
 //tryagain:\r
        for (search = 0; search<3; search++)\r
@@ -1023,7 +1112,7 @@ void MM_GetPtr (memptr *baseptr, dword size, global_game_variables_t *gvar)
                //heapdump();\r
 #endif\r
                printf(OUT_OF_MEM_MSG,(size-gvar->mmi.nearheap));\r
-               Quit(gvar, "for stability reasons the program will shut down! wwww\n");\r
+               Quit (gvar, "for stability reasons the program will shut down! wwww\n");\r
        }\r
        else\r
                gvar->mm.mmerror = true;\r
@@ -1051,13 +1140,13 @@ void MM_FreePtr (memptr *baseptr, global_game_variables_t *gvar)
        if (baseptr == gvar->mm.mmrover->useptr)        // removed the last allocated block\r
                gvar->mm.mmrover = gvar->mm.mmhead;\r
 \r
-       while(scan->useptr != baseptr && scan)\r
+       while (scan->useptr != baseptr && scan)\r
        {\r
                last = scan;\r
                scan = scan->next;\r
        }\r
 \r
-       if(!scan)\r
+       if (!scan)\r
                Quit (gvar, "MM_FreePtr: Block not found!");\r
 \r
        last->next = scan->next;\r
@@ -1094,7 +1183,7 @@ void MM_SetPurge (memptr *baseptr, int purge, global_game_variables_t *gvar)
                else if (gvar->mm.mmrover == start)\r
                        Quit (gvar, "MM_SetPurge: Block not found!");\r
 \r
-       } while(1);\r
+       } while (1);\r
 \r
        gvar->mm.mmrover->attributes &= ~PURGEBITS;\r
        gvar->mm.mmrover->attributes |= purge;\r
@@ -1169,24 +1258,25 @@ void MM_SortMem (global_game_variables_t *gvar)
                        playing += STARTADLIBSOUNDS;\r
                        break;\r
                }\r
-               MM_SetLock((memptr *)&audiosegs[playing],true);\r
+               MM_SetLock(MEMPTRCONV audiosegs[playing],true);\r
        }\r
 \r
 \r
        SD_StopSound();*/\r
+\r
        oldborder = gvar->video.bordercolor;\r
-       gvar->video.bordercolor = modexPalOverscan(15);\r
+       gvar->video.bordercolor = VL_modexPalOverscan(gvar->video.palette, 4);\r
 \r
-       if(beforesort)\r
+       if (beforesort)\r
                beforesort();\r
 \r
        scan = gvar->mm.mmhead;\r
 \r
        last = NULL;            // shut up compiler warning\r
 \r
-       while(scan)\r
+       while (scan)\r
        {\r
-               if(scan->attributes & LOCKBIT)\r
+               if (scan->attributes & LOCKBIT)\r
                {\r
                //\r
                // block is locked, so try to pile later blocks right after it\r
@@ -1195,7 +1285,7 @@ void MM_SortMem (global_game_variables_t *gvar)
                }\r
                else\r
                {\r
-                       if(scan->attributes & PURGEBITS)\r
+                       if (scan->attributes & PURGEBITS)\r
                        {\r
                        //\r
                        // throw out the purgable block\r
@@ -1211,12 +1301,12 @@ void MM_SortMem (global_game_variables_t *gvar)
                        //\r
                        // push the non purgable block on top of the last moved block\r
                        //\r
-                               if(scan->start != start)\r
+                               if (scan->start != start)\r
                                {\r
                                        length = scan->length;\r
                                        source = scan->start;\r
                                        dest = start;\r
-                                       while(length > 0xf00)\r
+                                       while (length > 0xf00)\r
                                        {\r
                                                movedata(source,0,dest,0,0xf00*16);\r
                                                length -= 0xf00;\r
@@ -1238,7 +1328,7 @@ void MM_SortMem (global_game_variables_t *gvar)
 \r
        gvar->mm.mmrover = gvar->mm.mmhead;\r
 \r
-       if(aftersort)\r
+       if (aftersort)\r
                aftersort();\r
 \r
        VL_ColorBorder (oldborder, &gvar->video);\r
@@ -1249,6 +1339,15 @@ void MM_SortMem (global_game_variables_t *gvar)
 \r
 //==========================================================================\r
 \r
+#ifdef __BORLANDC__\r
+extern char global_temp_status_text[512];\r
+extern char global_temp_status_text2[512];\r
+#endif\r
+#ifdef __WATCOMC__\r
+//#define MMSMPANVID\r
+#define MMSMSCANINFO\r
+#endif\r
+\r
 /*\r
 =====================\r
 =\r
@@ -1257,18 +1356,19 @@ void MM_SortMem (global_game_variables_t *gvar)
 =====================\r
 */\r
 \r
-#ifdef __WATCOMC__\r
-//#define MMSMPANVID\r
-#define MMSMSCANINFO\r
-#endif\r
-\r
 void MM_ShowMemory (global_game_variables_t *gvar)\r
 {\r
        mmblocktype far *scan;\r
-       unsigned color,temp,x,y         ,w,q,width;\r
+       unsigned color,temp,x,y         ,q,w/*,width*/,sw;\r
        sdword  end,owner;\r
        byte            scratch[160],scratch0[4096],str[16];\r
+#ifdef MMSMSCANINFO\r
        mmshowmemoryinfo_t scaninfo[MAXBLOCKS];\r
+       byte scratch1[4];\r
+       unsigned                /*xpos,ypos, */oldq,maxq;\r
+       boolean         done,restarted,mmsmscaninfoxyposinew;\r
+       ScanCode                scancode;\r
+#endif\r
 \r
        if(!gvar->video.page[0].width) gvar->video.page[0].sw = gvar->video.page[0].width = 320;        //to prevent division by 0\r
 //--   VL_SetLineWidth(40, gvar);\r
@@ -1276,16 +1376,23 @@ void MM_ShowMemory (global_game_variables_t *gvar)
        //gvar->video.ofs.bufferofs = gvar->video.ofs.displayofs;\r
        temp = BDOFSCONV gvar->video.BOFS;\r
        gvar->video.BOFS = gvar->video.DOFS;\r
+#ifdef MMSMSCANINFO\r
+       oldq = 0; restarted = false; mmsmscaninfoxyposinew = false;\r
+reset:\r
+#endif\r
        scan = gvar->mm.mmhead;\r
 \r
-       end = -1; w = 0;\r
+       end = -1; w = 0; q = 0;\r
 \r
-       width = gvar->video.page[0].width; q = 0;\r
+       //width = gvar->video.page[0].width;\r
+       sw = gvar->video.page[0].sw;\r
 \r
        CA_OpenDebug (gvar);\r
        while (scan)\r
        {\r
+#ifdef MMSMSCANINFO\r
                scaninfo[q].scan = scan;\r
+#endif\r
                strcpy(scratch, AARESET);\r
                if(scan->attributes & PURGEBITS)\r
                {\r
@@ -1304,29 +1411,35 @@ void MM_ShowMemory (global_game_variables_t *gvar)
                {\r
                        printf("\nend==%d\n\n", end);\r
                        strcat(scratch, "MM_ShowMemory: Memory block order currupted!\n");\r
-                       strcat(scratch, "End's Size: ");\r
-                       ultoa (end,str,10);\r
-                       strcat (scratch,str);\r
-                       strcat(scratch, "\nscan->start's Size: ");\r
-                       ultoa (scan->start,str,10);\r
-                       strcat (scratch,str);\r
+                       strcat(scratch, "End's Size: ");        ultoa (end,str,10);     strcat (scratch,str);\r
+                       strcat(scratch, "\nscan->start's Size: ");      ultoa (scan->start,str,10);     strcat (scratch,str);\r
                        write(gvar->handle.debughandle,scratch,strlen(scratch));\r
                        Quit (gvar, "MM_ShowMemory: Memory block order currupted!");\r
                }\r
                end = scan->length-1;\r
-               y = scan->start/width;\r
-               x = scan->start%width;\r
-               scaninfo[q].x = x;\r
-               scaninfo[q].y = y;\r
+               y = gvar->video.page[0].dx+(scan->start/sw);\r
+               x = gvar->video.page[0].dy+(scan->start%sw);\r
+#if 0\r
+//def MMSMSCANINFO\r
+               if(restarted){\r
+                       y += gvar->video.page[0].dy;\r
+                       x += gvar->video.page[0].dx;\r
+               }\r
+#if 0\r
+               else{\r
+                       scaninfo[q].y = y;\r
+                       scaninfo[q].x = x;\r
+               }\r
+#endif\r
+#endif\r
                VW_Hlin(x,x+end,y,color,gvar);\r
                VL_Plot(x,y,5,gvar);\r
+//++==++==optional                     strcat(scratch0, AARESET); strcat(scratch0, AAGREY); strcat(scratch0,"_");\r
                for(w=(scan->start)/80;w<=end/80;w++)\r
                {\r
 //printf("+    %u      %lu\n", w, scan->length);\r
                        strcat(scratch0, "+");\r
                }\r
-               //++==++==optional\r
-               strcat(scratch0, AARESET); strcat(scratch0, AAGREY); strcat(scratch0,"_");\r
 \r
                if (scan->next && scan->next->start > end+1)\r
                {\r
@@ -1363,7 +1476,10 @@ void MM_ShowMemory (global_game_variables_t *gvar)
 #endif\r
                strcat(scratch0, AARESET);\r
                //strcat(scratch0,"\n");\r
-               strcat(scratch,"Seg:");\r
+               strcat(scratch,"Block:");\r
+               ultoa (q,str,10);\r
+               strcat (scratch,str);\r
+               strcat(scratch,"\tSeg:");\r
                ultoa (scan->start,str,16);\r
                strcat (scratch,str);\r
 //             strcat(scratch, AABLACK); strcat(scratch,"\t"); strcat(scratch, AARESET);\r
@@ -1378,11 +1494,14 @@ void MM_ShowMemory (global_game_variables_t *gvar)
                strcat (scratch,"\n");\r
                write(gvar->handle.debughandle,scratch,strlen(scratch));\r
                write(gvar->handle.debughandle,scratch0,strlen(scratch0));\r
-//fprintf(stdout, "%s", scratch);\r
+//0000fprintf(stdout, "\n[%s]", scratch);\r
+//0000fprintf(stdout, "[\n%s\n]", scratch0);\r
+//0000fprintf(stdout, "[%u]\n", q);\r
 \r
                scan = scan->next;\r
                q++;\r
-//if(color!=6) IN_Ack(gvar);\r
+\r
+//0000if(gvar->video.VL_Started && color!=6) IN_Ack(gvar);\r
        }\r
 \r
        CA_CloseDebug (gvar);\r
@@ -1393,7 +1512,9 @@ void MM_ShowMemory (global_game_variables_t *gvar)
                odx = gvar->video.page[0].dx;\r
                ody = gvar->video.page[0].dy;\r
                dx = dy = 0;\r
-               while(!gvar->in.inst->Keyboard[sc_Escape])\r
+\r
+               while (!(scancode = gvar->in.inst->LastScan)){}\r
+               while(!gvar->in.inst->Keyboard[sc_Escape] && !gvar->in.inst->Keyboard[sc_Space])\r
                {\r
                        if(gvar->in.inst->Keyboard[sc_UpArrow])\r
                        {\r
@@ -1425,83 +1546,167 @@ void MM_ShowMemory (global_game_variables_t *gvar)
        }\r
 #endif\r
 #ifdef MMSMSCANINFO\r
+       if (gvar->video.VL_Started) IN_Ack(gvar);\r
+       maxq = q-1;\r
+       if(restarted) q = oldq;\r
+       else q = 0;\r
+       restarted = false;\r
+\r
+       while (!(scancode = gvar->in.inst->LastScan)){}\r
+//     IN_ClearKey(scancode);\r
+//     IN_Ack(gvar);\r
+\r
+       for (done = false;!done;)\r
        {\r
-               unsigned                maxq = q;\r
-               boolean                 done;\r
-               ScanCode                scancode;\r
-               int xpos,ypos;\r
-               word qq, ccolor = 3;\r
-               IN_Ack(gvar);\r
-//             VL_ClearVideo (8);\r
-               for (qq = 0,done = false;!done;)\r
+               if(scaninfo[q].scan->attributes & PURGEBITS)\r
+               {\r
+                       color = 6;              // dark purple = purgable\r
+                       strcpy(scratch1, AAMAGENTA);            // dark purple = purgable\r
+                       //printf("%s", AAMAGENTA);\r
+               }else{\r
+                       color = 2;              // medium blue = non purgable\r
+                       strcpy(scratch1, AABLUE);               // medium blue = non purgable\r
+                       //printf("%s", AABLUE);\r
+               }\r
+               if(scaninfo[q].scan->attributes & LOCKBIT)\r
+               {\r
+                       color = 1;              // red = locked\r
+                       strcpy(scratch1, AARED);                // red = locked\r
+                       //printf("%s", AARED);\r
+               }\r
+               end = scaninfo[q].scan->length-1;\r
+\r
+               gvar->video.print.t=1;\r
+               gvar->video.print.tlsw=1;\r
+               gvar->video.print.color=color;\r
+               gvar->video.print.bgcolor=8;\r
+#define MMSMPRINTMEMINFO       VL_print(global_temp_status_text, 0, gvar); gvar->video.print.y+=8;\r
+//modexprint(&(gvar->video.page[0]), xpos, ypos, 1, 1, color, 8, gvar->video.VL_Started, global_temp_status_text);\r
+#ifdef __WATCOMC__\r
+               if(gvar->video.VL_Started)\r
+               {\r
+                       VL_ShowPage(&gvar->video.page[0], 1, 0);\r
+                       modexClearRegion(&gvar->video.page[0], gvar->video.page[0].dx, gvar->video.page[0].dy, gvar->video.page[0].sw, gvar->video.page[0].sh, 8);\r
+               }else\r
+#endif\r
                {\r
-                       if(scaninfo[qq].scan->attributes & PURGEBITS)\r
+                       clrscr();\r
+               }\r
+               sprintf(global_temp_status_text, "block #%04u", q); MMSMPRINTMEMINFO\r
+//             sprintf(global_temp_status_text, "%Fp", scaninfo[q].scan->useptr); MMSMPRINTMEMINFO\r
+               sprintf(global_temp_status_text, "start:  %04x", (unsigned)scaninfo[q].scan->start); MMSMPRINTMEMINFO\r
+               sprintf(global_temp_status_text, "useptr: %04x", (unsigned)scaninfo[q].scan->useptr); MMSMPRINTMEMINFO\r
+               sprintf(global_temp_status_text, "size: %05u", (unsigned)scaninfo[q].scan->length); MMSMPRINTMEMINFO\r
+               if (scaninfo[q].scan->next && scaninfo[q].scan->next->start > end+1)\r
+               {\r
+                       sprintf(global_temp_status_text, "free: %05u", (unsigned)(scaninfo[q].scan->next->start-scaninfo[q].scan->start)); MMSMPRINTMEMINFO\r
+               }else   /*ypos*/gvar->video.print.y+=8;\r
+               if(gvar->video.VL_Started)\r
+               {\r
+                       y = scaninfo[q].scan->start/sw;\r
+                       x = scaninfo[q].scan->start%sw;\r
+                       if(!mmsmscaninfoxyposinew)\r
                        {\r
-                               ccolor = 6;             // dark purple = purgable\r
+                               y = gvar->video.print.y;//ypos;\r
+                               x = gvar->video.print.x;//xpos;\r
                        }else{\r
-                               ccolor = 2;             // medium blue = non purgable\r
+                               //y = scaninfo[q].y;\r
+                               //x = scaninfo[q].x;\r
+                               y += gvar->video.page[0].dy;\r
+                               x += gvar->video.page[0].dx;\r
                        }\r
-                       if(scaninfo[qq].scan->attributes & LOCKBIT)\r
+                       VW_Hlin(x,x+end,y,color,gvar);\r
+                       VL_Plot(x,y,5,gvar);\r
+               }\r
+               else\r
+               {\r
+                       printf("%s", scratch1);\r
+                       printf("%s", AAGREY); printf("_");\r
+                       for(w=(scaninfo[q].scan->start)/80;w<=end/80;w++)\r
                        {\r
-                               ccolor = 1;             // red = locked\r
+                               //strcat(scratch1, "+");\r
+                               printf("+");\r
                        }\r
-/*typedef struct mmblockstruct{\r
-       word    start,length;\r
-       unsigned        attributes;\r
-       memptr          *useptr;        // pointer to the segment start\r
-       struct mmblockstruct far *next;\r
-} mmblocktype;*/\r
-                       //modexprint(page, x, y, t, tlsw, color, bgcolor, vidsw, const byte *str);\r
-#define MMSMPRINTMEMINFO modexprint(&(gvar->video.page[0]), xpos, ypos, 1, 0, ccolor, 8, gvar->video.VL_Started, global_temp_status_text); ypos+=8;\r
-                       VL_ShowPage(&gvar->video.page[0], 1, 0);\r
-                       if(!gvar->video.VL_Started) clrscr(); else\r
+               }\r
+\r
+\r
+               if (scaninfo[q].scan->next && scaninfo[q].scan->next->start > end+1) if(!gvar->video.VL_Started)\r
+               {\r
+                       //strcat(scratch1, AARESET);\r
+                       printf("%s", AARESET);\r
+                       //strcat(scratch1,AAGREEN);\r
+                       printf("%s", AAGREEN);\r
+                       for(w=(end+1)/80;w<=((scaninfo[q].scan->next->start-scaninfo[q].scan->start)/80);w++)\r
                        {\r
-                               modexClearRegion(&gvar->video.page[0], 0, 0, gvar->video.page[0].width, gvar->video.page[0].height, 8);\r
+                               //strcat(scratch1,"0");\r
+                               printf("0");\r
                        }\r
-                       sprintf(global_temp_status_text, "block #%04u", qq); MMSMPRINTMEMINFO\r
-//                     sprintf(global_temp_status_text, "%Fp", scaninfo[qq].scan->useptr); MMSMPRINTMEMINFO\r
-                       sprintf(global_temp_status_text, "%04x", (unsigned)scaninfo[qq].scan->useptr); MMSMPRINTMEMINFO\r
-                       sprintf(global_temp_status_text, "size: %05u", (unsigned)scan->length); MMSMPRINTMEMINFO\r
-                       sprintf(global_temp_status_text, "free: %05u", (unsigned)(scaninfo[qq].scan->next->start-scaninfo[qq].scan->start)); MMSMPRINTMEMINFO\r
-                       end = scaninfo[qq].scan->length-1;\r
-                       y = ypos;//scaninfo[qq].scan->start/width;\r
-                       x = xpos;//scaninfo[qq].scan->start%width;\r
-                       VW_Hlin(x,x+end,y,ccolor,gvar);\r
-                       VL_Plot(x,y,5,gvar);\r
-                       if (scaninfo[qq].scan->next && scaninfo[qq].scan->next->start > end+1)\r
-                               VW_Hlin(x+end+1,x+(scaninfo[qq].scan->next->start-scan->start),y,3,gvar);       // black = free//now green\r
+               }else VW_Hlin(x+end+1,x+(scaninfo[q].scan->next->start-scaninfo[q].scan->start),y,3,gvar);      // black = free//now green\r
+\r
 \r
+               if(gvar->video.VL_Started)\r
+               {\r
                        //if (scan->next && scan->next->start > end+1) free\r
-                       xpos = 16;\r
-                       ypos = 16;//(gvar->video.page[0].sh-(32));//8*4\r
-                       while (!(scancode = gvar->in.inst->LastScan)){}\r
+                       /*xpos*/gvar->video.print.x = gvar->video.page[0].dx;\r
+                       /*ypos*/gvar->video.print.y = gvar->video.page[0].dy;\r
+               }\r
+               else\r
+               {\r
+                       //printf("%s\n", scratch1);\r
+                       printf("%s", AARESET);\r
+                       printf("\n");\r
+               }\r
 \r
-                       IN_ClearKey(scancode);\r
-                       switch (scancode)\r
-                       {\r
-                               case sc_LeftArrow:\r
-                                       if(qq>0) qq--;\r
-                                       else    qq = maxq;\r
-                               break;\r
-                               case sc_RightArrow:\r
-                                       if(qq<maxq) qq++;\r
-                                       else qq = 0;\r
-                               break;\r
-                               case sc_Escape:\r
-                                       done = true;\r
-                               break;\r
-                       }\r
+\r
+               while (!(scancode = gvar->in.inst->LastScan)){}\r
+\r
+               IN_ClearKey(scancode);\r
+               switch (scancode)\r
+               {\r
+                       case sc_Enter:\r
+                               if(!mmsmscaninfoxyposinew) mmsmscaninfoxyposinew = true;\r
+                               else mmsmscaninfoxyposinew = false;\r
+                               //mmsmscaninfoxyposinew!=mmsmscaninfoxyposinew;\r
+                       break;\r
+                       case sc_LeftArrow:\r
+                               if(q>0) q--;\r
+                               else    q = maxq;\r
+                       break;\r
+                       case sc_RightArrow:\r
+                               if(q<maxq) q++;\r
+                               else q = 0;\r
+                       break;\r
+                       case sc_UpArrow:\r
+                               if(q>9) q-=10;\r
+                               else    q = maxq;\r
+                       break;\r
+                       case sc_DownArrow:\r
+                               if(q<maxq-9) q+=10;\r
+                               else q = 0;\r
+                       break;\r
+                       case sc_Space:\r
+                               oldq = q;\r
+                               restarted = true;\r
+#ifdef __WATCOMC__\r
+                               if(gvar->video.VL_Started) modexClearRegion(&gvar->video.page[0], gvar->video.page[0].dx, gvar->video.page[0].dy, gvar->video.page[0].sw, gvar->video.page[0].sh, 8);\r
+#endif\r
+                               goto reset;\r
+\r
+                       case sc_Escape:\r
+                               done = true;\r
+                       break;\r
                }\r
        }\r
+#else\r
+       if(gvar->video.VL_Started) IN_Ack(gvar);\r
 #endif\r
 \r
-       IN_Ack(gvar);\r
-\r
        gvar->video.BOFS = (byte __far *)temp;\r
 }\r
 \r
 //==========================================================================\r
 \r
+\r
 /*\r
 =====================\r
 =\r
@@ -1518,22 +1723,10 @@ void MM_DumpData (global_game_variables_t *gvar)
        char    lock,purge;\r
        FILE    *dumpfile;\r
 \r
-#ifdef __WATCOMC__\r
        _nfree(gvar->mm.nearheap);\r
-#endif\r
-#ifdef __BORLANDC__\r
-       free(gvar->mm.nearheap);\r
-#endif\r
-#ifdef __BORLANDC__\r
-               dumpfile = fopen ("mmdump.16b","w");\r
-#endif\r
-#ifdef __WATCOMC__\r
-               dumpfile = fopen ("mmdump.16w","w");\r
-#endif\r
-       if (!dumpfile){\r
-               printf("MM_DumpData: Couldn't open MMDUMP.16!\n");\r
-               return;\r
-       }\r
+       dumpfile = fopen (gvar->handle.datadumpfilename, "w");\r
+       if (!dumpfile)\r
+               Quit (gvar, "MM_DumpData: Couldn't open MMDUMP.16!\n");\r
 \r
        lowest = -1;\r
        do\r
@@ -1571,8 +1764,16 @@ void MM_DumpData (global_game_variables_t *gvar)
 \r
        } while (lowest != 0xffff);\r
 \r
-       fclose(dumpfile);\r
-       printf("MMDUMP.16 created.\n");\r
+       fclose (dumpfile);\r
+\r
+       //reset filename\r
+#ifdef __BORLANDC__\r
+       strcpy(gvar->handle.datadumpfilename, "mmdump.16b");\r
+#endif\r
+#ifdef __WATCOMC__\r
+       strcpy(gvar->handle.datadumpfilename, "mmdump.16w");\r
+#endif\r
+//00   printf ("MMDUMP.16 created.\n");\r
 }\r
 \r
 //==========================================================================\r