highload.inc

来自「Dos6.0」· INC 代码 · 共 1,910 行 · 第 1/5 页

INC
1,910
字号

gxnE:	stc			; In this case, we need to set the carry
	jmp short gxnX		; and leave--there were no digits given.

gxnQ:	dec	si		; Don't read in the offensive character.
	clc			; And clear carry, so they know it's okay.

gxnX:	popreg	<ds, cx, bx>
	ret
GetXNum	endp

; -----------------------------------------------------------------------------
;*** mul32 - multiplies the number in DX:AX by gnradix
; -----------------------------------------------------------------------------
; ENTRY:   DX:AX = the number to be multiplied, BX = 0, gnradix = multiplier
; EXIT:    DX:AX has been multiplied by gnradix if carry clear; BX still 0
; ERROR:   Carry set if number was too large
; USES:    Flags, AX, DX
; -----------------------------------------------------------------------------

mul32	proc	near
	push	ax		; DX=old:hi, AX=old:lo, TOS=old:lo, BX=0
	mov	ax, dx		; DX=old:hi, AX=old:hi, TOS=old:lo, BX=0
	mul	gnradix		; DX=?,      AX=new:hi, TOS=old:lo, BX=0
	jc	m32E		; Too big?

	mov	dx, ax		; DX=new:hi, AX=new:hi, TOS=old:lo, BX=0
	pop	ax		; DX=new:hi, AX=old:lo, TOS=orig,   BX=0

	xchg	dx, bx		; DX=0,      AX=old:lo, TOS=orig,   BX=new:hi
	mul	gnradix		; DX=carry,  AX=new:lo, TOS=orig,   BX=new:hi
	xchg	dx, bx		; DX=new:hi, AX=new:lo, TOS=orig,   BX=carry
	add	dx, bx		; DX=new:hi, AX=new:lo, TOS=orig,   BX=carry
	xor	bx, bx		; DX=new:hi, AX=new:lo, TOS=orig,   BX=0
	ret

m32E:	pop	ax
	ret
mul32	endp

; -----------------------------------------------------------------------------
;*** toPara - divides DX:AX by 16; result in AX only (discards extra DX data)
; -----------------------------------------------------------------------------
; ENTRY:   DX:AX = the number to be divided
; EXIT:    Interpereting DX:AX as bytes, AX=paragraph equivalent, 0xFFFF max
; ERROR:   None
; USES:    Flags, AX, DX
; -----------------------------------------------------------------------------
; Note: The 386 has a 32-bit SHR, which would work perfectly for this... but we
;       can't ensure a 386 host machine.  Sorry.
; -----------------------------------------------------------------------------

toPara	proc	near
	push	cx		; DX:AX=HHHH hhhh hhhh hhhh:LLLL llll llll llll

	mov	cl, 4		;
	shr	ax, cl		; DX:AX=HHHH hhhh hhhh hhhh:0000 LLLL llll llll
	xchg	ax, dx		; DX:AX=0000 LLLL llll llll:HHHH hhhh hhhh hhhh
	mov	cl, 12
	shl	ax, cl		; DX:AX=0000 LLLL llll llll:hhhh 0000 0000 0000
	or	ax, dx		;    AX=hhhh LLLL llll llll

	pop	cx
	ret
toPara	endp

ifdef DEBUG_PRTABLE
; -----------------------------------------------------------------------------
;*** PrTable - produces a printout of the variables in highvar.inc
;            -- The data are reported in this format:
;
;	ShrinkUMBs? (01/00)	LoadAddr (DH only)	UMB0 (load UMB number)
;	00	conv_used?	conv_size (ignored)
;	01	umb1_used?	umb1_size (00==not specified)
;	02	umb2_used?	umb2_size
;		...
;	0F	umb15_used?	umb15_size
;
; -----------------------------------------------------------------------------
; ENTRY/EXIT : Nothing
; USES:        Flags, AX
; -----------------------------------------------------------------------------
; This routine is for debugging only, and should not be included in the final
; versions of loadhigh and devicehigh (if it's called, you'll know).  To use
; it, you'll need to add "include wordout.inc" if it's not available already.
; -----------------------------------------------------------------------------

	public	PrTable

PrTable	proc	near
	pushreg	<cx, si, ds>
	dataseg	ds			; Point DS into appropriate data seg

	mov	al, fUmbTiny
	call	byteout
	printtab
	mov	ax, SegLoad
	call	wordout
	printtab
	mov	al, UmbLoad
	call	byteout
	printtab
	mov	al, fInHigh
	call	byteout
	printcr
	printcr

	xor	cx,  cx			; For each entry

; ----------------------------
; PT10--CL = index into arrays
; ----------------------------

