https://github.com/akkartik/mu/blob/main/shell/life.mu
1 fn state _grid: (addr array boolean), x: int, y: int -> _/eax: boolean {
2
3 compare x, 0
4 {
5 break-if->=
6 return 0/false
7 }
8 compare y, 0
9 {
10 break-if->=
11 return 0/false
12 }
13 compare x, 0x100/width
14 {
15 break-if-<
16 return 0/false
17 }
18 compare y, 0xc0/height
19 {
20 break-if-<
21 return 0/false
22 }
23 var idx/eax: int <- copy y
24 idx <- shift-left 8/log2width
25 idx <- add x
26 var grid/esi: (addr array boolean) <- copy _grid
27 var result/eax: (addr boolean) <- index grid, idx
28 return *result
29 }
30
31 fn set-state _grid: (addr array boolean), x: int, y: int, val: boolean {
32
33 var idx/eax: int <- copy y
34 idx <- shift-left 8/log2width
35 idx <- add x
36 var grid/esi: (addr array boolean) <- copy _grid
37 var result/eax: (addr boolean) <- index grid, idx
38 var src/ecx: boolean <- copy val
39 copy-to *result, src
40 }
41
42 fn num-live-neighbors grid: (addr array boolean), x: int, y: int -> _/eax: int {
43 var result/edi: int <- copy 0
44
45 decrement y
46 decrement x
47 var s/eax: boolean <- state grid, x, y
48 {
49 compare s, 0/false
50 break-if-=
51 result <- increment
52 }
53 increment x
54 s <- state grid, x, y
55 {
56 compare s, 0/false
57 break-if-=
58 result <- increment
59 }
60 increment x
61 s <- state grid, x, y
62 {
63 compare s, 0/false
64 break-if-=
65 result <- increment
66 }
67
68 increment y
69 s <- state grid, x, y
70 {
71 compare s, 0/false
72 break-if-=
73 result <- increment
74 }
75 subtract-from x, 2
76 s <- state grid, x, y
77 {
78 compare s, 0/false
79 break-if-=
80 result <- increment
81 }
82
83 increment y
84 s <- state grid, x, y
85 {
86 compare s, 0/false
87 break-if-=
88 result <- increment
89 }
90 increment x
91 s <- state grid, x, y
92 {
93 compare s, 0/false
94 break-if-=
95 result <- increment
96 }
97 increment x
98 s <- state grid, x, y
99 {
100 compare s, 0/false
101 break-if-=
102 result <- increment
103 }
104 return result
105 }
106
107 fn step old-grid: (addr array boolean), new-grid: (addr array boolean) {
108 var y/ecx: int <- copy 0
109 {
110 compare y, 0xc0/height
111 break-if->=
112 var x/edx: int <- copy 0
113 {
114 compare x, 0x100/width
115 break-if->=
116 var n/eax: int <- num-live-neighbors old-grid, x, y
117
118 {
119 compare n, 2
120 break-if->=
121 set-state new-grid, x, y, 0/dead
122 }
123
124 {
125 compare n, 3
126 break-if-<=
127 set-state new-grid, x, y, 0/dead
128 }
129
130 {
131 compare n, 2
132 break-if-!=
133 var old-state/eax: boolean <- state old-grid, x, y
134 set-state new-grid, x, y, old-state
135 }
136
137 {
138 compare n, 3
139 break-if-!=
140 set-state new-grid, x, y, 1/live
141 }
142 x <- increment
143 loop
144 }
145 y <- increment
146 loop
147 }
148 }
149
150
151 fn render-square _x: int, _y: int, color: int {
152 var y/edx: int <- copy _y
153 y <- shift-left 2/log2side
154 var side/ebx: int <- copy 1
155 side <- shift-left 2/log2side
156 var ymax/ecx: int <- copy y
157 ymax <- add side
158 {
159 compare y, ymax
160 break-if->=
161 {
162 var x/eax: int <- copy _x
163 x <- shift-left 2/log2side
164 var xmax/ecx: int <- copy x
165 xmax <- add side
166 {
167 compare x, xmax
168 break-if->=
169 pixel-on-real-screen x, y, color
170 x <- increment
171 loop
172 }
173 }
174 y <- increment
175 loop
176 }
177 }
178
179 fn render grid: (addr array boolean) {
180 var y/ecx: int <- copy 0
181 {
182 compare y, 0xc0/height
183 break-if->=
184 var x/edx: int <- copy 0
185 {
186 compare x, 0x100/width
187 break-if->=
188 var state/eax: boolean <- state grid, x, y
189 compare state, 0/false
190 {
191 break-if-=
192 render-square x, y, 3/cyan
193 }
194 compare state, 0/false
195 {
196 break-if-!=
197 render-square x, y, 0/black
198 }
199 x <- increment
200 loop
201 }
202 y <- increment
203 loop
204 }
205 }
206
207 fn life {
208
209
210
211
212
213
214 var grid1-storage: (handle array boolean)
215 var grid1-ah/eax: (addr handle array boolean) <- address grid1-storage
216 populate grid1-ah, 0xc000
217 var _grid1/eax: (addr array boolean) <- lookup *grid1-ah
218 var grid1/esi: (addr array boolean) <- copy _grid1
219 var grid2-storage: (handle array boolean)
220 var grid2-ah/eax: (addr handle array boolean) <- address grid2-storage
221 populate grid2-ah, 0xc000
222 var _grid2/eax: (addr array boolean) <- lookup *grid2-ah
223 var grid2/edi: (addr array boolean) <- copy _grid2
224
225 set-state grid1, 0x80, 0x5f, 1/live
226 set-state grid1, 0x81, 0x5f, 1/live
227 set-state grid1, 0x7f, 0x60, 1/live
228 set-state grid1, 0x80, 0x60, 1/live
229 set-state grid1, 0x80, 0x61, 1/live
230
231 render grid1
232 {
233 var key/eax: byte <- read-key 0/keyboard
234 compare key, 0
235
236 break-if-!=
237
238 step grid1, grid2
239 render grid2
240
241 step grid2, grid1
242 render grid1
243 loop
244 }
245 }