https://github.com/akkartik/mu/blob/main/baremetal/500text-screen.mu
1
2
3
4
5
6
7
8
9 type screen {
10 width: int
11 height: int
12 data: (handle array screen-cell)
13 cursor-x: int
14 cursor-y: int
15 }
16
17 type screen-cell {
18 data: grapheme
19 color: int
20 background-color: int
21 }
22
23 fn initialize-screen screen: (addr screen), width: int, height: int {
24 var screen-addr/esi: (addr screen) <- copy screen
25 var tmp/eax: int <- copy 0
26 var dest/edi: (addr int) <- copy 0
27
28 dest <- get screen-addr, width
29 tmp <- copy width
30 copy-to *dest, tmp
31
32 dest <- get screen-addr, height
33 tmp <- copy height
34 copy-to *dest, tmp
35
36 {
37 var data-addr/edi: (addr handle array screen-cell) <- get screen-addr, data
38 tmp <- multiply width
39 populate data-addr, tmp
40 }
41
42 dest <- get screen-addr, cursor-x
43 copy-to *dest, 0
44
45 dest <- get screen-addr, cursor-y
46 copy-to *dest, 0
47 }
48
49
50 fn screen-size screen: (addr screen) -> _/eax: int, _/ecx: int {
51 var width/eax: int <- copy 0
52 var height/ecx: int <- copy 0
53 compare screen, 0
54 {
55 break-if-!=
56 return 0x80/128, 0x30/48
57 }
58
59 var screen-addr/esi: (addr screen) <- copy screen
60 var tmp/edx: (addr int) <- get screen-addr, width
61 width <- copy *tmp
62 tmp <- get screen-addr, height
63 height <- copy *tmp
64 return width, height
65 }
66
67
68 fn draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int, background-color: int {
69 {
70 compare screen, 0
71 break-if-!=
72 draw-grapheme-on-real-screen g, x, y, color, background-color
73 return
74 }
75
76 var screen-addr/esi: (addr screen) <- copy screen
77 var idx/ecx: int <- screen-cell-index screen-addr, x, y
78 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
79 var data/eax: (addr array screen-cell) <- lookup *data-ah
80 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
81 var dest-cell/ecx: (addr screen-cell) <- index data, offset
82 var dest-grapheme/eax: (addr grapheme) <- get dest-cell, data
83 var g2/edx: grapheme <- copy g
84 copy-to *dest-grapheme, g2
85 var dest-color/eax: (addr int) <- get dest-cell, color
86 var src-color/edx: int <- copy color
87 copy-to *dest-color, src-color
88 dest-color <- get dest-cell, background-color
89 src-color <- copy background-color
90 copy-to *dest-color, src-color
91 }
92
93
94 fn draw-code-point screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int {
95 var g/eax: grapheme <- copy c
96 draw-grapheme screen, g, x, y, color, background-color
97 }
98
99
100 fn screen-cell-index screen-on-stack: (addr screen), x: int, y: int -> _/ecx: int {
101 var screen/esi: (addr screen) <- copy screen-on-stack
102
103 {
104 var xmax/eax: (addr int) <- get screen, width
105 var xcurr/ecx: int <- copy x
106 compare xcurr, *xmax
107 break-if-<
108 abort "tried to print out of screen bounds"
109 }
110 var width-addr/eax: (addr int) <- get screen, width
111 var result/ecx: int <- copy y
112 result <- multiply *width-addr
113 result <- add x
114 return result
115 }
116
117 fn cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int {
118 {
119 compare screen, 0
120 break-if-!=
121 var x/eax: int <- copy 0
122 var y/ecx: int <- copy 0
123 x, y <- cursor-position-on-real-screen
124 return x, y
125 }
126
127 var screen-addr/esi: (addr screen) <- copy screen
128 var cursor-x-addr/eax: (addr int) <- get screen-addr, cursor-x
129 var cursor-y-addr/ecx: (addr int) <- get screen-addr, cursor-y
130 return *cursor-x-addr, *cursor-y-addr
131 }
132
133 fn set-cursor-position screen: (addr screen), x: int, y: int {
134 {
135 compare screen, 0
136 break-if-!=
137 set-cursor-position-on-real-screen x, y
138 return
139 }
140
141 var screen-addr/esi: (addr screen) <- copy screen
142
143 {
144 compare x, 0
145 break-if->=
146 return
147 }
148
149 {
150 var width-addr/eax: (addr int) <- get screen-addr, width
151 var width/eax: int <- copy *width-addr
152 compare x, width
153 break-if-<=
154 return
155 }
156
157 {
158 compare y, 0
159 break-if->=
160 return
161 }
162
163 {
164 var height-addr/eax: (addr int) <- get screen-addr, height
165 var height/eax: int <- copy *height-addr
166 compare y, height
167 break-if-<
168 return
169 }
170
171 var dest/edi: (addr int) <- get screen-addr, cursor-x
172 var src/eax: int <- copy x
173 copy-to *dest, src
174
175 dest <- get screen-addr, cursor-y
176 src <- copy y
177 copy-to *dest, src
178 }
179
180 fn show-cursor screen: (addr screen), g: grapheme {
181 {
182 compare screen, 0
183 break-if-!=
184 show-cursor-on-real-screen g
185 return
186 }
187
188 var cursor-x/eax: int <- copy 0
189 var cursor-y/ecx: int <- copy 0
190 cursor-x, cursor-y <- cursor-position screen
191 draw-grapheme screen, g, cursor-x, cursor-y, 0/fg, 7/bg
192 }
193
194 fn clear-screen screen: (addr screen) {
195 {
196 compare screen, 0
197 break-if-!=
198 clear-real-screen
199 return
200 }
201
202 set-cursor-position screen, 0, 0
203 var screen-addr/esi: (addr screen) <- copy screen
204 var y/eax: int <- copy 0
205 var height/ecx: (addr int) <- get screen-addr, height
206 {
207 compare y, *height
208 break-if->=
209 var x/edx: int <- copy 0
210 var width/ebx: (addr int) <- get screen-addr, width
211 {
212 compare x, *width
213 break-if->=
214 draw-code-point screen, 0x20/space, x, y, 0/fg=black, 0/bg=black
215 x <- increment
216 loop
217 }
218 y <- increment
219 loop
220 }
221 set-cursor-position screen, 0, 0
222 }
223
224
225
226 fn clear-real-screen {
227 var y/eax: int <- copy 0
228 {
229 compare y, 0x300/screen-height=768
230 break-if->=
231 var x/edx: int <- copy 0
232 {
233 compare x, 0x400/screen-width=1024
234 break-if->=
235 pixel-on-real-screen x, y, 0/color=black
236 x <- increment
237 loop
238 }
239 y <- increment
240 loop
241 }
242 }
243
244 fn screen-grapheme-at screen-on-stack: (addr screen), x: int, y: int -> _/eax: grapheme {
245 var screen-addr/esi: (addr screen) <- copy screen-on-stack
246 var idx/ecx: int <- screen-cell-index screen-addr, x, y
247 var result/eax: grapheme <- screen-grapheme-at-idx screen-addr, idx
248 return result
249 }
250
251 fn screen-grapheme-at-idx screen-on-stack: (addr screen), idx-on-stack: int -> _/eax: grapheme {
252 var screen-addr/esi: (addr screen) <- copy screen-on-stack
253 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
254 var data/eax: (addr array screen-cell) <- lookup *data-ah
255 var idx/ecx: int <- copy idx-on-stack
256 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
257 var cell/eax: (addr screen-cell) <- index data, offset
258 var src/eax: (addr grapheme) <- get cell, data
259 return *src
260 }
261
262 fn screen-color-at screen-on-stack: (addr screen), x: int, y: int -> _/eax: int {
263 var screen-addr/esi: (addr screen) <- copy screen-on-stack
264 var idx/ecx: int <- screen-cell-index screen-addr, x, y
265 var result/eax: int <- screen-color-at-idx screen-addr, idx
266 return result
267 }
268
269 fn screen-color-at-idx screen-on-stack: (addr screen), idx-on-stack: int -> _/eax: int {
270 var screen-addr/esi: (addr screen) <- copy screen-on-stack
271 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
272 var data/eax: (addr array screen-cell) <- lookup *data-ah
273 var idx/ecx: int <- copy idx-on-stack
274 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
275 var cell/eax: (addr screen-cell) <- index data, offset
276 var src/eax: (addr int) <- get cell, color
277 var result/eax: int <- copy *src
278 return result
279 }
280
281 fn screen-background-color-at screen-on-stack: (addr screen), x: int, y: int -> _/eax: int {
282 var screen-addr/esi: (addr screen) <- copy screen-on-stack
283 var idx/ecx: int <- screen-cell-index screen-addr, x, y
284 var result/eax: int <- screen-background-color-at-idx screen-addr, idx
285 return result
286 }
287
288 fn screen-background-color-at-idx screen-on-stack: (addr screen), idx-on-stack: int -> _/eax: int {
289 var screen-addr/esi: (addr screen) <- copy screen-on-stack
290 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
291 var data/eax: (addr array screen-cell) <- lookup *data-ah
292 var idx/ecx: int <- copy idx-on-stack
293 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
294 var cell/eax: (addr screen-cell) <- index data, offset
295 var src/eax: (addr int) <- get cell, background-color
296 var result/eax: int <- copy *src
297 return result
298 }