pt10:	mov	al, cl
	call	byteout
	printtab

	mov	si, offset DS:UmbUsed	; on the UmbUsed array,
	mov	ax, cx
	add	ax, si
	mov	si, ax
	lodsb				; Get used element
	call	byteout
	printtab

	mov	si, offset DS:UmbSize	; on the UmbSize array,
	mov	ax, cx
	shl	ax,  1			; ax *= 2 (two bytes per element)
	add	ax, si
	mov	si, ax
	lodsw				; Get size element
	call	wordout
	printcr

	inc	cx
	cmp	cx, MAXUMB
	jb	pt10

	popreg	<ds, si, cx>
	normseg	ds			; Return DS
	ret
PrTable endp

endif	; DEBUG_PRTABLE

; -----------------------------------------------------------------------------
;*** UmbHead - returns in AX the address of the first UMB block (0x9FFF)
; -----------------------------------------------------------------------------
; ENTRY:  Nothing
; EXIT:   AX contains 0x9FFF for most systems
; ERROR:  Carry set if pointer is 0xFFFF (if not set up yet--DH runs into this)
; USES:   Flags, AX
; -----------------------------------------------------------------------------
; Early in the boot-cycle, the pointer used to obtain this value isn't set up;
; to be precise, before a UMB provider is around.  In this event, the pointer
; is always set to 0xFFFF; it changes once a provider is around.  On most
; machines (all of 'em I've seen), it changes to 0x9FFF at that point.
; -----------------------------------------------------------------------------

	public	UmbHead

UmbHead	proc	near
	pushreg	<si, ds, es>

	mov	ah, DOS_GET_DOS_LISTS	; Call int 21h, function 52h...
	int	21h

	mov	ax, es:[DOS_UMB_HEAD]	; And read what's in ES:[008C]
	cmp	ax, 0FFFFh
	jz	uhE			; If it's 0xFFFF, it's an error...

	clc				; Else, it isn't (CLC done by prev cmp)
	jmp short uhX

uhE:	stc
uhX:	popreg	<es, ds, si>
	ret
UmbHead	endp

; -----------------------------------------------------------------------------
;*** isSysMCB - sets ZF iff ES points to an MCB owned by "SC" + (8 or 9)
; -----------------------------------------------------------------------------
; ENTRY:  ES:0 should point to a valid MCB
; EXIT:   ZF set if owned by SC+8 or SC+9 (for japan)
; USES:   Flags
; -----------------------------------------------------------------------------

isSysMCB	proc	near
	push	ax

	mov	ax, es:[arena_owner]	; Check the owner...
	cmp	ax, SystemPSPOwner	; 8 (for US OR Japan) is valid
	jz	ism10
	cmp	ax, JapanPSPOwner	; 9 (for Japan) is valid
	jz	ism10
	jmp short ismX			; Anything else isn't.

ism10:	mov	ax, word ptr es:[arena_name]	; Check the name...
	cmp	ax, 'CS'

ismX:	pop	ax
	ret
isSysMCB	endp

; -----------------------------------------------------------------------------
;*** AddrToUmb - converts a segment address in AX to its appropriate UMB number
; -----------------------------------------------------------------------------
; ENTRY:  AX contains a segment address
; EXIT:   AX will contain the UMB number which contains the address (0==conv)
; ERROR:  If the address is above UM Range, AX will return as FFFF.
; USES:   Flags, AX
; -----------------------------------------------------------------------------
; An address in the following areas is treated as:
;    0      <-> umbhead (0x9FFF)          = Conventional memory
;    0x9FFF <-> addr of first UM sys MCB  = UMB #1
;      ...
;    addr of last UM sys MCB <-> TOM      = invalid; returns #0xFFFF
; -----------------------------------------------------------------------------

AddrToUmb	proc	near
	pushreg	<cx, dx, es>

	mov	dx, ax		; DX = address to search for

	call	UmbHead		; AX = first segment
	jc	atuE		; If it couldn't get it, error out.

	mov	es, ax		; ES = first UMB segment
	xor	cx, cx		; Pretend we're on UMB 0 for now... (cx = UMB#)

; ----------------------------------------
; ATU10--ES - Current MCB address
;        DX - Address given for conversion
;        CX - Current UMB #
; ----------------------------------------

atu10:	mov	ax, es
        cmp	ax, dx		; Present segment >= given segment?
	jae	atuX		; Yep--done.

	call	isSysMCB	; Returns with ZF set if this is a system MCB
	jnz	atu20

	inc	cx		; If it _was_ a system MCB, we're in a new UMB.

atu20:	mov	al, es:[arena_signature]
	cmp	al, arena_signature_end
	jz	atu30		; 'Z' means this was the last MCB... that's it.

	NextMCB	es, ax

	jmp short atu10

