; Hovertank 3-D 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. ifndef ??version ?debug macro endm publicdll macro name public name endm $comm macro name,dist,size,count comm dist name:BYTE:count*size endm else $comm macro name,dist,size,count comm dist name[size]:BYTE:count endm endif ?debug S "memmgr.c" ?debug C E90E549D16086D656D6D67722E63 ?debug C E9D03A9E160749444C49422E48 ?debug C E9AE10A3160A4752415048484F562E48 ?debug C E92592951609534E4453484F562E48 ?debug C E900104D1616433A5C42435C494E434C5544455C7374646172672E+ ?debug C 68 ?debug C E900104D1613433A5C42435C494E434C5544455C646F732E68 ?debug C E900104D1613433A5C42435C494E434C5544455C6D656D2E68 ?debug C E900104D1618433A5C42435C494E434C5544455C7379735C737461+ ?debug C 742E68 ?debug C E900104D1615433A5C42435C494E434C5544455C66636E746C2E68 ?debug C E900104D1616433A5C42435C494E434C5544455C7374646C69622E+ ?debug C 68 ?debug C E900104D1615433A5C42435C494E434C5544455C616C6C6F632E68 ?debug C E900104D1612433A5C42435C494E434C5544455C696F2E68 _TEXT segment byte public 'CODE' _TEXT ends DGROUP group _DATA,_BSS assume cs:_TEXT,ds:DGROUP _DATA segment word public 'DATA' d@ label byte d@w label word _DATA ends _BSS segment word public 'BSS' b@ label byte b@w label word _BSS ends _DATA segment word public 'DATA' db 69 db 77 db 77 db 88 db 88 db 88 db 88 db 48 db 1 dup (0) _DATA ends _TEXT segment byte public 'CODE' ; ; void CheckForEMS (void) ; assume cs:_TEXT _CheckForEMS proc near push bp mov bp,sp sub sp,10 push ss lea ax,word ptr [bp-10] push ax push ds mov ax,offset DGROUP:d@+0 push ax mov cx,9 call near ptr N_SCOPY@ ; ; { ; char emmname[9] = "EMMXXXX0"; ; ; asm mov dx,OFFSET emmname ; mov dx,OFFSET [bp-10] ; ; asm mov ax,0x3d00 ; mov ax,03d00H ; ; asm int 0x21 // try to open EMMXXXX0 device ; int 021H ; ; asm jc error ; jc short @1@506 ; ; ; asm mov bx,ax ; mov bx,ax ; ; asm mov ax,0x4400 ; mov ax,04400H ; ; ; asm int 0x21 // get device info ; int 021H ; ; asm jc error ; jc short @1@506 ; ; ; asm and dx,0x80 ; and dx,080H ; ; asm jz error ; je short @1@506 ; ; ; asm mov ax,0x4407 ; mov ax,04407H ; ; ; asm int 0x21 // get status ; int 021H ; ; asm jc error ; jc short @1@506 ; ; asm or al,al ; or al,al ; ; asm jz error ; je short @1@506 ; ; ; asm mov ah,0x3e ; mov ah,03eH ; ; asm int 0x21 // close handle ; int 021H ; ; asm jc error ; jc short @1@506 ; ; ; // ; // EMS is good ; // ; ; ; return; ; jmp short @1@530 @1@506: ; ; ; error: ; // ; // EMS is bad ; // ; EMSpresent = 0; ; mov word ptr DGROUP:_EMSpresent,0 @1@530: ; ; ; } ; mov sp,bp pop bp ret _CheckForEMS endp ; ; int FindBlock (memptr *ptr) ; assume cs:_TEXT _FindBlock proc near push bp mov bp,sp push si ; ; { ; int i; ; for (i=1;i=MAXBLOCKS) ; inc word ptr DGROUP:_numblocks mov ax,word ptr DGROUP:_numblocks cmp ax,1500 jl short @4@314 ; ; Quit ("Memory manager error: Too many blocks!"); ; mov ax,offset DGROUP:s@+39 push ax call near ptr _Quit pop cx @4@314: ; ; } ; pop di pop si mov sp,bp pop bp ret _InsertBlock endp ; ; void MMStartup (void) ; assume cs:_TEXT _MMStartup proc near push bp mov bp,sp sub sp,14 push si push di ; ; { ; unsigned long length; ; void far *start; ; unsigned nearstart,farstart,EMSstart,seg; ; unsigned nearlength,farlength,emslength,xmslength; ; ; // ; // get all available near conventional memory ; // ; length=coreleft(); ; call near ptr _coreleft mov word ptr [bp-2],0 mov word ptr [bp-4],ax ; ; start = (void far *)(nearheap = malloc(length)); ; push word ptr [bp-4] call near ptr _malloc pop cx mov word ptr DGROUP:_nearheap,ax mov word ptr [bp-6],ds mov word ptr [bp-8],ax ; ; ; // ; // paragraph align it and figure size ; // ; length -= 16-(FP_OFF(start)&15); ; mov ax,word ptr [bp-8] and ax,15 mov dx,16 sub dx,ax sub word ptr [bp-4],dx sbb word ptr [bp-2],0 ; ; length -= EXTRASTACKSIZE; ; sub word ptr [bp-4],4096 sbb word ptr [bp-2],0 ; ; nearlength = length / 16; // now in paragraphs ; mov dx,word ptr [bp-2] mov ax,word ptr [bp-4] mov cl,4 call near ptr N_LXURSH@ mov word ptr [bp-12],ax ; ; nearstart = FP_SEG(start)+(FP_OFF(start)+15)/16; ; mov ax,word ptr [bp-8] add ax,15 mov cl,4 shr ax,cl mov dx,word ptr [bp-6] add dx,ax mov si,dx ; ; ; // ; // get all available far conventional memory ; // ; length=farcoreleft(); ; call near ptr _farcoreleft mov word ptr [bp-2],dx mov word ptr [bp-4],ax ; ; start = farheap = farmalloc(length); ; push word ptr [bp-2] push word ptr [bp-4] call near ptr _farmalloc pop cx pop cx mov word ptr DGROUP:_farheap+2,dx mov word ptr DGROUP:_farheap,ax mov word ptr [bp-6],dx mov word ptr [bp-8],ax ; ; ; // ; // paragraph align it and figure size ; // ; if (FP_OFF(start)) ; cmp word ptr [bp-8],0 je short @5@74 ; ; { ; length -= 16-FP_OFF(start); ; mov ax,16 sub ax,word ptr [bp-8] sub word ptr [bp-4],ax sbb word ptr [bp-2],0 ; ; start = (void far *)MK_FP(FP_SEG(start)+1,0); ; mov ax,word ptr [bp-6] inc ax mov word ptr [bp-6],ax mov word ptr [bp-8],0 @5@74: ; ; } ; farlength = length / 16; // now in paragraphs ; mov dx,word ptr [bp-2] mov ax,word ptr [bp-4] mov cl,4 call near ptr N_LXURSH@ mov word ptr [bp-14],ax ; ; farstart = FP_SEG(start); ; mov di,word ptr [bp-6] ; ; ; totalmem = nearlength + farlength; ; mov ax,word ptr [bp-12] add ax,word ptr [bp-14] mov word ptr DGROUP:_totalmem,ax ; ; ; // ; // detect EMS and allocate 64K at page frame ; // ; CheckForEMS(); ; call near ptr _CheckForEMS ; ; if (EMSpresent) ; cmp word ptr DGROUP:_EMSpresent,0 je short @5@122 ; ; { ; EMSstart = 0xffff; ; mov word ptr [bp-10],65535 ; ; totalmem += 0x1000; // 64k of EMS ; add word ptr DGROUP:_totalmem,4096 ; ; MMMapEMS(); // map in used pages ; call near ptr _MMMapEMS ; ; } ; jmp short @5@146 @5@122: ; ; else ; { ; EMSstart = 0xffff; ; mov word ptr [bp-10],65535 @5@146: ; ; } ; ; // ; // set up locked blocks ; // ; numblocks = 0; ; mov word ptr DGROUP:_numblocks,0 ; ; ; blocks[numblocks].start = 0; ; mov bx,word ptr DGROUP:_numblocks shl bx,1 shl bx,1 shl bx,1 mov word ptr DGROUP:_blocks[bx],0 ; ; blocks[numblocks].length = nearstart; ; mov bx,word ptr DGROUP:_numblocks shl bx,1 shl bx,1 shl bx,1 mov word ptr DGROUP:_blocks[bx+2],si ; ; blocks[numblocks].attributes = LOCKBIT; ; mov bx,word ptr DGROUP:_numblocks shl bx,1 shl bx,1 shl bx,1 mov word ptr DGROUP:_blocks[bx+4],32768 ; ; ; numblocks++; ; inc word ptr DGROUP:_numblocks ; ; ; blocks[numblocks].start = nearstart+nearlength; ; mov bx,word ptr DGROUP:_numblocks shl bx,1 shl bx,1 shl bx,1 mov ax,si add ax,word ptr [bp-12] mov word ptr DGROUP:_blocks[bx],ax ; ; blocks[numblocks].length = farstart-(nearstart+nearlength); ; mov bx,word ptr DGROUP:_numblocks shl bx,1 shl bx,1 shl bx,1 mov ax,si add ax,word ptr [bp-12] mov dx,di sub dx,ax mov word ptr DGROUP:_blocks[bx+2],dx ; ; blocks[numblocks].attributes = LOCKBIT; ; mov bx,word ptr DGROUP:_numblocks shl bx,1 shl bx,1 shl bx,1 mov word ptr DGROUP:_blocks[bx+4],32768 ; ; ; numblocks++; ; inc word ptr DGROUP:_numblocks ; ; ; blocks[numblocks].start = farstart+farlength; ; mov bx,word ptr DGROUP:_numblocks shl bx,1 shl bx,1 shl bx,1 mov ax,di add ax,word ptr [bp-14] mov word ptr DGROUP:_blocks[bx],ax ; ; blocks[numblocks].length = EMSstart-(farstart+farlength); ; mov bx,word ptr DGROUP:_numblocks shl bx,1 shl bx,1 shl bx,1 mov ax,di add ax,word ptr [bp-14] mov dx,word ptr [bp-10] sub dx,ax mov word ptr DGROUP:_blocks[bx+2],dx ; ; blocks[numblocks].attributes = LOCKBIT; ; mov bx,word ptr DGROUP:_numblocks shl bx,1 shl bx,1 shl bx,1 mov word ptr DGROUP:_blocks[bx+4],32768 ; ; ; numblocks++; ; inc word ptr DGROUP:_numblocks ; ; ; ; } ; pop di pop si mov sp,bp pop bp ret _MMStartup endp ; ; void MMShutdown (void) ; assume cs:_TEXT _MMShutdown proc near push bp mov bp,sp ; ; { ; farfree (farheap); ; push word ptr DGROUP:_farheap+2 push word ptr DGROUP:_farheap call near ptr _farfree pop cx pop cx ; ; free (nearheap); ; push word ptr DGROUP:_nearheap call near ptr _free pop cx ; ; ; } ; pop bp ret _MMShutdown endp ; ; void MMMapEMS (void) ; assume cs:_TEXT _MMMapEMS proc near push bp mov bp,sp ; ; { ; ; } ; pop bp ret _MMMapEMS endp ; ; void MMGetPtr (memptr *baseptr,long size) ; assume cs:_TEXT _MMGetPtr proc near push bp mov bp,sp sub sp,8 push si push di ; ; { ; int i,j,k,try; ; unsigned start,end; ; ; // ; // change size from bytes to paragraphs ; // ; size = (size+15)/16; ; xor ax,ax mov dx,16 push ax push dx mov ax,word ptr [bp+8] mov dx,word ptr [bp+6] add dx,15 adc ax,0 push ax push dx call near ptr N_LDIV@ mov word ptr [bp+8],dx mov word ptr [bp+6],ax ; ; ; // ; // try a normal scan, then compress if not found ; // ; for (try=0;try<2;try++) ; mov word ptr [bp-4],0 jmp @8@482 @8@50: ; ; { ; for (i=0;idest) ; cmp si,di jbe short @13@170 ; ; { ; asm cld ; cld jmp short @13@122 @13@98: ; ; while (paragraphs>0xfff) ; { ; MoveParaBase (source,dest,0xfff*8); ; mov ax,32760 push ax push di push si call near ptr _MoveParaBase add sp,6 ; ; source += 0xfff*8; ; add si,32760 ; ; dest += 0xfff*8; ; add di,32760 ; ; paragraphs -= 0xfff; ; sub word ptr [bp+8],4095 @13@122: cmp word ptr [bp+8],4095 ja short @13@98 ; ; } ; MoveParaBase (source,dest,paragraphs*8); ; mov ax,word ptr [bp+8] shl ax,1 shl ax,1 shl ax,1 push ax push di push si call near ptr _MoveParaBase add sp,6 ; ; } ; jmp short @13@314 @13@170: ; ; else ; { ; asm std ; std ; ; source+=paragraphs; ; add si,word ptr [bp+8] ; ; dest+=paragraphs; ; add di,word ptr [bp+8] jmp short @13@242 @13@218: ; ; while (paragraphs>0xfff) ; { ; source-=0xfff; ; sub si,4095 ; ; dest-=0xfff; ; sub di,4095 ; ; MoveParaBaseUp (source,dest,0xfff*8); ; mov ax,32760 push ax push di push si call near ptr _MoveParaBaseUp add sp,6 ; ; paragraphs -= 0xfff; ; sub word ptr [bp+8],4095 @13@242: cmp word ptr [bp+8],4095 ja short @13@218 ; ; } ; source-=paragraphs; ; sub si,word ptr [bp+8] ; ; dest-=paragraphs; ; sub di,word ptr [bp+8] ; ; MoveParaBaseUp (source,dest,paragraphs*8); ; mov ax,word ptr [bp+8] shl ax,1 shl ax,1 shl ax,1 push ax push di push si call near ptr _MoveParaBaseUp add sp,6 ; ; asm cld ; cld @13@314: ; ; } ; } ; pop di pop si pop bp ret _MoveParas endp ; ; void PushUp (int move) ; assume cs:_TEXT _PushUp proc near push bp mov bp,sp sub sp,6 push si push di mov di,word ptr [bp+4] ; ; { ; unsigned source,dest,size; ; int i; ; ; size = blocks[move].length; ; mov bx,di shl bx,1 shl bx,1 shl bx,1 mov ax,word ptr DGROUP:_blocks[bx+2] mov word ptr [bp-6],ax ; ; source = blocks[move].start; ; mov bx,di shl bx,1 shl bx,1 shl bx,1 mov ax,word ptr DGROUP:_blocks[bx] mov word ptr [bp-2],ax ; ; ; for (i=numblocks-1;i>keyblock;i--) ; mov ax,word ptr DGROUP:_numblocks dec ax mov si,ax jmp @14@122 @14@50: ; ; { ; // ; // if the block can fit under this block, move it ; // ; dest = blocks[i].start - size; ; mov bx,si shl bx,1 shl bx,1 shl bx,1 mov ax,word ptr DGROUP:_blocks[bx] sub ax,word ptr [bp-6] mov word ptr [bp-4],ax ; ; if (blocks[i-1].start+blocks[i-1].length <= dest) ; mov bx,si shl bx,1 shl bx,1 shl bx,1 mov ax,word ptr DGROUP:_blocks[bx-8] mov bx,si shl bx,1 shl bx,1 shl bx,1 add ax,word ptr DGROUP:_blocks[bx-6] cmp ax,word ptr [bp-4] ja short @14@98 ; ; { ; // ; // make a copy of block 'move' under block 'i' ; // ; InsertBlock (i-1); ; mov ax,si dec ax push ax call near ptr _InsertBlock pop cx ; ; blocks[i] = blocks[move]; ; mov ax,si shl ax,1 shl ax,1 shl ax,1 add ax,offset DGROUP:_blocks push ds push ax mov ax,di shl ax,1 shl ax,1 shl ax,1 add ax,offset DGROUP:_blocks push ds push ax mov cx,8 call near ptr N_SCOPY@ ; ; blocks[i].start = dest; ; mov bx,si shl bx,1 shl bx,1 shl bx,1 mov ax,word ptr [bp-4] mov word ptr DGROUP:_blocks[bx],ax ; ; *(blocks[i].useptr) = (void _seg *)dest; // modify the pointer to the new spot ; mov bx,si shl bx,1 shl bx,1 shl bx,1 mov bx,word ptr DGROUP:_blocks[bx+6] mov ax,word ptr [bp-4] mov word ptr [bx],ax ; ; MoveParas (source,dest,size); ; push word ptr [bp-6] push word ptr [bp-4] push word ptr [bp-2] call near ptr _MoveParas add sp,6 ; ; break; ; jmp short @14@146 @14@98: dec si @14@122: cmp si,word ptr DGROUP:_keyblock jle @@86 jmp @14@50 @@86: @14@146: ; ; } ; } ; ; // ; // erase original position ; // ; RemoveBlock (move); ; push di call near ptr _RemoveBlock pop cx ; ; keyblock--; // because a block below it was removed ; dec word ptr DGROUP:_keyblock ; ; } ; pop di pop si mov sp,bp pop bp ret _PushUp endp ; ; void PushDown (void) ; assume cs:_TEXT _PushDown proc near push bp mov bp,sp sub sp,10 push si push di ; ; { ; unsigned source,dest,size,end,lowblock,checkblock,i; ; ; size = blocks[keyblock].length; ; mov bx,word ptr DGROUP:_keyblock shl bx,1 shl bx,1 shl bx,1 mov ax,word ptr DGROUP:_blocks[bx+2] mov word ptr [bp-4],ax ; ; source = blocks[keyblock].start; ; mov bx,word ptr DGROUP:_keyblock shl bx,1 shl bx,1 shl bx,1 mov ax,word ptr DGROUP:_blocks[bx] mov word ptr [bp-2],ax ; ; ; // ; // find the lowest space it can be moved into ; // ; for (lowblock = 0;lowblocklowblock+1;i--) ; mov ax,word ptr DGROUP:_keyblock mov word ptr [bp-10],ax jmp short @15@362 @15@314: ; ; blocks[i]=blocks[i-1]; ; mov ax,word ptr [bp-10] shl ax,1 shl ax,1 shl ax,1 add ax,offset DGROUP:_blocks push ds push ax mov ax,word ptr [bp-10] dec ax shl ax,1 shl ax,1 shl ax,1 add ax,offset DGROUP:_blocks push ds push ax mov cx,8 call near ptr N_SCOPY@ dec word ptr [bp-10] @15@362: mov ax,si inc ax cmp ax,word ptr [bp-10] jb short @15@314 ; ; blocks[lowblock+1] = tempblock; ; mov ax,si inc ax shl ax,1 shl ax,1 shl ax,1 add ax,offset DGROUP:_blocks push ds push ax mov ax,offset DGROUP:_tempblock push ds push ax mov cx,8 call near ptr N_SCOPY@ @15@410: ; ; } ; ; //MMBlockDump(); // DEBUG ; } ; return; ; jmp short @15@482 @15@434: inc si @15@458: cmp si,word ptr DGROUP:_keyblock jae @@90 jmp @15@50 @@90: @15@482: ; ; ; nofit:; // keep looking... ; ; } ; } ; pop di pop si mov sp,bp pop bp ret _PushDown endp ; ; void MMSortMem (void) ; assume cs:_TEXT _MMSortMem proc near push bp mov bp,sp dec sp dec sp push si push di ; ; { ; unsigned i,source,dest; ; ; keyblock = 0; ; mov word ptr DGROUP:_keyblock,0 @16@50: ; ; ; do ; { ; keyblock++; ; inc word ptr DGROUP:_keyblock ; ; ; // ; // non-purgable, unlocked blocks will be pushed low in memory ; // ; if ( !(blocks[keyblock].attributes & PURGEBITS) && ; ; ; !(blocks[keyblock].attributes & LOCKBIT) ) ; mov bx,word ptr DGROUP:_keyblock shl bx,1 shl bx,1 shl bx,1 test word ptr DGROUP:_blocks[bx+4],3 jne short @16@122 mov bx,word ptr DGROUP:_keyblock shl bx,1 shl bx,1 shl bx,1 test word ptr DGROUP:_blocks[bx+4],32768 jne short @16@122 ; ; PushDown (); ; call near ptr _PushDown @16@122: ; ; ; } while (keyblock0;i--) ; mov ax,word ptr DGROUP:_numblocks add ax,65534 mov si,ax jmp @16@266 @16@170: ; ; { ; // ; // push all purgable blocks as high as possible ; // Currently they are NOT moved around locked blocks! ; // ; if ( blocks[i].attributes & PURGEBITS ) ; mov bx,si shl bx,1 shl bx,1 shl bx,1 test word ptr DGROUP:_blocks[bx+4],3 jne @@91 jmp @16@242 @@91: ; ; { ; source= blocks[i].start; ; mov bx,si shl bx,1 shl bx,1 shl bx,1 mov ax,word ptr DGROUP:_blocks[bx] mov word ptr [bp-2],ax ; ; dest= blocks[i+1].start-blocks[i].length; ; mov bx,si inc bx shl bx,1 shl bx,1 shl bx,1 mov ax,word ptr DGROUP:_blocks[bx] mov bx,si shl bx,1 shl bx,1 shl bx,1 sub ax,word ptr DGROUP:_blocks[bx+2] mov di,ax ; ; if (source!=dest) ; cmp word ptr [bp-2],di je short @16@242 ; ; { ; MoveParas (source,dest,blocks[i].length); ; mov bx,si shl bx,1 shl bx,1 shl bx,1 push word ptr DGROUP:_blocks[bx+2] push di push word ptr [bp-2] call near ptr _MoveParas add sp,6 ; ; blocks[i].start = dest; ; mov bx,si shl bx,1 shl bx,1 shl bx,1 mov word ptr DGROUP:_blocks[bx],di ; ; *(blocks[i].useptr) = (void _seg *)dest; // modify the pointer to the new spot ; mov bx,si shl bx,1 shl bx,1 shl bx,1 mov bx,word ptr DGROUP:_blocks[bx+6] mov word ptr [bx],di @16@242: dec si @16@266: or si,si jbe @@92 jmp @16@170 @@92: ; ; } ; } ; } ; ; PatchPointers(); // let the main program fix up any ; call near ptr _PatchPointers ; ; // internal references ; } ; pop di pop si mov sp,bp pop bp ret _MMSortMem endp ?debug C E900104D1615433A5C42435C494E434C5544455C535444494F2E48 ; ; void MMBlockDump (void) ; assume cs:_TEXT _MMBlockDump proc near push bp mov bp,sp push si push di ; ; { ; int i; ; unsigned free; ; ; fprintf (stdprn,"-------------\n"); ; mov ax,offset DGROUP:s@+115 push ax mov ax,offset DGROUP:__streams+64 push ax call near ptr _fprintf pop cx pop cx ; ; for (i=0;i