File:  [OS/2 SDKs] / os2sdk / demos / apps / mandel / manditer.asm
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:25:57 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: os2sdk-1988, HEAD
Microsoft OS/2 SDK 03-01-1988

	page	,132
	title	manditer - compute next iteration of mandelbrot set
	%out	manditer

;	Conditional assembly flags:
;
;	TARGET_287	Defined if the target machine will be a 286
;			with a 287.  This allows the 287 specific
;			instruction FSTSW AX to be used.
;
;	DO_SCAN 	Defined if an entire scan is to be processed.
;			If so, extra parameters are supplied consisting
;			of the increment for the real portion of the
;			seed, a word buffer where the results will be
;			stored, and the count of points to compute.

TARGET_287	equ	0
DO_SCAN 	equ	0

ifdef	TARGET_287
	.286c
	.287
else
	.8087
endif


memS	equ	1			;Define small model program
?PLM	=	0			;Define 'C' calling convention
?WIN	=	0			;Define non-windows prologue

	.xlist
	include cmacros.inc
	.list


sBegin	code
assumes cs,code
assumes ds,nothing

four	dq	4.0			;Constant 4.0


;	The Mandelbrot set is defined to be the set of all complex
;	numbers C for which the size of Z^2 + C is finite after an
;	indefinite number of iterations (Z is initially 0).
;
;	The square of a complex number C = C_Real + C_imag is
;
;		(C_Real^2) - (2*C_Real*C_Imag)i - (C_Imag^2)
;
;
;	The size of a complex number is just it's distance from
;	the complex number 0.  The distance from complex 0 is
;	the hypotenuse of the right triangle whose sides are the
;	real and imaginary parts of the complex number.  Thus the
;	size is SQRT(Z_real^2 + Z_imag).  If the size ever becomes
;	>= 2, the number will grow to infinity.



cProc	manditer,<PUBLIC>

	parmq	creal			;Real part of mandelbrot seed
	parmq	cimag			;Imaginary part of mandelbrot seed
	parmw	max_iteration		;Maximum loop counter

	ifdef	DO_SCAN 		;If to do an entire scan line
	parmw	point_count		;Number of points to calculate
	parmw	results_buffer		;Near pointer to where results go
	parmq	creal_step		;Increment to next point
	endif

	ifndef	TARGET_287		;If not explicitly for a 287
	localw	fstatus 		;x87 status word
	endif

cBegin
	ifdef	DO_SCAN 		;If to do an entire scan line
	push	si			;'C' requires SI to be saved
	mov	si,results_buffer	;DS:SI --> destination buffer
	mov	dx,point_count		;# of points to calculate
	endif

	finit				;Initialize co-processor

	mov	bx,max_iteration	;Max iteration counter

	fld	four			;Load constant 4.0 for comparison
;      |-------------------------------|
;      | 4			       | st(0)
;      |-------------------------------|


	fld	creal			;Load real part of seed
;      |-------------------------------|
;      | C real 		       | st(1)
;      |-------------------------------|
;      | 4			       | st(2)
;      |-------------------------------|


	fld	cimag			;Load imaginary part of seed
;      |-------------------------------|
;      | C imag 		       | st(0)
;      |-------------------------------|
;      | C real 		       | st(1)
;      |-------------------------------|
;      | 4			       | st(2)
;      |-------------------------------|


	ifdef	DO_SCAN 		;If to do an entire scan
	fld	creal_step		;  load creal increment
	else				;else
	fdecstp 			;  Reserve location, tag as invalid
	endif
;      |-------------------------------|
;      | Reserved or C real increment  | st(0)
;      |-------------------------------|
;      | C imag 		       | st(1)
;      |-------------------------------|
;      | C real 		       | st(2)
;      |-------------------------------|
;      | 4			       | st(3)
;      |-------------------------------|


scan_loop:

;	Because this program optimizes the use of C real ^ 2
;	and C imag ^ 2, the size test will terminate one iteration
;	late.  The original Mandelzoom was:
;
;	    Z = 0
;	    Count = 0;
;	    repeat
;		Z = Z^2 + C
;		count = count + 1
;		size = size of Z
;	    until (count > 1000 or size >= 4)
;
;	This program uses the intermediate calculations used for
;	the squaring for the size test.  However, the result of
;	the first complex square operation will simply be the
;	constant C (0^2+C).  By setting the initial value of Z
;	to C instead of 0, this latency will be corrected.



	fld	st(1)			;Initialize imaginary part of sum
;      |-------------------------------|
;      | Z imag = C imag	       | st(0)
;      |-------------------------------|
;      | Reserved or C real increment  | st(1)
;      |-------------------------------|
;      | C imag 		       | st(2)
;      |-------------------------------|
;      | C real 		       | st(3)
;      |-------------------------------|
;      | 4			       | st(4)
;      |-------------------------------|


	fld	st(3)			;Initialize real part of sum
