You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
4.7 KiB
192 lines
4.7 KiB
page ,132
|
|
subttl emspec.asm - Special emulator functions for speed
|
|
;***
|
|
;emspec.asm - Special emulator functions for speed
|
|
;
|
|
; Copyright (c) 1987-89, Microsoft Corporation
|
|
;
|
|
;Purpose:
|
|
; Special emulator functions for speed
|
|
;
|
|
; This Module contains Proprietary Information of Microsoft
|
|
; Corporation and should be treated as Confidential.
|
|
;
|
|
;Revision History:
|
|
; See emulator.hst
|
|
;
|
|
;*******************************************************************************
|
|
|
|
|
|
ProfBegin SPEC
|
|
|
|
|
|
pub loadcontrolword
|
|
ifdef QB3
|
|
or al,2 ; mask denormal exceptions
|
|
endif ;QB3
|
|
mov [UserControlWord],ax ; save user's version
|
|
and ax,0FF3CH ; Turn off reserved, IEM, Denormal
|
|
; & invalid exception mask bits
|
|
ifndef frontend
|
|
ifndef only87
|
|
cmp [Have8087],0 ; Non-0 if 8087 present
|
|
je EmulateFLDCW
|
|
endif ;only87
|
|
|
|
mov [REMLSW],ax ; use this cell (not busy)
|
|
fnop ; fix for intel erratum #8
|
|
fldcw [REMLSW] ; 8087 gets new control word
|
|
endif ;frontend
|
|
|
|
pub EmulateFLDCW
|
|
mov [ControlWord],ax ; save internal control word
|
|
ret
|
|
|
|
|
|
;-----------------------------------------------------------------------------
|
|
|
|
ifndef QB3 ; rest not needed if QB 3
|
|
|
|
pub storecontrolword
|
|
mov ax,[UserControlWord] ; get user's version
|
|
ret
|
|
|
|
|
|
pub storestatusword
|
|
xor ax,ax
|
|
ifndef frontend
|
|
cmp al,[Have8087]
|
|
je no87status
|
|
fstsw [NewStatusWord]
|
|
fwait
|
|
mov al,byte ptr [NewStatusWord] ; get exception summary
|
|
and al,03Fh ; only low 6 bits are wanted
|
|
endif ;frontend
|
|
|
|
pub no87status
|
|
or ax,[UserStatusWord] ; or with full status
|
|
and ax,UStatMask ; mask down to actual status bits
|
|
mov [UserStatusWord],ax ; update full status word
|
|
ret
|
|
|
|
page
|
|
|
|
; Procedure to truncate TOS to integer TOS
|
|
|
|
; ax = new rounding control
|
|
|
|
pub truncateTOS
|
|
and ax,RoundControl shl 8 ; mask to new rounding control
|
|
|
|
ifndef frontend
|
|
ifndef only87
|
|
cmp [Have8087],0
|
|
je Emulatetruncate
|
|
endif ;only87
|
|
|
|
FSTCW [ControlWord] ; get control word
|
|
FWAIT ; synchronize
|
|
MOV CX,[ControlWord] ; round mode saved
|
|
and ch,not RoundControl ; clear rounding control bits
|
|
OR ax,cx ; set new rounding
|
|
MOV [REMLSW],AX ; back to memory
|
|
FLDCW [REMLSW] ; reset rounding
|
|
FRNDINT ; "round" top of stack
|
|
FLDCW [ControlWord] ; restore rounding
|
|
RET ; simple return
|
|
endif ;frontend
|
|
|
|
ifndef only87
|
|
pub Emulatetruncate
|
|
mov cx,[ControlWord]
|
|
push cx ; remember what control word was
|
|
and ch,not RoundControl ; clear rounding control bits
|
|
OR ah,ch ; set new rounding
|
|
MOV [CWcntl],ah ; flag new rounding mode
|
|
PUSH BP ; save BP
|
|
CALL eFRNDINT
|
|
POP BP ; restore BP
|
|
POP [ControlWord] ; set back to the way it was
|
|
|
|
call checktrunc ; check for truncation error
|
|
|
|
RET ; finished
|
|
endif ;only87
|
|
|
|
page
|
|
|
|
; Procedure to truncate TOS to integer in DX:AX
|
|
|
|
; ax = new rounding control
|
|
|
|
pub truncateTOSto32int
|
|
and ax,RoundControl shl 8
|
|
|
|
ifndef frontend
|
|
ifndef only87
|
|
cmp [Have8087],0
|
|
je Emulatetruncateto32int
|
|
endif ;only87
|
|
|
|
FSTCW [ControlWord] ; get control word
|
|
FWAIT ; synchronize
|
|
MOV CX,[ControlWord] ; round mode saved
|
|
and ch,not RoundControl ; clear rounding control bits
|
|
OR ax,cx ; set new rounding
|
|
MOV [REMLSW],AX ; back to memory
|
|
FLDCW [REMLSW] ; reset rounding
|
|
FISTP dword ptr [REMLSW] ; "round" top of stack
|
|
FLDCW [ControlWord] ; restore rounding
|
|
mov ax,[REMLSW]
|
|
mov dx,[REMLSW+2]
|
|
RET ; simple return
|
|
endif ;frontend
|
|
|
|
ifndef only87
|
|
pub Emulatetruncateto32int
|
|
mov cx,[ControlWord]
|
|
push cx ; remember what control word was
|
|
and ch,not RoundControl ; clear rounding control bits
|
|
OR ah,ch ; set new rounding
|
|
MOV [CWcntl],ah ; flag new rounding mode
|
|
PUSH BP ; save BP
|
|
CALL TOSto32int ; convert to 32-bit int in BX:DX
|
|
POP BP ; restore BP
|
|
mov ax,dx
|
|
mov dx,bx
|
|
|
|
call checktrunc ; check for truncation error
|
|
|
|
POPST ; pop of current stack entry
|
|
POP [ControlWord] ; set back to the way it was
|
|
|
|
pub truncerrOK ; (reuse RET for routine below)
|
|
RET ; finished
|
|
|
|
; check for errors
|
|
|
|
pub checktrunc ; !!! check emmain for same code
|
|
MOV cx,[CURerr] ; fetch errors
|
|
or [UserStatusWord],cx ; OR into user status word
|
|
OR [SWerr],cl ; set errors in sticky error flag
|
|
NOT cl ; make a zero mean an error
|
|
MOV ch,byte ptr [UserControlWord] ; get user's IEEE control word
|
|
OR ch,0C2H ; mask reserved, IEM and denormal bits
|
|
AND ch,03FH ; unmask invalid instruction,
|
|
; stack overflow.
|
|
OR cl,ch ; mask for IEEE exceptions
|
|
NOT cl ; make a one mean an error
|
|
MOV ch,byte ptr (CURerr+1) ; get stack over/underflow flags
|
|
TEST cx,0FFFFh-MemoryOperand ; test for errors to report
|
|
jz truncerrOK ; error is masked
|
|
|
|
xchg ax,cx ; ax = exception
|
|
jmp CommonExceptions ; handle error (??? unclean stack)
|
|
|
|
endif ;only87
|
|
|
|
|
|
endif ;QB3
|
|
|
|
|
|
ProfEnd SPEC
|