summaryrefslogblamecommitdiffstats
path: root/private/mvdm/wow16/win87em/emspec.asm
blob: b6f5d61bffe3cec584e19667d90bc4f1c8e45f4d (plain) (tree)































































































































































































                                                                                
	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