From e3a3ac3518f3adb6828f198418edea00cb69115a Mon Sep 17 00:00:00 2001 From: sparky4 Date: Wed, 1 Jul 2015 21:31:45 -0500 Subject: [PATCH] wwwwwwwww modified: exmmtest.exe modified: inputest.exe modified: src/exmmtest.c modified: src/lib/16_mm.c modified: src/lib/16_mm.h --- exmmtest.exe | Bin 39475 -> 39406 bytes inputest.exe | Bin 41934 -> 41932 bytes src/exmmtest.c | 6 +- src/lib/16_mm.c | 2345 +++++++++++++++++++++++------------------------ src/lib/16_mm.h | 74 +- 5 files changed, 1211 insertions(+), 1214 deletions(-) diff --git a/exmmtest.exe b/exmmtest.exe index 925ed18a0a3fbd8c5e5361d85698b97e08493b57..98206db250fa0f090448316ec4045d57154bf3f6 100644 GIT binary patch delta 13273 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 diff --git a/inputest.exe b/inputest.exe index f483a62d346abba3430751ba12743d5625553515..2befbe0643eb2471f27f34a12fe1b73a17e406e3 100644 GIT binary patch delta 1676 zcmZvce@xV69LJx}m*a=I8r;EgnsEXyIhkB~dSM7LT$qkz+2&nE62g7)sY9qSbQ3$g$PZG5;avT1Lx%bdFJ3pXYn=tNHx#+WUFlpU>xc zp3n2$cVbkzF{)hhIp{n19htG^&kK=`B&Pubjznt4h+}))~dRowb8oCZVd)1 ztseIQmZ+%vKH;JeB2oEOfZj?m_Ql@k>57Irca?}2E#%>R(xcp$^_+|wqr(;MkPvY- zP`pqI*;Q*8SCVcg$trr*Ewn=6BoBssd1aki@c~{Qqu1Pxu7%XAy!0cHpqzj!R3Grp zmy{c-30z<%N!6?IEVA|6^lBW7Z7jGPZxE0h3}BCc%T`%h_4E8){a<=jWf9g->Qxtu zE`2}8t3H;q`dOLULdRn`^DKt^>*6YTA$u6peq-Dj4#_US-~QC52unMaS9(K2*^+UJ zV|eCqduxPZ&lrxHs;8n_C@*Bl%dvZ~!dvBW31$0y_Y3=m`gc0At^eQC1TH9pS|x($matEm5nS^D=BOtqWRQ`gE#af*yvR!cm~D~c$@Pi+>ujz?|z zQlIp$!aQslIo>3!^B4#3Nd$H&agxX3KSM7xFhG0S=y zrVcYbh1?EHf{{1VDRTnTy(W4U$2u%@69Y^gZgEgK9x_kB*lDKAurn`VA9E57%ye`z z_u>oY2e`!?#Y5(O7`vovXO?1LmxYhs%z6ZU%xQeXjK|N+&bDqdUBg;t5emC4bOnc4 zKfuXub9~xHdA4S>cCVshjPrUUW|(L2M30RN6!e(MhW$OZjpuV@WJA8}W%06RMjL-e z^S>&P{wL^bOK!5tgx6n`3%L>tBbrd8`C-j>EO=5x{Tj``tNHvrFBwrktogrde*F?x z{P(ytgT1{L+Jqy$W(p$0`Vp@8+UO(9^;()}vpn9>BAI!3S$ed*UGpDkKJT<-ME(7m zpSeRCa%FKu{S%ts#+~|9C%?AEp?!Ob7)1YR3uR-1IfU8MX8IGRh?(+`%X|+`<^{aN pyo+w84Z}=7CYjxXvk_AaokLRJYUA3N$Nm2Yi~3q(bT|0V@h>5Rk9hz9 delta 1528 zcmZvceN5DK9LK+(9~>OnE$)5_hfhB|Ej`IjwWqcr=Go?1Qsjw6w|Ihq z8u>$Y!+GmbAw;J3vjAxvCLtnvslK0$MFI&xxfG_BL#(Wv>E02HOF0tS;wNy@x8+|StK3r zbG;d1dE0SYwzg1n3U?mFiO9UPS~l`d;>SqVj(#r5TPahUHwPMO8cpFSqRruWRA`G` z`#H(cmQY-11+G@^;wTshZ53LP>*Rk)Gw7=m+7m8$T+Y7i3)KewLR)dKoJYpw>9r^C zl{ALx8sc$(NNA<5wQq2nm_p@iDxMZYJTX&~n;9W9Jb7QwuyMcpI>?>oTb#_)pVj3F zbNI2T6~oa5FH~}Fgu=dP{p6VAvQm>Ap;$Z`2-U?n7lc+1?fn0jpsn(>rjsXD>l3;u zzp118U%Ht!xF&XW=9C$H_v(9y5k3#km@VIZwLe}S_50OZ%V#nJLBBeBGlH!<=`;M+ zx|)7MVOu^05NI=~4SSg9@d5L1oMYx;tj%rPI7^6B%`%mDAZFooLbo1Pj%zALd!4q+ zDkxLw6!;bvpnRH~M_85AX%)U{chfNbX)mD- zSPp|a@gnmSwli;_2PL!@S6C0?4)WDC{)o7}hhdps~}ix!iJ2ZoaH>s;+g)d0aVG)zyM;xpGALb%nC>4^=s? zoDD_NNvcX03X=w(c74*#H?o8Emw1nP9Yahjt}>IDV4j81Wl$MbcDd;U0<8bUo-QNZ zSS0te6YqBA&}y7xe>=vQ{m9st&l5`a8B~BxtPi7&^$i?j=HL>u48Jpjuy-5OjwQ@r z@qD+NmSQ{WIC@x5;B0q3y@Na5Zkx7LuJ!s;a{o>0M8(P(SB?kQ5>p>k#@sSlGEtJtIGfY diff --git a/src/exmmtest.c b/src/exmmtest.c index 24229f7d..5e737db4 100644 --- a/src/exmmtest.c +++ b/src/exmmtest.c @@ -27,15 +27,15 @@ void main(int argc, char *argv[]) { - mminfo_t mm; - mminfotype mmi; + mminfo_t mm; mminfotype mmi; + mm.mmstarted=0; printf("start!\n"); MM_Startup(&mm, &mmi); printf("done!\n"); printf("&main()=%Fp\n", *argv[0]); MM_ShowMemory(&mm); - MM_Report(&mm, &mmi); +//++++ MM_Report(&mm, &mmi); printf("stop!\n"); MM_Shutdown(&mm); printf("done!\n"); diff --git a/src/lib/16_mm.c b/src/lib/16_mm.c index 5ef27f8d..34c0363b 100644 --- a/src/lib/16_mm.c +++ b/src/lib/16_mm.c @@ -1,222 +1,222 @@ -/* 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 - -============================================================================= -*/ - -#include "src/lib/16_mm.h" - -/* -============================================================================= - - GLOBAL VARIABLES - -============================================================================= -*/ - -//mminfo_t mminfo; -//memptr bufferseg; -//boolean mmerror; - -void (* beforesort) (void); +/* 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 + +============================================================================= +*/ + +#include "src/lib/16_mm.h" + +/* +============================================================================= + + GLOBAL VARIABLES + +============================================================================= +*/ + +//mminfo_t mminfo; +//memptr bufferseg; +//boolean mmerror; + +void (* beforesort) (void); void (* aftersort) (void); -void (* XMSaddr) (void); // far pointer to XMS driver - -/* -============================================================================= - - LOCAL VARIABLES - -============================================================================= -*/ - -//boolean mmstarted; - -//void far *farheap; -//void *nearheap; - -//mmblocktype far mmblocks[MAXBLOCKS],far *mmhead,far *mmfree,far *mmrover,far *mmnew; - -//boolean bombonerror; - +void (* XMSaddr) (void); // far pointer to XMS driver + +/* +============================================================================= + + LOCAL VARIABLES + +============================================================================= +*/ + +//boolean mmstarted; + +//void far *farheap; +//void *nearheap; + +//mmblocktype far mmblocks[MAXBLOCKS],far *mmhead,far *mmfree,far *mmrover,far *mmnew; + +//boolean bombonerror; + //unsigned totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle; -//unsigned int EMSVer; - -//void (* XMSaddr) (void); // far pointer to XMS driver - +//unsigned int EMSVer; + +//void (* XMSaddr) (void); // far pointer to XMS driver + //unsigned numUMBs,UMBbase[MAXUMBS]; static char *ParmStringsexmm[] = {"noems","noxms",""}; - -/* -====================== -= -= MML_CheckForEMS -= -= Routine from p36 of Extending DOS -= -======================= -*/ - -boolean MML_CheckForEMS(void) -{ - boolean emmcfems; - char emmname[] = "EMMXXXX0"; -// mov dx,OFFSET emmname - __asm { - LEA DX, emmname //fix by andrius4669 - mov ax,0x3d00 - int 0x21 // try to open EMMXXXX0 device - jc error - - mov bx,ax - mov ax,0x4400 - - int 0x21 // get device info - jc error - - and dx,0x80 - jz error - - mov ax,0x4407 - - int 0x21 // get status - jc error - or al,al - jz error - - mov ah,0x3e - int 0x21 // close handle - jc error - // - // EMS is good - // - mov emmcfems,1 - jmp End - error: - // - // EMS is bad - // - mov emmcfems,0 - End: - } - return(emmcfems); -} - - -/* -====================== -= -= MML_SetupEMS -= -======================= -*/ - -unsigned MML_SetupEMS(mminfo_t *mm) -{ - char str[80],str2[10]; - unsigned err; - boolean errorflag=false; - union REGS CPURegs; - + +/* +====================== += += MML_CheckForEMS += += Routine from p36 of Extending DOS += +======================= +*/ + +boolean MML_CheckForEMS(void) +{ + boolean emmcfems; + char emmname[] = "EMMXXXX0"; +// mov dx,OFFSET emmname + __asm { + LEA DX, emmname //fix by andrius4669 + mov ax,0x3d00 + int 0x21 // try to open EMMXXXX0 device + jc error + + mov bx,ax + mov ax,0x4400 + + int 0x21 // get device info + jc error + + and dx,0x80 + jz error + + mov ax,0x4407 + + int 0x21 // get status + jc error + or al,al + jz error + + mov ah,0x3e + int 0x21 // close handle + jc error + // + // EMS is good + // + mov emmcfems,1 + jmp End + error: + // + // EMS is bad + // + mov emmcfems,0 + End: + } + return(emmcfems); +} + + +/* +====================== += += MML_SetupEMS += +======================= +*/ + +unsigned MML_SetupEMS(mminfo_t *mm) +{ + char str[80],str2[10]; + unsigned err; + boolean errorflag=false; + union REGS CPURegs; + unsigned int EMSVer = 0; - 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 - 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 - - cmp bx,4 - jle getpages // there is only 1,2,3,or 4 pages - mov bx,4 // we can't use more than 4 pages - -getpages: - mov [EMSpagesmapped],bx - mov ah,EMS_ALLOCPAGES // allocate up to 64k of EMS - int EMS_INT - or ah,ah - jnz error - mov [EMShandle],dx - jmp End -error: - mov errorflag,1 - jmp End -noEMS: -End: - } - if(errorflag==true) - { - err = CPURegs.h.ah; - strcpy(str,"MML_SetupEMS: EMS error 0x"); - itoa(err,str2,16); - strcpy(str,str2); + 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 + 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 + + cmp bx,4 + jle getpages // there is only 1,2,3,or 4 pages + mov bx,4 // we can't use more than 4 pages + +getpages: + mov [EMSpagesmapped],bx + mov ah,EMS_ALLOCPAGES // allocate up to 64k of EMS + int EMS_INT + or ah,ah + jnz error + mov [EMShandle],dx + jmp End +error: + mov errorflag,1 + jmp End +noEMS: +End: + } + if(errorflag==true) + { + err = CPURegs.h.ah; + strcpy(str,"MML_SetupEMS: EMS error 0x"); + itoa(err,str2,16); + strcpy(str,str2); printf("%s\n",str); - return err; + return err; } mm->totalEMSpages=totalEMSpages; mm->freeEMSpages=freeEMSpages; @@ -224,984 +224,981 @@ End: mm->EMSpagesmapped=EMSpagesmapped; mm->EMShandle=EMShandle; mm->EMSVer=EMSVer; - return 0; -} - - -/* -====================== -= -= MML_ShutdownEMS -= -======================= -*/ - -void MML_ShutdownEMS(mminfo_t *mm) -{ + 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!"); //++++ 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. -= -==================== -*/ - -unsigned MM_MapEMS(mminfo_t *mm) -{ - char str[80],str2[10]; - unsigned err, EMShandle; - boolean errorflag=false; - int i; + if(!EMShandle) + return; + __asm + { + mov ah,EMS_FREEPAGES + mov dx,[EMShandle] + int EMS_INT + or ah,ah + jz ok + mov errorflag,1 + ok: + } + if(errorflag==true) printf("MML_ShutdownEMS: Error freeing EMS!"); //++++ add something +} + +/* +==================== += += MM_MapEMS += += Maps the 64k of EMS used by memory manager into the page frame += for general use. This only needs to be called if you are keeping += other things in EMS. += +==================== +*/ + +unsigned MM_MapEMS(mminfo_t *mm) +{ + char str[80],str2[10]; + unsigned err, EMShandle; + boolean errorflag=false; + int i; union REGS CPURegs; - EMShandle=mm->EMShandle; - - for (i=0;iEMSpagesmapped;i++) - { - __asm - { - mov ah,EMS_MAPPAGE - mov bx,[i] // logical page - mov al,bl // physical page - mov dx,[EMShandle] // handle - int EMS_INT - or ah,ah - jnz error - jmp End - error: - mov errorflag,1 - End: - } - if(errorflag==true) - { - err = CPURegs.h.ah; - strcpy(str,"MM_MapEMS: EMS error 0x"); - itoa(err,str2,16); - strcpy(str,str2); + EMShandle=mm->EMShandle; + + for (i=0;iEMSpagesmapped;i++) + { + __asm + { + mov ah,EMS_MAPPAGE + mov bx,[i] // logical page + mov al,bl // physical page + mov dx,[EMShandle] // handle + int EMS_INT + or ah,ah + jnz error + jmp End + error: + mov errorflag,1 + End: + } + if(errorflag==true) + { + err = CPURegs.h.ah; + strcpy(str,"MM_MapEMS: EMS error 0x"); + itoa(err,str2,16); + strcpy(str,str2); printf("%s\n",str); - return err; - } - } - 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; - - __asm - { - mov ax,0x4310 - int 0x2f - mov [WORD PTR XMSaddr],bx - mov [WORD PTR XMSaddr+2],es // function pointer to XMS driver - } -getmemory: - __asm - { - mov ah,XMS_ALLOCUMB - mov dx,0xffff // try for largest block possible - call [DWORD PTR XMSaddr] - or ax,ax - jnz gotone - - cmp bl,0xb0 // error: smaller UMB is available - jne done; - - mov ah,XMS_ALLOCUMB - call [DWORD PTR XMSaddr] // DX holds largest available UMB - or ax,ax - jz done // another error... - -gotone: - mov [base],bx - mov [size],dx -done: - } - MML_UseSpace(base,size, 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; + return err; + } + } + 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; + + __asm + { + mov ax,0x4310 + int 0x2f + mov [WORD PTR XMSaddr],bx + mov [WORD PTR XMSaddr+2],es // function pointer to XMS driver + } +getmemory: + __asm + { + mov ah,XMS_ALLOCUMB + mov dx,0xffff // try for largest block possible + call [DWORD PTR XMSaddr] + or ax,ax + jnz gotone + + cmp bl,0xb0 // error: smaller UMB is available + jne done; + + mov ah,XMS_ALLOCUMB + call [DWORD PTR XMSaddr] // DX holds largest available UMB + or ax,ax + jz done // another error... + +gotone: + mov [base],bx + mov [size],dx +done: + } + MML_UseSpace(base,size, 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;inumUMBs;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(unsigned segstart, unsigned seglength, mminfo_t *mm) -{ - mmblocktype far *scan,far *last; - unsigned oldend; - long 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; - } - -// -// take the given range out of the block -// - oldend = scan->start + scan->length; - extra = oldend - (segstart+seglength); - if(extra < 0) - { - printf("MML_UseSpace: Segment spans two blocks!"); - return; - } - - - if (segstart == scan->start) - { - last->next = scan->next; // unlink block - MM_FreeBlock(scan, mm); - scan = last; - } - else - scan->length = segstart-scan->start; // shorten block - - 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; - } - -} - -//========================================================================== - -/* -==================== -= -= MML_ClearBlock -= -= We are out of blocks, so free a purgable block -= -==================== -*/ - -void MML_ClearBlock(mminfo_t *mm) -{ - mmblocktype far *scan,far *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!"); -} - - -//========================================================================== - -/* -=================== -= -= 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; - void far *start; - unsigned segstart,seglength,endfree; - - if(mm->mmstarted) - MM_Shutdown(mm); - - mm->mmstarted = true; - mm->bombonerror = true; -// -// set up the linked list (everything in the free list; -// - mm->mmhead = NULL; - mm->mmfree = &(mm->mmblocks[0]); + + for (i=0;inumUMBs;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(unsigned segstart, unsigned seglength, mminfo_t *mm) +{ + mmblocktype far *scan,far *last; + unsigned oldend; + long 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; + } + +// +// take the given range out of the block +// + oldend = scan->start + scan->length; + extra = oldend - (segstart+seglength); + if(extra < 0) + { + printf("MML_UseSpace: Segment spans two blocks!"); + return; + } + + + if(segstart == scan->start) + { + last->next = scan->next; // unlink block + MM_FreeBlock(scan, mm); + scan = last; + } + else + scan->length = segstart-scan->start; // shorten block + + 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; + } + +} + +//========================================================================== + +/* +==================== += += MML_ClearBlock += += We are out of blocks, so free a purgable block += +==================== +*/ + +void MML_ClearBlock(mminfo_t *mm) +{ + mmblocktype far *scan,far *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!"); +} + + +//========================================================================== + +/* +=================== += += 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; + void far *start; + unsigned segstart,seglength,endfree; + + if(mm->mmstarted) + MM_Shutdown(mm); + + mm->mmstarted = true; + mm->bombonerror = true; +// +// set up the linked list (everything in the free list; +// + mm->mmhead = NULL; + mm->mmfree = &(mm->mmblocks[0]); for(i=0;immblocks[i].next = &(mm->mmblocks[i+1]); - } - mm->mmblocks[i].next = NULL; - -// -// locked block of all memory until we punch out free space -// - //GETNEWBLOCK; - 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 -// + } + mm->mmblocks[i].next = NULL; + +// +// locked block of all memory until we punch out free space +// + 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(); - _nheapgrow(); - length=_memavl(); - start = (void far *)(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; - -// -// get all available far conventional memory segments -// + _nheapgrow(); + length=_memavl(); + start = (void far *)(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; + +// +// get all available far conventional memory segments +// //---- length=farcoreleft(); - _fheapgrow(); - length=_memavl(); - 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; - mmi->mainmem = mmi->nearheap + mmi->farheap; - - -// -// detect EMS and allocate up to 64K at page frame -// - mmi->EMSmem = 0; - for(i = 1;i < __argc;i++) - { - if(US_CheckParm(__argv[i],ParmStringsexmm) == 0) - goto emsskip; // param NOEMS - } - - if(MML_CheckForEMS()) - { - printf("EMS1\n"); - MML_SetupEMS(mm); // allocate space - printf("EMS2\n"); -printf("segstart=%x\n", segstart); -printf("mm->EMSpageframe=%x\n", mm->EMSpageframe); - MML_UseSpace(mm->EMSpageframe,mm->EMSpagesmapped*0x400, mm); - printf("EMS3\n"); - MM_MapEMS(mm); // map in used pages - printf("EMS4\n"); - mmi->EMSmem = mm->EMSpagesmapped*0x4000l; - } - -// -// 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 - } - - if(MML_CheckForXMS(mm)) - { - 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; - + _fheapgrow(); + length=_memavl(); + 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; + mmi->mainmem = mmi->nearheap + mmi->farheap; + + +// +// detect EMS and allocate up to 64K at page frame +// + mmi->EMSmem = 0; + for(i = 1;i < __argc;i++) + { + if(US_CheckParm(__argv[i],ParmStringsexmm) == 0) + goto emsskip; // param NOEMS + } + + if(MML_CheckForEMS()) + { +//printf("EMS1\n"); + MML_SetupEMS(mm); // allocate space +printf("EMS2\t"); printf("segstart=%x\t", segstart); printf("mm->EMSpageframe=%x\n", mm->EMSpageframe); //bug + MML_UseSpace(mm->EMSpageframe,mm->EMSpagesmapped*0x400, mm); +//printf("EMS3\n"); + MM_MapEMS(mm); // map in used pages +//printf("EMS4\n"); + mmi->EMSmem = mm->EMSpagesmapped*0x4000l; + } + +// +// 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 + } + + if(MML_CheckForXMS(mm)) + { +//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"); + printf("far freed\n"); free(mm->nearheap); - printf("near freed\n"); + printf("near freed\n"); //hfree(mm->hugeheap); - //printf("huge freed\n"); + //printf("huge freed\n"); MML_ShutdownEMS(mm); - printf("EMS freed\n"); + printf("EMS freed\n"); 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 far *scan,far *lastscan,far *endscan - ,far *purge,far *next; - int search; - unsigned needed,startseg; - - needed = (size+15)/16; // convert size from bytes to paragraphs - - 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)); - else - mm->mmerror = true; -} - -//========================================================================== - -/* -==================== -= -= MM_FreePtr -= -= Allocates an unlocked, unpurgable block -= -==================== -*/ - -void MM_FreePtr(memptr *baseptr, mminfo_t *mm) -{ - mmblocktype far *scan,far *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!"); - 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 far *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 far *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 far *scan,far *last,far *next; - unsigned start,length,source,dest,oldborder; - int playing; - - // - // lock down a currently playing sound - // -/*++++ playing = SD_SoundPlaying (); - if (playing) - { - switch (SoundMode) - { - case sdm_PC: - playing += STARTPCSOUNDS; - break; - case sdm_AdLib: - playing += STARTADLIBSOUNDS; - break; - } - MM_SetLock(&(memptr)audiosegs[playing],true); - } - - - SD_StopSound();*/ -// oldborder = bordercolor; -// VW_ColorBorder (15); - - if(beforesort) - beforesort(); - - scan = 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(mminfo_t *mm) -{ - mmblocktype far *scan; - unsigned color,temp;//, i; - long end,owner; - char scratch[80],str[10]; - -//**** VW_SetDefaultColors(); -//**** VW_SetLineWidth(40); -//++++mh temp = bufferofs; -//++++mh bufferofs = 0; -//**** VW_SetScreen (0,0); - - scan = mm->mmhead; - - end = -1; - -//CA_OpenDebug (); - - while (scan) - { - if (scan->attributes & PURGEBITS) - color = 5; // dark purple = purgable - else - color = 9; // medium blue = non purgable - if(scan->attributes & LOCKBIT) - color = 12; // red = locked - if(scan->start<=end) - { - printf("MM_ShowMemory: Memory block order currupted!"); - return; - } - end = scan->start+scan->length-1; -//++++ VW_Hlin(scan->start,(unsigned)end,0,color); -//++++ VW_Plot(scan->start,0,15); - if(scan->next->start > end+1) -//++++ VW_Hlin(end+1,scan->next->start,0,0); // black = free - -//****#if 0 -printf("Location:"); -printf("%Fp\t", scan->start); -strcpy (scratch,"Size:"); -ltoa ((long)scan->length*16,str,10); -strcat (scratch,str); -strcat (scratch,"\tOwner:0x"); -owner = (unsigned)scan->useptr; -ultoa (owner,str,16); -strcat (scratch,str); -strcat (scratch,"\n"); -//++++write (debughandle,scratch,strlen(scratch)); -fprintf(stdout, "%s", scratch); -//****#endif - - scan = scan->next; - } - -//CA_CloseDebug (); - -//++++mh IN_Ack(); -//**** VW_SetLineWidth(64); -//++++mh bufferofs = temp; -} -//****#endif - -//========================================================================== - - -/* -====================== -= -= MM_UnusedMemory -= -= Returns the total free space without purging -= -====================== -*/ - -dword MM_UnusedMemory(mminfo_t *mm) -{ - unsigned free; - mmblocktype far *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) -{ - unsigned free; - mmblocktype far *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(mminfo_t *mm, mminfotype *mmi) -{ - printf("EMM %x available\n", mm->EMSVer); - printf("totalEMSpages=%u\n", mm->totalEMSpages); - printf("freeEMSpages=%u\n", mm->freeEMSpages); - printf("EMSpageframe=%Fp\n", mm->EMSpageframe); - 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)); -// printf("\n"); -// printf("UnusedMemory=%lu kb\n", MM_UnusedMemory()/10248); -// printf("TotalFree=%lu kb\n", MM_TotalFree()/10248); -} - -//========================================================================== - -/* -===================== -= -= MM_EMSVer -= -===================== - - -int MM_EMSVer(void) -{ - int EMSver; - __asm - { - mov ah,EMS_VERSION - int EMS_INT - mov EMSver,ax - } - return(EMSver); -}*/ - -//========================================================================== - -/* -===================== -= -= MM_BombOnError -= -===================== -*/ - -void MM_BombOnError(boolean bomb, mminfo_t *mm) -{ - mm->bombonerror = bomb; -} + printf("XMS freed\n"); +} + +//========================================================================== + +/* +==================== += += MM_GetPtr += += Allocates an unlocked, unpurgable block += +==================== +*/ + +void MM_GetPtr(memptr *baseptr,dword size, mminfo_t *mm, mminfotype *mmi) +{ + mmblocktype far *scan,far *lastscan,far *endscan + ,far *purge,far *next; + int search; + unsigned needed,startseg; + + needed = (size+15)/16; // convert size from bytes to paragraphs + + 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)); + else + mm->mmerror = true; +} + +//========================================================================== + +/* +==================== += += MM_FreePtr += += Allocates an unlocked, unpurgable block += +==================== +*/ + +void MM_FreePtr(memptr *baseptr, mminfo_t *mm) +{ + mmblocktype far *scan,far *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!"); + 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 far *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 far *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 far *scan,far *last,far *next; + unsigned start,length,source,dest,oldborder; + int playing; + + // + // lock down a currently playing sound + // +/*++++ playing = SD_SoundPlaying (); + if(playing) + { + switch (SoundMode) + { + case sdm_PC: + playing += STARTPCSOUNDS; + break; + case sdm_AdLib: + playing += STARTADLIBSOUNDS; + break; + } + MM_SetLock(&(memptr)audiosegs[playing],true); + } + + + SD_StopSound();*/ +// oldborder = bordercolor; +// VW_ColorBorder (15); + + if(beforesort) + beforesort(); + + scan = 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(mminfo_t *mm) +{ + mmblocktype far *scan; + unsigned color,temp;//, i; + long end,owner; + char scratch[80],str[10]; + +//**** VW_SetDefaultColors(); +//**** VW_SetLineWidth(40); +//++++mh temp = bufferofs; +//++++mh bufferofs = 0; +//**** VW_SetScreen (0,0); + + scan = mm->mmhead; + + end = -1; + +//CA_OpenDebug (); + + while (scan) + { + if(scan->attributes & PURGEBITS) + color = 5; // dark purple = purgable + else + color = 9; // medium blue = non purgable + if(scan->attributes & LOCKBIT) + color = 12; // red = locked + if(scan->start<=end) + { + printf("MM_ShowMemory: Memory block order currupted!"); + return; + } + end = scan->start+scan->length-1; +//++++ VW_Hlin(scan->start,(unsigned)end,0,color); +//++++ VW_Plot(scan->start,0,15); + if(scan->next->start > end+1) +//++++ VW_Hlin(end+1,scan->next->start,0,0); // black = free + +//****#if 0 +printf("Location:"); +printf("%x\t", scan->start); +strcpy (scratch,"Size:"); +ltoa ((long)scan->length*16,str,10); +strcat (scratch,str); +strcat (scratch,"\tOwner:0x"); +owner = (unsigned)scan->useptr; +ultoa (owner,str,16); +strcat (scratch,str); +strcat (scratch,"\n"); +//++++write (debughandle,scratch,strlen(scratch)); +fprintf(stdout, "%s", scratch); +//****#endif + + scan = scan->next; + } + +//CA_CloseDebug (); + +//++++mh IN_Ack(); +//**** VW_SetLineWidth(64); +//++++mh bufferofs = temp; +} +//****#endif + +//========================================================================== + + +/* +====================== += += MM_UnusedMemory += += Returns the total free space without purging += +====================== +*/ + +dword MM_UnusedMemory(mminfo_t *mm) +{ + unsigned free; + mmblocktype far *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) +{ + unsigned free; + mmblocktype far *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(mminfo_t *mm, mminfotype *mmi) +{ + printf("EMM %x available\n", mm->EMSVer); + printf("totalEMSpages=%u\n", mm->totalEMSpages); + printf("freeEMSpages=%u\n", mm->freeEMSpages); + printf("EMSpageframe=%Fp\n", mm->EMSpageframe); + 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)); +// printf("\n"); +// printf("UnusedMemory=%lu kb\n", MM_UnusedMemory()/10248); +// printf("TotalFree=%lu kb\n", MM_TotalFree()/10248); +} + +//========================================================================== + +/* +===================== += += MM_EMSVer += +===================== + + +int MM_EMSVer(void) +{ + int EMSver; + __asm + { + mov ah,EMS_VERSION + int EMS_INT + mov EMSver,ax + } + return(EMSver); +}*/ + +//========================================================================== + +/* +===================== += += MM_BombOnError += +===================== +*/ + +void MM_BombOnError(boolean bomb, mminfo_t *mm) +{ + mm->bombonerror = bomb; +} void MM_GetNewBlock(mminfo_t *mm) { diff --git a/src/lib/16_mm.h b/src/lib/16_mm.h index 08a72dd2..1fb701a2 100644 --- a/src/lib/16_mm.h +++ b/src/lib/16_mm.h @@ -1,19 +1,19 @@ -/* 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. +/* 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 @@ -129,7 +129,7 @@ typedef struct memptr bufferseg; boolean mmstarted, bombonerror, mmerror; //void huge *hugeheap; - void huge/*far*/ *farheap; + void huge/*far*/ *farheap; void *nearheap; unsigned totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle; unsigned int EMSVer; @@ -181,29 +181,29 @@ static unsigned numUMBs,UMBbase[MAXUMBS];*/ //========================================================================== -boolean MML_CheckForEMS(void); -unsigned MML_SetupEMS(mminfo_t *mm); -void MML_ShutdownEMS(mminfo_t *mm); -unsigned MM_MapEMS(mminfo_t *mm); -boolean MML_CheckForXMS(mminfo_t *mm); +boolean MML_CheckForEMS(void); +unsigned MML_SetupEMS(mminfo_t *mm); +void MML_ShutdownEMS(mminfo_t *mm); +unsigned MM_MapEMS(mminfo_t *mm); +boolean MML_CheckForXMS(mminfo_t *mm); void MML_SetupXMS(mminfo_t *mm, mminfotype *mmi); -void MML_ShutdownXMS(mminfo_t *mm); -void MML_UseSpace(unsigned segstart, unsigned seglength, mminfo_t *mm); +void MML_ShutdownXMS(mminfo_t *mm); +void MML_UseSpace(unsigned segstart, unsigned seglength, mminfo_t *mm); void MML_ClearBlock(mminfo_t *mm); - -void MM_Startup(mminfo_t *mm, mminfotype *mmi); + +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(mminfo_t *mm); -dword MM_UnusedMemory(mminfo_t *mm); -dword MM_TotalFree(mminfo_t *mm); -void MM_Report(mminfo_t *mm, mminfotype *mmi); -int MM_EMSVer(void); + +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(mminfo_t *mm); +dword MM_UnusedMemory(mminfo_t *mm); +dword MM_TotalFree(mminfo_t *mm); +void MM_Report(mminfo_t *mm, mminfotype *mmi); +int MM_EMSVer(void); void MM_BombOnError(boolean bomb, mminfo_t *mm); void MM_GetNewBlock(mminfo_t *mm); void MM_FreeBlock(mmblocktype *x, mminfo_t *mm); -- 2.39.5