https://github.com/akkartik/mu/blob/main/mandelbrot-silhouette.mu
1
2
3
4
5
6
7
8
9
10
11
12
13 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
14 mandelbrot screen
15 }
16
17 fn mandelbrot screen: (addr screen) {
18 var a/eax: int <- copy 0
19 var b/ecx: int <- copy 0
20 a, b <- screen-size screen
21 var width/esi: int <- copy a
22 width <- shift-left 3/log2-font-width
23 var height/edi: int <- copy b
24 height <- shift-left 4/log2-font-height
25 var y/ecx: int <- copy 0
26 {
27 compare y, height
28 break-if->=
29 var imaginary/xmm1: float <- viewport-to-imaginary y, width, height
30 var x/edx: int <- copy 0
31 {
32 compare x, width
33 break-if->=
34 var real/xmm0: float <- viewport-to-real x, width
35 var iterations/eax: int <- mandelbrot-iterations-for-point real, imaginary, 0x400/max
36 compare iterations, 0x400/max
37 {
38 break-if->=
39 pixel screen, x, y, 0xf/white
40 }
41 compare iterations, 0x400/max
42 {
43 break-if-<
44 pixel screen, x, y, 0/black
45 }
46 x <- increment
47 loop
48 }
49 y <- increment
50 loop
51 }
52 }
53
54 fn mandelbrot-iterations-for-point real: float, imaginary: float, max: int -> _/eax: int {
55 var zero: float
56 var x/xmm0: float <- copy zero
57 var y/xmm1: float <- copy zero
58 var iterations/ecx: int <- copy 0
59 {
60 var done?/eax: boolean <- mandelbrot-done? x, y
61 compare done?, 0/false
62 break-if-!=
63 compare iterations, max
64 break-if->=
65 var newx/xmm2: float <- mandelbrot-x x, y, real
66 var newy/xmm3: float <- mandelbrot-y x, y, imaginary
67 x <- copy newx
68 y <- copy newy
69 iterations <- increment
70 loop
71 }
72 return iterations
73 }
74
75 fn mandelbrot-done? x: float, y: float -> _/eax: boolean {
76
77 var x2/xmm0: float <- copy x
78 x2 <- multiply x
79 var y2/xmm1: float <- copy y
80 y2 <- multiply y
81 var sum/xmm0: float <- copy x2
82 sum <- add y2
83 var four/eax: int <- copy 4
84 var four-f/xmm1: float <- convert four
85 compare sum, four-f
86 {
87 break-if-float>
88 return 0/false
89 }
90 return 1/true
91 }
92
93 fn mandelbrot-x x: float, y: float, real: float -> _/xmm2: float {
94
95 var x2/xmm0: float <- copy x
96 x2 <- multiply x
97 var y2/xmm1: float <- copy y
98 y2 <- multiply y
99 var result/xmm0: float <- copy x2
100 result <- subtract y2
101 result <- add real
102 return result
103 }
104
105 fn mandelbrot-y x: float, y: float, imaginary: float -> _/xmm3: float {
106
107 var two/eax: int <- copy 2
108 var result/xmm0: float <- convert two
109 result <- multiply x
110 result <- multiply y
111 result <- add imaginary
112 return result
113 }
114
115
116
117
118
119 fn viewport-to-real x: int, width: int -> _/xmm0: float {
120
121 var result/xmm0: float <- convert x
122 var width-f/xmm1: float <- convert width
123 var two/eax: int <- copy 2
124 var two-f/xmm2: float <- convert two
125 var half-width-f/xmm2: float <- reciprocal two-f
126 half-width-f <- multiply width-f
127 result <- subtract half-width-f
128 var four/eax: int <- copy 4
129 var four-f/xmm2: float <- convert four
130 result <- multiply four-f
131 result <- divide width-f
132 return result
133 }
134
135 fn viewport-to-imaginary y: int, width: int, height: int -> _/xmm1: float {
136
137 var result/xmm0: float <- convert y
138 var height-f/xmm1: float <- convert height
139 var half-height-f/xmm1: float <- copy height-f
140 var two/eax: int <- copy 2
141 var two-f/xmm2: float <- convert two
142 half-height-f <- divide two-f
143 result <- subtract half-height-f
144 var four/eax: int <- copy 4
145 var four-f/xmm1: float <- convert four
146 result <- multiply four-f
147 var width-f/xmm1: float <- convert width
148 result <- divide width-f
149 return result
150 }