;	FRACASM.ASM - Assembler subroutines for fractals.c

;			 required for compatibility if Turbo ASM
IFDEF ??version
MASM51
QUIRKS
ENDIF

.MODEL	medium,c

.8086

	; these must NOT be in any segment!!
	; this get's rid of TURBO-C fixup errors
	extrn	multiply:far		; this routine is in 'general.asm'

	extrn	floatbailout:word		; this routine is in 'fractals.c'

.data

	extrn	lold:qword, lnew:qword	; each defined as LCMPLX in fractals.c
	extrn	ltempsqrx:dword 	; for fractals.c
	extrn	ltempsqry:dword 	; for fractals.c
	extrn	lmagnitud:dword 	; for fractals.c
	extrn	llimit:dword		; from calcfrac.c
	extrn	llimit2:dword		; from calcfrac.c
	extrn	bitshift:word		; fudgefactor for integer math
	extrn	overflow:word		; error from integer math

.code FRACTALS_TEXT

;; Note: the check for overflow is now in StandardFractal(), JCO 2/12/95

asmlMODbailout	proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  lmagnitud = ltempsqrx + ltempsqry;
;  if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2
;	 || labs(lnew.y) > llimit2 || overflow)
;	       { overflow=0; return(1); }
;  lold = lnew;
;  return(0);
;
;  ltempsqrx = lsqr(lnew.x);
	push	bitshift
	push	WORD PTR lnew+2
	push	WORD PTR lnew
	push	WORD PTR lnew+2
	push	WORD PTR lnew
	call	FAR PTR multiply
	mov	WORD PTR ltempsqrx,ax
	mov	WORD PTR ltempsqrx+2,dx
;  ltempsqry = lsqr(lnew.y);
	push	bitshift
	push	WORD PTR lnew+6
	push	WORD PTR lnew+4
	push	WORD PTR lnew+6
	push	WORD PTR lnew+4
	call	FAR PTR multiply
	add	sp,20
	mov	WORD PTR ltempsqry,ax
	mov	WORD PTR ltempsqry+2,dx
;  lmagnitud = ltempsqrx + ltempsqry;
	add	ax,WORD PTR ltempsqrx
	adc	dx,WORD PTR ltempsqrx+2
	mov	WORD PTR lmagnitud,ax
	mov	WORD PTR lmagnitud+2,dx
;  if (lmagnitud >= llimit
	cmp	dx,WORD PTR llimit+2
	jl	chkvs0
	jg	bailout
	cmp	ax,WORD PTR llimit
	jae	bailout
;   || lmagnitud < 0
chkvs0: or	dx,dx
	js	bailout
;   || labs(lnew.x) > llimit2		; This test and next one are extraneous:
;	mov	ax,WORD PTR lnew		; take    x > llimit2  and sqr both sides
;	mov	dx,WORD PTR lnew+2	;       x^2 > llimit
;	or	dx,dx				; if    x^2 > llimit then surely
;	jge	lnewx				; x^2 + y^2 > llimit
;	neg	ax				; which was just checked!
;	adc	dx,0
;	neg	dx
;lnewx:	cmp	dx,WORD PTR llimit2+2
;	jl	chklnewy
;	jg	bailout
;	cmp	ax,WORD PTR llimit2
;	ja	bailout
;   || labs(lnew.y) > llimit2
;chklnewy:
;	mov	ax,WORD PTR lnew+4
;	mov	dx,WORD PTR lnew+6
;	or	dx,dx
;	jge	lnewy
;	neg	ax
;	adc	dx,0
;	neg	dx
;lnewy:	cmp	dx,WORD PTR llimit2+2
;	jl	chkoflow
;	jg	bailout
;	cmp	ax,WORD PTR llimit2
;	ja	bailout
;   || overflow)
chkoflow:
;	cmp	overflow,0
;	jne	bailout
;  else {
;  lold = lnew;
	mov	ax,WORD PTR lnew
	mov	dx,WORD PTR lnew+2
	mov	WORD PTR lold,ax
	mov	WORD PTR lold+2,dx
	mov	ax,WORD PTR lnew+4
	mov	dx,WORD PTR lnew+6
	mov	WORD PTR lold+4,ax
	mov	WORD PTR lold+6,dx
;  return(0); }
	sub	ax,ax
	ret
bailout:
;  { overflow=0; return(1); }
;	mov	overflow,0
	mov	ax,1
	ret
asmlMODbailout	endp

