Subversion Repositories Kolibri OS

Rev

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: