highload.inc
来自「Dos6.0」· INC 代码 · 共 1,910 行 · 第 1/5 页
INC
1,910 行
; -----------------------------------------------------------------------------
isSpecified proc near
push ax
xor bh, bh
mov bl, al
getdata al, DS:UmbUsed[bx]
or al, al ; Sets ZF if al==0 (ie, if unspecified)
pop ax
ret
isSpecified endp
; -----------------------------------------------------------------------------
;*** shrinkMCB - breaks an MCB into two pieces, the lowest one's size==AX
; -----------------------------------------------------------------------------
; ENTRY: AX == new size, ES:0 == current MCB
; EXIT: None; MCB broken if carry clear
; ERROR: Carry set if MCB isn't as large as AX+0x20 (not a useful split)
; USES: Flags
; -----------------------------------------------------------------------------
; If the size of the to-be-split MCB isn't at least 0x20 bytes greater than
; the specified new size, the split is useless; if it's onnly 0x10 bytes, that
; 0x10 will be used to make a header that mentions a 0-byte free space, and
; that just sucks up 0x10 bytes for nothing. So we make 0x20 bytes the
; minimum for performing a split.
; -----------------------------------------------------------------------------
MIN_SPLIT_SIZE equ 20h
shrinkMCB proc near
pushreg <bx, cx, es>
mov bx, ax ; Move things around... and
mov ax, es ; save this one for later.
mov cx, es:[arena_size]
sub cx, MIN_SPLIT_SIZE
cmp bx, cx ; {New size} vs {Current Size-20h}
ja smE ; if wanted_size > cur-20h, abort.
mov dl, es:[arena_signature]
mov cx, es:[arena_size]
mov word ptr es:[arena_size], bx
mov byte ptr es:[arena_signature], 'M'
add ax, bx
inc ax
mov es, ax ; Move to new arena area
mov ax, cx
sub ax, bx
dec ax ; And prepare the new size
mov byte ptr es:[arena_signature], dl
mov word ptr es:[arena_owner], 0
mov word ptr es:[arena_size], ax
mov ax, ' '
mov word ptr es:[arena_name+0], ax
mov word ptr es:[arena_name+2], ax
mov word ptr es:[arena_name+4], ax
mov word ptr es:[arena_name+6], ax
clc
jmp short smX
smE: stc
smX: popreg <es, cx, bx>
ret
shrinkMCB endp
; -----------------------------------------------------------------------------
;*** hideUMB? - hides as appropriate the UMB in CL
; -----------------------------------------------------------------------------
; ENTRY: CL should be to a valid UMB number, and AX to its address (findUMB)
; EXIT: None; UMB is hidden as necessary
; ERROR: None
; USES: Flags, AX, CX
; -----------------------------------------------------------------------------
; PRIMARY LOGIC:
;
; If the UMB is specified in the DH/LH statement, then:
; If the largest free segment is too small (check specified size), then:
; Pretend it wasn't ever specified, and fall out of this IF.
; Else, if largest free segment is LARGER than specified size, then:
; If /S was given on the command-line, then:
; Break that element into two pieces
; Set a flag that we're shrinking
; Endif
; Endif
; Endif
; If the UMB is NOT specified (or was removed by the above):
; Hide all free elements in the UMB
; If the flag that we're shrinking was set, then:
; UN-hide the lower portion of the shrunken UMB
; ENDIF
; ENDIF
; -----------------------------------------------------------------------------
hideUMB? proc
pushreg <bx, dx, es>
mov al, cl
call isSpecified ; Returns ZF set if al's umb was NOT specified
jz hu?20
mov al, cl ; Retrieve the size of the largest
call BigFree ; free element in AX; put its address in ES
jc hu?20 ; Oops. Errors mean skip this part.
push ax ; TOS==size of BigFree in UMB (popped as BX)
mov al, cl ; Retrieve the user's specified
call GetSize ; minimum size for this umb (into AX)
pop bx ; Now BX==BigFree, AX==Specified Size
or ax, ax ; If they didn't specify one,
jz hu?20 ; Skip over all this.
cmp ax, bx ; Ah... if (specified > max free)
jbe hu?10
mov al, cl ; Then mark that UMB as unused. Nya nya.
call unMarkUMB
jmp short hu?20
hu?10: call isTiny ; Returns ZF clear if user specified /S
jz hu?20
call shrinkMCB ; They specified /S, so shrink the MCB to AX
jc hu?20 ; Ah... if didn't shrink after all, skip this:
mov dx, es
jmp short hu?30 ; Skip the spec check.. we wanna hide this one.
hu?20: mov ax, cx
call isSpecified ; If they specified this UMB, we're done...
jnz hu?X ; so leave.
xor dx, dx
hu?30: mov al, cl
call hideUMB ; Hides everything in UMB #al
or dx, dx ; Did we shrink a UMB? If not, DX==0,
jz hu?X ; So we should leave.
mov es, dx ; Ah, but if it isn't, DX==the MCB's address;
call unHideMCB ; Un-hides the lower portion of that MCB.
hu?X: popreg <es, dx, bx>
ret
hideUMB? endp
; -----------------------------------------------------------------------------
;*** UnFreeze - Marks FROZEN elements as FREE
; -----------------------------------------------------------------------------
; Entry: None
; Exit: None; all 8+FROZEN elements are marked as FREE, from any UMB.
; Error: None
; Uses: Flags
; -----------------------------------------------------------------------------
public UnFreeze
UnFreeze proc near
pushreg <ax, es>
call UmbHead ; Returns with carry if err, else ES == MCB
jc ufX
mov es, ax
; ------------------------------
; UF10--ES - Current MCB address
; ------------------------------
uf10: call isFrozMCB ; Returns with ZF set if MCB is FROZEN
jnz uf20
call unHideMCB
uf20: mov al, es:[arena_signature]
cmp al, arena_signature_end
jz ufX ; 'Z' means this was the last MCB... that's it.
NextMCB es, ax ; Go on forward.
jmp short uf10
ufX: popreg <es, ax>
ret
UnFreeze endp
; -----------------------------------------------------------------------------
;*** isFrozMCB - returns with ZF set if current MCB (ES:0) is FROZEN
; -----------------------------------------------------------------------------
; ENTRY: ES:0 should point to an MCB
; EXIT: ZF set if MCB is frozen, else !ZF
; ERROR: None
; USES: Flags
; -----------------------------------------------------------------------------
isFrozMCB proc near
push ax
mov ax, es:[arena_owner] ; Check the owner...
cmp ax, SystemPSPOwner ; 8 (for US OR Japan) is valid
jnz ifmX
mov ax, word ptr es:[arena_name]
cmp ax, 'RF'
jnz ifmX
mov ax, word ptr es:[arena_name+2]
cmp ax, 'ZO'
jnz ifmX
mov ax, word ptr es:[arena_name+4]
cmp ax, 'NE'
jnz ifmX
mov ax, word ptr es:[arena_name+6]
cmp ax, ' '
ifmX: pop ax
ret
isFrozMCB endp
; -----------------------------------------------------------------------------
;*** frezMCB - marks as 8+FROZEN the MCB at ES:0
; -----------------------------------------------------------------------------
; ENTRY: ES:0 should point to an MCB
; EXIT: None; MCB frozen
; ERROR: None
; USES: None
; -----------------------------------------------------------------------------
frezMCB proc near
mov es:[arena_owner], SystemPSPOwner
mov word ptr es:[arena_name+0], 'RF'
mov word ptr es:[arena_name+2], 'ZO'
mov word ptr es:[arena_name+4], 'NE'
mov word ptr es:[arena_name+6], ' '
ret
frezMCB endp
; -----------------------------------------------------------------------------
;*** FreezeUM - Marks FROZEN all UM elements now FREE, save those in load UMB
; -----------------------------------------------------------------------------
; Entry: None
; Exit: None; all free elements not in load UMB marked as 8+FROZEN
; Error: None
; Uses: Flags
; -----------------------------------------------------------------------------
FreezeUM proc near
pushreg <ax, cx, dx, es>
call GetLoadUMB
xor ah, ah ; Zap ah, so al==ax
mov dx, ax ; Store the load UMB in DX, so we can skip it
call UmbHead ; Returns first UMB segment in AX
mov es, ax
xor cx, cx ; Pretend we're on UMB 0 for now...
; -----------------------------------------
; FUM10--ES - Current MCB address
; CX - Current UMB number
; DX - UMB number to skip (load UMB)
; -----------------------------------------
fum10: call isSysMCB ; Returns with ZF set if owner is SYSTEM
jnz fum20
inc cx ; If it _was_ SYSTEM, we're in a new UMB.
fum20: cmp cx, dx ; If this is the load UMB, we don't want to
jz fum30 ; freeze anything... so skip that section.
call isFreeMCB ; Oh. If it's not free, we can't freeze it
jnz fum30 ; either.
call frezMCB
fum30: mov al, es:[arena_signature]
cmp al, arena_signature_end
jz fumX ; 'Z' means this was the last MCB... that's it.
NextMCB es, ax ; Go on forward.
jmp short fum10
fumX: popreg <es, dx, cx, ax>
ret
FreezeUM endp
; -----------------------------------------------------------------------------
;*** UmbTest - returns with carry set if UMBs are not available, else CF==false
; -----------------------------------------------------------------------------
; ENTRY: None
; EXIT: Carry is clear if UMBs are available, or set if they are not
; ERROR: None
; USES: CF (AX,BX,DS,ES pushed 'cause they're used by others)
; -----------------------------------------------------------------------------
public UmbTest
UmbTest proc near
pushreg <ax, bx, ds, es>
call fm_link ; Link in UMBs (if not already linked)
call WalkMem ; Check to see if they're really linked
pushf ; And remember what we found out
call fm_unlink ; Unlink UMBs (if WE have linked 'em)
popf ; And restore what we found out.
popreg <es, ds, bx, ax>
ret
UmbTest endp
; -----------------------------------------------------------------------------
;*** WalkMem - travels memory chain and returns carry clear iff UMBs are linked
; -----------------------------------------------------------------------------
; ENTRY: None
; EXIT: Carry SET if MCB chain stops before 9FFF, CLEAR if stops >= 9FFF.
; ERROR: None
; USES: Flags
; -----------------------------------------------------------------------------
WalkMem proc near
pushreg <ax, bx, es>
mov ah, DOS_GET_DOS_LISTS ; Call int 21h, function 52h...
int 21h
mov ax, es:[bx -2]
mov es, ax
; ------------------------------
; UM10: ES = Current MCB pointer
; ------------------------------
um10: mov al, es:[arena_signature]
cmp al, arena_signature_end
jz um20 ; If signature == 'Z', hay no more.
NextMCB es, bx ; Move to the next MCB
jmp short um10 ; And restart the loop.
um20: mov ax, es
cmp ax, 9FFFh ; This sets CF iff ax < 9FFF.
popreg <es, bx, ax>
ret
WalkMem endp
; -----------------------------------------------------------------------------
;*** hl_unlink - unlinks UMBs if fm_umb is set to 0; restores strategy too
; -----------------------------------------------------------------------------
; ENTRY: fm_umb == 1 : leave linked, else unlink
; EXIT: None
; ERROR: None
; USES: AX, BX
; -----------------------------------------------------------------------------
hl_unlink proc near
xor bh, bh
getdata bl, fm_umb ; Restore original link-state
mov ax, DOS_SET_UMBLINK
int 21h
ifdef HV_LoadHigh
xor bh, bh
getdata bl, fm_strat ; Restore original mem-alloc strategy
mov ax, DOS_SET_STRATEGY
int 21h
endif
ret
hl_unlink endp
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?