asmlREALbailout	proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  if (ltempsqrx >= llimit || overflow)
;	       { overflow=0; return(1); }
;  lold = lnew;
;  return(0);
;
;  ltempsqry = lsqr(lnew.y);
	push	bitshift
	push	WORD PTR lnew+6
	push	WORD PTR lnew+4
	push	WORD PTR lnew+6
	push	WORD PTR lnew+4
	call	FAR PTR multiply
	mov	WORD PTR ltempsqry,ax
	mov	WORD PTR ltempsqry+2,dx
;  ltempsqrx = lsqr(lnew.x);
	push	bitshift
	push	WORD PTR lnew+2
	push	WORD PTR lnew
	push	WORD PTR lnew+2
	push	WORD PTR lnew
	call	FAR PTR multiply
	add	sp,20
	mov	WORD PTR ltempsqrx,ax
	mov	WORD PTR ltempsqrx+2,dx
;  lmagnitud = ltempsqrx + ltempsqry;
	add	ax,WORD PTR ltempsqry
	adc	dx,WORD PTR ltempsqry+2
	mov	WORD PTR lmagnitud,ax
	mov	WORD PTR lmagnitud+2,dx
	mov	ax,WORD PTR ltempsqrx	; restore ltempsqrx to ax & dx
	mov	dx,WORD PTR ltempsqrx+2
;  if (ltempsqrx >= llimit
	cmp	dx,WORD PTR llimit+2
	jl	chkoflow
	jg	bailout
	cmp	ax,WORD PTR llimit
	jae	bailout
;   || overflow)
chkoflow:
;	cmp	overflow,0
;	jne	bailout
;  else {
;  lold = lnew;
	mov	ax,WORD PTR lnew
	mov	dx,WORD PTR lnew+2
	mov	WORD PTR lold,ax
	mov	WORD PTR lold+2,dx
	mov	ax,WORD PTR lnew+4
	mov	dx,WORD PTR lnew+6
	mov	WORD PTR lold+4,ax
	mov	WORD PTR lold+6,dx
;  return(0); }
	sub	ax,ax
	ret
bailout:
;  { overflow=0; return(1); }
;	mov	overflow,0
	mov	ax,1
	ret
asmlREALbailout	endp

asmlIMAGbailout	proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  if (ltempsqry >= llimit || overflow)
;	       { overflow=0; return(1); }
;  lold = lnew;
;  return(0);
;
;  ltempsqrx = lsqr(lnew.x);
	push	bitshift
	push	WORD PTR lnew+2
	push	WORD PTR lnew
	push	WORD PTR lnew+2
	push	WORD PTR lnew
	call	FAR PTR multiply
	mov	WORD PTR ltempsqrx,ax
	mov	WORD PTR ltempsqrx+2,dx
;  ltempsqry = lsqr(lnew.y);
	push	bitshift
	push	WORD PTR lnew+6
	push	WORD PTR lnew+4
	push	WORD PTR lnew+6
	push	WORD PTR lnew+4
	call	FAR PTR multiply
	add	sp,20
	mov	WORD PTR ltempsqry,ax
	mov	WORD PTR ltempsqry+2,dx
;  lmagnitud = ltempsqrx + ltempsqry;
	add	ax,WORD PTR ltempsqrx
	adc	dx,WORD PTR ltempsqrx+2
	mov	WORD PTR lmagnitud,ax
	mov	WORD PTR lmagnitud+2,dx
	mov	ax,WORD PTR ltempsqry	; restore ltempsqry to ax & dx
	mov	dx,WORD PTR ltempsqry+2
;  if (ltempsqry >= llimit
	cmp	dx,WORD PTR llimit+2
	jl	chkoflow
	jg	bailout
	cmp	ax,WORD PTR llimit
	jae	bailout
;   || overflow)
chkoflow:
;	cmp	overflow,0
;	jne	bailout
;  else {
;  lold = lnew;
	mov	ax,WORD PTR lnew
	mov	dx,WORD PTR lnew+2
	mov	WORD PTR lold,ax
	mov	WORD PTR lold+2,dx
	mov	ax,WORD PTR lnew+4
	mov	dx,WORD PTR lnew+6
	mov	WORD PTR lold+4,ax
	mov	WORD PTR lold+6,dx
;  return(0); }
	sub	ax,ax
	ret
bailout:
;  { overflow=0; return(1); }
;	mov	overflow,0
	mov	ax,1
	ret
asmlIMAGbailout	endp

