File: dos\fracsuba.asm
1 ; FRACASM.ASM - Assembler subroutines for fractals.c
2
3 ; required for compatibility if Turbo ASM
4 IFDEF ??version
5 MASM51
6 QUIRKS
7 ENDIF
8
9 .MODEL medium,c
10
11 .8086
12
13 ; these must NOT be in any segment!!
14 ; this get's rid of TURBO-C fixup errors
extrn multiply:far ; this routine is in 'general.asm'
extrn floatbailout:word ; this routine is in 'fractals.c'
.data
extrn lold:qword, lnew:qword ; each defined as LCMPLX in fractals.c
extrn ltempsqrx:dword ; for fractals.c
extrn ltempsqry:dword ; for fractals.c
extrn lmagnitud:dword ; for fractals.c
extrn llimit:dword ; from calcfrac.c
extrn llimit2:dword ; from calcfrac.c
extrn bitshift:word ; fudgefactor for integer math
extrn overflow:word ; error from integer math
.code FRACTALS_TEXT
;; Note: the check for overflow is now in StandardFractal(), JCO 2/12/95
asmlMODbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; lmagnitud = ltempsqrx + ltempsqry;
; if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2
; || labs(lnew.y) > llimit2 || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push WORD PTR lnew+2
push WORD PTR lnew
push WORD PTR lnew+2
push WORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push WORD PTR lnew+6
push WORD PTR lnew+4
push WORD PTR lnew+6
push WORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
add ax,WORD PTR ltempsqrx
adc dx,WORD PTR ltempsqrx+2
mov WORD PTR lmagnitud,ax
mov WORD PTR lmagnitud+2,dx
; if (lmagnitud >= llimit
cmp dx,WORD PTR llimit+2
jl chkvs0
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || lmagnitud < 0
chkvs0: or dx,dx
js bailout
; || labs(lnew.x) > llimit2 ; This test and next one are extraneous:
; mov ax,WORD PTR lnew ; take x > llimit2 and sqr both sides
; mov dx,WORD PTR lnew+2 ; x^2 > llimit
; or dx,dx ; if x^2 > llimit then surely
; jge lnewx ; x^2 + y^2 > llimit
; neg ax ; which was just checked!
; adc dx,0
; neg dx
;lnewx: cmp dx,WORD PTR llimit2+2
; jl chklnewy
; jg bailout
; cmp ax,WORD PTR llimit2
; ja bailout
; || labs(lnew.y) > llimit2
;chklnewy:
; mov ax,WORD PTR lnew+4
; mov dx,WORD PTR lnew+6
; or dx,dx
; jge lnewy
; neg ax
; adc dx,0
; neg dx
;lnewy: cmp dx,WORD PTR llimit2+2
; jl chkoflow
; jg bailout
; cmp ax,WORD PTR llimit2
; ja bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
mov WORD PTR lold,ax
mov WORD PTR lold+2,dx
mov ax,WORD PTR lnew+4
mov dx,WORD PTR lnew+6
mov WORD PTR lold+4,ax
mov WORD PTR lold+6,dx
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asmlMODbailout endp
asmlREALbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; if (ltempsqrx >= llimit || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqry = lsqr(lnew.y);
push bitshift
push WORD PTR lnew+6
push WORD PTR lnew+4
push WORD PTR lnew+6
push WORD PTR lnew+4
call FAR PTR multiply
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; ltempsqrx = lsqr(lnew.x);
push bitshift
push WORD PTR lnew+2
push WORD PTR lnew
push WORD PTR lnew+2
push WORD PTR lnew
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
add ax,WORD PTR ltempsqry
adc dx,WORD PTR ltempsqry+2
mov WORD PTR lmagnitud,ax
mov WORD PTR lmagnitud+2,dx
mov ax,WORD PTR ltempsqrx ; restore ltempsqrx to ax & dx
mov dx,WORD PTR ltempsqrx+2
; if (ltempsqrx >= llimit
cmp dx,WORD PTR llimit+2
jl chkoflow
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
mov WORD PTR lold,ax
mov WORD PTR lold+2,dx
mov ax,WORD PTR lnew+4
mov dx,WORD PTR lnew+6
mov WORD PTR lold+4,ax
mov WORD PTR lold+6,dx
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asmlREALbailout endp
asmlIMAGbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; if (ltempsqry >= llimit || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push WORD PTR lnew+2
push WORD PTR lnew
push WORD PTR lnew+2
push WORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push WORD PTR lnew+6
push WORD PTR lnew+4
push WORD PTR lnew+6
push WORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
add ax,WORD PTR ltempsqrx
adc dx,WORD PTR ltempsqrx+2
mov WORD PTR lmagnitud,ax
mov WORD PTR lmagnitud+2,dx
mov ax,WORD PTR ltempsqry ; restore ltempsqry to ax & dx
mov dx,WORD PTR ltempsqry+2
; if (ltempsqry >= llimit
cmp dx,WORD PTR llimit+2
jl chkoflow
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
mov WORD PTR lold,ax
mov WORD PTR lold+2,dx
mov ax,WORD PTR lnew+4
mov dx,WORD PTR lnew+6
mov WORD PTR lold+4,ax
mov WORD PTR lold+6,dx
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asmlIMAGbailout endp
asmlORbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; if (ltempsqrx >= llimit || ltempsqry >= llimit || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push WORD PTR lnew+2
push WORD PTR lnew
push WORD PTR lnew+2
push WORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push WORD PTR lnew+6
push WORD PTR lnew+4
push WORD PTR lnew+6
push WORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
add ax,WORD PTR ltempsqrx
adc dx,WORD PTR ltempsqrx+2
mov WORD PTR lmagnitud,ax
mov WORD PTR lmagnitud+2,dx
mov ax,WORD PTR ltempsqry ; restore ltempsqry to ax & dx
mov dx,WORD PTR ltempsqry+2
; if (ltempsqry >= llimit
cmp dx,WORD PTR llimit+2
jl chkxnxt
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || ltempsqrx >= llimit
chkxnxt:
mov ax,WORD PTR ltempsqrx
mov dx,WORD PTR ltempsqrx+2
cmp dx,WORD PTR llimit+2
jl chkoflow
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
mov WORD PTR lold,ax
mov WORD PTR lold+2,dx
mov ax,WORD PTR lnew+4
mov dx,WORD PTR lnew+6
mov WORD PTR lold+4,ax
mov WORD PTR lold+6,dx
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asmlORbailout endp
asmlANDbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; if ((ltempsqrx >= llimit && ltempsqry >= llimit) || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push WORD PTR lnew+2
push WORD PTR lnew
push WORD PTR lnew+2
push WORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push WORD PTR lnew+6
push WORD PTR lnew+4
push WORD PTR lnew+6
push WORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
add ax,WORD PTR ltempsqrx
adc dx,WORD PTR ltempsqrx+2
mov WORD PTR lmagnitud,ax
mov WORD PTR lmagnitud+2,dx
mov ax,WORD PTR ltempsqry ; restore ltempsqry to ax & dx
mov dx,WORD PTR ltempsqry+2
; if ((ltempsqry >= llimit
cmp dx,WORD PTR llimit+2
jl chkoflow
jg chkx
cmp ax,WORD PTR llimit
jae chkx
jmp short chkoflow
; && ltempsqrx >= llimit)
chkx: mov ax,WORD PTR ltempsqrx
mov dx,WORD PTR ltempsqrx+2
cmp dx,WORD PTR llimit+2
jl chkoflow
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
mov WORD PTR lold,ax
mov WORD PTR lold+2,dx
mov ax,WORD PTR lnew+4
mov dx,WORD PTR lnew+6
mov WORD PTR lold+4,ax
mov WORD PTR lold+6,dx
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asmlANDbailout endp
asmlMANHbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; magnitude = fabs(new.x) + fabs(new.y);
; if(magnitude * magnitude) >= rqlim) return(1);
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push WORD PTR lnew+2
push WORD PTR lnew
push WORD PTR lnew+2
push WORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push WORD PTR lnew+6
push WORD PTR lnew+4
push WORD PTR lnew+6
push WORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
add ax,WORD PTR ltempsqrx
adc dx,WORD PTR ltempsqrx+2
mov WORD PTR lmagnitud,ax
mov WORD PTR lmagnitud+2,dx
; lold = abs(new.x) + abs(new.y) ; use lold as temp storage
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
cmp dx,0
jge xpos ; if negative, negate + 1
not ax
not dx
add ax,1
adc dx,0
xpos: mov bx,WORD PTR lnew+4
mov cx,WORD PTR lnew+6
cmp cx,0
jge ypos ; if negative, negate + 1
not bx
not cx
add bx,1
adc cx,0
ypos: add ax,bx
adc dx,cx
jge oksum
mov overflow,1
jmp short bailout
oksum: mov WORD PTR lold,ax
mov WORD PTR lold+2,dx
; lold * lold;
push bitshift
push WORD PTR lold+2
push WORD PTR lold
push WORD PTR lold+2
push WORD PTR lold
call FAR PTR multiply
add sp,10
; if ((lold * lold) >= llimit
cmp dx,WORD PTR llimit+2
jl chkoflow
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
mov WORD PTR lold,ax
mov WORD PTR lold+2,dx
mov ax,WORD PTR lnew+4
mov dx,WORD PTR lnew+6
mov WORD PTR lold+4,ax
mov WORD PTR lold+6,dx
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asmlMANHbailout endp
asmlMANRbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; magnitude = fabs(new.x + new.y);
; if(magnitude * magnitude) >= rqlim) return(1);
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push WORD PTR lnew+2
push WORD PTR lnew
push WORD PTR lnew+2
push WORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push WORD PTR lnew+6
push WORD PTR lnew+4
push WORD PTR lnew+6
push WORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
add ax,WORD PTR ltempsqrx
adc dx,WORD PTR ltempsqrx+2
mov WORD PTR lmagnitud,ax
mov WORD PTR lmagnitud+2,dx
; lold = abs(new.x + new.y) ; lold used as temp storage
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
add ax,WORD PTR lnew+4
adc dx,WORD PTR lnew+6 ; square next, don't need abs
15 mov WORD PTR lold,ax
16 mov WORD PTR lold+2,dx
17 ; lmagnitud * lmagnitud;
18 push bitshift
19 push WORD PTR lold+2
20 push WORD PTR lold
21 push WORD PTR lold+2
22 push WORD PTR lold
23 call FAR PTR multiply
24 add sp,10
25 ; if ((lold * lold) >= llimit
26 cmp dx,WORD PTR llimit+2
27 jl chkoflow
28 jg bailout
29 cmp ax,WORD PTR llimit
30 jae bailout
31 ; || overflow)
32 chkoflow:
33 ; cmp overflow,0
34 ; jne bailout
35 ; else {
36 ; lold = lnew;
37 mov ax,WORD PTR lnew
38 mov dx,WORD PTR lnew+2
39 mov WORD PTR lold,ax
40 mov WORD PTR lold+2,dx
41 mov ax,WORD PTR lnew+4
42 mov dx,WORD PTR lnew+6
43 mov WORD PTR lold+4,ax
44 mov WORD PTR lold+6,dx
45 ; return(0); }
46 sub ax,ax
47 ret
48 bailout:
49 ; { overflow=0; return(1); }
50 ; mov overflow,0
51 mov ax,1
52 ret
53 asmlMANRbailout endp
54
55
56 .386
57
58 asm386lMODbailout proc near
59 ;
60 ; equivalent to the C code:
61 ; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
62 ; lmagnitud = ltempsqrx + ltempsqry;
63 ; if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2
64 ; || labs(lnew.y) > llimit2 || overflow)
65 ; { overflow=0; return(1); }
66 ; lold = lnew;
67 ; return(0);
68 ;
69 ; ltempsqrx = lsqr(lnew.x);
70 push bitshift
71 push DWORD PTR lnew
72 push DWORD PTR lnew
73 call FAR PTR multiply
74 mov WORD PTR ltempsqrx,ax
75 mov WORD PTR ltempsqrx+2,dx
76 ; ltempsqry = lsqr(lnew.y);
77 push bitshift
78 push DWORD PTR lnew+4
79 push DWORD PTR lnew+4
80 call FAR PTR multiply
81 add sp,20
82 mov WORD PTR ltempsqry,ax
83 mov WORD PTR ltempsqry+2,dx
84 ; lmagnitud = ltempsqrx + ltempsqry;
85 mov eax,DWORD PTR ltempsqry
86 add eax,DWORD PTR ltempsqrx
87 mov DWORD PTR lmagnitud,eax
88 ; if (lmagnitud >= llimit
89 cmp eax,DWORD PTR llimit
90 jae bailout
91 ; || overflow)
92 chkoflow:
93 ; cmp overflow,0
94 ; jne bailout
95 ; else {
96 ; lold = lnew;
97 mov eax,DWORD PTR lnew
98 mov DWORD PTR lold,eax
99 mov eax,DWORD PTR lnew+4
100 mov DWORD PTR lold+4,eax
101 ; return(0); }
102 sub ax,ax
103 ret
104 bailout:
105 ; { overflow=0; return(1); }
106 ; mov overflow,0
107 mov ax,1
108 ret
109 asm386lMODbailout endp
110
111 asm386lREALbailout proc near
112 ;
113 ; equivalent to the C code:
114 ; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
115 ; if (ltempsqrx >= llimit || overflow)
116 ; { overflow=0; return(1); }
117 ; lold = lnew;
118 ; return(0);
119 ;
120 ; ltempsqry = lsqr(lnew.y);
121 push bitshift
122 push DWORD PTR lnew+4
123 push DWORD PTR lnew+4
124 call FAR PTR multiply
125 mov WORD PTR ltempsqry,ax
126 mov WORD PTR ltempsqry+2,dx
127 ; ltempsqrx = lsqr(lnew.x);
128 push bitshift
129 push DWORD PTR lnew
130 push DWORD PTR lnew
131 call FAR PTR multiply
132 add sp,20
133 mov WORD PTR ltempsqrx,ax
134 mov WORD PTR ltempsqrx+2,dx
135 ; lmagnitud = ltempsqrx + ltempsqry;
136 mov eax,DWORD PTR ltempsqry
137 add eax,DWORD PTR ltempsqrx
138 mov DWORD PTR lmagnitud,eax
139 ; if (ltempsqrx >= llimit
140 mov eax,DWORD PTR ltempsqrx
141 cmp eax,DWORD PTR llimit
142 jae bailout
143 ; || overflow)
144 chkoflow:
145 ; cmp overflow,0
146 ; jne bailout
147 ; else {
148 ; lold = lnew;
149 mov eax,DWORD PTR lnew
150 mov DWORD PTR lold,eax
151 mov eax,DWORD PTR lnew+4
152 mov DWORD PTR lold+4,eax
153 ; return(0); }
154 sub ax,ax
155 ret
156 bailout:
157 ; { overflow=0; return(1); }
158 ; mov overflow,0
159 mov ax,1
160 ret
161 asm386lREALbailout endp
162
163 asm386lIMAGbailout proc near
164 ;
165 ; equivalent to the C code:
166 ; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
167 ; if (ltempsqry >= llimit || overflow)
168 ; { overflow=0; return(1); }
169 ; lold = lnew;
170 ; return(0);
171 ;
172 ; ltempsqrx = lsqr(lnew.x);
173 push bitshift
174 push DWORD PTR lnew
175 push DWORD PTR lnew
176 call FAR PTR multiply
177 mov WORD PTR ltempsqrx,ax
178 mov WORD PTR ltempsqrx+2,dx
179 ; ltempsqry = lsqr(lnew.y);
180 push bitshift
181 push DWORD PTR lnew+4
182 push DWORD PTR lnew+4
183 call FAR PTR multiply
184 add sp,20
185 mov WORD PTR ltempsqry,ax
186 mov WORD PTR ltempsqry+2,dx
187 ; lmagnitud = ltempsqrx + ltempsqry;
188 mov eax,DWORD PTR ltempsqry
189 add eax,DWORD PTR ltempsqrx
190 mov DWORD PTR lmagnitud,eax
191 ; if (ltempsqry >= llimit
192 mov eax,DWORD PTR ltempsqry
193 cmp eax,DWORD PTR llimit
194 jae bailout
195 ; || overflow)
196 chkoflow:
197 ; cmp overflow,0
198 ; jne bailout
199 ; else {
200 ; lold = lnew;
201 mov eax,DWORD PTR lnew
202 mov DWORD PTR lold,eax
203 mov eax,DWORD PTR lnew+4
204 mov DWORD PTR lold+4,eax
205 ; return(0); }
206 sub ax,ax
207 ret
208 bailout:
209 ; { overflow=0; return(1); }
210 ; mov overflow,0
211 mov ax,1
212 ret
213 asm386lIMAGbailout endp
214
215 asm386lORbailout proc near
216 ;
217 ; equivalent to the C code:
218 ; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
219 ; if (ltempsqrx >= llimit || ltempsqry >= llimit || overflow)
220 ; { overflow=0; return(1); }
221 ; lold = lnew;
222 ; return(0);
223 ;
224 ; ltempsqrx = lsqr(lnew.x);
225 push bitshift
226 push DWORD PTR lnew
227 push DWORD PTR lnew
228 call FAR PTR multiply
229 mov WORD PTR ltempsqrx,ax
230 mov WORD PTR ltempsqrx+2,dx
231 ; ltempsqry = lsqr(lnew.y);
232 push bitshift
233 push DWORD PTR lnew+4
234 push DWORD PTR lnew+4
235 call FAR PTR multiply
236 add sp,20
237 mov WORD PTR ltempsqry,ax
238 mov WORD PTR ltempsqry+2,dx
239 ; lmagnitud = ltempsqrx + ltempsqry;
240 mov eax,DWORD PTR ltempsqry
241 add eax,DWORD PTR ltempsqrx
242 mov DWORD PTR lmagnitud,eax
243 ; if (ltempsqry >= llimit
244 mov eax,DWORD PTR ltempsqry
245 cmp eax,DWORD PTR llimit
246 jae bailout
247 ; || ltempsqrx >= llimit
248 chkxnxt:
249 mov eax,DWORD PTR ltempsqrx
250 cmp eax,DWORD PTR llimit
251 jae bailout
252 ; || overflow)
253 chkoflow:
254 ; cmp overflow,0
255 ; jne bailout
256 ; else {
257 ; lold = lnew;
258 mov eax,DWORD PTR lnew
259 mov DWORD PTR lold,eax
260 mov eax,DWORD PTR lnew+4
261 mov DWORD PTR lold+4,eax
262 ; return(0); }
263 sub ax,ax
264 ret
265 bailout:
266 ; { overflow=0; return(1); }
267 ; mov overflow,0
268 mov ax,1
269 ret
270 asm386lORbailout endp
271
272 asm386lANDbailout proc near
273 ;
274 ; equivalent to the C code:
275 ; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
276 ; if ((ltempsqrx >= llimit && ltempsqry >= llimit) || overflow)
277 ; { overflow=0; return(1); }
278 ; lold = lnew;
279 ; return(0);
280 ;
281 ; ltempsqrx = lsqr(lnew.x);
282 push bitshift
283 push DWORD PTR lnew
284 push DWORD PTR lnew
285 call FAR PTR multiply
286 mov WORD PTR ltempsqrx,ax
287 mov WORD PTR ltempsqrx+2,dx
288 ; ltempsqry = lsqr(lnew.y);
289 push bitshift
290 push DWORD PTR lnew+4
291 push DWORD PTR lnew+4
292 call FAR PTR multiply
293 add sp,20
294 mov WORD PTR ltempsqry,ax
295 mov WORD PTR ltempsqry+2,dx
296 ; lmagnitud = ltempsqrx + ltempsqry;
297 mov eax,DWORD PTR ltempsqry
298 add eax,DWORD PTR ltempsqrx
299 mov DWORD PTR lmagnitud,eax
300 ; if ((ltempsqry >= llimit
301 mov eax,DWORD PTR ltempsqry
302 cmp eax,DWORD PTR llimit
303 jl chkoflow
304 ; && ltempsqrx >= llimit)
305 chkx: mov eax,DWORD PTR ltempsqrx
306 cmp eax,DWORD PTR llimit
307 jae bailout
308 ; || overflow)
309 chkoflow:
310 ; cmp overflow,0
311 ; jne bailout
312 ; else {
313 ; lold = lnew;
314 mov eax,DWORD PTR lnew
315 mov DWORD PTR lold,eax
316 mov eax,DWORD PTR lnew+4
317 mov DWORD PTR lold+4,eax
318 ; return(0); }
319 sub ax,ax
320 ret
321 bailout:
322 ; { overflow=0; return(1); }
323 ; mov overflow,0
324 mov ax,1
325 ret
326 asm386lANDbailout endp
327
328 asm386lMANHbailout proc near
329 ;
330 ; equivalent to the C code:
331 ; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
332 ; magnitude = fabs(new.x) + fabs(new.y);
333 ; if(magnitude * magnitude) >= rqlim) return(1);
334 ; lold = lnew;
335 ; return(0);
336 ;
337 ; ltempsqrx = lsqr(lnew.x);
338 push bitshift
339 push DWORD PTR lnew
340 push DWORD PTR lnew
341 call FAR PTR multiply
342 mov WORD PTR ltempsqrx,ax
343 mov WORD PTR ltempsqrx+2,dx
344 ; ltempsqry = lsqr(lnew.y);
345 push bitshift
346 push DWORD PTR lnew+4
347 push DWORD PTR lnew+4
348 call FAR PTR multiply
349 add sp,20
350 mov WORD PTR ltempsqry,ax
351 mov WORD PTR ltempsqry+2,dx
352 ; lmagnitud = ltempsqrx + ltempsqry;
353 mov eax,DWORD PTR ltempsqry
354 add eax,DWORD PTR ltempsqrx
355 mov DWORD PTR lmagnitud,eax
356 ; lold = (abs(new.x) + abs(new.y))^2 ; lold used for storage
357 mov eax,DWORD PTR lnew
358 cmp eax,0
359 jge xpos ; if negative, negate
360 neg eax
361 xpos: mov ebx,DWORD PTR lnew+4
362 cmp ebx,0
363 jge ypos ; if negative, negate
364 neg ebx
365 ypos: add eax,ebx
366 jno oksum
367 mov overflow,1
368 jmp short bailout
369 oksum: mov DWORD PTR lold,eax
370 ; lold * lold;
371 push bitshift
372 push DWORD PTR lold
373 push DWORD PTR lold
374 call FAR PTR multiply
375 add sp,10
376 ; put results returned in ax and dx into edx
377 shl edx,16
378 mov dx,ax
379 ; if ((lold * lold) >= llimit
380 cmp edx,DWORD PTR llimit
381 jae bailout
382 ; || overflow)
383 chkoflow:
384 ; cmp overflow,0
385 ; jne bailout
386 ; else {
387 ; lold = lnew;
388 mov eax,DWORD PTR lnew
389 mov DWORD PTR lold,eax
390 mov eax,DWORD PTR lnew+4
391 mov DWORD PTR lold+4,eax
392 ; return(0); }
393 sub ax,ax
394 ret
395 bailout:
396 ; { overflow=0; return(1); }
397 ; mov overflow,0
398 mov ax,1
399 ret
400 asm386lMANHbailout endp
401
402 asm386lMANRbailout proc near
403 ;
404 ; equivalent to the C code:
405 ; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
406 ; magnitude = fabs(new.x + new.y);
407 ; if(magnitude * magnitude) >= rqlim) return(1);
408 ; lold = lnew;
409 ; return(0);
410 ;
411 ; ltempsqrx = lsqr(lnew.x);
412 push bitshift
413 push DWORD PTR lnew
414 push DWORD PTR lnew
415 call FAR PTR multiply
416 mov WORD PTR ltempsqrx,ax
417 mov WORD PTR ltempsqrx+2,dx
418 ; ltempsqry = lsqr(lnew.y);
419 push bitshift
420 push DWORD PTR lnew+4
421 push DWORD PTR lnew+4
422 call FAR PTR multiply
423 add sp,20
424 mov WORD PTR ltempsqry,ax
425 mov WORD PTR ltempsqry+2,dx
426 ; lmagnitud = ltempsqrx + ltempsqry;
427 mov eax,DWORD PTR ltempsqry
428 add eax,DWORD PTR ltempsqrx
429 mov DWORD PTR lmagnitud,eax
430 ; lold = abs(new.x + new.y) ; lold used as temp storage
431 mov eax,DWORD PTR lnew
432 add eax,DWORD PTR lnew+4
433 mov DWORD PTR lold,eax ; square next, don't need abs
; lold * lold;
push bitshift
push DWORD PTR lold
push DWORD PTR lold
call FAR PTR multiply
add sp,10
; put results returned in ax and dx into edx
shl edx,16
mov dx,ax
; if ((lold * lold) >= llimit
cmp edx,DWORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov eax,DWORD PTR lnew
mov DWORD PTR lold,eax
mov eax,DWORD PTR lnew+4
mov DWORD PTR lold+4,eax
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asm386lMANRbailout endp
; Fast fractal orbit calculation procs for Fractint.
; By Chuck Ebbert CIS: (76306,1226)
;
; FManOWarfpFractal()
; FJuliafpFractal()
; FBarnsley1FPFractal()
; FBarnsley2FPFractal()
; FLambdaFPFractal()
;
; asmfloatbailout() -- bailout proc (NEAR proc used by above)
; NOTE: asmfloatbailout() modifies SI and DI.
;
; These will only run on machines with a 287 or a 387 (and a 486 of course.)
;
; Some of the speed gains from this code are due to the storing of the NPU
; status word directly to the AX register. FRACTINT will use these
; routines only when it finds a 287 or better coprocessor installed.
.286
.287
.data
extrn new:qword, old:qword, tmp:qword
extrn rqlim:qword, magnitude:qword, tempsqrx:qword, tempsqry:qword
extrn cpu:word, fpu:word, floatparm:word
.code FRACTALS_TEXT
; px,py = floatparm->x,y
; ox,oy = oldx,oldy
; nx,ny = newx,newy
; nx2,ny2 = newxsquared,newysquared
; tx,ty = tempx, tempy (used in lambda)
FManOWarfpFractal proc uses si di
; From Art Matrix via Lee Skinner
fld tempsqrx ; ox2
fsub tempsqry ; ox2-oy2
mov bx,floatparm
fadd tmp ; ox2-oy2+tx
fadd qword ptr [bx] ; newx
fld old ; oldx newx
fmul old+8 ; oldx*oldy newx
fadd st,st ; oldx*oldy*2 newx
fadd tmp+8 ; oldx*oldy*2+tmp.y newx
fadd qword ptr [bx+8] ; newy newx
fstp qword ptr new+8 ; newx
fstp qword ptr new ; stack is empty
mov si,offset old ; tmp=old
mov di,offset tmp
mov ax,ds
mov es,ax
mov cx,8
rep movsw
; call near ptr asmfloatbailout
call word ptr [floatbailout]
ret
FManOWarfpFractal endp
FJuliafpFractal proc uses si di
; Julia/Mandelbrot floating-point orbit function.
fld tempsqrx
fsub tempsqry
mov bx,floatparm
fadd qword ptr [bx] ;/* add floatparm->x */
fld qword ptr old ;/* now get 2*x*y+floatparm->y */
fmul qword ptr old+8
fadd st,st
fadd qword ptr [bx+8] ; add floatparm->y
fstp qword ptr new+8 ; newx
fstp qword ptr new ; stack is empty
; call near ptr asmfloatbailout
call word ptr [floatbailout]
ret
FJuliafpFractal endp
FBarnsley1FPFractal proc uses si di
; From Fractals Everywhere by Michael Barnsley
mov bx,floatparm
fld qword ptr [bx] ;/* STACK: px */
fld qword ptr [bx+8] ;/* py px */
fld qword ptr old ;/* ox py px */
ftst ;/*** we will want this later */
fstsw ax ;/*** 287 or better only */
fld old+8 ;/* oy ox py px */
fld st(1) ;/* ox oy ox py px */
fmul st,st(4) ;/* ox*px oy ox py px */
fld st(1) ;/* oy ox*px oy ox py px */
fmul st,st(4) ;/* oy*py ox*px oy ox py px */
fsub ;/* (ox*px-oy*py) oy ox py px */
fxch ;/* oy (oxpx-oypy) ox py px */
fmul st,st(4) ;/* oy*px (oxpx-oypy) ox py px */
fxch st(2) ;/* ox (oxpx-oypy) oy*px py px */
fmul st,st(3) ;/* ox*py (oxpx-oypy) oy*px py px */
faddp st(2),st ;/* oxpx-oypy oypx+oxpy py px */
sahf ;/*** use the saved status (finally) */
jb BFPM1add
fsubrp st(3),st ;/* oypx+oxpy py nx */
fsubr ;/* ny nx */
jmp short BFPM1cont
BFPM1add:
faddp st(3),st ;/* oypx+oxpy py nx */
fadd ;/* ny nx */
BFPM1cont:
fstp qword ptr new+8 ; newx
fstp qword ptr new ; stack is empty
; call near ptr asmfloatbailout
call word ptr [floatbailout]
ret
FBarnsley1FPFractal endp
FBarnsley2FPFractal proc uses si di
; Also from Fractals Everywhere
mov bx,floatparm
fld qword ptr [bx] ;/* STACK: px */
fld qword ptr [bx+8] ;/* py px */
fld qword ptr old ;/* ox py px */
fld qword ptr old+8 ;/* oy ox py px */
fld st(1) ;/* ox oy ox py px */
fmul st,st(4) ;/* ox*px oy ox py px */
fld st(1) ;/* oy ox*px oy ox py px */
fmul st,st(4) ;/* oy*py ox*px oy ox py px */
fsub ;/* (ox*px-oy*py) oy ox py px */
fxch st(2) ;/* ox oy (oxpx-oypy) py px */
fmul st,st(3) ;/* ox*py oy (oxpx-oypy) py px */
fxch ;/* oy ox*py (oxpx-oypy) py px */
fmul st,st(4) ;/* oy*px ox*py (oxpx-oypy) py px */
fadd ;/* oypx+oxpy oxpx-oypy py px */
ftst
fstsw ax ;/* 287 or better only */
sahf
jb BFPM2add
fsubrp st(2),st ;/* oxpx-oypy ny px */
fsubrp st(2),st ;/* ny nx */
jmp short BFPM2cont
BFPM2add:
faddp st(2),st ;/* oxpx-oypy ny px */
faddp st(2),st ;/* ny nx */
BFPM2cont:
fstp qword ptr new+8 ; newx
fstp qword ptr new ; stack is empty
; call near ptr asmfloatbailout
call word ptr [floatbailout]
ret
FBarnsley2FPFractal endp
FLambdaFPFractal proc uses si di
; tempsqrx and tempsqry can be used -- the C code doesn't use them!
434 fld tempsqry ;oy2
435 fsub tempsqrx ;oy2-ox2
436 fld old ;ox oy2-ox2
437 fadd st(1),st ;ox tx=ox+oy2-ox2
438 fadd st,st ;2ox tx
439 fld1 ;1 2ox tx
440 fsubr ;(1-2ox) tx
441 fmul old+8 ;ty=oy(1-2ox) tx
442 fld st(1) ;tx ty tx -- duplicate these now
443 fld st(1) ;ty tx ty tx
444 mov bx,floatparm
445 fld qword ptr [bx+8] ;py ty tx ty tx -- load y first
446 fld qword ptr [bx] ;px py ty tx ty tx
447 fmul st(5),st ;px py ty tx ty pxtx
448 fmulp st(4),st ;py ty tx pxty pxtx
449 fmul st(2),st ;py ty pytx pxty pxtx
450 fmul ;pyty pytx pxty pxtx
451 fsubp st(3),st ;pytx pxty nx=pxtx-pyty
452 fadd ;ny=pxty+pytx nx
453 fstp qword ptr new+8 ; newx
454 fstp qword ptr new ; stack is empty
455 ; call near ptr asmfloatbailout
456 call word ptr [floatbailout]
457 ret
458 FLambdaFPFractal endp
459
460 ; The following is no longer used.
461 asmfloatbailout proc near
462 ; called with new.y and new.x on stack and clears the stack
463 ; destroys SI and DI: caller must save them
464 fst qword ptr new+8
465 fmul st,st ;/* ny2 nx */
466 fst tempsqry
467 fxch ;/* nx ny2 */
468 fst qword ptr new
469 fmul st,st ;/* nx2 ny2 */
470 fst tempsqrx
471 fadd
472 fst magnitude
473 fcomp rqlim ;/*** stack is empty */
474 fstsw ax ;/*** 287 and up only */
475 sahf
476 jae bailout
477 mov si,offset new
478 mov di,offset old
479 mov ax,ds
480 mov es,ax
481 mov cx,8
482 rep movsw
483 xor ax,ax
484 ret
485 bailout:
486 mov ax,1
487 ret
488 asmfloatbailout endp
489 ; The preceeding is no longer used.
490
491 asmfpMODbailout proc near uses si di
492 fld qword ptr new+8
493 fmul st,st ;/* ny2 */
494 fst tempsqry
495 fld qword ptr new ;/* nx ny2 */
496 fmul st,st ;/* nx2 ny2 */
497 fst tempsqrx
498 fadd
499 fst magnitude
500 fcomp rqlim ;/*** stack is empty */
501 fstsw ax ;/*** 287 and up only */
502 sahf
503 jae bailout
504 mov si,offset new
505 mov di,offset old
506 mov ax,ds
507 mov es,ax
508 mov cx,8
509 rep movsw
510 xor ax,ax
511 ret
512 bailout:
513 mov ax,1
514 ret
515 asmfpMODbailout endp
516
517 asmfpREALbailout proc near uses si di
518 fld qword ptr new
519 fmul st,st ;/* nx2 */
520 fst tempsqrx
521 fld qword ptr new+8 ;/* ny nx2 */
522 fmul st,st ;/* ny2 nx2 */
523 fst tempsqry ;/* ny2 nx2 */
524 fadd st,st(1) ;/* ny2+nx2 nx2 */
525 fstp magnitude ;/* nx2 */
526 fcomp rqlim ;/*** stack is empty */
527 fstsw ax ;/*** 287 and up only */
528 sahf
529 jae bailout
530 mov si,offset new
531 mov di,offset old
532 mov ax,ds
533 mov es,ax
534 mov cx,8
535 rep movsw
536 xor ax,ax
537 ret
538 bailout:
539 mov ax,1
540 ret
541 asmfpREALbailout endp
542
543 asmfpIMAGbailout proc near uses si di
544 fld qword ptr new+8
545 fmul st,st ;/* ny2 */
546 fst tempsqry
547 fld qword ptr new ;/* nx ny2 */
548 fmul st,st ;/* nx2 ny2 */
549 fst tempsqrx ;/* nx2 ny2 */
550 fadd st,st(1) ;/* nx2+ny2 ny2 */
551 fstp magnitude ;/* ny2 */
552 fcomp rqlim ;/*** stack is empty */
553 fstsw ax ;/*** 287 and up only */
554 sahf
555 jae bailout
556 mov si,offset new
557 mov di,offset old
558 mov ax,ds
559 mov es,ax
560 mov cx,8
561 rep movsw
562 xor ax,ax
563 ret
564 bailout:
565 mov ax,1
566 ret
567 asmfpIMAGbailout endp
568
569 asmfpORbailout proc near uses si di
570 fld qword ptr new+8
571 fmul st,st ;/* ny2 */
572 fst tempsqry
573 fld qword ptr new ;/* nx ny2 */
574 fmul st,st ;/* nx2 ny2 */
575 fst tempsqrx
576 fld st(1) ;/* ny2 nx2 ny2 */
577 fadd st,st(1) ;/* ny2+nx2 nx2 ny2 */
578 fstp magnitude ;/* nx2 ny2 */
579 fcomp rqlim ;/* ny2 */
580 fstsw ax ;/*** 287 and up only */
581 sahf
582 jae bailoutp
583 fcomp rqlim ;/*** stack is empty */
584 fstsw ax ;/*** 287 and up only */
585 sahf
586 jae bailout
587 mov si,offset new
588 mov di,offset old
589 mov ax,ds
590 mov es,ax
591 mov cx,8
592 rep movsw
593 xor ax,ax
594 ret
595 bailoutp:
596 finit ;/* cleans up stack */
597 bailout:
598 mov ax,1
599 ret
600 asmfpORbailout endp
601
602 asmfpANDbailout proc near uses si di
603 fld qword ptr new+8
604 fmul st,st ;/* ny2 */
605 fst tempsqry
606 fld qword ptr new ;/* nx ny2 */
607 fmul st,st ;/* nx2 ny2 */
608 fst tempsqrx
609 fld st(1) ;/* ny2 nx2 ny2 */
610 fadd st,st(1) ;/* ny2+nx2 nx2 ny2 */
611 fstp magnitude ;/* nx2 ny2 */
612 fcomp rqlim ;/* ny2 */
613 fstsw ax ;/*** 287 and up only */
614 sahf
615 jb nobailoutp
616 fcomp rqlim ;/*** stack is empty */
617 fstsw ax ;/*** 287 and up only */
618 sahf
619 jae bailout
620 jmp short nobailout
621 nobailoutp:
622 finit ;/* cleans up stack */
623 nobailout:
624 mov si,offset new
625 mov di,offset old
626 mov ax,ds
627 mov es,ax
628 mov cx,8
629 rep movsw
630 xor ax,ax
631 ret
632 bailout:
633 mov ax,1
634 ret
635 asmfpANDbailout endp
636
637 asmfpMANHbailout proc near uses si di
638 fld qword ptr new+8
639 fld st
640 fmul st,st ;/* ny2 ny */
641 fst tempsqry
642 fld qword ptr new ;/* nx ny2 ny */
643 fld st
644 fmul st,st ;/* nx2 nx ny2 ny */
645 fst tempsqrx
646 faddp st(2),st ;/* nx nx2+ny2 ny */
647 fxch st(1) ;/* nx2+ny2 nx ny */
648 fstp magnitude ;/* nx ny */
649 fabs
650 fxch
651 fabs
652 fadd ;/* |nx|+|ny| */
653 fmul st,st ;/* (|nx|+|ny|)2 */
654 fcomp rqlim ;/*** stack is empty */
655 fstsw ax ;/*** 287 and up only */
656 sahf
657 jae bailout
658 jmp short nobailout
659 nobailoutp:
660 finit ;/* cleans up stack */
661 nobailout:
662 mov si,offset new
663 mov di,offset old
664 mov ax,ds
665 mov es,ax
666 mov cx,8
667 rep movsw
668 xor ax,ax
669 ret
670 bailout:
671 mov ax,1
672 ret
673 asmfpMANHbailout endp
674
675 asmfpMANRbailout proc near uses si di
676 fld qword ptr new+8
677 fld st
678 fmul st,st ;/* ny2 ny */
679 fst tempsqry
680 fld qword ptr new ;/* nx ny2 ny */
681 fld st
682 fmul st,st ;/* nx2 nx ny2 ny */
683 fst tempsqrx
684 faddp st(2),st ;/* nx nx2+ny2 ny */
685 fxch st(1) ;/* nx2+ny2 nx ny */
686 fstp magnitude ;/* nx ny */
687 fadd ;/* nx+ny */
688 fmul st,st ; square, don't need abs
fcomp rqlim ;/*** stack is empty */
fstsw ax ;/*** 287 and up only */
sahf
jae bailout
jmp short nobailout
nobailoutp:
finit ;/* cleans up stack */
nobailout:
mov si,offset new
mov di,offset old
mov ax,ds
mov es,ax
mov cx,8
rep movsw
xor ax,ax
ret
bailout:
mov ax,1
ret
asmfpMANRbailout endp
.8086
.8087
end