;      |-------------------------------|
;      | Z real = C real	       | st(0)
;      |-------------------------------|
;      | Z imag = C image	       | st(1)
;      |-------------------------------|
;      | Reserved or C real increment  | st(2)
;      |-------------------------------|
;      | C imag 		       | st(3)
;      |-------------------------------|
;      | C real 		       | st(4)
;      |-------------------------------|
;      | 4			       | st(5)
;      |-------------------------------|


	mov	cx,bx			;max iteration counter

iterate_loop:


	fld	st(0)
;      |-------------------------------|
;      | Z real 		       | st(0)
;      |-------------------------------|
;      | Z real 		       | st(1)
;      |-------------------------------|
;      | Z imag 		       | st(2)
;      |-------------------------------|
;      | Reserved or C real increment  | st(3)
;      |-------------------------------|
;      | C imag 		       | st(4)
;      |-------------------------------|
;      | C real 		       | st(5)
;      |-------------------------------|
;      | 4			       | st(6)
;      |-------------------------------|


	fmul	st(1),st
;      |-------------------------------|
;      | Z real 		       | st(0)
;      |-------------------------------|
;      | (Z real)^2		       | st(1)
;      |-------------------------------|
;      | Z imag 		       | st(2)
;      |-------------------------------|
;      | Reserved or C real increment  | st(3)
;      |-------------------------------|
;      | C imag 		       | st(4)
;      |-------------------------------|
;      | C real 		       | st(5)
;      |-------------------------------|
;      | 4			       | st(6)
;      |-------------------------------|


	fmul	st,st(2)
;      |-------------------------------|
;      | Z real * Z imag	       | st(0)
;      |-------------------------------|
;      | (Z real)^2		       | st(1)
;      |-------------------------------|
;      | Z imag 		       | st(2)
;      |-------------------------------|
;      | Reserved or C real increment  | st(3)
;      |-------------------------------|
;      | C imag 		       | st(4)
;      |-------------------------------|
;      | C real 		       | st(5)
;      |-------------------------------|
;      | 4			       | st(6)
;      |-------------------------------|


	fadd	st,st(0)
;      |-------------------------------|
;      | Z real * Z imag * 2	       | st(0)
;      |-------------------------------|
;      | Z real ^ 2		       | st(1)
;      |-------------------------------|
;      | Z imag 		       | st(2)
;      |-------------------------------|
;      | Reserved or C real increment  | st(3)
;      |-------------------------------|
;      | C imag 		       | st(4)
;      |-------------------------------|
;      | C real 		       | st(5)
;      |-------------------------------|
;      | 4			       | st(6)
;      |-------------------------------|


	fadd	st,st(4)
;      |-------------------------------|
;      | Z real * Z imag * 2 + C imag  | st(0)
;      |-------------------------------|
;      | Z real ^ 2		       | st(1)
;      |-------------------------------|
;      | Z imag 		       | st(2)
;      |-------------------------------|
;      | Reserved or C real increment  | st(3)
;      |-------------------------------|
;      | C imag 		       | st(4)
;      |-------------------------------|
;      | C real 		       | st(5)
;      |-------------------------------|
;      | 4			       | st(6)
;      |-------------------------------|


	fxch	st(2)
;      |-------------------------------|
;      | Z imag 		       | st(0)
;      |-------------------------------|
;      | Z real ^ 2		       | st(1)
;      |-------------------------------|
;      | Z real * Z imag * 2 + C imag  | st(2)
;      |-------------------------------|
;      | Reserved or C real increment  | st(3)
;      |-------------------------------|
;      | C imag 		       | st(4)
;      |-------------------------------|
;      | C real 		       | st(5)
;      |-------------------------------|
;      | 4			       | st(6)
;      |-------------------------------|


	fmul	st,st(0)
;      |-------------------------------|
;      | Z imag ^ 2		       | st(0)
;      |-------------------------------|
;      | Z real ^ 2		       | st(1)
;      |-------------------------------|
;      | Z real * Z imag * 2 + C imag  | st(2)
;      |-------------------------------|
;      | Reserved or C real increment  | st(3)
;      |-------------------------------|
;      | C imag 		       | st(4)
;      |-------------------------------|
;      | C real 		       | st(5)
;      |-------------------------------|
;      | 4			       | st(6)
;      |-------------------------------|


	fld	st(1)
;      |-------------------------------|
;      | Z real ^ 2		       | st(0)
;      |-------------------------------|
;      | Z imag ^ 2		       | st(1)
;      |-------------------------------|
;      | Z real ^ 2		       | st(2)
;      |-------------------------------|
;      | Z real * Z imag * 2 + C imag  | st(3)
;      |-------------------------------|
;      | Reserved or C real increment  | st(4)
;      |-------------------------------|
;      | C imag 		       | st(5)
;      |-------------------------------|
;      | C real 		       | st(6)
;      |-------------------------------|
;      | 4			       | st(7)
;      |-------------------------------|


	fadd	st,st(1)
;      |-------------------------------|
;      | Z real ^ 2 + Z imag ^ 2       | st(0)
;      |-------------------------------|
;      | Z imag ^ 2		       | st(1)
;      |-------------------------------|
;      | Z real ^ 2		       | st(2)
;      |-------------------------------|
;      | Z real * Z imag * 2 + C imag  | st(3)
;      |-------------------------------|
;      | Reserved or C real increment  | st(4)
;      |-------------------------------|
;      | C imag 		       | st(5)
;      |-------------------------------|
;      | C real 		       | st(6)
;      |-------------------------------|
;      | 4			       | st(7)
;      |-------------------------------|


	fcomp	st(7)
;      |-------------------------------|
;      | Z imag ^ 2		       | st(0)
;      |-------------------------------|
;      | Z real ^ 2		       | st(1)
;      |-------------------------------|
;      | Z real * Z imag * 2 + C imag  | st(2)
;      |-------------------------------|
;      | Reserved or C real increment  | st(3)
;      |-------------------------------|
;      | C imag 		       | st(4)
;      |-------------------------------|
;      | C real 		       | st(5)
;      |-------------------------------|
;      | 4			       | st(6)
;      |-------------------------------|


	ifdef	TARGET_287		;If 287, then store status word
	fwait				;  straight to ax.  Have to wait!
	fstsw	ax			;
	else				;else
	fstsw	fstatus 		;  will have to store to memory
	endif
;      |-------------------------------|
;      | Z imag ^ 2		       | st(0)
;      |-------------------------------|
;      | Z real ^ 2		       | st(1)
;      |-------------------------------|
;      | Z real * Z imag * 2 + C imag  | st(2)
;      |-------------------------------|
;      | Reserved or C real increment  | st(3)
;      |-------------------------------|
;      | C imag 		       | st(4)
;      |-------------------------------|
;      | C real 		       | st(5)
;      |-------------------------------|
;      | 4			       | st(6)
;      |-------------------------------|


	fsubp	st(1),st
;      |-------------------------------|
;      | Z real ^ 2 - Z imag ^ 2       | st(0)
;      |-------------------------------|
;      | Z real * Z imag * 2 + C imag  | st(1)
;      |-------------------------------|
;      | Reserved or C real increment  | st(2)
;      |-------------------------------|
;      | C imag 		       | st(3)
;      |-------------------------------|
;      | C real 		       | st(4)
;      |-------------------------------|
;      | 4			       | st(5)
;      |-------------------------------|



;	Do a little work while the FSUBP executes

	ifndef	TARGET_287		;If not a 287
	mov	ah,byte ptr (fstatus+1) ;  load status word from memory
	endif

	and	ah,045h 		;If size>= 4, outside of mandelbrot
	xor	ah,1			;  set.
	jnz	done_iterating		;Outside of set


	fadd	st,st(4)
;      |-------------------------------|
;      | Z real^2 - Z imag^2 + C real  | st(0)
;      |-------------------------------|
;      | Z real * Z imag * 2 + C imag  | st(1)
;      |-------------------------------|
;      | Reserved or C real increment  | st(2)
;      |-------------------------------|
;      | C imag 		       | st(3)
;      |-------------------------------|
;      | C real 		       | st(4)
;      |-------------------------------|
;      | 4			       | st(5)
;      |-------------------------------|


	loop	iterate_loop		;If loop expires, in mandelbrot set

done_iterating:
	mov	ax,bx			;Max iteration count
	sub	ax,cx			;Compute number of iterations

	ifdef	DO_SCAN 		;If to do an entire scan
	mov	word ptr [si],ax	;Save result in result_buffer
	add	si,2			;--> next slot of buffer
	dec	dx			;Any more points?
	jz	done_scan		;No, all done

	fstp	st(0)			;Remove sum from stack
	fstp	st(0)
;      |-------------------------------|
;      | Reserved or C real increment  | st(0)
;      |-------------------------------|
;      | C imag 		       | st(1)
;      |-------------------------------|
;      | C real 		       | st(2)
;      |-------------------------------|
;      | 4			       | st(3)
;      |-------------------------------|


	fadd	st(2),st		;Update c real
;      |-------------------------------|
;      | Reserved or C real increment  | st(0)
;      |-------------------------------|
;      | C imag 		       | st(1)
;      |-------------------------------|
;      | C real + C real increment     | st(2)
;      |-------------------------------|
;      | 4			       | st(3)
;      |-------------------------------|

	jmp	scan_loop

done_scan:
	pop	si			;Return last result
	endif


cEnd

sEnd	code
end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.