pouët.net

Hires Mandelbrot by Řrřola [web]

; Hires Mandelbrot   v v                            ..::::..
; a 64-byte intro by Rrrola <rrrola@gmail.com>   .::::::::::::.
; greets to everyone who's ever programed the Mandelbrot:fractal.
;                                            .::::::::-:::-:::::::.
;                                         .:::::::::---:...:-::::::.
;                                      .:::::::::::---:..:.:--:::::::.
;                                   .::::::::::::--:...:%*:.::-::::::::.
;                                .:::::::::::::----:.=#@@@%=::--:::::::::.
;                            ..::::::::::::--------.:#@@@@@#::----::::::::: 
;                         .::::::::::::::::::--::::..=@@@@@=..:::------::::: 
;                     ..::::::::::::::--:..:.:..-=-+**#%@@#**==:=.:-:::.:-::.
;                  .:::::::::::::::::---:.:##*:+#@@@@@@@@@@@@@@%%=:.-=::.:::.
;               ..::::::::::::::::::----:.:*%@@@@@@@@@@@@@@@@@@@@@%+@@%::-:::
;             .::::::::::::::::::-----::..+#@@@@@@@@@@@@@@@@@@@@@@@@@#=.---::
;           .:::::::::----------------.-%#@@@@@@@@@@@@@@@@@@@@@@@@@@@@*-:-:-:
;         .:::::::--.:-----::--------::-#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+-:.::
;       .:::::::::--:....:....:::--::.=@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#=:::
;     .::::::::::----..-*-:-*+-=.....-%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+.:-:
;  .:::::::::::----::..=@%@@@@@@#+:..+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#-:-:
;::::::::::::--::-:..-*@@@@@@@@@@@%=:%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*.-::
;:::::::::-----:.....*@@@@@@@@@@@@@@=@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%:--::
;:--:--------::..=**=@@@@@@@@@@@@@@@%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%---:::
;:::-+::........+%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+.---:::

; This is a bog-standard Mandelbrot set with the default palette.
; The escape condition is magnitude > 3.5355 (usually it's > 2).
; There are a few tricks I've learned over the years to make it smaller:
; - [si] also used as a float constant
; - the number of rows 0x04D8 is also the instruction "fadd dword[si]"
; - i*i, r*i, r*r computed in two loops with different strides
; - jump into the middle of the D loop

org 100h        ; assume bp~0x912 si=0x100 cl=0xff

  mov ax,0x4f02 ; [si]: D = -0.00315873139 (float32 0xbb4f02b8) ~ -1/316.6
  mov bx,107h   ; VESA mode 1280x1024, 256 colors
;  mov bx,105h   ; VESA mode 1024x768, 256 colors

  fldl2e        ;; y=1.44  ; no builtin constant to show the whole fractal
  ;fldpi        ;; y=3.14

;  mov dh,3      ; dx in 768..1023
;  mov dh,4
  mov dx,0x4D8   ; dx = 1240  ; D8 04 = fadd dword[si] <- overlapped
Y ;fadd dword[si];; y+=D
  fldln2        ;; x=0.693 y
;  mov ch,4      ; cx = 1279 on init, 1024 afterwards
  mov ch,5      ; cx = 1534 on init, 1280 afterwards
;  mov cx,0x4D8   ; cx = 1240  ; D8 04 = fadd dword[si]
X fadd dword[si];; x+=D y
  int 10h       ; set VESA mode or put pixel
                ; BIOS put pixel - ah=0xc bh:page=1 dx:y cx:x al:color=128..255|0
                ; (assume putpixel works in a VESA mode and bh:page is ignored)

  mov ax,0x0c7f ; al: max 129 iterations, ah: put pixel

; First iteration: 3x duplicate and swap two stack items (start with {x y})
; Later iterations: 2x duplicate and swap two stack items (start with {i r x y})
D fld st0
  fld st2       ;; i=y r=x x y
I inc si        ; <- jump here in later iterations
  jpo D         ;; i r r i i r x y  ; si=0x103

; Multiply
M fmulp st3,st0 ;; r r ii i r x y
  dec si        ;; r ii ri r x y
  jpo M         ;; ii ri rr x y     ; si=0x100

; Mandelbrot iteration: r, i = r*r-i*i+x, 2*r*i+y
  fld st2
  fadd st1
  fistp word[bp+si] ; <- int16(round_even(rr+ii = magnitude^2))

  fsub st3      ;; ii-x ri rr x y
  fsubp st2,st0 ;; ri rr-ii+x x y
  fadd st0      ;; 2ri rr-ii+x x y
  fadd st3      ;; i=2ri+y r=rr-ii+x x y

  cmp ah,[bp+si]; cf = (ah=12 < round_even(magnitude^2))
                ;    = (12.5 < magnitude^2)
                ;    = (3.5355 < magnitude)
  inc al        ; zf = (al == 0) ; al = 128 + number of iterations
  jnbe I        ; stop when al == 0 or magnitude > 3.5355
                ; jump into the middle of the loop => do it only twice

  fcompp        ;; x y
  loop X

  fcomp st1     ;; y
  dec dx
  jns Y-2

  ret