Subversion Repositories Kolibri OS

Rev

Rev 485 | Go to most recent revision | 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
;
48
; to assemble & link:
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
 
54
PIXWIDTH    equ 511
55
PIXHEIGHT   equ 255
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
CHAR_COLOR  equ 0fh       ; white on black background (for PRINTZOOM feature)
65
 
66
 
67
 
68
; ************************************************************
69
;
70
;   Menuet header
71
 
72
 
73
use32
74
 
75
                  org     0x0
76
 
77
                  db      'MENUET01'
78
                  dd      0x01
79
                  dd      START
80
                  dd      I_END
81
                  dd      0x62000
82
                  dd      0x1000
83
                  dd      0,0
84
 
85
include 'lang.inc'
485 heavyiron 86
include '..\..\..\macros.inc'
31 halyavin 87
 
88
STARTX  dd  200
89
STARTY  dd  120
90
 
91
scaleaddy dd 120
92
scaleaddx dd 200
93
 
94
START:
95
 
485 heavyiron 96
red:
31 halyavin 97
        call    draw_window
98
        call    draw_fractal
99
 
100
still:
101
 
102
        mov  eax,10
485 heavyiron 103
        mcall
31 halyavin 104
 
485 heavyiron 105
        dec  eax
106
        jz   red
107
        dec  eax
108
        jz   key
31 halyavin 109
 
485 heavyiron 110
      button:
111
        mov  al,17
112
        mcall
113
 
114
        cmp  ah,1
115
        jne  no_close
116
        or   eax,-1
117
        mcall
118
      no_close:
119
 
120
        cmp  ah,2
121
        jne  no_bgr
122
 
123
 
124
        mov  eax,15   ; bgr 512 x 256
125
        mov  ebx,1
126
        mov  ecx,512
127
        mov  edx,256
128
        mcall
129
 
130
        mov  eax,15
131
        mov  ebx,5
132
        mov  ecx,0x1000
133
        mov  edx,0
134
        mov  esi,512*3*256
135
        mcall
136
 
137
        mov  eax,15
138
        mov  ebx,3
139
        mcall
140
 
31 halyavin 141
        jmp  still
142
 
485 heavyiron 143
      no_bgr:
144
 
145
        cmp  ah,3
146
        jb   no_color
147
        cmp  ah,5
148
        jg   no_color
149
        shr  eax,8
150
        sub  eax,3
151
        imul eax,8
152
        add  eax,8
153
        not  eax
154
        and  eax,11000b
155
        mov  [shlc],al
156
        call draw_fractal
31 halyavin 157
        jmp  still
158
 
485 heavyiron 159
      no_color:
160
 
161
        jmp  still
162
 
163
 
31 halyavin 164
      key:
485 heavyiron 165
        mov  al,2
166
        mcall
31 halyavin 167
 
168
        cmp  ah,'e'
169
        je   cycle
170
        cmp  ah,'r'
171
        je   cycle
172
        jmp  no_cycle
173
      cycle:
174
        call color_cycle
175
        jmp  still
176
      no_cycle:
177
 
178
        cmp  ah,'q'
179
        jne  no_in
180
        inc  byte [scale]
181
        mov  ebx,[STARTX]
182
        imul ebx,2
183
        sub  ebx,[scaleaddx]
184
        mov  [STARTX],ebx
185
        mov  ebx,[STARTY]
186
        imul ebx,2
187
        sub  ebx,[scaleaddy]
188
        mov  [STARTY],ebx
189
      no_in:
190
 
191
        cmp  ah,'w'
192
        jne  no_out
193
        dec  byte [scale]
194
        mov  ebx,[STARTX]
195
        add  ebx,[scaleaddx]
196
        shr  ebx,1
197
        mov  [STARTX],ebx
198
        mov  ebx,[STARTY]
199
        add  ebx,[scaleaddy]
200
        shr  ebx,1
201
        mov  [STARTY],ebx
202
      no_out:
203
 
204
        cmp  ah,130+48
205
        jne  no_up
206
        sub  [STARTY],100
207
      no_up:
208
 
209
        cmp  ah,129+48
210
        jne  no_down
211
        add  [STARTY],100
212
      no_down:
213
 
214
        cmp  ah,128+48
