home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mega A/V
/
mega_av.zip
/
mega_av
/
GRAPHUTL
/
FRASR172.ZIP
/
NEWTON.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-11-01
|
6KB
|
349 lines
; NEWTON.ASM : Procedure NewtonFractal() from FRACTINT.
; Lee Daniel Crocker, 4/23/89.
;
; Tabs: 8
;
; Modifications:
; BT = Bert Tyler
; TW = Timothy Wegner
; RD = Robert Day
; MP = Mark Peterson
;
; Note: newton.asm was totally rewritten by Lee Crocker for FRACTINT 10.0
; for integration with the newly structured fractal engine in calcmand.c
; and fractals.c. The current routine consists of the inner orbit
; calculation, with the supporting code removed. Early versions of
; newton.asm contained a complete newton fractal function.
;
; Assembled by Microsoft Macro Assembler 5.1, for use with Microsoft C 5.1.
;
; Required for compatibility if Turbo ASM (BT 5/20/89)
IFDEF ??version
MASM51
QUIRKS
EMUL
ENDIF
.model medium, c
public NewtonFractal2
public invertz2
.data
extrn color:word, maxcolor:word, degree:word, basin:word
extrn row:word, col:word
extrn dx0:dword, dy0:dword
extrn dx1:dword, dy1:dword
extrn old:qword, new:qword, d1overd:qword, roverd:qword
extrn threshold:qword, floatmin:qword, floatmax:qword
extrn f_radius:qword, f_xcenter:qword, f_ycenter:qword
extrn roots:word, tempsqrx:qword
statw dw ?
.code
public NewtonFractal2
NewtonFractal2 proc
;
; cpower(&old, degree-1, &tmp)
;
mov ax, degree
dec ax
fld old + 8
fld old
;
; cpower() is expanded inline here.
;
shr ax, 1
jnc load1 ; if (exp & 1)
fld st(1)
fld st(1)
jmp short looptop ; tmp = old
load1:
fldz
fld1 ; else tmp = [1,0]
looptop:
cmp ax, 0
je loopexit ; while (exp)
fld st(2) ; RD 5/7/89: Calculate xt^2 - yt^2
fadd st, st(4) ; by using (xt+yt)*(xt-yt), which
fld st(3) ; trades one multiplication for an
fsub st, st(5) ; addition. This trick saves a
fmul ; whopping 1.2% of time.
fld st(4)
fmul st, st(4)
fadd st, st ; yt = 2 * xt * yt
fstp st(5) ; tmp.y = yt
fstp st(3) ; tmp.x = xt
shr ax, 1
jnc looptop ; if (exp & 1)
fld st(2)
fmul st, st(1)
fld st(4)
fmul st, st(3)
fsub ; tmp.x = xt * tmp.x - yt * tmp.y
fld st(3)
fmul st, st(3)
fld st(5)
fmul st, st(3)
fadd ; tmp.y = xt * tmp.y + yt * tmp.x
fstp st(3)
fstp st(1)
jmp short looptop
loopexit:
fstp st(2)
fstp st(2)
;
; End of complex_power() routine. Result is in ST, ST(1)
;
;
; complex_mult(tmp, old, &new);
;
fld old + 8
fld old
fld st(3) ; tmp.y
fmul st, st(1) ; old.x
fld st(3) ; tmp.x
fmul st, st(3) ; old.y
fadd
fld st(3) ; tmp.x
fmul st, st(2) ; old.x
fld st(5) ; tmp.y
fmul st, st(4) ; old.y
fsub
;
; if (DIST1(new) < THRESHOLD) {
;
fld1
fsubr st, st(1)
fmul st, st
fld st(2) ; new.y
fmul st, st
fadd
fcomp threshold
fstsw statw
mov ax, statw
sahf
jnc notless
;
; if (fractype == NEWTBASIN) {
;
mov ax, basin
cmp ax, 0
je notbasin
mov bx, roots
mov dx, -1 ; tempcolor = -1
sub cx, cx
dloop:
fld qword ptr [bx] ; roots[i].x
fsub st, st(3) ; old.x
fmul st, st
fld qword ptr [bx+8]; roots[i].y
fsub st, st(5) ; old.y
fmul st, st
fadd
fcomp threshold
fstsw statw
mov ax, statw
sahf ; if (distance(roots[i],old) < threshold)...
jnc nl2
; TW commented out next few lines and add dx,ax to eliminate newtbasin
; color shades per Phil Wilson's request 12/03/89
; TW put it back in in response to another use as an option! 7/7/90
mov dx, cx
cmp basin,2 ; basin==2 is flag for stripes
jne nostripes
mov ax, color
and ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
and dx, 7
add dx, ax
nostripes:
inc dx ; tempcolor = 1+(i&7)+((color&1)<<3)
jmp short nfb ; break
nl2:
add bx, 16
inc cx
cmp cx, degree
jl dloop
nfb:
mov ax, dx
cmp dx, -1
jne notm1
mov ax, maxcolor ; if (tmpcolor == -1)...
notm1:
mov color, ax
notbasin:
mov ax, 1
jmp nlexit
notless:
fld d1overd
fmul st(2), st ; new.y *= d1overd
fmul
fld roverd
fadd ; new.x = d1overd * new.x + roverd
fld st(5) ; tmp.y
fmul st, st
fld st(5) ; tmp.x
fmul st, st
fadd
fcom floatmin
fstsw statw
mov ax, statw
sahf ; if (mod(tmp) < FLT_MIN) {
jnc cont
mov ax, 1
fstp st
jmp nlexit
cont:
fld1
fdivr
fst st(4) ; old.y
fstp st(3) ; old.x
fld st(4) ; tmp.x
fmul st, st(1) ; new.x
fld st(6) ; tmp.y
fmul st, st(3) ; new.y
fadd
fmulp st(3), st ; old.x
fld st(4) ; tmp.x
fmul st, st(2) ; new.y
fld st(6) ; tmp.y
fmul st, st(2) ; new.x
fsub
fmulp st(4), st ; old.y ; old = new / tmp
; MP Orbit Bug Fix 11/1/90
; fstp new
; fstp new + 8
; fstp old
; fstp old + 8
fstp st
fstp st
fst new
fstp old
fst new + 8
fstp old + 8
mov ax, 0
jmp nlx2
nlexit:
;MP Orbit Bug Fix 11/1/90
; fstp new
; fstp new + 8
fstp st
fstp st
fstp new
fstp new + 8
nlx2:
fstp st
fstp st
ret
NewtonFractal2 endp
;
;
;
public invertz2
invertz2 proc uses si, zval:word ; TW 11/03/89 changed zval to near
fld f_xcenter
fld f_ycenter
mov bx, col
shl bx, 1
shl bx, 1
shl bx, 1
mov cx, row
shl cx, 1
shl cx, 1
shl cx, 1
mov ax, ds
lds si, dx0
add si, bx
fld qword ptr [si]
mov ds, ax
lds si, dx1
add si, cx
fld qword ptr [si]
fadd
fsub st, st(2)
mov ds, ax
lds si, dy0
add si, cx
fld qword ptr [si]
mov ds, ax
lds si, dy1
add si, bx
fld qword ptr [si]
fadd
fsub st, st(2)
mov ds, ax
fld st(1)
fmul st, st
fld st(1)
fmul st, st
fadd
fcom floatmin
fstsw statw
mov ax, statw
sahf
jnc inl1
fstp st
fld floatmax
jmp icom
inl1:
fld f_radius
fdivr
icom:
fst tempsqrx
fmul st(2), st
fmul
faddp st(2), st
faddp st(2), st
; lds si, zval ; TW 11/03/89 zval is now a near pointer
mov si, zval ; TW
fstp qword ptr [si+8]
fstp qword ptr [si]
ret
invertz2 endp
END