Subversion Repositories Kolibri OS

Rev

Rev 551 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 512
  55. PIXHEIGHT   equ 256
  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
  62. THRESHOLD   equ  7        ; must be in the range of (0,255)
  63. STARTSCALE  equ  5        ; a number from 0 to ZOOMLIMIT, inclusive
  64.  
  65. IMGBUF      equ 0x1000
  66.  
  67. ; ************************************************************
  68. ;
  69. ;   KolibriOS header
  70. ;
  71. ; ************************************************************
  72.  
  73. use32
  74.         org     0x0
  75.  
  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
  83.  
  84. include 'lang.inc'
  85. include '..\..\..\macros.inc'
  86.  
  87. START:
  88.         call draw_fractal
  89. redraw:
  90.         call draw_window
  91. still:
  92.         mcall 10
  93.  
  94.         dec  eax
  95.         jz   redraw
  96.         dec  eax
  97.         jz   key
  98.  
  99.       button:
  100.         mcall 17
  101.         cmp  ah,1
  102.         jne  still
  103.         mcall -1
  104.  
  105.       key:
  106.         mcall 2
  107.         shr eax,16
  108.  
  109.         cmp  al,24 ;'o'
  110.                 je cycle
  111.         cmp  al,23 ;'i'
  112.         je   cycle
  113.         jmp  no_cycle
  114.       cycle:
  115.         call color_cycle
  116.         jmp  still
  117.       no_cycle:
  118.  
  119.         cmp  al,13 ;'+'
  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
  130.         call draw_fractal
  131.         jmp  still
  132.       no_in:
  133.  
  134.         cmp  al,12 ;'-'
  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
  145.         call draw_fractal
  146.         jmp  still
  147.       no_out:
  148.  
  149.         cmp  al,72
  150.         jne  no_up
  151.         sub  [STARTY],100
  152.         call draw_fractal
  153.         jmp  still
  154.       no_up:
  155.  
  156.         cmp  al,80
  157.         jne  no_down
  158.         add  [STARTY],100
  159.         call draw_fractal
  160.         jmp  still
  161.       no_down:
  162.  
  163.         cmp  al,75
  164.         jne  no_left
  165.         sub  [STARTX],100
  166.         call draw_fractal
  167.         jmp  still
  168.       no_left:
  169.  
  170.         cmp  al,77
  171.         jne  no_right
  172.         add  [STARTX],100
  173.         call draw_fractal
  174.         jmp  still
  175.       no_right:
  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:
  205.  
  206.         jmp  still
  207.  
  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.  
  219. color_cycle:
  220.  
  221.      pusha
  222.      mov  ecx,0x08080808
  223.      mov  esi,(PIXHEIGHT/8)*5
  224.      cmp  al,24
  225.      je   f_out
  226.      mov  ecx,-0x08080808
  227.      mov  esi,(PIXHEIGHT/8)*5-1
  228.    f_out:
  229.  
  230.    newcycle:
  231.      mov  edi,IMGBUF
  232.    newpix:
  233.      mov  eax,[edi]
  234.      add  eax,ecx
  235.      mov  [edi],eax
  236.      add  edi,4
  237.      cmp  edi,IMGBUF+PIXWIDTH*PIXHEIGHT*3
  238.      jb   newpix
  239.      call put_image
  240.      mov  eax,5
  241.      mov  ebx,1
  242.      mcall
  243.      dec  esi
  244.      jnz  newcycle
  245.  
  246.      mov  eax,0
  247.      mov  edi,IMGBUF
  248.      mov  ecx,PIXWIDTH*PIXHEIGHT*3 / 4 +50
  249.      cld
  250.      rep  stosd
  251.  
  252.      popa
  253.  
  254.      call draw_fractal
  255.  
  256.      ret
  257.  
  258.  
  259. ; **********************************************************************
  260. ;
  261. ;    Tinyfrac
  262. ;
  263. ; **********************************************************************
  264.  
  265. draw_fractal:
  266.  
  267.         pusha
  268.         mcall 4, 10*65536+10, 0xD0ffffff, calc_txt, 0
  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.  
  279.         mov     cx, PIXHEIGHT ; height of screen in pixels
  280.  
  281.         sub     di,cx           ; adjust our Y offset
  282. @@CalcRow:
  283.  
  284.         push    cx
  285.  
  286.         mov     cx, PIXWIDTH ; width of screen in pixels
  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
  356.         mov     [IMGBUF+edi],eax
  357.         popa
  358.  
  359.         ret
  360.  
  361.  
  362. ;****************************************************************************
  363. ;
  364. ;       This routine multiplies AX by DX and shifts the result (in
  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. ;
  388. ;     WINDOW DEFINITIONS AND DRAW
  389. ;
  390. ; **********************************************************************
  391.  
  392. draw_window:
  393.       pusha
  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
  403.       popa
  404.       ret
  405.  
  406. put_image:
  407.         pusha
  408.         mcall 7, IMGBUF, PIXWIDTH*65536+PIXHEIGHT, 0*65536+0
  409.         popa
  410.         ret
  411.  
  412.  
  413. ; **********************************************************************
  414. ;
  415. ;     DATA AREA
  416. ;
  417. ; **********************************************************************
  418.  
  419. header_txt  db 'Move by Arrows, zoom +/-, cycle O/I, bgr W, color R/G/B',0
  420. calc_txt    db 'Calculating...',0
  421.  
  422. STARTX  dd  200
  423. STARTY  dd  120
  424.  
  425. scaleaddy dd 120
  426. scaleaddx dd 200
  427.  
  428. I_END: