Subversion Repositories Kolibri OS

Rev

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