asmlORbailout	proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  if (ltempsqrx >= llimit || ltempsqry >= llimit || overflow)
;	       { overflow=0; return(1); }
;  lold = lnew;
;  return(0);
;
;  ltempsqrx = lsqr(lnew.x);
	push	bitshift
	push	WORD PTR lnew+2
	push	WORD PTR lnew
	push	WORD PTR lnew+2
	push	WORD PTR lnew
	call	FAR PTR multiply
	mov	WORD PTR ltempsqrx,ax
	mov	WORD PTR ltempsqrx+2,dx
;  ltempsqry = lsqr(lnew.y);
	push	bitshift
	push	WORD PTR lnew+6
	push	WORD PTR lnew+4
	push	WORD PTR lnew+6
	push	WORD PTR lnew+4
	call	FAR PTR multiply
	add	sp,20
	mov	WORD PTR ltempsqry,ax
	mov	WORD PTR ltempsqry+2,dx
;  lmagnitud = ltempsqrx + ltempsqry;
	add	ax,WORD PTR ltempsqrx
	adc	dx,WORD PTR ltempsqrx+2
	mov	WORD PTR lmagnitud,ax
	mov	WORD PTR lmagnitud+2,dx
	mov	ax,WORD PTR ltempsqry	; restore ltempsqry to ax & dx
	mov	dx,WORD PTR ltempsqry+2
;  if (ltempsqry >= llimit
	cmp	dx,WORD PTR llimit+2
	jl	chkxnxt
	jg	bailout
	cmp	ax,WORD PTR llimit
	jae	bailout
;   || ltempsqrx >= llimit
chkxnxt:
	mov	ax,WORD PTR ltempsqrx
	mov	dx,WORD PTR ltempsqrx+2
	cmp	dx,WORD PTR llimit+2
	jl	chkoflow
	jg	bailout
	cmp	ax,WORD PTR llimit
	jae	bailout
;   || overflow)
chkoflow:
;	cmp	overflow,0
;	jne	bailout
;  else {
;  lold = lnew;
	mov	ax,WORD PTR lnew
	mov	dx,WORD PTR lnew+2
	mov	WORD PTR lold,ax
	mov	WORD PTR lold+2,dx
	mov	ax,WORD PTR lnew+4
	mov	dx,WORD PTR lnew+6
	mov	WORD PTR lold+4,ax
	mov	WORD PTR lold+6,dx
;  return(0); }
	sub	ax,ax
	ret
bailout:
;  { overflow=0; return(1); }
;	mov	overflow,0
	mov	ax,1
	ret
asmlORbailout	endp

asmlANDbailout	proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  if ((ltempsqrx >= llimit && ltempsqry >= llimit) || overflow)
;	       { overflow=0; return(1); }
;  lold = lnew;
;  return(0);
;
;  ltempsqrx = lsqr(lnew.x);
	push	bitshift
	push	WORD PTR lnew+2
	push	WORD PTR lnew
	push	WORD PTR lnew+2
	push	WORD PTR lnew
	call	FAR PTR multiply
	mov	WORD PTR ltempsqrx,ax
	mov	WORD PTR ltempsqrx+2,dx
;  ltempsqry = lsqr(lnew.y);
	push	bitshift
	push	WORD PTR lnew+6
	push	WORD PTR lnew+4
	push	WORD PTR lnew+6
	push	WORD PTR lnew+4
	call	FAR PTR multiply
	add	sp,20
	mov	WORD PTR ltempsqry,ax
	mov	WORD PTR ltempsqry+2,dx
;  lmagnitud = ltempsqrx + ltempsqry;
	add	ax,WORD PTR ltempsqrx
	adc	dx,WORD PTR ltempsqrx+2
	mov	WORD PTR lmagnitud,ax
	mov	WORD PTR lmagnitud+2,dx
	mov	ax,WORD PTR ltempsqry	; restore ltempsqry to ax & dx
	mov	dx,WORD PTR ltempsqry+2
;  if ((ltempsqry >= llimit
	cmp	dx,WORD PTR llimit+2
	jl	chkoflow
	jg	chkx
	cmp	ax,WORD PTR llimit
	jae	chkx
	jmp	short chkoflow
;  && ltempsqrx >= llimit)
chkx:	mov	ax,WORD PTR ltempsqrx
	mov	dx,WORD PTR ltempsqrx+2
	cmp	dx,WORD PTR llimit+2
	jl	chkoflow
	jg	bailout
	cmp	ax,WORD PTR llimit
	jae	bailout
;   || overflow)
chkoflow:
;	cmp	overflow,0
;	jne	bailout
;  else {
;  lold = lnew;
	mov	ax,WORD PTR lnew
	mov	dx,WORD PTR lnew+2
	mov	WORD PTR lold,ax
	mov	WORD PTR lold+2,dx
	mov	ax,WORD PTR lnew+4
	mov	dx,WORD PTR lnew+6
	mov	WORD PTR lold+4,ax
	mov	WORD PTR lold+6,dx
;  return(0); }
	sub	ax,ax
	ret
bailout:
;  { overflow=0; return(1); }
;	mov	overflow,0
	mov	ax,1
	ret
asmlANDbailout	endp


.386

asm386lMODbailout	proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  lmagnitud = ltempsqrx + ltempsqry;
;  if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2
;	 || labs(lnew.y) > llimit2 || overflow)
;	       { overflow=0; return(1); }
;  lold = lnew;
;  return(0);
;
;  ltempsqrx = lsqr(lnew.x);
	push	bitshift
	push	DWORD PTR lnew
	push	DWORD PTR lnew
	call	FAR PTR multiply
	mov	WORD PTR ltempsqrx,ax
	mov	WORD PTR ltempsqrx+2,dx
;  ltempsqry = lsqr(lnew.y);
	push	bitshift
	push	DWORD PTR lnew+4
	push	DWORD PTR lnew+4
	call	FAR PTR multiply
	add	sp,20
	mov	WORD PTR ltempsqry,ax
	mov	WORD PTR ltempsqry+2,dx
;  lmagnitud = ltempsqrx + ltempsqry;
	mov	eax,DWORD PTR ltempsqry
	add	eax,DWORD PTR ltempsqrx
	mov	DWORD PTR lmagnitud,eax
;  if (lmagnitud >= llimit
	cmp	eax,DWORD PTR llimit
	jae	bailout
;   || overflow)
chkoflow:
;	cmp	overflow,0
;	jne	bailout
;  else {
;  lold = lnew;
	mov	eax,DWORD PTR lnew
	mov	DWORD PTR lold,eax
	mov	eax,DWORD PTR lnew+4
	mov	DWORD PTR lold+4,eax
;  return(0); }
	sub	ax,ax
	ret
bailout:
;  { overflow=0; return(1); }
;	mov	overflow,0
	mov	ax,1
	ret
asm386lMODbailout	endp

asm386lREALbailout	proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  if (ltempsqrx >= llimit || overflow)
;	       { overflow=0; return(1); }
;  lold = lnew;
;  return(0);
;
;  ltempsqry = lsqr(lnew.y);
	push	bitshift
	push	DWORD PTR lnew+4
	push	DWORD PTR lnew+4
	call	FAR PTR multiply
	mov	WORD PTR ltempsqry,ax
	mov	WORD PTR ltempsqry+2,dx
;  ltempsqrx = lsqr(lnew.x);
	push	bitshift
	push	DWORD PTR lnew
	push	DWORD PTR lnew
	call	FAR PTR multiply
	add	sp,20
	mov	WORD PTR ltempsqrx,ax
	mov	WORD PTR ltempsqrx+2,dx
;  lmagnitud = ltempsqrx + ltempsqry;
	mov	eax,DWORD PTR ltempsqry
	add	eax,DWORD PTR ltempsqrx
	mov	DWORD PTR lmagnitud,eax
;  if (ltempsqrx >= llimit
	mov	eax,DWORD PTR ltempsqrx
	cmp	eax,DWORD PTR llimit
	jae	bailout
;   || overflow)
chkoflow:
;	cmp	overflow,0
;	jne	bailout
;  else {
;  lold = lnew;
	mov	eax,DWORD PTR lnew
	mov	DWORD PTR lold,eax
	mov	eax,DWORD PTR lnew+4
	mov	DWORD PTR lold+4,eax
;  return(0); }
	sub	ax,ax
	ret
bailout:
;  { overflow=0; return(1); }
;	mov	overflow,0
	mov	ax,1
	ret
asm386lREALbailout	endp

asm386lIMAGbailout	proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  if (ltempsqry >= llimit || overflow)
;	       { overflow=0; return(1); }
;  lold = lnew;
;  return(0);
;
;  ltempsqrx = lsqr(lnew.x);
	push	bitshift
	push	DWORD PTR lnew
	push	DWORD PTR lnew
	call	FAR PTR multiply
	mov	WORD PTR ltempsqrx,ax
	mov	WORD PTR ltempsqrx+2,dx
