		NAME	MathUnit
		PAGE	55,132
;
; Function:	determines math co-processor type.
;
; Caller:	Turbo C:
;			int MathUnit(void);
;
; Returns:	0 - no coprocessor detected
;		1 - Intel 8087
;		2 - Intel 80287
;		3 - Intel 80387
;		4 - Wietek 1167
;		5 - Weitek 1167 and 80387
;
; Source algorithm by Peter Norton, System Information,
;	Advanced Edition 4.50

.286p

		ifdef	__NEAR__
prog		equ	near
quit		equ	ret
		else
prog		equ	far
quit		equ	retf
		endif

_TEXT		SEGMENT	byte public 'CODE'
		ASSUME	cs:_TEXT

		PUBLIC	_MathUnit
_MathUnit	PROC	prog

		push	bp
		push	ds

		mov	ax,sp		; 86/186 or 286/386
		push	sp		; 86/186 will push sp-2
		pop	cx		; others will push sp
		cmp	ax,cx
		jne	short no_386	; no 80286/80386

		sub	sp,6
		mov	bp,sp		; allocate room for SGDT

		ifndef	PWORD
		sgdt	FWORD PTR ss:[bp]	; 286 assemblers
		else
		sgdt	PWORD PTR ss:[bp]	; 386 assemblers
		endif

		add	sp,4		; trash limit and base (low word)
		pop	ax
		inc	ah		; 286 stores -1, 386 stores 0 or 1
		jz	no_386

		db	66h		; xor	eax,eax
		xor	ax,ax

		int	11h

		db	66h
		test	ax,0		; test	eax,01000000h
		dw	0100h

		jz	no_386
		mov	dl,4
		jmp	short l_305b
no_386:		mov	dl,0
l_305b:
		mov	bp,sp		; save sp
		sub	sp,18		; reserve working space
		and	sp,0FFF0h	; align to paragraph
		mov	ax,sp
		mov	cl,4
		shr	ax,cl		; offset to seg addr
		mov	cx,ss
		add	ax,cx
		mov	ds,ax

		xor	ax,ax
		xor	bx,bx
clear:		mov	ds:[bx],ax	; clear working space
		inc	bx
		test	bl,0F0h
		jz	clear

		dw	0E3DBh		; finit
		xor	cx,cx
		jmp	short $+2	; wait a moment
		dw	03ED9h,0	; fstcw	  word ptr ds:[0]
		xor	cx,cx
		jmp	short $+2	; wait a moment
		xor	cx,cx
		jmp	short $+2	; wait a moment
		cmp	byte ptr ds:[1],3
		jne	l_303c
		cmp	dl,4
		je	l_2fdf
		mov	dl,1
l_2fdf:		wait
		dw	036D9h,2	; fstenv  ds:[2]
		wait
		and	word ptr ds:[0],0FF7Fh
		wait
		dw	02ED9h,0	; fldcw	  word ptr ds:[0]
		wait
		dw	0E1DBh		; fdisi
		wait
		dw	03ED9h,0	; fstcw	  word ptr ds:[0]
		wait
		test	word ptr ds:[0],80h
		jnz	l_3037
		dw	0E3DBh		; finit
		cmp	dl,4
		je	l_300f
		mov	dl,2
l_300f:		wait
		dw	0E8D9h		; fld1
		wait
		dw	0EED9h		; fldz
		wait
		dw	0F9DEh		; fdivp	  st(1),st
		wait
		dw	0C0D9h		; fld	  st(0)
		wait
		dw	0E0D9h		; fchs
		wait
		dw	0D9DEh		; fcompp  st(1)
		wait
		dw	03EDDh,0	; fstsw	  word ptr ds:[0]
		mov	ax,ds:[0]
		sahf
		je	short l_3037
		cmp	dl,4
		je	short l_3036
		mov	dl,3
		jmp	short l_3037
l_3036:		inc	dl
l_3037:		wait
		dw	026D9h,2	; fldenv  ds:[2]
l_303c:		mov	al,dl
		xor	ah,ah

		mov	sp,bp
		pop	ds
		pop	bp
		quit

_MathUnit	ENDP

_TEXT		ENDS

		END

