Rev 551 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
31 | halyavin | 1 | ; tinyfrac.asm |
2 | ; |
||
3 | ; teeny program displays the Mandelbrot set. |
||
4 | ; |
||
5 | ; written on Sun 03-26-1995 by Ed Beroset (Fidonet 1:3641/1.250) |
||
6 | ; |
||
7 | ; This program was based on a program by Frank Hommers, later optimized |
||
8 | ; for size by Mikko Hyvarinen and posted in Fidonet's 80XXX echo. |
||
9 | ; |
||
10 | ; This new version has many new features and was based on my own |
||
11 | ; optimization of Hyvarinen's version. Some features: |
||
12 | ; |
||
13 | ; pan using the arrow keys, one can navigate the fractal. |
||
14 | ; |
||
15 | ; Home Up PgUp |
||
16 | ; Left Right correspond to 8 obvious directions |
||
17 | ; End Dn PgDn |
||
18 | ; |
||
19 | ; zoom there are now ten levels of magnification available. If the |
||
20 | ; program is assembled with FEATURES defined, the number |
||
21 | ; corresponding to the zoom level (0-9, zero is most zoomed in) |
||
22 | ; is displayed in the upper left hand corner of the screen just |
||
23 | ; before each new fractal is drawn. The gray '+' key zooms out, |
||
24 | ; the gray '-' key zooms in. |
||
25 | ; |
||
26 | ; beep the program will beep at the completion of each fractal |
||
27 | ; drawing or if the user attempts to zoom past either limit. |
||
28 | ; |
||
29 | ; mode if the program is assembled with MODECHANGE defined, the |
||
30 | ; will change to the next video mode if the 'v' key is pressed. |
||
31 | ; This is handy because drawing fractals at high resolution can |
||
32 | ; be very timeconsuming. The user can find an interesting spot |
||
33 | ; in a low res mode and then change to a high res mode to see it |
||
34 | ; more fully rendered. |
||
35 | ; |
||
36 | ; size this whole project was started off as a size optimization |
||
37 | ; exercise, so there have been some rather ugly tradeoffs to |
||
38 | ; sacrifice speed for size. |
||
39 | ; |
||
40 | ; 8086 yes, it runs on an 8086 although only if you leave out either |
||
41 | ; the FEATURES option or the MODECHANGE option and it would be |
||
42 | ; slower and more painful than oral surgery. |
||
43 | ; |
||
44 | ; cost there IS such a thing as a free lunch! This code is hereby |
||
45 | ; released to the public domain by the author. |
||
46 | ; |
||
47 | ; |
||
8253 | leency | 48 | ; to assemble & link: |
31 | halyavin | 49 | ; TASM /m2 tinyfrac (assemble using two pass mode if required) |
50 | ; TLINK /Tdc tinyfrac (link Target platform is DOS, COM file) |
||
51 | ; |
||
52 | ; |
||
53 | |||
8253 | leency | 54 | PIXWIDTH equ 512 |
55 | PIXHEIGHT equ 256 |
||
31 | halyavin | 56 | |
57 | ZOOMLIMIT equ 13 ; can change to up to 13 for extended zoom in |
||
58 | |||
59 | ; feel free to experiment with the following constants: |
||
60 | |||
61 | DELTA equ 200 ; the unit of pan movement in pixels |
||
485 | heavyiron | 62 | THRESHOLD equ 7 ; must be in the range of (0,255) |
31 | halyavin | 63 | STARTSCALE equ 5 ; a number from 0 to ZOOMLIMIT, inclusive |
64 | |||
8253 | leency | 65 | IMGBUF equ 0x1000 |
31 | halyavin | 66 | |
67 | ; ************************************************************ |
||
68 | ; |
||
8253 | leency | 69 | ; KolibriOS header |
70 | ; |
||
71 | ; ************************************************************ |
||
31 | halyavin | 72 | |
73 | use32 |
||
8253 | leency | 74 | org 0x0 |
31 | halyavin | 75 | |
8253 | leency | 76 | db 'MENUET01' |
77 | dd 0x01 |
||
78 | dd START |
||
79 | dd I_END |
||
80 | dd PIXWIDTH*PIXHEIGHT*3+IMGBUF+I_END |
||
81 | dd 0x1000 |
||
82 | dd 0,0 |
||
31 | halyavin | 83 | |
84 | include 'lang.inc' |
||
485 | heavyiron | 85 | include '..\..\..\macros.inc' |
31 | halyavin | 86 | |
87 | START: |
||
8253 | leency | 88 | call draw_fractal |
89 | redraw: |
||
90 | call draw_window |
||
31 | halyavin | 91 | still: |
8253 | leency | 92 | mcall 10 |
31 | halyavin | 93 | |
485 | heavyiron | 94 | dec eax |
8253 | leency | 95 | jz redraw |
485 | heavyiron | 96 | dec eax |
97 | jz key |
||
31 | halyavin | 98 | |
485 | heavyiron | 99 | button: |
8253 | leency | 100 | mcall 17 |
485 | heavyiron | 101 | cmp ah,1 |
8253 | leency | 102 | jne still |
103 | mcall -1 |
||
485 | heavyiron | 104 | |
31 | halyavin | 105 | key: |
8253 | leency | 106 | mcall 2 |
107 | shr eax,16 |
||
31 | halyavin | 108 | |
8253 | leency | 109 | cmp al,24 ;'o' |
110 | je cycle |
||
111 | cmp al,23 ;'i' |
||
31 | halyavin | 112 | je cycle |
113 | jmp no_cycle |
||
114 | cycle: |
||
115 | call color_cycle |
||
116 | jmp still |
||
117 | no_cycle: |
||
118 | |||
8253 | leency | 119 | cmp al,13 ;'+' |
31 | halyavin | 120 | jne no_in |
121 | inc byte [scale] |
||
122 | mov ebx,[STARTX] |
||
123 | imul ebx,2 |
||
124 | sub ebx,[scaleaddx] |
||
125 | mov [STARTX],ebx |
||
126 | mov ebx,[STARTY] |
||
127 | imul ebx,2 |
||
128 | sub ebx,[scaleaddy] |
||
129 | mov [STARTY],ebx |
||
8253 | leency | 130 | call draw_fractal |
131 | jmp still |
||
31 | halyavin | 132 | no_in: |
133 | |||
8253 | leency | 134 | cmp al,12 ;'-' |
31 | halyavin | 135 | jne no_out |
136 | dec byte [scale] |
||
137 | mov ebx,[STARTX] |
||
138 | add ebx,[scaleaddx] |
||
139 | shr ebx,1 |
||
140 | mov [STARTX],ebx |
||
141 | mov ebx,[STARTY] |
||
142 | add ebx,[scaleaddy] |
||
143 | shr ebx,1 |
||
144 | mov [STARTY],ebx |
||
8253 | leency | 145 | call draw_fractal |
146 | jmp still |
||
31 | halyavin | 147 | no_out: |
148 | |||
8253 | leency | 149 | cmp al,72 |
31 | halyavin | 150 | jne no_up |
151 | sub [STARTY],100 |
||
8253 | leency | 152 | call draw_fractal |
153 | jmp still |
||
31 | halyavin | 154 | no_up: |
155 | |||
8253 | leency | 156 | cmp al,80 |
31 | halyavin | 157 | jne no_down |
158 | add [STARTY],100 |
||
8253 | leency | 159 | call draw_fractal |
160 | jmp still |
||
31 | halyavin | 161 | no_down: |
162 | |||
8253 | leency | 163 | cmp al,75 |
31 | halyavin | 164 | jne no_left |
165 | sub [STARTX],100 |
||
8253 | leency | 166 | call draw_fractal |
167 | jmp still |
||
31 | halyavin | 168 | no_left: |
169 | |||
8253 | leency | 170 | cmp al,77 |
31 | halyavin | 171 | jne no_right |
172 | add [STARTX],100 |
||
8253 | leency | 173 | call draw_fractal |
174 | jmp still |
||
31 | halyavin | 175 | no_right: |
8253 | leency | 176 | |
177 | cmp al,19 ;'r' |
||
178 | jne no_red |
||
179 | mov ah,3 |
||
180 | call colorize |
||
181 | jmp still |
||
182 | no_red: |
||
183 | |||
184 | cmp al,34 ;'g' |
||
185 | jne no_green |
||
186 | mov ah,4 |
||
187 | call colorize |
||
188 | jmp still |
||
189 | no_green: |
||
190 | |||
191 | cmp al,48 ;'b' |
||
192 | jne no_blue |
||
193 | mov ah,5 |
||
194 | call colorize |
||
195 | jmp still |
||
196 | no_blue: |
||
197 | |||
198 | cmp al,17 ;'w' |
||
199 | jne no_set_as_wallpaper |
||
200 | mcall 15, 1, PIXWIDTH, PIXHEIGHT |
||
201 | mcall 15, 4, 1 ;mode 1-tiled, 0-stretch |
||
202 | mcall 15, 5, IMGBUF, 0, PIXWIDTH*3*PIXHEIGHT |
||
203 | mcall 15, 3 |
||
204 | no_set_as_wallpaper: |
||
31 | halyavin | 205 | |
206 | jmp still |
||
207 | |||
8253 | leency | 208 | colorize: |
209 | shr eax,8 |
||
210 | sub eax,3 |
||
211 | imul eax,8 |
||
212 | add eax,8 |
||
213 | not eax |
||
214 | and eax,11000b |
||
215 | mov [shlc],al |
||
216 | call draw_fractal |
||
217 | ret |
||
218 | |||
31 | halyavin | 219 | color_cycle: |
220 | |||
221 | pusha |
||
222 | mov ecx,0x08080808 |
||
8253 | leency | 223 | mov esi,(PIXHEIGHT/8)*5 |
224 | cmp al,24 |
||
31 | halyavin | 225 | je f_out |
226 | mov ecx,-0x08080808 |
||
8253 | leency | 227 | mov esi,(PIXHEIGHT/8)*5-1 |
31 | halyavin | 228 | f_out: |
229 | |||
230 | newcycle: |
||
8253 | leency | 231 | mov edi,IMGBUF |
31 | halyavin | 232 | newpix: |
233 | mov eax,[edi] |
||
234 | add eax,ecx |
||
235 | mov [edi],eax |
||
236 | add edi,4 |
||
8253 | leency | 237 | cmp edi,IMGBUF+PIXWIDTH*PIXHEIGHT*3 |
31 | halyavin | 238 | jb newpix |
239 | call put_image |
||
240 | mov eax,5 |
||
241 | mov ebx,1 |
||
485 | heavyiron | 242 | mcall |
31 | halyavin | 243 | dec esi |
244 | jnz newcycle |
||
245 | |||
246 | mov eax,0 |
||
8253 | leency | 247 | mov edi,IMGBUF |
248 | mov ecx,PIXWIDTH*PIXHEIGHT*3 / 4 +50 |
||
31 | halyavin | 249 | cld |
250 | rep stosd |
||
251 | |||
252 | popa |
||
253 | |||
254 | call draw_fractal |
||
255 | |||
256 | ret |
||
257 | |||
258 | |||
259 | ; ********************************************************************** |
||
260 | ; |
||
261 | ; Tinyfrac |
||
262 | ; |
||
8253 | leency | 263 | ; ********************************************************************** |
31 | halyavin | 264 | |
265 | draw_fractal: |
||
266 | |||
267 | pusha |
||
8253 | leency | 268 | mcall 4, 10*65536+10, 0xD0ffffff, calc_txt, 0 |
31 | halyavin | 269 | popa |
270 | pusha |
||
271 | |||
272 | movzx ebp,word [STARTX] |
||
273 | movzx edi,word [STARTY] |
||
274 | |||
275 | |||
276 | ; This routine is the fractal drawing engine. It has been |
||
277 | ; optimized for size, sacrificing speed. |
||
278 | |||
8253 | leency | 279 | mov cx, PIXHEIGHT ; height of screen in pixels |
31 | halyavin | 280 | |
281 | sub di,cx ; adjust our Y offset |
||
282 | @@CalcRow: |
||
283 | |||
284 | push cx |
||
285 | |||
8253 | leency | 286 | mov cx, PIXWIDTH ; width of screen in pixels |
31 | halyavin | 287 | |
288 | sub bp,cx ; |
||
289 | @@CalcPixel: |
||
290 | push cx ; save the column counter on stack |
||
291 | xor cx, cx ; clear out color loop counter |
||
292 | xor bx, bx ; zero i coefficient |
||
293 | xor dx, dx ; zero j coefficient |
||
294 | @@CycleColors: |
||
295 | push dx ; save j value for later |
||
296 | mov ax, bx ; ax = i |
||
297 | sub ax, dx ; ax = i - j |
||
298 | add dx, bx ; dx = i + j |
||
299 | stc ; one additional shift, please |
||
300 | call Shifty ; ax = ((i+j)*(i-j)) shifted right |
||
301 | pop dx ; retrieve our saved value for j |
||
302 | add ax,bp ; account for base offset... |
||
303 | cmp ah,THRESHOLD ; Q: is i > THRESHOLD * 256? |
||
304 | xchg bx,ax ; now swap new i with old i |
||
305 | jg @@draw ; Y: draw this pixel |
||
306 | clc ; no additional shifts here, please |
||
307 | call Shifty ; now dx:ax = old i * j |
||
308 | xchg dx,ax ; |
||
309 | add dx,di ; account for base offset... |
||
310 | inc cl ; increment color |
||
311 | jnz @@CycleColors ; keep going until we're done |
||
312 | @@draw: |
||
313 | xchg ax, cx ; mov color into al |
||
314 | pop cx ; retrieve our column counter |
||
315 | pop dx ; fetch row (column already in cx) |
||
316 | push dx ; must leave a copy on the stack |
||
317 | xor bx,bx ; write to video page zero |
||
318 | |||
319 | call put_pixel |
||
320 | |||
321 | inc bp |
||
322 | loop @@CalcPixel |
||
323 | inc di |
||
324 | pop cx |
||
325 | loop @@CalcRow |
||
326 | |||
327 | call put_image |
||
328 | |||
329 | popa |
||
330 | |||
331 | ret |
||
332 | |||
333 | shlc db 0 |
||
334 | |||
335 | put_pixel: |
||
336 | |||
337 | pusha |
||
338 | sub edi,[STARTY] |
||
339 | sub ebp,[STARTX] |
||
340 | and edi,0xff |
||
341 | and ebp,0x1ff |
||
342 | shl edi,9 |
||
343 | mov ebx,edi ; * 3 - Y |
||
344 | add edi,ebx |
||
345 | add edi,ebx |
||
346 | mov ebx,ebp |
||
347 | add ebp,ebx |
||
348 | add ebp,ebx |
||
349 | add edi,ebp |
||
350 | mov cl,[shlc] |
||
351 | mov ebx,0xff |
||
352 | shl ebx,cl |
||
353 | add cl,3 |
||
354 | shl eax,cl |
||
355 | and eax,ebx |
||
8253 | leency | 356 | mov [IMGBUF+edi],eax |
31 | halyavin | 357 | popa |
358 | |||
359 | ret |
||
360 | |||
361 | |||
362 | ;**************************************************************************** |
||
8253 | leency | 363 | ; |
364 | ; This routine multiplies AX by DX and shifts the result (in |
||
31 | halyavin | 365 | ; DX:AX) to the right by scale bits (or scale+1 bits if CY is |
366 | ; set). The resulting value is left in AX. DX is destroyed. |
||
367 | ; |
||
368 | ;**************************************************************************** |
||
369 | |||
370 | Shifty: |
||
371 | push cx ; save middle bits (i*i - j*j) |
||
372 | db 0b1h ; code for mov cl,immed8 |
||
373 | scale db STARTSCALE |
||
374 | adc cl,0 ; adjust per CY flag |
||
375 | imul dx ; do the multiply |
||
376 | |||
377 | xchg ax,dx ; |
||
378 | shl eax,16 ; put hi part in hi 16 bits |
||
379 | xchg ax,dx |
||
380 | shr eax,cl ; |
||
381 | |||
382 | pop cx ; |
||
383 | ret ; |
||
384 | |||
385 | |||
386 | ; ********************************************************************** |
||
387 | ; |
||
8253 | leency | 388 | ; WINDOW DEFINITIONS AND DRAW |
31 | halyavin | 389 | ; |
390 | ; ********************************************************************** |
||
391 | |||
392 | draw_window: |
||
393 | pusha |
||
8253 | leency | 394 | mcall 12, 1 |
395 | |||
396 | mcall 48, 4 ;get skin height |
||
397 | lea ecx, [50*65536+PIXHEIGHT+4+eax] |
||
398 | mcall 0,<50,PIXWIDTH+9>,,0x74000000,,header_txt ;draw window |
||
399 | |||
400 | call put_image |
||
401 | |||
402 | mcall 12, 2 |
||
31 | halyavin | 403 | popa |
404 | ret |
||
405 | |||
8253 | leency | 406 | put_image: |
407 | pusha |
||
408 | mcall 7, IMGBUF, PIXWIDTH*65536+PIXHEIGHT, 0*65536+0 |
||
409 | popa |
||
410 | ret |
||
31 | halyavin | 411 | |
8253 | leency | 412 | |
413 | ; ********************************************************************** |
||
31 | halyavin | 414 | ; |
415 | ; DATA AREA |
||
416 | ; |
||
8253 | leency | 417 | ; ********************************************************************** |
31 | halyavin | 418 | |
8253 | leency | 419 | header_txt db 'Move by Arrows, zoom +/-, cycle O/I, bgr W, color R/G/B',0 |
420 | calc_txt db 'Calculating...',0 |
||
31 | halyavin | 421 | |
8253 | leency | 422 | STARTX dd 200 |
423 | STARTY dd 120 |
||
31 | halyavin | 424 | |
8253 | leency | 425 | scaleaddy dd 120 |
426 | scaleaddx dd 200 |
||
31 | halyavin | 427 | |
485 | heavyiron | 428 | I_END:50,PIXWIDTH+9> |