|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.