		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

		push	sp		; 86/186 or 286/386
		pop	cx		; 86/186 will push sp-2
		cmp	ax,sp		; others will push sp
		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 CPU_ok
no_386:		mov	dl,0
CPU_ok:
		db	0DBh,0E3h	; finit
		mov	bp,sp
		mov	byte ptr ss:[bp-17],0
		xor	cx,cx
		jmp	short $+2	; wait a moment
		db	0D9h,07Eh,0EEh	; fstcw word ptr ss:[bp-18]
		xor	cx,cx
		jmp	short $+2	; wait a moment
		xor	cx,cx
		jmp	short $+2	; wait a moment
		cmp	byte ptr ss:[bp-17],3
		jne	l_303c
		cmp	dl,4
		je	l_2fdf
		mov	dl,1
l_2fdf:		wait
		db	0D9h,076h,0F0h	; fstenv word ptr ss:[bp-16]
		wait
		and	word ptr ss:[bp-18],0FF7Fh
		wait
		db	0D9h,06Eh,0EEh	; fldcw word ptr ss:[bp-18]
		wait
		db	0DBh,0E1h	; fdisi
		wait
		db	0D9h,07Eh,0EEh	; fstcw word ptr ss:[bp-18]
		wait
		test	word ptr ss:[bp-18],80h
		jnz	l_3037
		db	0DBh,0E3h	; finit
		cmp	dl,4
		je	l_300f
		mov	dl,2
l_300f:		wait
		db	0D9h,0E8h	; fld1
		wait
		db	0D9h,0EEh	; fldz
		wait
		db	0DEh,0F9h	; fdivp	  st(1),st
		wait
		db	0D9h,0C0h	; fld	  st(0)
		wait
		db	0D9h,0E0h	; fchs
		wait
		db	0DEh,0D9h	; fcompp  st(1)
		wait
		fstsw	word ptr ss:[bp-18]
		mov	ax,word ptr ss:[bp-18]
		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
		fldenv	ss:[bp-16]
l_303c:		mov	al,dl
		xor	ah,ah

		pop	ds
		pop	bp
		quit

_MathUnit	ENDP

_TEXT		ENDS

		END

