|
|
1.1 root 1: page ,132
2: title manditer - compute next iteration of mandelbrot set
3: %out manditer
4:
5: ; Conditional assembly flags:
6: ;
7: ; TARGET_287 Defined if the target machine will be a 286
8: ; with a 287. This allows the 287 specific
9: ; instruction FSTSW AX to be used.
10: ;
11: ; DO_SCAN Defined if an entire scan is to be processed.
12: ; If so, extra parameters are supplied consisting
13: ; of the increment for the real portion of the
14: ; seed, a word buffer where the results will be
15: ; stored, and the count of points to compute.
16:
17: TARGET_287 equ 0
18: DO_SCAN equ 0
19:
20: ifdef TARGET_287
21: .286c
22: .287
23: else
24: .8087
25: endif
26:
27:
28: memS equ 1 ;Define small model program
29: ?PLM = 0 ;Define 'C' calling convention
30: ?WIN = 0 ;Define non-windows prologue
31:
32: .xlist
33: include cmacros.inc
34: .list
35:
36:
37: sBegin code
38: assumes cs,code
39: assumes ds,nothing
40:
41: four dq 4.0 ;Constant 4.0
42:
43:
44: ; The Mandelbrot set is defined to be the set of all complex
45: ; numbers C for which the size of Z^2 + C is finite after an
1.1.1.2 ! root 46: ; indefinite number of iterations (Z is initially 0).
1.1 root 47: ;
48: ; The square of a complex number C = C_Real + C_imag is
49: ;
50: ; (C_Real^2) - (2*C_Real*C_Imag)i - (C_Imag^2)
51: ;
52: ;
53: ; The size of a complex number is just it's distance from
54: ; the complex number 0. The distance from complex 0 is
55: ; the hypotenuse of the right triangle whose sides are the
56: ; real and imaginary parts of the complex number. Thus the
57: ; size is SQRT(Z_real^2 + Z_imag). If the size ever becomes
58: ; >= 2, the number will grow to infinity.
59:
60:
61:
62: cProc manditer,<PUBLIC>
63:
64: parmq creal ;Real part of mandelbrot seed
65: parmq cimag ;Imaginary part of mandelbrot seed
66: parmw max_iteration ;Maximum loop counter
67:
68: ifdef DO_SCAN ;If to do an entire scan line
69: parmw point_count ;Number of points to calculate
70: parmw results_buffer ;Near pointer to where results go
71: parmq creal_step ;Increment to next point
72: endif
73:
74: ifndef TARGET_287 ;If not explicitly for a 287
75: localw fstatus ;x87 status word
76: endif
77:
78: cBegin
79: ifdef DO_SCAN ;If to do an entire scan line
80: push si ;'C' requires SI to be saved
81: mov si,results_buffer ;DS:SI --> destination buffer
82: mov dx,point_count ;# of points to calculate
83: endif
84:
1.1.1.2 ! root 85: finit ;Initialize co-processor
1.1 root 86:
87: mov bx,max_iteration ;Max iteration counter
88:
89: fld four ;Load constant 4.0 for comparison
90: ; |-------------------------------|
91: ; | 4 | st(0)
92: ; |-------------------------------|
93:
94:
95: fld creal ;Load real part of seed
96: ; |-------------------------------|
97: ; | C real | st(1)
98: ; |-------------------------------|
99: ; | 4 | st(2)
100: ; |-------------------------------|
101:
102:
103: fld cimag ;Load imaginary part of seed
104: ; |-------------------------------|
105: ; | C imag | st(0)
106: ; |-------------------------------|
107: ; | C real | st(1)
108: ; |-------------------------------|
109: ; | 4 | st(2)
110: ; |-------------------------------|
111:
112:
113: ifdef DO_SCAN ;If to do an entire scan
114: fld creal_step ; load creal increment
115: else ;else
116: fdecstp ; Reserve location, tag as invalid
117: endif
118: ; |-------------------------------|
119: ; | Reserved or C real increment | st(0)
120: ; |-------------------------------|
121: ; | C imag | st(1)
122: ; |-------------------------------|
123: ; | C real | st(2)
124: ; |-------------------------------|
125: ; | 4 | st(3)
126: ; |-------------------------------|
127:
128:
129: scan_loop:
130:
131: ; Because this program optimizes the use of C real ^ 2
132: ; and C imag ^ 2, the size test will terminate one iteration
133: ; late. The original Mandelzoom was:
134: ;
135: ; Z = 0
136: ; Count = 0;
137: ; repeat
138: ; Z = Z^2 + C
139: ; count = count + 1
140: ; size = size of Z
141: ; until (count > 1000 or size >= 4)
142: ;
143: ; This program uses the intermediate calculations used for
144: ; the squaring for the size test. However, the result of
145: ; the first complex square operation will simply be the
146: ; constant C (0^2+C). By setting the initial value of Z
147: ; to C instead of 0, this latency will be corrected.
148:
149:
150:
151: fld st(1) ;Initialize imaginary part of sum
152: ; |-------------------------------|
153: ; | Z imag = C imag | st(0)
154: ; |-------------------------------|
155: ; | Reserved or C real increment | st(1)
156: ; |-------------------------------|
157: ; | C imag | st(2)
158: ; |-------------------------------|
159: ; | C real | st(3)
160: ; |-------------------------------|
161: ; | 4 | st(4)
162: ; |-------------------------------|
163:
164:
165: fld st(3) ;Initialize real part of sum
166: ; |-------------------------------|
167: ; | Z real = C real | st(0)
168: ; |-------------------------------|
169: ; | Z imag = C image | st(1)
170: ; |-------------------------------|
171: ; | Reserved or C real increment | st(2)
172: ; |-------------------------------|
173: ; | C imag | st(3)
174: ; |-------------------------------|
175: ; | C real | st(4)
176: ; |-------------------------------|
177: ; | 4 | st(5)
178: ; |-------------------------------|
179:
180:
181: mov cx,bx ;max iteration counter
182:
183: iterate_loop:
184:
185:
186: fld st(0)
187: ; |-------------------------------|
188: ; | Z real | st(0)
189: ; |-------------------------------|
190: ; | Z real | st(1)
191: ; |-------------------------------|
192: ; | Z imag | st(2)
193: ; |-------------------------------|
194: ; | Reserved or C real increment | st(3)
195: ; |-------------------------------|
196: ; | C imag | st(4)
197: ; |-------------------------------|
198: ; | C real | st(5)
199: ; |-------------------------------|
200: ; | 4 | st(6)
201: ; |-------------------------------|
202:
203:
204: fmul st(1),st
205: ; |-------------------------------|
206: ; | Z real | st(0)
207: ; |-------------------------------|
208: ; | (Z real)^2 | st(1)
209: ; |-------------------------------|
210: ; | Z imag | st(2)
211: ; |-------------------------------|
212: ; | Reserved or C real increment | st(3)
213: ; |-------------------------------|
214: ; | C imag | st(4)
215: ; |-------------------------------|
216: ; | C real | st(5)
217: ; |-------------------------------|
218: ; | 4 | st(6)
219: ; |-------------------------------|
220:
221:
222: fmul st,st(2)
223: ; |-------------------------------|
224: ; | Z real * Z imag | st(0)
225: ; |-------------------------------|
226: ; | (Z real)^2 | st(1)
227: ; |-------------------------------|
228: ; | Z imag | st(2)
229: ; |-------------------------------|
230: ; | Reserved or C real increment | st(3)
231: ; |-------------------------------|
232: ; | C imag | st(4)
233: ; |-------------------------------|
234: ; | C real | st(5)
235: ; |-------------------------------|
236: ; | 4 | st(6)
237: ; |-------------------------------|
238:
239:
240: fadd st,st(0)
241: ; |-------------------------------|
242: ; | Z real * Z imag * 2 | st(0)
243: ; |-------------------------------|
244: ; | Z real ^ 2 | st(1)
245: ; |-------------------------------|
246: ; | Z imag | st(2)
247: ; |-------------------------------|
248: ; | Reserved or C real increment | st(3)
249: ; |-------------------------------|
250: ; | C imag | st(4)
251: ; |-------------------------------|
252: ; | C real | st(5)
253: ; |-------------------------------|
254: ; | 4 | st(6)
255: ; |-------------------------------|
256:
257:
258: fadd st,st(4)
259: ; |-------------------------------|
260: ; | Z real * Z imag * 2 + C imag | st(0)
261: ; |-------------------------------|
262: ; | Z real ^ 2 | st(1)
263: ; |-------------------------------|
264: ; | Z imag | st(2)
265: ; |-------------------------------|
266: ; | Reserved or C real increment | st(3)
267: ; |-------------------------------|
268: ; | C imag | st(4)
269: ; |-------------------------------|
270: ; | C real | st(5)
271: ; |-------------------------------|
272: ; | 4 | st(6)
273: ; |-------------------------------|
274:
275:
276: fxch st(2)
277: ; |-------------------------------|
278: ; | Z imag | st(0)
279: ; |-------------------------------|
280: ; | Z real ^ 2 | st(1)
281: ; |-------------------------------|
282: ; | Z real * Z imag * 2 + C imag | st(2)
283: ; |-------------------------------|
284: ; | Reserved or C real increment | st(3)
285: ; |-------------------------------|
286: ; | C imag | st(4)
287: ; |-------------------------------|
288: ; | C real | st(5)
289: ; |-------------------------------|
290: ; | 4 | st(6)
291: ; |-------------------------------|
292:
293:
294: fmul st,st(0)
295: ; |-------------------------------|
296: ; | Z imag ^ 2 | st(0)
297: ; |-------------------------------|
298: ; | Z real ^ 2 | st(1)
299: ; |-------------------------------|
300: ; | Z real * Z imag * 2 + C imag | st(2)
301: ; |-------------------------------|
302: ; | Reserved or C real increment | st(3)
303: ; |-------------------------------|
304: ; | C imag | st(4)
305: ; |-------------------------------|
306: ; | C real | st(5)
307: ; |-------------------------------|
308: ; | 4 | st(6)
309: ; |-------------------------------|
310:
311:
312: fld st(1)
313: ; |-------------------------------|
314: ; | Z real ^ 2 | st(0)
315: ; |-------------------------------|
316: ; | Z imag ^ 2 | st(1)
317: ; |-------------------------------|
318: ; | Z real ^ 2 | st(2)
319: ; |-------------------------------|
320: ; | Z real * Z imag * 2 + C imag | st(3)
321: ; |-------------------------------|
322: ; | Reserved or C real increment | st(4)
323: ; |-------------------------------|
324: ; | C imag | st(5)
325: ; |-------------------------------|
326: ; | C real | st(6)
327: ; |-------------------------------|
328: ; | 4 | st(7)
329: ; |-------------------------------|
330:
331:
332: fadd st,st(1)
333: ; |-------------------------------|
334: ; | Z real ^ 2 + Z imag ^ 2 | st(0)
335: ; |-------------------------------|
336: ; | Z imag ^ 2 | st(1)
337: ; |-------------------------------|
338: ; | Z real ^ 2 | st(2)
339: ; |-------------------------------|
340: ; | Z real * Z imag * 2 + C imag | st(3)
341: ; |-------------------------------|
342: ; | Reserved or C real increment | st(4)
343: ; |-------------------------------|
344: ; | C imag | st(5)
345: ; |-------------------------------|
346: ; | C real | st(6)
347: ; |-------------------------------|
348: ; | 4 | st(7)
349: ; |-------------------------------|
350:
351:
352: fcomp st(7)
353: ; |-------------------------------|
354: ; | Z imag ^ 2 | st(0)
355: ; |-------------------------------|
356: ; | Z real ^ 2 | st(1)
357: ; |-------------------------------|
358: ; | Z real * Z imag * 2 + C imag | st(2)
359: ; |-------------------------------|
360: ; | Reserved or C real increment | st(3)
361: ; |-------------------------------|
362: ; | C imag | st(4)
363: ; |-------------------------------|
364: ; | C real | st(5)
365: ; |-------------------------------|
366: ; | 4 | st(6)
367: ; |-------------------------------|
368:
369:
370: ifdef TARGET_287 ;If 287, then store status word
371: fwait ; straight to ax. Have to wait!
372: fstsw ax ;
373: else ;else
374: fstsw fstatus ; will have to store to memory
375: endif
376: ; |-------------------------------|
377: ; | Z imag ^ 2 | st(0)
378: ; |-------------------------------|
379: ; | Z real ^ 2 | st(1)
380: ; |-------------------------------|
381: ; | Z real * Z imag * 2 + C imag | st(2)
382: ; |-------------------------------|
383: ; | Reserved or C real increment | st(3)
384: ; |-------------------------------|
385: ; | C imag | st(4)
386: ; |-------------------------------|
387: ; | C real | st(5)
388: ; |-------------------------------|
389: ; | 4 | st(6)
390: ; |-------------------------------|
391:
392:
393: fsubp st(1),st
394: ; |-------------------------------|
395: ; | Z real ^ 2 - Z imag ^ 2 | st(0)
396: ; |-------------------------------|
397: ; | Z real * Z imag * 2 + C imag | st(1)
398: ; |-------------------------------|
399: ; | Reserved or C real increment | st(2)
400: ; |-------------------------------|
401: ; | C imag | st(3)
402: ; |-------------------------------|
403: ; | C real | st(4)
404: ; |-------------------------------|
405: ; | 4 | st(5)
406: ; |-------------------------------|
407:
408:
409:
410: ; Do a little work while the FSUBP executes
411:
412: ifndef TARGET_287 ;If not a 287
413: mov ah,byte ptr (fstatus+1) ; load status word from memory
414: endif
415:
416: and ah,045h ;If size>= 4, outside of mandelbrot
417: xor ah,1 ; set.
418: jnz done_iterating ;Outside of set
419:
420:
421: fadd st,st(4)
422: ; |-------------------------------|
423: ; | Z real^2 - Z imag^2 + C real | st(0)
424: ; |-------------------------------|
425: ; | Z real * Z imag * 2 + C imag | st(1)
426: ; |-------------------------------|
427: ; | Reserved or C real increment | st(2)
428: ; |-------------------------------|
429: ; | C imag | st(3)
430: ; |-------------------------------|
431: ; | C real | st(4)
432: ; |-------------------------------|
433: ; | 4 | st(5)
434: ; |-------------------------------|
435:
436:
437: loop iterate_loop ;If loop expires, in mandelbrot set
438:
439: done_iterating:
440: mov ax,bx ;Max iteration count
441: sub ax,cx ;Compute number of iterations
442:
443: ifdef DO_SCAN ;If to do an entire scan
444: mov word ptr [si],ax ;Save result in result_buffer
445: add si,2 ;--> next slot of buffer
446: dec dx ;Any more points?
447: jz done_scan ;No, all done
448:
449: fstp st(0) ;Remove sum from stack
450: fstp st(0)
451: ; |-------------------------------|
452: ; | Reserved or C real increment | st(0)
453: ; |-------------------------------|
454: ; | C imag | st(1)
455: ; |-------------------------------|
456: ; | C real | st(2)
457: ; |-------------------------------|
458: ; | 4 | st(3)
459: ; |-------------------------------|
460:
461:
462: fadd st(2),st ;Update c real
463: ; |-------------------------------|
464: ; | Reserved or C real increment | st(0)
465: ; |-------------------------------|
466: ; | C imag | st(1)
467: ; |-------------------------------|
468: ; | C real + C real increment | st(2)
469: ; |-------------------------------|
470: ; | 4 | st(3)
471: ; |-------------------------------|
472:
473: jmp scan_loop
474:
475: done_scan:
476: pop si ;Return last result
477: endif
478:
479:
480: cEnd
481:
482: sEnd code
483: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.