;  ltempsqry = lsqr(lnew.y);
	push	bitshift
	push	DWORD PTR lnew+4
	push	DWORD PTR lnew+4
	call	FAR PTR multiply
	add	sp,20
	mov	WORD PTR ltempsqry,ax
	mov	WORD PTR ltempsqry+2,dx
;  lmagnitud = ltempsqrx + ltempsqry;
	mov	eax,DWORD PTR ltempsqry
	add	eax,DWORD PTR ltempsqrx
	mov	DWORD PTR lmagnitud,eax
;  if (ltempsqry >= llimit
	mov	eax,DWORD PTR ltempsqry
	cmp	eax,DWORD PTR llimit
	jae	bailout
;   || overflow)
chkoflow:
;	cmp	overflow,0
;	jne	bailout
;  else {
;  lold = lnew;
	mov	eax,DWORD PTR lnew
	mov	DWORD PTR lold,eax
	mov	eax,DWORD PTR lnew+4
	mov	DWORD PTR lold+4,eax
;  return(0); }
	sub	ax,ax
	ret
bailout:
;  { overflow=0; return(1); }
;	mov	overflow,0
	mov	ax,1
	ret
asm386lIMAGbailout	endp

asm386lORbailout	proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  if (ltempsqrx >= llimit || ltempsqry >= llimit || overflow)
;	       { overflow=0; return(1); }
;  lold = lnew;
;  return(0);
;
;  ltempsqrx = lsqr(lnew.x);
	push	bitshift
	push	DWORD PTR lnew
	push	DWORD PTR lnew
	call	FAR PTR multiply
	mov	WORD PTR ltempsqrx,ax
	mov	WORD PTR ltempsqrx+2,dx
;  ltempsqry = lsqr(lnew.y);
	push	bitshift
	push	DWORD PTR lnew+4
	push	DWORD PTR lnew+4
	call	FAR PTR multiply
	add	sp,20
	mov	WORD PTR ltempsqry,ax
	mov	WORD PTR ltempsqry+2,dx
;  lmagnitud = ltempsqrx + ltempsqry;
	mov	eax,DWORD PTR ltempsqry
	add	eax,DWORD PTR ltempsqrx
	mov	DWORD PTR lmagnitud,eax
;  if (ltempsqry >= llimit
	mov	eax,DWORD PTR ltempsqry
	cmp	eax,DWORD PTR llimit
	jae	bailout
;   || ltempsqrx >= llimit
chkxnxt:
	mov	eax,DWORD PTR ltempsqrx
	cmp	eax,DWORD PTR llimit
	jae	bailout
;   || overflow)
chkoflow:
;	cmp	overflow,0
;	jne	bailout
;  else {
;  lold = lnew;
	mov	eax,DWORD PTR lnew
	mov	DWORD PTR lold,eax
	mov	eax,DWORD PTR lnew+4
	mov	DWORD PTR lold+4,eax
;  return(0); }
	sub	ax,ax
	ret
bailout:
;  { overflow=0; return(1); }
;	mov	overflow,0
	mov	ax,1
	ret
asm386lORbailout	endp

asm386lANDbailout	proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  if ((ltempsqrx >= llimit && ltempsqry >= llimit) || overflow)
;	       { overflow=0; return(1); }
;  lold = lnew;
;  return(0);
;
;  ltempsqrx = lsqr(lnew.x);
	push	bitshift
	push	DWORD PTR lnew
	push	DWORD PTR lnew
	call	FAR PTR multiply
	mov	WORD PTR ltempsqrx,ax
	mov	WORD PTR ltempsqrx+2,dx
;  ltempsqry = lsqr(lnew.y);
	push	bitshift
	push	DWORD PTR lnew+4
	push	DWORD PTR lnew+4
	call	FAR PTR multiply
	add	sp,20
	mov	WORD PTR ltempsqry,ax
	mov	WORD PTR ltempsqry+2,dx
;  lmagnitud = ltempsqrx + ltempsqry;
	mov	eax,DWORD PTR ltempsqry
	add	eax,DWORD PTR ltempsqrx
	mov	DWORD PTR lmagnitud,eax
;  if ((ltempsqry >= llimit
	mov	eax,DWORD PTR ltempsqry
	cmp	eax,DWORD PTR llimit
	jl	chkoflow
;  && ltempsqrx >= llimit)
chkx:	mov	eax,DWORD PTR ltempsqrx
	cmp	eax,DWORD PTR llimit
	jae	bailout
;   || overflow)
chkoflow:
;	cmp	overflow,0
;	jne	bailout
;  else {
;  lold = lnew;
	mov	eax,DWORD PTR lnew
	mov	DWORD PTR lold,eax
	mov	eax,DWORD PTR lnew+4
	mov	DWORD PTR lold+4,eax
;  return(0); }
	sub	ax,ax
	ret
