File: dos\newton.asm
1 ; NEWTON.ASM : Procedure NewtonFractal() from FRACTINT.
2 ; Lee Daniel Crocker, 4/23/89.
3 ;
4 ; Tabs: 8
5 ;
6 ; Modifications:
7 ; BT = Bert Tyler
8 ; TW = Timothy Wegner
9 ; RD = Robert Day
10 ; MP = Mark Peterson
11 ;
12 ; Note: newton.asm was totally rewritten by Lee Crocker for FRACTINT 10.0
13 ; for integration with the newly structured fractal engine in calcmand.c
14 ; and fractals.c. The current routine consists of the inner orbit
15 ; calculation, with the supporting code removed. Early versions of
16 ; newton.asm contained a complete newton fractal function.
17 ;
18 ; Assembled by Microsoft Macro Assembler 6.1, for use with Microsoft C 7.0.
19 ;
20
21 ; Required for compatibility if Turbo ASM (BT 5/20/89)
22
23 IFDEF ??version
24 MASM51
25 QUIRKS
26 ENDIF
27
28 .model medium, c
29
30 public NewtonFractal2
31 public invertz2
32
33 .data
34 extrn coloriter:dword, maxcolor:word, degree:word, basin:word
35 extrn row:word, col:word
36
37 extrn dx0:dword, dy0:dword
38 extrn dx1:dword, dy1:dword
39
40 extrn old:qword, new:qword, d1overd:qword, roverd:qword
41 extrn threshold:qword, floatmin:qword, floatmax:qword
42 extrn f_radius:qword, f_xcenter:qword, f_ycenter:qword
43 extrn roots:word, tempsqrx:qword
44 extrn delxx:tbyte, delxx2:tbyte
45 extrn delyy:tbyte, delyy2:tbyte
46 extrn xxmin:qword, yymax:qword
47 extrn use_grid:word
48 statw dw ?
49
50 .code
51
52 public NewtonFractal2
53 NewtonFractal2 proc
54
55 ;
56 ; cpower(&old, degree-1, &tmp)
57 ;
58 mov ax, degree
59 dec ax
60
61 fld old + 8
62 fld old
63 ;
64 ; cpower() is expanded inline here.
65 ;
66 shr ax, 1
67 jnc load1 ; if (exp & 1)
68
69 fld st(1)
70 fld st(1)
71 jmp short looptop ; tmp = old
72 load1:
73 fldz
74 fld1 ; else tmp = [1,0]
75 looptop:
76 cmp ax, 0
77 je loopexit ; while (exp)
78
79 fld st(2) ; RD 5/7/89: Calculate xt^2 - yt^2
80 fadd st, st(4) ; by using (xt+yt)*(xt-yt), which
81 fld st(3) ; trades one multiplication for an
82 fsub st, st(5) ; addition. This trick saves a
83 fmul ; whopping 1.2 of time.
84
85 fld st(4)
86 fmul st, st(4)
87 fadd st, st ; yt = 2 * xt * yt
88
89 fstp st(5) ; tmp.y = yt
90 fstp st(3) ; tmp.x = xt
91
92 shr ax, 1
93 jnc looptop ; if (exp & 1)
94
95 fld st(2)
96 fmul st, st(1)
97 fld st(4)
98 fmul st, st(3)
99 fsub ; tmp.x = xt * tmp.x - yt * tmp.y
100
101 fld st(3)
102 fmul st, st(3)
103 fld st(5)
104 fmul st, st(3)
105 fadd ; tmp.y = xt * tmp.y + yt * tmp.x
106 fstp st(3)
107 fstp st(1)
108
109 jmp short looptop
110 loopexit:
111 fstp st(2)
112 fstp st(2)
113 ;
114 ; End of complex_power() routine. Result is in ST, ST(1)
115 ;
116 ;
117 ; complex_mult(tmp, old, &new);
118 ;
119 fld old + 8
120 fld old
121
122 fld st(3) ; tmp.y
123 fmul st, st(1) ; old.x
124 fld st(3) ; tmp.x
125 fmul st, st(3) ; old.y
126 fadd
127 fld st(3) ; tmp.x
128 fmul st, st(2) ; old.x
129 fld st(5) ; tmp.y
130 fmul st, st(4) ; old.y
131 fsub
132 ;
133 ; if (DIST1(new) < THRESHOLD) {
134 ;
135 fld1
136 fsubr st, st(1)
137 fmul st, st
138 fld st(2) ; new.y
139 fmul st, st
140 fadd
141 fcomp threshold
142 fstsw statw
143 mov ax, statw
144 sahf
145 jnc notless
146 ;
147 ; if (fractype == NEWTBASIN) {
148 ;
149 mov ax, basin
150 cmp ax, 0
151 je notbasin
152
153 mov bx, roots
154 mov dx, -1 ; tempcolor = -1
155 sub cx, cx
156 dloop:
157 fld qword ptr [bx] ; roots[i].x
158 fsub st, st(3) ; old.x
159 fmul st, st
160 fld qword ptr [bx+8]; roots[i].y
161 fsub st, st(5) ; old.y
162 fmul st, st
163 fadd
164 fcomp threshold
165 fstsw statw
166 mov ax, statw
167 sahf ; if (distance(roots[i],old) < threshold)...
168 jnc nl2
169
170 ; TW commented out next few lines and add dx,ax to eliminate newtbasin
171 ; 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, word ptr coloriter
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 word ptr coloriter, ax
mov word ptr coloriter+2, 0
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
;
;
;
; TW added support for no grid version - does not use dx0/dx1 pixel
; grid id use_grid == 0.
public invertz2
invertz2 proc uses si, zval:word
fld f_xcenter ; xcent
fld f_ycenter ; ycent xcent
mov ax, ds
cmp use_grid,0 ; inversion support added
je skip_grid ; don't use dx0 grid
172
173 mov bx, col ; use dx0 grid
174 shl bx, 1
175 shl bx, 1
176 shl bx, 1
177
178 mov cx, row
179 shl cx, 1
180 shl cx, 1
181 shl cx, 1
182
183 lds si, dx0
184 add si, bx
185 fld qword ptr [si] ; dx0[col] ycent xcent
186 mov ds, ax
187 lds si, dx1
188 add si, cx
189 fld qword ptr [si] ; dx1[row] dx0[col] ycent xcent
190 fadd ; dx1[row]+dx0[col] ycent xcent
191 fsub st, st(2) ; dx1[row]+dx0[col]-xcent ycent xcent
192
193 mov ds, ax
194 lds si, dy0
195 add si, cx
196 fld qword ptr [si] ; dy0[row] dx1[row]+dx0[col]-xcent ycent xcent
197 mov ds, ax
198 lds si, dy1
199 add si, bx
200 fld qword ptr [si] ; dy1[col] dy0[row] dx1[row]+dx0[col]-xcent ycent xcent
201 fadd ; dy1[col]+dy0[row] dx1[row]+dx0[col]-xcent ycent xcent
202 fsub st, st(2) ; dy1[col]+dy0[row]-ycent dx1[row]+dx0[col]-xcent ycent xcent
203
204 jmp after_load
205 skip_grid:
206 fild word ptr row ; row ycent xcent
207 fld tbyte ptr delxx2 ; delxx2 row ycent xcent
208 fmulp st(1),st(0) ; delxx2*row ycent xcent
209 fild word ptr col ; col delxx2*row ycent xcent
210 fld tbyte ptr delxx ; delxx col delxx2*row ycent xcent
211 fmulp st(1),st(0) ; delxx*col delxx2*row ycent xcent
212 faddp st(1),st(0) ; delxx*col+delxx2*row ycent xcent
213 fadd qword ptr xxmin ; xxmin+delxx*col+delxx2*row ycent xcent
214 fsub st, st(2) ; xxmin+col*delxx+row*delxx2-xcent ycent xcent
215
216 fild word ptr row
217 fld tbyte ptr delyy
218 fmulp st(1),st(0)
219 fsubr qword ptr yymax
220 fild word ptr col
221 fld tbyte ptr delyy2
222 fmulp st(1),st(0)
223 fsubp st(1),st(0)
224 fsub st, st(2)
225 after_load:
226
227 mov ds, ax
228 fld st(1)
229 fmul st, st
230 fld st(1)
231 fmul st, st
232 fadd
233
234 fcom floatmin
235 fstsw statw
236 mov ax, statw
237 sahf
238 jnc inl1
239
240 fstp st
241 fld floatmax
242 jmp icom
243 inl1:
244 fld f_radius
245 fdivr
246 icom:
247 fst tempsqrx
248
249 fmul st(2), st
250 fmul
251 faddp st(2), st
252 faddp st(2), st
253
254 mov si, zval
255 fstp qword ptr [si+8]
256 fstp qword ptr [si]
257
258 ret
259 invertz2 endp
260
261 END
262