215
        jne  no_left
216
        sub  [STARTX],100
217
      no_left:
218
 
219
        cmp  ah,131+48
220
        jne  no_right
221
        add  [STARTX],100
222
      no_right:
223
 
224
        call draw_fractal
225
        jmp  still
226
 
227
color_cycle:
228
 
229
     pusha
230
     mov  ecx,0x08080808
231
     mov  esi,(256/8)*5
232
     cmp  ah,'e'
233
     je   f_out
234
     mov  ecx,-0x08080808
235
     mov  esi,(256/8)*5-1
236
   f_out:
237
 
238
   newcycle:
239
     mov  edi,0x1000
240
   newpix:
241
     mov  eax,[edi]
242
     add  eax,ecx
243
     mov  [edi],eax
244
     add  edi,4
245
     cmp  edi,0x1000+512*256*3
246
     jb   newpix
247
     call put_image
248
     mov  eax,5
249
     mov  ebx,1
485 heavyiron 250
     mcall
31 halyavin 251
     dec  esi
252
     jnz  newcycle
253
 
254
     mov  eax,0
255
     mov  edi,0x1000
256
     mov  ecx,512*256*3 / 4 +50
257
     cld
258
     rep  stosd
259
 
260
     popa
261
 
262
     call draw_fractal
263
 
264
     ret
265
 
266
 
267
 
268
 
269
 
270
; **********************************************************************
271
;
272
;    Tinyfrac
273
;
274
 
275
 
276
draw_fractal:
277
 
278
        pusha
279
        mov     eax,4
485 heavyiron 280
        mov     ebx,10*65536+30
281
        mov     ecx,0x80ffffff
31 halyavin 282
        mov     edx,calc
485 heavyiron 283
        mcall
31 halyavin 284
        popa
285
        pusha
286
 
287
        movzx   ebp,word [STARTX]
288
        movzx   edi,word [STARTY]
289
 
290
 
291
;       This routine is the fractal drawing engine.  It has been
292
;       optimized for size, sacrificing speed.
293
 
294
        mov     cx, PIXHEIGHT   ; height of screen in pixels
295
 
296
        sub     di,cx           ; adjust our Y offset
297
@@CalcRow:
298
 
299
        push    cx
300
 
301
        mov     cx, PIXWIDTH -1  ; width of screen in pixels
302
 
303
        sub     bp,cx           ;
304
@@CalcPixel:
305
        push    cx              ; save the column counter on stack
306
        xor     cx, cx          ; clear out color loop counter
307
        xor     bx, bx          ; zero i coefficient
308
        xor     dx, dx          ; zero j coefficient
309
@@CycleColors:
310
        push    dx              ; save j value for later
311
        mov     ax, bx          ; ax = i
312
        sub     ax, dx          ; ax = i - j
313
        add     dx, bx          ; dx = i + j
314
        stc                     ; one additional shift, please
315
        call    Shifty          ; ax = ((i+j)*(i-j)) shifted right
316
        pop     dx              ; retrieve our saved value for j
317
        add     ax,bp           ; account for base offset...
318
        cmp     ah,THRESHOLD    ; Q: is i > THRESHOLD * 256?
319
        xchg    bx,ax           ; now swap new i with old i
320
        jg      @@draw          ; Y: draw this pixel
321
        clc                     ; no additional shifts here, please
322
        call    Shifty          ; now dx:ax = old i * j
323
        xchg    dx,ax           ;
324
        add     dx,di           ; account for base offset...
325
        inc     cl              ; increment color
326
        jnz     @@CycleColors   ; keep going until we're done
327
@@draw:
328
        xchg    ax, cx          ; mov color into al
329
        pop     cx              ; retrieve our column counter
330
        pop     dx              ; fetch row (column already in cx)
331
        push    dx              ; must leave a copy on the stack
332
        xor     bx,bx           ; write to video page zero
333
 
334
        call    put_pixel
335
 
336
        inc     bp
337
        loop    @@CalcPixel
338
        inc     di
339
        pop     cx
340
        loop    @@CalcRow
341
 
342
        call    put_image
343
 
344
        popa
345
 
346
        ret
347
 
348
 
349
put_image:
350
 
351
        pusha
352
 
353
        mov  eax,7
354
        mov  ebx,0x1000
485 heavyiron 355
        mov  ecx,512*65536+256
356
        mov  edx,4*65536+21
357
        mcall
31 halyavin 358
 
359
        popa
360
 
361
        ret
362
 
363
 
364
shlc db 0
365
 
366
put_pixel:
367
 
368
        pusha
369
        sub     edi,[STARTY]
370
        sub     ebp,[STARTX]
371
        and     edi,0xff
372
        and     ebp,0x1ff
373
        shl     edi,9
374
        mov     ebx,edi ; * 3 - Y
375
        add     edi,ebx
376
        add     edi,ebx
377
        mov     ebx,ebp
378
        add     ebp,ebx
379
        add     ebp,ebx
380
        add     edi,ebp
381
        mov     cl,[shlc]
382
        mov     ebx,0xff
383
        shl     ebx,cl
384
        add     cl,3
385
        shl     eax,cl
386
        and     eax,ebx
387
        mov     [0x1000+edi],eax
388
        popa
389
 
390
        ret
391
 
392
 
393
;****************************************************************************
394
 ;
395
 ;       This routine multiplies AX by DX and shifts the result (in
396
;       DX:AX) to the right by scale bits (or scale+1 bits if CY is
397
;       set).  The resulting value is left in AX.  DX is destroyed.
398
;
399
;****************************************************************************
400
 
401
Shifty:
402
        push    cx              ; save middle bits (i*i - j*j)
403
        db      0b1h            ; code for mov cl,immed8
404
scale   db      STARTSCALE
405
        adc     cl,0            ; adjust per CY flag
406
        imul    dx              ; do the multiply
407
 
408
        xchg    ax,dx           ;
409
        shl     eax,16          ; put hi part in hi 16 bits
410
        xchg    ax,dx
411
        shr     eax,cl          ;
412
 
413
        pop     cx              ;
414
        ret                     ;
415
 
416
 
417
 
418
; **********************************************************************
419
;
420
;                   WINDOW DEFINITIONS AND DRAW
421
;
422
; **********************************************************************
423
 
424
 
425
 
426
draw_window:
427
 
428
      pusha
429
 
430
      mov  eax,12
431
      mov  ebx,1
485 heavyiron 432
      mcall
31 halyavin 433
 
485 heavyiron 434
      xor  eax,eax
435
      mov  ebx,50*65536+PIXWIDTH+8
436
      mov  ecx,100*65536+PIXHEIGHT+25
551 spraid 437
      mov  edx,0x14334455
485 heavyiron 438
      mov  edi,title
439
      mcall
31 halyavin 440
 
441
      mov  eax,8
485 heavyiron 442
      mov  ebx,290*65536+112
31 halyavin 443
      mov  ecx,5*65536+12
444
      mov  edx,2
445
      mov  esi,0x808080
485 heavyiron 446
      mcall
31 halyavin 447
 
485 heavyiron 448
      mov  ebx,420*65536+12
31 halyavin 449
      mov  ecx,5*65536+12
450
      mov  edx,3
451
      mov  esi,0xa00000
452
      mov  edi,3
485 heavyiron 453
      ;mov  eax,8
31 halyavin 454
    newcolor:
485 heavyiron 455
      mcall
31 halyavin 456
      add  ebx,13*65536
457
      shr  esi,8
458
      inc  edx
459
      dec  edi
460
      jnz  newcolor
461
 
462
      mov  eax,4
485 heavyiron 463
      mov  ebx,300*65536+8
464
      mov  ecx,0x80ffffff
465
      mov  edx,button_txt
466
      mcall
31 halyavin 467
 
468
      mov  eax,12
469
      mov  ebx,2
485 heavyiron 470
      mcall
31 halyavin 471
 
472
      popa
473
      ret
474
 
475
 
476
; ***************************************************************
477
;
478
;     DATA AREA
479
;
480
 
481
 
485 heavyiron 482
title      db 'Tinyfrac - MOVE: ARROWS, ZOOM Q/W, CYCLE: E/R',0
483
button_txt  db 'Set as wallpaper',0
31 halyavin 484
 
485 heavyiron 485
calc        db 'CALCULATING',0
31 halyavin 486
 
485 heavyiron 487
I_END: