📄 mtfloat.asm
字号:
TITLE MTFLOAT - Floating call helper functions
;***
; MTFLOAT - Float call helper functions
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
; The majority of floating point math support for the runtime is via
; 'Float Calls', i.e., calls to floating point routines at a level
; that utilize an 80[2]87 if present, and the emulator mathpack if not.
; Functions in this module augment those float calls to provide
; additional functionality not provided by the current float call
; interface.
;
;******************************************************************************
INCLUDE switch.inc
INCLUDE rmacros.inc ;Runtime Macro Defintions
USESEG <DV_TEXT>
USESEG MT
USESEG _DATA
USESEG _BSS
INCLUDE seg.inc
INCLUDE compvect.inc ; component dispatch vectors
INCLUDE idmac.inc
INCLUDE rtps.inc
sBegin DV_TEXT
externNP B$NearRet ;for disp vectors in compvect.inc
sEnd DV_TEXT
sBegin _DATA
externW B$AC
externW B$DAC
sEnd _DATA
sBegin _BSS
externB b$VTYP
sEnd _BSS
externFP B$FIST ; IEEE round to nearest integer in DX:AX
sBegin MT_TEXT
ASSUMES CS,MT_TEXT
externNP B$ERR_TM
;***
;B$fmldw - push integer in BX onto top of numeric stack (ST0)
;Purpose:
; This routine is used as an interface to __fldw when the
; 2-byte integer is already in a register.
;Entry:
; BX contains the 2-byte integer to be put on the numeric stack.
;Exit:
; ST0 contains floating point equivalent of the given integer.
;Preserves:
; SI, DI, BX
;******************************************************************************
cProc B$fmldw,<NEAR,PUBLIC>
cBegin
push bx ; put integer in memory
mov bx,sp ; bx = address of integer
fild word ptr [bx] ; load integer
pop bx ; restore BX
cEnd
;***
;B$fmlds - push s.p. number in CXDX onto top of numeric stack (ST0)
;Purpose:
; This routine is used as an interface to __flds when the
; 4-byte real is already in registers.
;Entry:
; CXDX contains the 4-byte s.p. number; the high byte is in CH,
; low byte is in DL.
;Exit:
; ST0 contains floating point equivalent of the given s.p. number.
;Preserves:
; SI, DI, CX, DX
;******************************************************************************
cProc B$fmlds,<NEAR,PUBLIC>
cBegin
PUSH CX ;push high word first
PUSH DX
MOV BX,SP ;now BX points to s.p. number
fld dword ptr [bx] ; load number into ST0
add sp,4 ; reset SP
cEnd
;***
;B$ftolrup - Round ST0 up and pop, result in DX:AX
;Purpose:
; This routine acts the same as __ftol, except the number is rounded
; up instead of being truncated toward zero.
;Entry:
; ST0 contains number to pop and round up.
;Exit:
; ST0 is popped, rounded 32-bit integer equivalent in DX:AX
;Preserves:
; SI, DI, BX, CX
;******************************************************************************
cProc B$ftolrup,<NEAR,PUBLIC>
cBegin
call B$FIST ; temp (incorrect) rounding hack
cEnd
;***
;B$ftolrnd - Round ST0 to nearest integer & pop, result in DX:AX
;Purpose:
; This routine acts the same as __ftol, except the number is rounded
; to the nearest integer (rounded to even number if equidistant) instead
; of being truncated toward zero.
;Entry:
; ST0 contains number to pop and round.
;Exit:
; ST0 is popped, rounded 32-bit integer equivalent in DX:AX
;Preserves:
; SI, DI, BX, CX
;******************************************************************************
cProc B$ftolrnd,<NEAR,PUBLIC>
cBegin
call B$FIST
cEnd
;***
;B$FRCINT - Force to integer routine compiler runtime interface routine
; Purpose:
; Convert contents of floating point accumulator to integer as
; follows: Determine the type of variable contained in the FAC by
; checking the contents of b$VTYP. If the variable is a string
; (b$VTYP = 3), issue a type mismatch error. If b$VTYP is greater
; than 3, assume single precision and return the integer equivalent
; in BX. If the b$VTYP is less than 3, assume integer and simply
; move the leftmost two bytes of the FAC contents to BX.
;
; Entry:
; FAC contains a variable, b$VTYP contains its type (integer is type 2,
; string is type 3, single precision is type 4, double precision is type
; 8). Most often the variable in the FAC is a single precision number.
; Exit:
; BX = integer result
; If no error occurred, b$VTYP = 2.
; Preserves:
; ES,SI,DI
;****
cProc B$FRCINT,<NEAR,PUBLIC>
cBegin
MOV BX,OFFSET DGROUP:B$AC
MOV DL,[b$VTYP]
CMP DL,VT_SD ; Is value type less than or equal to 3?
JNB ISFLPT ;No: assume it is single precision
JZ STRERR ;String: type mismatch error
MOV BX,[BX] ;Put integer in BX
RET
STRERR: ;String: issue type mismatch error
JMP B$ERR_TM ;Type mismatch error routine
ISFLPT: ;Floating pt number in accumulator
PUSH ES ;save across float calls
PUSH BX ;save pointer to B$AC
CMP DL,VT_R4
JNZ FRC_DUBL ;brif vtyp not s.p.
fld dword ptr [bx] ; load s.p. number to ST0
JMP SHORT FRC_CONT
FRC_DUBL:
DbAssertRelB DL,z,8d,MT_TEXT,<MTFLOAT.ASM: B$FRCINT: invalid var type>
fld qword ptr [bx] ; load d.p. number to ST0
FRC_CONT:
CALL B$ftolrnd ;DX:AX = integer equiv. of number
AND DX,08000H ; mask off all but sign bit
OR AX,DX ;mask sign bit into 2-byte integer
POP BX ;BX points to B$AC
POP ES
MOV [BX],AX ;save integer in B$AC
XCHG AX,BX ;BX is retval
MOV [b$VTYP],VT_I2 ; Make value type integer
cEnd
sEnd MT_TEXT
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -