Subversion Repositories Kolibri OS

Rev

Rev 109 | Rev 551 | Go to most recent revision | 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 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. red:
  97.         call    draw_window
  98.         call    draw_fractal
  99.  
  100. still:
  101.  
  102.         mov  eax,10
  103.         mcall
  104.  
  105.         dec  eax
  106.         jz   red
  107.         dec  eax
  108.         jz   key
  109.  
  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.  
  141.         jmp  still
  142.  
  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
  157.         jmp  still
  158.  
  159.       no_color:
  160.  
  161.         jmp  still
  162.  
  163.  
  164.       key:
  165.         mov  al,2
  166.         mcall
  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
  250.      mcall
  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
  280.         mov     ebx,10*65536+30
  281.         mov     ecx,0x80ffffff
  282.         mov     edx,calc
  283.         mcall
  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
  355.         mov  ecx,512*65536+256
  356.         mov  edx,4*65536+21
  357.         mcall
  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
  432.       mcall
  433.  
  434.       xor  eax,eax
  435.       mov  ebx,50*65536+PIXWIDTH+8
  436.       mov  ecx,100*65536+PIXHEIGHT+25
  437.       mov  edx,0x13334455
  438.       mov  edi,title
  439.       mcall
  440.  
  441.       mov  eax,8
  442.       mov  ebx,290*65536+112
  443.       mov  ecx,5*65536+12
  444.       mov  edx,2
  445.       mov  esi,0x808080
  446.       mcall
  447.  
  448.       mov  ebx,420*65536+12
  449.       mov  ecx,5*65536+12
  450.       mov  edx,3
  451.       mov  esi,0xa00000
  452.       mov  edi,3
  453.       ;mov  eax,8
  454.     newcolor:
  455.       mcall
  456.       add  ebx,13*65536
  457.       shr  esi,8
  458.       inc  edx
  459.       dec  edi
  460.       jnz  newcolor
  461.  
  462.       mov  eax,4
  463.       mov  ebx,300*65536+8
  464.       mov  ecx,0x80ffffff
  465.       mov  edx,button_txt
  466.       mcall
  467.  
  468.       mov  eax,12
  469.       mov  ebx,2
  470.       mcall
  471.  
  472.       popa
  473.       ret
  474.  
  475.  
  476. ; ***************************************************************
  477. ;
  478. ;     DATA AREA
  479. ;
  480.  
  481.  
  482. title      db 'Tinyfrac - MOVE: ARROWS, ZOOM Q/W, CYCLE: E/R',0
  483. button_txt  db 'Set as wallpaper',0
  484.  
  485. calc        db 'CALCULATING',0
  486.  
  487. I_END: