📄 grspace.asm
字号:
PAGE 56,132
TITLE GRSPACE - Compute space left in an array
;***
; GRSPACE - Compute space left in an array
;
; Copyright <C> 1987, Microsoft Corporation
;
;Purpose:
;
; Graphics support routines for computing space left in an array.
;
;******************************************************************************
INCLUDE switch.inc
INCLUDE rmacros.inc ; Runtime Macro Defintions
useSeg _BSS
useSeg GR_TEXT
useSeg FH_TEXT
INCLUDE seg.inc
INCLUDE array.inc
sBegin _BSS
externB b$HugeShift ;OS dependent selector increment
sEnd _BSS
sBegin FH_TEXT
externNP B$ADArraySize
sEnd FH_TEXT
sBegin GR_TEXT
assumes CS,GR_TEXT
externNP B$ERR_BS
SUBTTL B$ComputeSpace - Compute space left in an array.
PAGE
;***
; B$ComputeSpace - compute space remaining in array
;
;Purpose:
; Given an array descriptor and an address into the array,
; compute the space, in bytes, from the address to the
; end of the array.
;
;Entry:
; fpData = array address (possibly after the array starting address)
; pAd = array descriptor
;Exit:
; [DX:AX] = array space remaining in bytes
; [ES:SI] = start address to use
;Uses:
;
;Exceptions:
; to B$ERR_BS
;******************************************************************************
cProc B$ComputeSpace,<PUBLIC,NEAR>
parmD fpData ;far ptr to start of array data
parmW pAd ;pointer to array descriptor of interest
cBegin
MOV BX,pAd ;[BX] = pointer to array descriptor
MOV AX,[BX].AD_fhd.FHD_hData ;get seg from array desc
CWD
OR AX,DX ;was seg 0 (array unallocated)?
JZ CompSpaceExit ;yes, exit with DX:AX = 0
cCall B$ADArraySize ;[DX:AX] = size of the array in bytes
PUSH DX
PUSH AX ;save that
LES SI,DWORD PTR [BX].AD_fhd.FHD_oData ;[ES:SI] = base array address
MOV DX,Seg_fpData
MOV AX,Off_fpData ;[DX:AX] = place to put data in array
OR DX,DX ;Is there a specified place?
JNZ ComputeSpace ;brif so
MOV DX,ES ;else use array base address
MOV AX,SI
ComputeSpace:
PUSH DX
PUSH AX ;save array address
; Convert seg:offset pairs into 20 bit addresses and subtract
; them to compute 20 bit offset from base of array.
cCall ConvToAddr ;convert seg:off in [DX:AX] to 20 bit addr
PUSH BX ;in [BX:AX]
PUSH AX ;save address of get data
XCHG AX,SI
MOV DX,ES ;[DX:AX] = array base seg:offset
cCall ConvToAddr ;[BX:AX] = converted 20 bit address
XCHG AX,CX ;[BX:CX] = array base address
POP AX
POP DX ;[DX:AX] = array get address
SUB AX,CX ;low offset
SBB DX,BX ;[DX:AX] = 20 bit offset from array base
JC OVERFL ;error if get addr < array base addr
POP SI
POP ES ;[ES:SI] = address for get data
POP BX
POP CX ;[CX:BX] = size of array
SUB BX,AX ;[BX] = low difference
SBB CX,DX ;[CX:BX] = room left for get data
XCHG CX,DX ;swap so that
XCHG BX,AX ; [DX:AX] = space remaining
JC OVERFL ;Jump if indexed off of array end
CompSpaceExit:
cEnd
OVERFL: JMP B$ERR_BS
;***
; ConvToAddr - converts a segment offset pair to 20 bit address
;
;Purpose:
; Converts the segment offset pair in DX:AX to a 20 bit address in BX:AX.
; Added for DOS 3 indexed GETs.
;
;Entry:
; DX:AX = segment offset pair to be converted.
;
;Exit:
; BX:AX = 20 bit address
;
;Uses:
; Per convention
;
;Exceptions:
; None.
;
;******************************************************************************
cProc ConvToAddr,<NEAR>
cBegin
XOR BX,BX
MOV CX,4
SegLoop:
SHL DX,1
RCL BX,1
LOOP SegLoop ;[BX] = high 4 bits of seg
ADD AX,DX ;add low 4 bits of seg to high 4 bits of offset
ADC BX,CX ;[BX:AX] = 20 bit address (CX=0 from LOOP)
cEnd
sEnd GR_TEXT
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -