	.386
	.model	use32 small

ME_DOMAIN = 1
ME_SING = 2
ME_OVERFLOW = 3
ME_UNDERFLOW = 4
ME_TLOSS = 5
ME_STACKFAULT = 7

	extrn	_printf : proc, __matherr : proc, __rexit : proc

	public	trigerr,singerr,negerr, negeerr,_fpstackpos,allerr

	.data
;
; next fields MUST be in this order and with no interruptions!!!
;
type	dd	0
nm	dd	offset DGROUP:normx
arg1	dq	0
arg2	dq	0
retval	dq	0
retpos	dd	0
_fpstackpos dd	0

sixtythree dd	63.0
val	dd	0
;
;
eferr	db	"floating point %s error - func %s",0
edomain	db	"domain",0
esing	db	"singularity",0
eover	db	"over",0
eunder	db	"under",0
etloss	db	"total significance loss",0
eploss	db	"partial significance loss",0
estack	db	"stack overflow",0
errm	dd	edomain,esing,eover,eunder,etloss,eploss,estack, negeerr
normx	db	"none",0

	.code
;
; error generator, calls __matherr and aborts or continues
;	
genmerr:
	mov	[type],eax
	mov	[nm],esi
	fst	qword ptr [retval]
	fld	qword ptr [ecx]
	fstp	qword ptr [arg1]
	fstp	qword ptr [arg2]
	or	edx,edx
	jz	nosecond
	fld	qword ptr [edx]
	fstp	qword ptr [arg1]
nosecond:
	cmp	ax,ME_TLOSS
	jz	rv1
	cmp	ax,ME_UNDERFLOW
	jz	rv1
	sub	eax,eax
	jmp	rv0
rv1:
	mov	eax,1
rv0:
	push	ecx
	push	edx
	push	offset DGROUP:type
	call	__matherr
	pop	ecx
	pop	edx
	pop	ecx
	or	al,al
	jnz	noerr
	push	[nm]
	mov	eax,[type]
	push	[eax*4+errm-4]
	push	offset DGROUP:eferr
	call	_printf
	add	esp,12
	mov	al,1
	jmp	__rexit
noerr:
	fcomp	st(1)
	fld	qword ptr [retval]
	wait
	fnclex
	ret
;
; various common errors
;
trigerr:
	push	esi
	mov	esi,eax
	sub	edx,edx
	fld	qword ptr [ecx]
	fxtract
	fcomp  	st(1)
	fabs
	fcomp	dword ptr [sixtythree]
	fstsw	ax
	wait
	sahf
	jc	allerr2
	mov	eax,ME_TLOSS
	call	genmerr
	pop	esi
	ret

singerr:
	push	esi
	mov	esi,eax
	fcompp
	fstsw	ax
	wait
	sahf
	jnz	allerr2
	mov	eax,ME_SING
	call	genmerr
	pop	esi
	ret

negeerr:
	push	esi
	mov	esi,eax
	fldz
	fcompp
	fstsw	ax
	wait
	sahf
	jnc	ner
	jmp	allerr2

negerr:
	push	esi
	mov	esi,eax
	fldz
	fcompp
	fstsw	ax
	wait
	sahf
	jc	allerr2
	je	allerr2
ner:
	mov	eax,ME_DOMAIN
	call	genmerr
	pop	esi
	ret

allerr:
	push	esi
	mov	esi,eax
allerr2:
	fstsw	ax
	and	al,59h	;SUOI
	jz	noaerr
	test	al,40h
	jz	notsf
	mov	ax,ME_STACKFAULT
	call	genmerr
	jmp	noaerr
notsf:
	test	al,1
	jz	notie
	mov	ax,ME_DOMAIN
	call	genmerr
	jmp	noaerr
notie:
	test	al,8
	jz	notoe
	mov	ax,ME_OVERFLOW
	call	genmerr
	jmp	noaerr

notoe:
	test	al,10h
	jz	noaerr
	mov	ax,ME_UNDERFLOW
	call	genmerr

noaerr:
	pop	esi
	ret
	end