; -----------------------------------------------------------------------------
; if we get to atu30, they specified a number that was past the last MCB.
; make sure it's not _inside_ that MCB before we return an error condition.
; -----------------------------------------------------------------------------

atu30:	mov	ax, es
	add	ax, es:[arena_size]
	cmp	ax, dx		; Present >= given?
	jae	atuX		; Yep! It _was_ inside.

atuE:	xor	cx, cx		; Else, fall through with UMB # == -1
	dec	cx		; (that makes it return 0xFFFF and sets CF)

atuX:	mov	ax, cx		; Return the UMB number in AX
	popreg	<es, dx, cx>
	ret
AddrToUmb	endp

; -----------------------------------------------------------------------------
;*** convUMB - checks after GetXNum to convert an address to a UMB number
;            -- if GetXNum read a hex number, we interperete that as a segment
; address rather than a UMB number... and use that address to look up a UMB.
; This routine checks for that condition and calls AddrToUmb if necessary.
; -----------------------------------------------------------------------------
; ENTRY:  AX contains a UMB number or segment, gnradix has been set by GetXNum
; EXIT:   AX will contain a UMB number
; ERROR:  None
; USES:   Flags, AX
; -----------------------------------------------------------------------------

convUMB	proc	near
	cmp	gnradix, 16
	jnz	cu10		; If it didn't read in hex, it's not an address
	call	AddrToUmb	; Else, convert the address to a UMB number
	cmp	ax, 0FFFFh
	jnz	cu10
	inc	ax		; If too high, ignore it (make it conventional)
cu10:	ret
convUMB	endp

; -----------------------------------------------------------------------------
;*** setUMBs - links umbs and sets allocation strategy for a load
;            -- if LoadHigh, the allocation strategy MAY be LOW_FIRST instead
; of the usual HIGH_FIRST.  See the code.
; -----------------------------------------------------------------------------
; ENTRY:  None
; EXIT:   None
; ERROR:  None
; USES:   Flags, fm_umb, fm_strat
; -----------------------------------------------------------------------------

setUMBs	proc	near
	pushreg	<ax, bx>

	call	fm_link

ifdef HV_LoadHigh
	mov	ax, DOS_CHECK_STRATEGY
	int	21h

	putdata	fm_strat, al	; Store the current strategy for later restore

	and	ax, 007Fh	; 0000.0000.0111.1111 == All that other stuff
	push	ax		; Watch this carefully...

	call	loadLow		; returns al==0 if load low, al==1 if loadhigh
	ror	al, 1		; Shift that to al==0 or al==0x80

	pop	bx		; ...pushed as AX above
	or	bl, al		; Now we have 0000.0000.?111.1111 in BX;

	mov	ax, DOS_SET_STRATEGY ; with ? ==1 if load highfirst.  Perfect!

	int	21h
endif

	popreg	<bx, ax>
	ret
setUMBs	endp

; -----------------------------------------------------------------------------
;*** loadLow - returns AL==0 if UMB0 == 0, else AL==1
; -----------------------------------------------------------------------------
; ENTRY:  None
; EXIT:   AL==0 if mem strategy should be set to LOW_FIRST, else AL==1
;         Carry set if UMB0 not specified (_NOT_ an error)
; ERROR:  None
; USES:   Flags, fm_strat, fm_umb
; -----------------------------------------------------------------------------
; We want to set the memory strategy to LOW_FIRST if the user specified a
; load UMB, and it is 0.  That 0 can be either from the user having _specified_
; zero (/L:0;...), or from having specified a too-big min size (/L:1,99999999)
; such that the load UMB is too small, and shouldn't be used.
; -----------------------------------------------------------------------------


loadLow	proc	near
	push	ds
	dataseg	ds		; Point DS into appropriate data segment

	mov	al, UmbLoad
	cmp	al, UNSPECIFIED
	jnz	ll10

	mov	al, 1		; Return with AL==1 && STC if no UMBs specified
	stc
	jmp short llX

ll10:	or	al, al		; AL=the load UMB: Is it == 0?
	jz	llX		; Yep... CF==0 (from OR) && AL=0, so just exit

	mov	al, 1
	clc

llX:	pop	ds		; Return DS to where it was
	normseg	ds		;
	ret
loadLow	endp

; -----------------------------------------------------------------------------
;*** HideUMBs - links UMBs and hides upper-memory as appropriate
; -----------------------------------------------------------------------------
; ENTRY:  None
; EXIT:   None
; ERROR:  None
; USES:   Flags, fm_strat, fm_umb
; -----------------------------------------------------------------------------

	public	HideUMBs

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?