** Revision Header * Header built automatically - do not edit! *************
*
*	(C) Copyright 1991 by Olaf `Olsen' Barthel, all rights reserved
*
*	Name .....: Iterate.asm
*	Created ..: Monday 26-Aug-91 11:20
*	Revision .: 3
*
*	Date            Author          Comment
*	=========       ========        ====================
*	17-Sep-91	Olsen		Loop rearranged again
*	12-Sep-91	Olsen		Loop rearranged for earlier termination
*	26-Aug-91	Olsen		Created this file!
*
****************************************************************************

	csect	text,0,0,1,2

	xdef	_Iterate

;	BYTE Iterate(double RealValue,double ImaginaryValue);
;
;		Fast hand-coded '881 assembly language subroutine,
;	all arguments are passed on the stack since either SAS/C
;	fails to correctly pass them in registers or the register
;	values have to be converted to extended precision (hey, I
;	don't have an '881 users' manual here!).
;
;	Register usage is a follows:
;
;		d0	= MaxIterations
;		d1	= Iterations
;
;		fp0	= RealTemp
;		fp1	= ImaginaryTemp
;
;		fp2	= Real
;		fp3	= Imaginary
;
;		fp4	= RealValue
;		fp5	= ImaginaryValue
;
;		fp6	= Scratch

RealArg		equ	12*7+4
ImaginaryArg	equ	RealArg+8

_Iterate:
	fmovem.x fp0-fp6,-(sp)			; Save registers

	fmove.d	RealArg(sp),fp4			; RealValue
	fmove.d	ImaginaryArg(sp),fp5		; ImaginaryValue

	move.l	_MaxIteration(a4),d0		; MaxIteration -> d0

	moveq	#0,d1				; i = 0

	fmove.x	fp4,fp2				; Real = RealValue
	fmove.x	fp5,fp3				; Imaginary = ImaginaryValue

	bra.b	Skip

Loop:	fmul.x	#2.0,fp3			; Imaginary *= 2
	fmul.x	fp2,fp3				; Imaginary *= Real
	fadd.x	fp5,fp3				; Imaginary += ImaginaryValue

	fmove.x	fp0,fp2				; Real = RealTemp
	fsub.x	fp1,fp2				; Real -= ImaginaryTemp
	fadd.x	fp4,fp2				; Real += RealValue

Skip:	fmove.x	fp2,fp0				; RealTemp = Real
	fmove.x	fp3,fp1				; ImaginaryTemp = Imaginary

	fmul.x	fp0,fp0				; RealTemp = RealTemp^2
	fmul.x	fp1,fp1				; ImaginaryTemp = ImaginaryTemp^2

	fmove.x	fp0,fp6				; RealTemp -> fp6
	fadd.x	fp1,fp6				; RealTemp += ImaginaryTemp
	fabs.x	fp6,fp6				; RealTemp = fabs(RealTemp)

	fcmp.x	#4.0,fp6			; RealTemp > 4?
	fbgt.w	Exit				; true -> break

	addq	#1,d1				; Iterations++;
	subq	#1,d0				; Maximum number reached?
	bgt.b	Loop				; false -> Loop;

	fmovem.x (sp)+,fp0-fp6			; Restore registers, return 0
	rts

Exit:	move.l	_Wave(a4),a0			; Get colour wave table
	move.b	(a0,d1.w),d0			; Get wave index, always > 0

	fmovem.x (sp)+,fp0-fp6			; Restore registers
	rts

	section	__MERGED,data

	xref	_Wave
	xref	_MaxIteration

	end