bailout:
;  { overflow=0; return(1); }
;	mov	overflow,0
	mov	ax,1
	ret
asm386lANDbailout	endp


;  Fast fractal orbit calculation procs for Fractint.
;  By Chuck Ebbert   CIS: (76306,1226)
;
;	FManOWarfpFractal()
;	FJuliafpFractal()
;	FBarnsley1FPFractal()
;	FBarnsley2FPFractal()
;	FLambdaFPFractal()
;
;	asmfloatbailout()     -- bailout proc (NEAR proc used by above)
;		NOTE: asmfloatbailout() modifies SI and DI.
;
;  These will only run on machines with a 287 or a 387 (and a 486 of course.)
;
;  Some of the speed gains from this code are due to the storing of the NPU
;    status word directly to the AX register.  FRACTINT will use these
;	 routines only when it finds a 287 or better coprocessor installed.

.286
.287

.data

	extrn new:qword, old:qword, tmp:qword
	extrn rqlim:qword, magnitude:qword, tempsqrx:qword, tempsqry:qword
	extrn cpu:word, fpu:word, floatparm:word

.code FRACTALS_TEXT

	; px,py = floatparm->x,y
	; ox,oy = oldx,oldy
	; nx,ny = newx,newy
	; nx2,ny2 = newxsquared,newysquared
	; tx,ty = tempx, tempy (used in lambda)

FManOWarfpFractal	proc uses si di
			   ; From Art Matrix via Lee Skinner
	fld	tempsqrx		; ox2
	fsub	tempsqry		; ox2-oy2
	mov	bx,floatparm
	fadd	tmp			; ox2-oy2+tx
	fadd	qword ptr [bx]		; newx
	fld	old			; oldx newx
	fmul	old+8			; oldx*oldy newx
	fadd	st,st			; oldx*oldy*2 newx
	fadd	tmp+8			; oldx*oldy*2+tmp.y newx
	fadd	qword ptr [bx+8]	; newy newx
	fstp	qword ptr new+8	; newx
	fstp	qword ptr new	; stack is empty
	mov	si,offset old		; tmp=old
	mov	di,offset tmp
	mov	ax,ds
	mov	es,ax
	mov	cx,8
	rep	movsw
;	call	near ptr asmfloatbailout
	call	word ptr [floatbailout]
	ret
FManOWarfpFractal	endp

FJuliafpFractal proc uses si di
	; Julia/Mandelbrot floating-point orbit function.
	fld	tempsqrx
	fsub	tempsqry
	mov	bx,floatparm
	fadd	qword ptr [bx]		;/* add floatparm->x */
	fld	qword ptr old		;/* now get 2*x*y+floatparm->y */
	fmul	qword ptr old+8
	fadd	st,st
	fadd	qword ptr [bx+8]	; add floatparm->y
	fstp	qword ptr new+8	; newx
	fstp	qword ptr new	; stack is empty
;	call	near ptr asmfloatbailout
	call	word ptr [floatbailout]
	ret
FJuliafpFractal 		endp

FBarnsley1FPFractal	proc uses si di
	; From Fractals Everywhere by Michael Barnsley
	mov	bx,floatparm
	fld	qword ptr [bx]		;/* STACK: px */
	fld	qword ptr [bx+8]	;/* py px */
	fld	qword ptr old		;/* ox py px */
	ftst				;/*** we will want this later */
	fstsw	ax			;/*** 287 or better only */
	fld	old+8			;/* oy ox py px */
	fld	st(1)			;/* ox oy ox py px */
	fmul	st,st(4)		;/* ox*px oy ox py px */
	fld	st(1)			;/* oy ox*px oy ox py px */
	fmul	st,st(4)		;/* oy*py ox*px oy ox py px */
	fsub				;/* (ox*px-oy*py) oy ox py px */
	fxch				;/* oy (oxpx-oypy) ox py px */
	fmul	st,st(4)		;/* oy*px (oxpx-oypy) ox py px */
	fxch	st(2)			;/* ox (oxpx-oypy) oy*px py px */
	fmul	st,st(3)		;/* ox*py (oxpx-oypy) oy*px py px */
	faddp	st(2),st		;/* oxpx-oypy oypx+oxpy py px */
	sahf				;/*** use the saved status (finally) */
	jb	BFPM1add
	fsubrp	st(3),st		;/* oypx+oxpy py nx */
	fsubr				;/* ny nx */
	jmp	short BFPM1cont
