home *** CD-ROM | disk | FTP | other *** search
/ The Party 1994: Try This At Home / disk_image.bin / source / fakesrc / part10 / mandel.asm < prev    next >
Assembly Source File  |  1993-10-10  |  16KB  |  489 lines

  1. ;=============================================================================
  2. ; mandel.asm - Mandelbrot Set calculation Routines.
  3. ;                                                    File created:  9-22-93
  4. ; Copyright (C) 1993, Carlos Hasan                  Last modified: 10-11-93
  5. ;
  6. ; Description:
  7. ;  This file implements the Mandelbrot Set fractal using a fast algorithm
  8. ;  based on the Fracint's Boundary trace method. The drawing is optimized
  9. ;  for using with VGA 320x200x256 graphics mode.
  10. ;
  11. ; Portability:
  12. ;  Requires Turbo Assembler 3.2 or better to be assembler.
  13. ;  Dependent on the IBM PC 386 or later microprocessor.
  14. ;=============================================================================
  15.  
  16.                 .model  small,pascal
  17.                 .386
  18.  
  19.                 global  DrawMandel:proc
  20.  
  21. ;======================= Mandelbrot Routine ==================================
  22.  
  23. ;-----------------------------------------------------------------------------
  24. ; Equates for Mandelbrot Set calculation.
  25. ;-----------------------------------------------------------------------------
  26.  
  27. MAXITER         equ     150                     ; max iterations
  28. FUDGE           equ     24                      ; fudge factor
  29. BAILOUT         equ     4 shl FUDGE             ; bait out
  30. PERIODMASK      equ     0FFFF0000h              ; periodicy mask
  31.  
  32. ;-----------------------------------------------------------------------------
  33. ; Miscellaneus Data used for calculation.
  34. ;-----------------------------------------------------------------------------
  35.  
  36.                 .data
  37.  
  38. SavedAnd        dw      ?
  39. SavedIncr       dw      ?
  40. SavedMask       dd      ?
  41. OldIter         dw      ?
  42. LinX            dd      ?
  43. LinY            dd      ?
  44. SavedX          dd      ?
  45. SavedY          dd      ?
  46.  
  47. ;-----------------------------------------------------------------------------
  48. ; CalcMand - Main Mandelbrot Set calculation routine.
  49. ; In:
  50. ;   ESI  - real part of the initial complex value.
  51. ;   EDI  - imaginary part of the initial complex value.
  52. ; Out:
  53. ;   AL   - Mandelbrot level.
  54. ; Modified:
  55. ;   EAX, EBX, ECX, EDX, ESI, EDI, Flags.
  56. ;-----------------------------------------------------------------------------
  57.  
  58.                 .code
  59.  
  60. CalcMand        proc near
  61.  
  62.                 mov     [SavedAnd],1            ; init periodicy check.
  63.                 mov     [SavedIncr],1
  64.                 mov     [SavedMask],1
  65.                 mov     [SavedX],0FFFFFFFFh     ; values impossibles
  66.                 mov     [SavedY],0FFFFFFFFh     ; for x and y.
  67.  
  68.                 mov     [LinX],esi              ; linx = real
  69.                 mov     [LinY],edi              ; liny = imag
  70.  
  71.                 xor     esi,esi                 ; x = 0
  72.                 xor     edi,edi                 ; y = 0
  73.  
  74.                 mov     cx,MAXITER              ; iter = maxiter
  75.  
  76. MandLoop:       mov     eax,esi                 ; ebx = x*x
  77.                 imul    esi
  78.                 shrd    eax,edx,FUDGE
  79.                 mov     ebx,eax
  80.  
  81.                 mov     eax,edi                 ; ebx = y*y
  82.                 imul    edi
  83.                 shrd    eax,edx,FUDGE
  84.  
  85.                 mov     edx,ebx                 ; edx = x*x + y*y
  86.                 add     edx,eax
  87.                 sub     ebx,eax                 ; ebx = x*x - y*y
  88.  
  89.                 cmp     edx,BAILOUT             ; x*x + y*y > bailout?
  90.                 jge     MandBreak               ; break.
  91.  
  92.                 mov     eax,edi                 ; y = 2*x*y + liny
  93.                 imul    esi
  94.                 shrd    eax,edx,FUDGE-1
  95.                 add     eax,[LinY]
  96.                 mov     edi,eax
  97.  
  98.                 add     ebx,[LinX]              ; x = x*x - y*y + linx
  99.                 mov     esi,ebx
  100.  
  101.                 cmp     [OldIter],cx            ; check periodicity.
  102.                 jle     MandContinue
  103.  
  104.                 mov     eax,esi
  105.                 xor     eax,[SavedX]
  106.                 test    eax,PERIODMASK
  107.                 jne     CheckSave
  108.                 mov     eax,edi
  109.                 xor     eax,[SavedY]
  110.                 test    eax,PERIODMASK
  111.                 jne     CheckSave
  112.                 xor     cx,cx
  113.                 jmp     MandBreak
  114.  
  115. CheckSave:      test    cx,[SavedAnd]
  116.                 jne     MandContinue
  117.                 mov     [SavedX],esi
  118.                 mov     [SavedY],edi
  119.                 dec     [SavedIncr]
  120.                 jne     MandContinue
  121.                 stc
  122.                 rcl     [SavedAnd],1
  123.                 mov     [SavedIncr],4
  124.  
  125. MandContinue:   dec     cx
  126.                 jne     MandLoop
  127.  
  128. MandBreak:      mov     ax,cx
  129.                 mov     bx,cx
  130.                 sub     bx,10
  131.                 test    cx,cx
  132.                 je      SetOldIter
  133.                 mov     bx,MAXITER
  134. SetOldIter:     mov     [OldIter],bx
  135.                 ret
  136.  
  137. CalcMand        endp
  138.  
  139.  
  140. ;=================== Boundary Trace Method (BTM) =============================
  141.  
  142. ;-----------------------------------------------------------------------------
  143. ; Equates for BTM into a 320x200x256 virtual screen.
  144. ;-----------------------------------------------------------------------------
  145.  
  146. MAXWIDTH        equ     320                     ; Virtual screen dimensions.
  147. MAXHEIGHT       equ     200
  148. XSTART          equ     0                       ; Virtual screen drawing
  149. XSTOP           equ     319                     ; window coordinates.
  150. YSTART          equ     0
  151. YSTOP           equ     199
  152. NORTH           equ     0                       ; Used for BTM algorithm.
  153. EAST            equ     1
  154. SOUTH           equ     2
  155. WEST            equ     3
  156. MAXINT          equ     7FFFh
  157.  
  158. ;-----------------------------------------------------------------------------
  159. ; Data used for BTM during plotting.
  160. ;-----------------------------------------------------------------------------
  161.  
  162.                 .data
  163.  
  164. LeftX           dw      MAXHEIGHT dup (?)       ; array of left and right
  165. RightX          dw      MAXHEIGHT dup (?)       ; limits for poly filling.
  166. ComplexX        dd      MAXWIDTH  dup (?)       ; translate screen coords
  167. ComplexY        dd      MAXHEIGHT dup (?)       ; to complex coords.
  168. FirstX          dw      ?                       ; temporary variables used
  169. FirstY          dw      ?                       ; for BTM algorithm.
  170. Iters           dw      ?
  171. Color           db      ?
  172. Dir             db      ?
  173.  
  174. ;-----------------------------------------------------------------------------
  175. ; GetPixel - get the pixel color at specified location.
  176. ; In:
  177. ;   ES      - Virtual screen segment.
  178. ;   (SI,DI) - Pixel position.
  179. ; Out:
  180. ;   AL      - Pixel color.
  181. ; Modified:
  182. ;   BX, Flags.
  183. ;-----------------------------------------------------------------------------
  184.  
  185.                 .code
  186.  
  187. GetPixel        macro
  188.  
  189.                 mov     bx,di
  190.                 imul    bx,MAXWIDTH
  191.                 add     bx,si
  192.                 mov     al,es:[bx]
  193.  
  194.                 endm
  195.  
  196. ;-----------------------------------------------------------------------------
  197. ; PutPixel - put the pixel color at specified location.
  198. ; In:
  199. ;   ES      - Virtual screen segment.
  200. ;   (SI,DI) - Pixel position.
  201. ;   AL      - Pixel color.
  202. ; Modified:
  203. ;   BX, Flags.
  204. ;-----------------------------------------------------------------------------
  205.  
  206. PutPixel        macro
  207.  
  208.                 mov     bx,di
  209.                 imul    bx,MAXWIDTH
  210.                 add     bx,si
  211.                 mov     es:[bx],al
  212.  
  213.                 endm
  214.  
  215. ;-----------------------------------------------------------------------------
  216. ; GetColor - get the pixel color using the MandelBrot Set routine or
  217. ;   the virtual screen if already painted.
  218. ; In:
  219. ;   ES       - Virtual screen segment.
  220. ;   (SI,DI)  - Pixel position.
  221. ; Out:
  222. ;   AL       - Pixel color.
  223. ; Modified:
  224. ;   EAX, EBX, ECX, EDX, Flags.
  225. ;-----------------------------------------------------------------------------
  226.  
  227. GetColor        proc near
  228.  
  229.                 GetPixel
  230.                 test    al,al
  231.                 jne     ColorNonZero
  232.                 push    si
  233.                 push    di
  234.                 shl     si,2
  235.                 shl     di,2
  236.                 mov     esi,[ComplexX+si]
  237.                 mov     edi,[ComplexY+di]
  238.                 call    CalcMand
  239.                 pop     di
  240.                 pop     si
  241.                 inc     al
  242.                 PutPixel                ; don't destroy AL.
  243. ColorNonZero:   ret
  244.  
  245. GetColor        endp
  246.  
  247. ;-----------------------------------------------------------------------------
  248. ; BoundTrace - Trace a boundary and fill it.
  249. ; In:
  250. ;   ES      - Virtual screen segment.
  251. ;   (SI,DI) - starting point inside of the boundary.
  252. ; Modified:
  253. ;   EAX, EBX, ECX, EDX, Flags.
  254. ;-----------------------------------------------------------------------------
  255.  
  256. BoundTrace      proc near
  257.  
  258.                 mov     [FirstX],si
  259.                 mov     [FirstY],di
  260.                 call    GetColor
  261.                 mov     [Color],al
  262.                 mov     [Dir],EAST
  263.                 mov     [Iters],0
  264.  
  265. BoundLoop:      mov     bx,di
  266.                 shl     bx,1
  267.                 cmp     si,[LeftX+bx]
  268.                 jge     NotLess
  269.                 mov     [LeftX+bx],si
  270. NotLess:        cmp     si,[RightX+bx]
  271.                 jle     NotGreat
  272.                 mov     [RightX+bx],si
  273. NotGreat:       mov     al,[Dir]
  274.                 cmp     al,NORTH
  275.                 je      GoNorth
  276.                 cmp     al,EAST
  277.                 je      GoEast
  278.                 cmp     al,SOUTH
  279.                 je      GoSouth
  280.                 cmp     al,WEST
  281.                 je      GoWest
  282.  
  283. GoNorth:        cmp     di,[FirstY]
  284.                 jle     SetEast
  285.                 dec     di
  286.                 call    GetColor
  287.                 inc     di
  288.                 cmp     al,[Color]
  289.                 jne     SetEast
  290.                 dec     di
  291.                 cmp     si,XSTART
  292.                 jle     BoundContinue
  293.                 dec     si
  294.                 call    GetColor
  295.                 inc     si
  296.                 cmp     al,[Color]
  297.                 jne     BoundContinue
  298.                 dec     si
  299.                 jmp     SetWest
  300.  
  301. GoEast:         cmp     si,XSTOP
  302.                 jge     SetSouth
  303.                 inc     si
  304.                 call    GetColor
  305.                 dec     si
  306.                 cmp     al,[Color]
  307.                 jne     SetSouth
  308.                 inc     si
  309.                 cmp     di,[FirstY]
  310.                 jle     BoundContinue
  311.                 dec     di
  312.                 call    GetColor
  313.                 inc     di
  314.                 cmp     al,[Color]
  315.                 jne     BoundContinue
  316.                 dec     di
  317.                 jmp     SetNorth
  318.  
  319. GoSouth:        cmp     di,YSTOP
  320.                 jge     SetWest
  321.                 inc     di
  322.                 call    GetColor
  323.                 dec     di
  324.                 cmp     al,[Color]
  325.                 jne     SetWest
  326.                 inc     di
  327.                 cmp     si,XSTOP
  328.                 jge     BoundContinue
  329.                 inc     si
  330.                 call    GetColor
  331.                 dec     si
  332.                 cmp     al,[Color]
  333.                 jne     BoundContinue
  334.                 inc     si
  335.                 jmp     SetEast
  336.  
  337. GoWest:         cmp     si,XSTART
  338.                 jle     SetNorth
  339.                 dec     si
  340.                 call    GetColor
  341.                 inc     si
  342.                 cmp     al,[Color]
  343.                 jne     SetNorth
  344.                 dec     si
  345.                 cmp     di,YSTOP
  346.                 jge     BoundContinue
  347.                 inc     di
  348.                 call    GetColor
  349.                 dec     di
  350.                 cmp     al,[Color]
  351.                 jne     BoundContinue
  352.                 inc     di
  353.                 jmp     SetSouth
  354.  
  355. SetNorth:       mov     [Dir],NORTH
  356.                 jmp     BoundContinue
  357.  
  358. SetEast:        mov     [Dir],EAST
  359.                 jmp     BoundContinue
  360.  
  361. SetSouth:       mov     [Dir],SOUTH
  362.                 jmp     BoundContinue
  363.  
  364. SetWest:        mov     [Dir],WEST
  365.  
  366. BoundContinue:  inc     [Iters]
  367.                 cmp     si,[FirstX]
  368.                 jne     BoundLoop
  369.                 cmp     di,[FirstY]
  370.                 jne     BoundLoop
  371.  
  372.                 cmp     [Iters],4
  373.                 jl      BoundExit
  374.  
  375.                 mov     si,[FirstY]
  376.                 cld
  377. BoundForY:      mov     bx,si
  378.                 shl     bx,1
  379.                 mov     ax,[LeftX+bx]
  380.                 mov     dx,[RightX+bx]
  381.                 mov     [LeftX+bx],+MAXINT
  382.                 mov     [RightX+bx],-MAXINT
  383.                 cmp     ax,dx
  384.                 jg      BoundExit
  385.                 mov     cx,dx
  386.                 sub     cx,ax
  387.                 inc     cx
  388.                 mov     di,si
  389.                 imul    di,MAXWIDTH
  390.                 add     di,ax
  391.                 mov     al,[Color]
  392. ScanColor:      repne   scasb
  393.                 jne     BoundNextY
  394.                 jcxz    BoundNextY
  395. FillBlank:      mov     ah,es:[di]
  396.                 test    ah,ah
  397.                 jne     ScanColor
  398.                 mov     es:[di],al
  399.                 inc     di
  400.                 dec     cx
  401.                 jne     FillBlank
  402. BoundNextY:     inc     si
  403.                 cmp     si,YSTOP
  404.                 jle     BoundForY
  405.  
  406. BoundExit:      mov     si,[FirstX]
  407.                 mov     di,[FirstY]
  408.                 ret
  409.  
  410. BoundTrace      endp
  411.  
  412. ;-----------------------------------------------------------------------------
  413. ; DrawMandel - Draw the Mandelbrot Set into a virtual 320x200x256 screen.
  414. ; In:
  415. ;   (PosX,PosX)      - top left corner complex number.
  416. ;   (DeltaX,DeltaY)  - complex windows extends.
  417. ;   ScreenSeg        - Virtual screen segment.
  418. ;-----------------------------------------------------------------------------
  419.  
  420. DrawMandel      proc    PosX:dword,PosY:dword, \
  421.                         DeltaX:dword,DeltaY:dword, ScreenSeg:word
  422.  
  423.                 mov     ax,ds
  424.                 mov     es,ax
  425.                 cld
  426.  
  427.                 mov     cx,MAXHEIGHT
  428.                 lea     di,[LeftX]
  429.                 mov     ax,+MAXINT
  430.                 rep     stosw
  431.  
  432.                 mov     cx,MAXHEIGHT
  433.                 lea     di,[RightX]
  434.                 mov     ax,-MAXINT
  435.                 rep     stosw
  436.  
  437.                 mov     ecx,XSTOP-XSTART
  438.                 mov     eax,[DeltaX]
  439.                 cdq
  440.                 div     ecx
  441.                 inc     cx
  442.                 mov     edx,eax
  443.                 add     eax,[PosX]
  444.                 add     eax,[PosX]
  445.                 sar     eax,1
  446.                 lea     di,[ComplexX]
  447. MakeX:          stosd
  448.                 add     eax,edx
  449.                 loop    MakeX
  450.  
  451.                 mov     ecx,YSTOP-YSTART
  452.                 mov     eax,[DeltaY]
  453.                 cdq
  454.                 div     ecx
  455.                 inc     cx
  456.                 mov     edx,eax
  457.                 add     eax,[PosY]
  458.                 add     eax,[PosY]
  459.                 sar     eax,1
  460.                 lea     di,[ComplexY]
  461. MakeY:          stosd
  462.                 add     eax,edx
  463.                 loop    MakeY
  464.  
  465.                 mov     ax,[ScreenSeg]
  466.                 mov     es,ax
  467.                 mov     cx,MAXWIDTH * MAXHEIGHT
  468.                 xor     di,di
  469.                 xor     ax,ax
  470.                 rep     stosb
  471.  
  472.                 mov     di,YSTART
  473. ForY:           mov     si,XSTART
  474. ForX:           GetPixel
  475.                 test    al,al
  476.                 jne     NextX
  477.                 call    BoundTrace
  478. NextX:          inc     si
  479.                 cmp     si,XSTOP
  480.                 jle     ForX
  481. NextY:          inc     di
  482.                 cmp     di,YSTOP
  483.                 jle     ForY
  484.                 ret
  485.  
  486. DrawMandel      endp
  487.  
  488.                 end
  489.