; Mandelbrot iteration functions - 16 bit low prec. and 32 bit high prec.
; By Neil A Carson, RiscBSD kernel team, 1995

R0  RN 0
R1  RN 1
R2  RN 2
R3  RN 3
R4  RN 4
R5  RN 5
R6  RN 6
R7  RN 7
R8  RN 8
R9  RN 9
R10 RN 10
R11 RN 11
R12 RN 12
R13 RN 13
R14 RN 14
R15 RN 15

pc  RN 15
lr  RN 14
sp  RN 13

x   RN 0
y   RN 1
u   RN 2
v   RN 3
max RN 4
cnt RN 5
dep RN 6
uu  RN 7
vv  RN 8
w1  RN 9
w2  RN 10
uv  RN 11
sgn RN 12

;
; Now changed so that maxiter is in R10 on entry
;

	AREA	|neils$$code|, CODE, READONLY

	EXPORT iterate
iterate
	STMFD	sp!, {R1-R12, lr}		; Stack registers

	; Set initial values

	MOV	max, R10			; max = maxiter ***CHANGED***
	MOV	u, x
	MOV	v, y
	MOV	dep, #0

	; Ready to loop

|loop16|
	MOV	u, u, ASR #&10			; Do multiplications
	MOV	v, v, ASR #&10			; to 16-bit precision
	MUL	uu, u, u
	MUL	vv, v, v
	MUL	uv, u, v
	ANDS	w1, uu, #&F0000000
	TEQNE	w1, #&F0000000
	BNE	|exit16|
	MOV	uu, uu, LSL #&03
	ANDS	w1, vv, #&F0000000
	TEQNE	w1, #&F0000000
	BNE	|exit16|
	MOV	vv, vv, LSL #&03
	ADDS	w1, uu, vv
	BVS	|exit16|
	MOV	uv, uv, LSL #&04

	SUB	uu, uu, vv
	ADD	u, uu, x
	ADD	v, uv, y
	ADD	dep, dep, #1
	CMP	dep, max
	BLE	|loop16|

	; Finish off

|exit16|

	CMP	dep, #0
	MOVEQ	dep, #1
	MOV	R0, dep				; Return iters in R0
	LDMFD	sp!, {R1-R12, pc}^

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; 	EXPORT iterate_32
; iterate_32
; 	STMFD	sp!, {R1-R12, lr}		; Stack registers
;
; 	; Set initial values
;
; 	MOV	max, R10			; max = maxiter
; 	MOV	u, x
; 	MOV	v, y
; 	MOV	dep, #0
;
; 	; Ready to loop
;
; |loop32|
; 	EOR	sgn, u, v
; 	TST	u, #&80000000
; 	RSBNE	u, u, #0
; 	TST	v, #&80000000
; 	RSBNE	v, v, #0
; 	MOV	w1, u, LSR #16
; 	BIC	w2, u, w1, LSL #16
; 	MUL	uv, w1, w2
; 	MUL	uu, w1, w1
; 	MUL	w1, w2, w2
; 	ADDS	w1, w1, uv, LSL #17
; 	ADC	uu, uu, uv, LSR #15
; 	MOVS	uu, uu, LSL #3
; 	ADD	uu, uu, w1, LSR #29
; 	BCS	|exit32|
; 	BMI	|exit32|
; 	MOV	w1, v, LSR #16
; 	BIC	w2, v, w1, LSL #16
; 	MUL	uv, w1, w2
; 	MUL	vv, w1, w1
; 	MUL	w1, w2, w2
; 	ADDS	w1, w1, uv, LSL #17
; 	ADC	vv, vv, uv, LSR #15
; 	MOVS	vv, vv, LSL #3
; 	ADD	vv, vv, w1, LSR #29
; 	BCS	|exit32|
; 	BMI	|exit32|
; 	ADDS	w1, uu, vv
; 	BMI	|exit32|
; 	MOV	w1, u, LSR #16
; 	BIC	u, u, w1, LSL #16
; 	MOV	w2, v, LSR #16
; 	BIC	v, v, w2, LSL #16
; 	MUL	uv, w1, w2
; 	MUL	w1, v, w1
; 	MUL	w2, u, w2
; 	MUL	u, v, u
; 	ADDS	v, w1, w2
; 	ADDCS	uv, uv, #&10000
; 	ADDS	u, u, v, LSL #16
; 	ADC	uv, uv, v, LSR #16
; 	MOV	uv, uv, LSL #4
; 	ADD	uv, uv, u, LSR #28
;
; 	TST	sgn, #&80000000
; 	RSBNE	uv, uv, #0
;
; 	SUB	uu, uu, vv
; 	ADD	u, uu, x
; 	ADD	v, uv, y
; 	ADD	dep, dep, #1
; 	CMP	dep, max
; 	BLE	|loop32|
;
; 	; Finish off
;
; |exit32|
; 	CMP	dep, #0
; 	MOVEQ	dep, #1
; 	MOV	R0, dep				; Return iters in R0
; 	LDMFD	sp!, {R1-R12, pc}^

	END