BFPM1add:
	faddp	st(3),st		;/* oypx+oxpy py nx */
	fadd				;/* ny nx */
BFPM1cont:
	fstp	qword ptr new+8	; newx
	fstp	qword ptr new	; stack is empty
;	call	near ptr asmfloatbailout
	call	word ptr [floatbailout]
	ret
FBarnsley1FPFractal endp

FBarnsley2FPFractal proc uses si di
	; Also from Fractals Everywhere
	mov	bx,floatparm
	fld	qword ptr [bx]		;/* STACK: px */
	fld	qword ptr [bx+8]	;/* py px */
	fld	qword ptr old		;/* ox py px */
	fld	qword ptr old+8 	;/* oy ox py px */
	fld	st(1)			;/* ox oy ox py px */
	fmul	st,st(4)		;/* ox*px oy ox py px */
	fld	st(1)			;/* oy ox*px oy ox py px */
	fmul	st,st(4)		;/* oy*py ox*px oy ox py px */
	fsub				;/* (ox*px-oy*py) oy ox py px */
	fxch	st(2)			;/* ox oy (oxpx-oypy) py px */
	fmul	st,st(3)		;/* ox*py oy (oxpx-oypy) py px */
	fxch				;/* oy ox*py (oxpx-oypy) py px */
	fmul	st,st(4)		;/* oy*px ox*py (oxpx-oypy) py px */
	fadd				;/* oypx+oxpy oxpx-oypy py px */
	ftst
	fstsw	ax			;/* 287 or better only */
	sahf
	jb	BFPM2add
	fsubrp	st(2),st		;/* oxpx-oypy ny px */
	fsubrp	st(2),st		;/* ny nx */
	jmp	short BFPM2cont
BFPM2add:
	faddp	st(2),st		;/* oxpx-oypy ny px */
	faddp	st(2),st		;/* ny nx */
BFPM2cont:
	fstp	qword ptr new+8	; newx
	fstp	qword ptr new	; stack is empty
;	call	near ptr asmfloatbailout
	call	word ptr [floatbailout]
	ret
FBarnsley2FPFractal endp

FLambdaFPFractal proc uses si di
	; tempsqrx and tempsqry can be used -- the C code doesn't use them!
	fld	tempsqry		;oy2
	fsub	tempsqrx		;oy2-ox2
	fld	old			;ox oy2-ox2
	fadd	st(1),st		;ox tx=ox+oy2-ox2
	fadd	st,st			;2ox tx
	fld1				;1 2ox tx
	fsubr				;(1-2ox) tx
	fmul	old+8			;ty=oy(1-2ox) tx
	fld	st(1)			;tx ty tx -- duplicate these now
	fld	st(1)			;ty tx ty tx
	mov	bx,floatparm
	fld	qword ptr [bx+8]	;py ty tx ty tx -- load y first
	fld	qword ptr [bx]		;px py ty tx ty tx
	fmul	st(5),st		;px py ty tx ty pxtx
	fmulp	st(4),st		;py ty tx pxty pxtx
	fmul	st(2),st		;py ty pytx pxty pxtx
	fmul				;pyty pytx pxty pxtx
	fsubp	st(3),st		;pytx pxty nx=pxtx-pyty
	fadd				;ny=pxty+pytx nx
	fstp	qword ptr new+8	; newx
	fstp	qword ptr new	; stack is empty
;	call	near ptr asmfloatbailout
	call	word ptr [floatbailout]
	ret
FLambdaFPFractal endp

; The following is no longer used.
asmfloatbailout proc near
	; called with new.y and new.x on stack and clears the stack
	; destroys SI and DI: caller must save them
	fst	qword ptr new+8
	fmul	st,st			;/* ny2 nx */
	fst	tempsqry
	fxch				;/* nx ny2 */
	fst	qword ptr new
	fmul	st,st			;/* nx2 ny2 */
	fst	tempsqrx
	fadd
	fst	magnitude
	fcomp	rqlim			;/*** stack is empty */
	fstsw	ax			;/*** 287 and up only */
	sahf
	jae	bailout
	mov	si,offset new
	mov	di,offset old
	mov	ax,ds
	mov	es,ax
	mov	cx,8
	rep	movsw
	xor	ax,ax
	ret
bailout:
	mov	ax,1
	ret
asmfloatbailout endp
; The preceeding is no longer used.

asmfpMODbailout proc near uses si di
	fld	qword ptr new+8
	fmul	st,st			;/* ny2 */
	fst	tempsqry
	fld	qword ptr new	;/* nx ny2 */
	fmul	st,st			;/* nx2 ny2 */
	fst	tempsqrx
	fadd
	fst	magnitude
	fcomp	rqlim			;/*** stack is empty */
	fstsw	ax			;/*** 287 and up only */
	sahf
	jae	bailout
	mov	si,offset new
	mov	di,offset old
	mov	ax,ds
	mov	es,ax
	mov	cx,8
	rep	movsw
	xor	ax,ax
	ret
bailout:
	mov	ax,1
	ret
asmfpMODbailout endp

asmfpREALbailout proc near uses si di
	fld	qword ptr new
	fmul	st,st			;/* nx2 */
	fst	tempsqrx
	fld	qword ptr new+8	;/* ny nx2 */
	fmul	st,st			;/* ny2 nx2 */
	fst	tempsqry		;/* ny2 nx2 */
	fadd	st,st(1)		;/* ny2+nx2 nx2 */
	fstp	magnitude		;/* nx2 */
	fcomp	rqlim			;/*** stack is empty */
	fstsw	ax			;/*** 287 and up only */
	sahf
	jae	bailout
	mov	si,offset new
	mov	di,offset old
	mov	ax,ds
	mov	es,ax
	mov	cx,8
	rep	movsw
	xor	ax,ax
	ret
bailout:
	mov	ax,1
	ret
asmfpREALbailout endp

asmfpIMAGbailout proc near uses si di
	fld	qword ptr new+8
	fmul	st,st			;/* ny2 */
	fst	tempsqry
	fld	qword ptr new	;/* nx ny2 */
	fmul	st,st			;/* nx2 ny2 */
	fst	tempsqrx		;/* nx2 ny2 */
	fadd	st,st(1)		;/* nx2+ny2 ny2 */
	fstp	magnitude		;/* ny2 */
	fcomp	rqlim			;/*** stack is empty */
	fstsw	ax			;/*** 287 and up only */
	sahf
	jae	bailout
	mov	si,offset new
	mov	di,offset old
	mov	ax,ds
	mov	es,ax
	mov	cx,8
	rep	movsw
	xor	ax,ax
	ret
bailout:
	mov	ax,1
	ret
asmfpIMAGbailout endp

asmfpORbailout proc near uses si di
	fld	qword ptr new+8
	fmul	st,st			;/* ny2 */
	fst	tempsqry
	fld	qword ptr new	;/* nx ny2 */
	fmul	st,st			;/* nx2 ny2 */
	fst	tempsqrx
	fld	st(1)			;/* ny2 nx2 ny2 */
	fadd	st,st(1)		;/* ny2+nx2 nx2 ny2 */
	fstp	magnitude		;/* nx2 ny2 */
	fcomp	rqlim			;/* ny2 */
	fstsw	ax			;/*** 287 and up only */
	sahf
	jae	bailoutp
	fcomp	rqlim			;/*** stack is empty */
	fstsw	ax			;/*** 287 and up only */
	sahf
	jae	bailout
	mov	si,offset new
	mov	di,offset old
	mov	ax,ds
	mov	es,ax
	mov	cx,8
	rep	movsw
	xor	ax,ax
	ret
bailoutp:
	finit		;/* cleans up stack */
bailout:
	mov	ax,1
	ret
asmfpORbailout endp

asmfpANDbailout proc near uses si di
	fld	qword ptr new+8
	fmul	st,st			;/* ny2 */
	fst	tempsqry
	fld	qword ptr new	;/* nx ny2 */
	fmul	st,st			;/* nx2 ny2 */
	fst	tempsqrx
	fld	st(1)			;/* ny2 nx2 ny2 */
	fadd	st,st(1)		;/* ny2+nx2 nx2 ny2 */
	fstp	magnitude		;/* nx2 ny2 */
	fcomp	rqlim			;/* ny2 */
	fstsw	ax			;/*** 287 and up only */
	sahf
	jb	nobailoutp
	fcomp	rqlim			;/*** stack is empty */
	fstsw	ax			;/*** 287 and up only */
	sahf
	jae	bailout
	jmp	short nobailout
nobailoutp:
	finit		;/* cleans up stack */
nobailout:
	mov	si,offset new
	mov	di,offset old
	mov	ax,ds
	mov	es,ax
	mov	cx,8
	rep	movsw
	xor	ax,ax
	ret
bailout:
	mov	ax,1
	ret
asmfpANDbailout endp

.8086
.8087

	end

