Created
June 7, 2018 06:25
-
-
Save gregkrsak/93308804807d5145bef798832432a4c7 to your computer and use it in GitHub Desktop.
Mandelbrot ASM code from /u/balkenbrij on Reddit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; | |
;; Draw a grayscale mandelbrot fractal | |
;; | |
;; i compiled with yasm: yasm -o mandel.com mandel.asm | |
;; but i think it should be quite portable to other assemblers. | |
;; | |
SECTION .data | |
maxi: equ 128 ; upto maxi iterations per pixel | |
palscale: equ 1 ; ammount to shift to fit maxi onto palette | |
crestep: equ 2 ; x (mandelwidth/320) * 2^shift | |
cimstep: equ 3 ; y (mandelheight/200) * 2^shift | |
one: equ 256 ; fixed point 1.0 | |
n15: equ -450 ; start of left side | |
two: equ 512 ; fixed point 2.0 | |
four: equ 1024 ; fixed point 4.0 | |
cim: dw 300 ; imaginary part of Y | |
cre: dw 0 ; imaginary part of X | |
x: dw 0 ; real part of X | |
y: dw 0 ; real part of Y | |
xx: dw 0 ; x*x placeholder | |
yy: dw 0 ; y*y placeholder | |
twox: dw 0 ; 2*x placeholder | |
xnew: dw 0 ; temporary x placeholder | |
row: dw 0 ; current row | |
col dw 0 ; current col | |
SECTION .text | |
ORG 0x100 ; dos .com file starts at 0100h | |
call setup ; setup screen mode | |
call draw ; draw the fractal | |
call waitkey ; wait for a keypress | |
exit: | |
mov ax, 3 ; back to text | |
int 0x10 ; mode | |
mov ax, 0x4c00 ; clean dos | |
int 0x21 ; exit | |
setup: | |
mov ax, 0x13 ; setup screen mode 13 | |
int 0x10 ; 320x200x256 | |
mov ax, 0 ; setup grayscale palette | |
mov dx, 0x03c8 ; setup register to receive | |
out dx, al ; full palette (768bytes of rgb data) | |
inc dx ; the next register expects data | |
setpalette: | |
out dx, al ; red value | |
out dx, al ; green value | |
out dx, al ; blue value | |
inc al ; next 'color' | |
jnz setpalette | |
mov ax, 0xa000 ; point es:di to | |
mov es, ax ; 0a000:0000 | |
xor di, di ; so stos functions write to vram | |
cld ; we move forward in memory | |
xor ax,ax ; clear | |
mov cx,32000 ; screen | |
rep stosw | |
xor di, di ; restore di to start of vram | |
ret | |
waitkey: | |
mov ax, 0 ; wait for | |
int 0x16 ; keypress | |
jnz waitkey ; none received, start over | |
ret | |
draw: | |
mov word [row], 200 ; 200 rows | |
yloop: | |
mov ax, n15 | |
mov [cre], ax ; start of left side | |
mov word [col], 320 ; 320 columns | |
xloop: | |
xor ax, ax | |
xor cx, cx ; iter = 0 | |
mov [x], ax ; x = 0 | |
mov [y], ax ; y = 0 | |
whileloop: ; while ( iter < maxi && x*x + y*y < 4) | |
cmp cx, maxi ; if iter == maxi | |
je escape ; escape | |
mov ax, [x] ; x*x | |
mov bx, ax | |
imul bx | |
mov bx, one | |
idiv bx | |
mov [xx], ax | |
mov ax, [y] ; y*y | |
mov bx, ax | |
imul bx | |
mov bx, one | |
idiv bx | |
mov [yy], ax | |
add ax, [xx] ; if x*x + y*y == | |
cmp ax, four ; four | |
jge escape ; escape | |
mov ax, [xx] ; xnew = x*x - y*y + cre | |
sub ax, [yy] | |
add ax, [cre] | |
mov [xnew], ax | |
mov ax, [x] ; x * 2 * y | |
mov bx, two | |
imul bx | |
mov bx, one | |
idiv bx | |
mov bx, [y] | |
imul bx | |
mov bx, one | |
idiv bx | |
add ax, [cim] ; + cim | |
mov [y], ax ; y = x * 2 * y + cim | |
mov ax, [xnew] ; x = xnew | |
mov [x], ax | |
inc cx ; ++iter | |
jmp whileloop | |
escape: | |
mov al, cl ; copy color index (iter) | |
cmp al, maxi ; plot pixel | |
jne color ; w/ black if maximum reached | |
xor al, al | |
color: ; otherwise w/ palette value | |
shl al, palscale ; scale to fit palette | |
stosb ; write pixel | |
add word [cre], crestep ; cre += crestep | |
dec word [col] | |
jnz xloop ; next column | |
sub word [cim], cimstep ; cim -= cimstep | |
dec word [row] ; next row | |
jnz yloop | |
ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment