https://github.com/akkartik/mu/blob/main/baremetal/501draw-text.mu
1
2
3 fn move-cursor-left screen: (addr screen) {
4 var cursor-x/eax: int <- copy 0
5 var cursor-y/ecx: int <- copy 0
6 cursor-x, cursor-y <- cursor-position screen
7 compare cursor-x, 0
8 {
9 break-if->
10 return
11 }
12 cursor-x <- decrement
13 set-cursor-position screen, cursor-x, cursor-y
14 }
15
16 fn move-cursor-right screen: (addr screen) {
17 var _width/eax: int <- copy 0
18 var dummy/ecx: int <- copy 0
19 _width, dummy <- screen-size screen
20 var limit/edx: int <- copy _width
21 limit <- decrement
22 var cursor-x/eax: int <- copy 0
23 var cursor-y/ecx: int <- copy 0
24 cursor-x, cursor-y <- cursor-position screen
25 compare cursor-x, limit
26 {
27 break-if-<
28 return
29 }
30 cursor-x <- increment
31 set-cursor-position screen, cursor-x, cursor-y
32 }
33
34 fn move-cursor-up screen: (addr screen) {
35 var cursor-x/eax: int <- copy 0
36 var cursor-y/ecx: int <- copy 0
37 cursor-x, cursor-y <- cursor-position screen
38 compare cursor-y, 0
39 {
40 break-if->
41 return
42 }
43 cursor-y <- decrement
44 set-cursor-position screen, cursor-x, cursor-y
45 }
46
47 fn move-cursor-down screen: (addr screen) {
48 var dummy/eax: int <- copy 0
49 var _height/ecx: int <- copy 0
50 dummy, _height <- screen-size screen
51 var limit/edx: int <- copy _height
52 limit <- decrement
53 var cursor-x/eax: int <- copy 0
54 var cursor-y/ecx: int <- copy 0
55 cursor-x, cursor-y <- cursor-position screen
56 compare cursor-y, limit
57 {
58 break-if-<
59 return
60 }
61 cursor-y <- increment
62 set-cursor-position screen, cursor-x, cursor-y
63 }
64
65 fn draw-grapheme-at-cursor screen: (addr screen), g: grapheme, color: int, background-color: int {
66 var cursor-x/eax: int <- copy 0
67 var cursor-y/ecx: int <- copy 0
68 cursor-x, cursor-y <- cursor-position screen
69 draw-grapheme screen, g, cursor-x, cursor-y, color, background-color
70 }
71
72
73 fn draw-code-point-at-cursor screen: (addr screen), c: code-point, color: int, background-color: int {
74 var g/eax: grapheme <- copy c
75 draw-grapheme-at-cursor screen, g, color, background-color
76 }
77
78
79
80
81 fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int {
82 var stream-storage: (stream byte 0x100)
83 var stream/esi: (addr stream byte) <- address stream-storage
84 write stream, text
85
86 var xcurr/ecx: int <- copy x
87 {
88 compare xcurr, xmax
89 break-if->
90 var g/eax: grapheme <- read-grapheme stream
91 compare g, 0xffffffff/end-of-file
92 break-if-=
93 xcurr <- increment
94 loop
95 }
96 compare xcurr, xmax
97 {
98 break-if-<=
99 return 0
100 }
101
102 rewind-stream stream
103 xcurr <- copy x
104 {
105 var g/eax: grapheme <- read-grapheme stream
106 compare g, 0xffffffff/end-of-file
107 break-if-=
108 draw-grapheme screen, g, xcurr, y, color, background-color
109 xcurr <- increment
110 loop
111 }
112 set-cursor-position screen, xcurr, y
113 return xcurr
114 }
115
116 fn draw-text-rightward-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int {
117 var width/eax: int <- copy 0
118 var height/ecx: int <- copy 0
119 width, height <- screen-size screen
120 var result/eax: int <- draw-text-rightward screen, text, x, width, y, color, background-color
121 return result
122 }
123
124 fn draw-text-rightward-from-cursor screen: (addr screen), text: (addr array byte), xmax: int, color: int, background-color: int -> _/eax: int {
125 var cursor-x/eax: int <- copy 0
126 var cursor-y/ecx: int <- copy 0
127 cursor-x, cursor-y <- cursor-position screen
128 var result/eax: int <- draw-text-rightward screen, text, cursor-x, xmax, cursor-y, color, background-color
129 return result
130 }
131
132
133
134
135
136 fn draw-text-wrapping-right-then-down screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
137 var stream-storage: (stream byte 0x100)
138 var stream/esi: (addr stream byte) <- address stream-storage
139 write stream, text
140
141 var xcurr/edx: int <- copy x
142 var ycurr/ecx: int <- copy y
143 {
144 compare ycurr, ymax
145 break-if->=
146 var g/eax: grapheme <- read-grapheme stream
147 compare g, 0xffffffff/end-of-file
148 break-if-=
149 xcurr <- increment
150 compare xcurr, xmax
151 {
152 break-if-<
153 xcurr <- copy xmin
154 ycurr <- increment
155 }
156 loop
157 }
158 compare ycurr, ymax
159 {
160 break-if-<
161 return 0, 0
162 }
163
164 rewind-stream stream
165 xcurr <- copy x
166 ycurr <- copy y
167 {
168 var g/eax: grapheme <- read-grapheme stream
169 compare g, 0xffffffff/end-of-file
170 break-if-=
171 draw-grapheme screen, g, xcurr, ycurr, color, background-color
172 xcurr <- increment
173 compare xcurr, xmax
174 {
175 break-if-<
176 xcurr <- copy xmin
177 ycurr <- increment
178 }
179 loop
180 }
181 set-cursor-position screen, xcurr, ycurr
182 return xcurr, ycurr
183 }
184
185 fn move-cursor-rightward-and-downward screen: (addr screen), xmin: int, xmax: int {
186 var cursor-x/eax: int <- copy 0
187 var cursor-y/ecx: int <- copy 0
188 cursor-x, cursor-y <- cursor-position screen
189 cursor-x <- increment
190 compare cursor-x, xmax
191 {
192 break-if-<
193 cursor-x <- copy xmin
194 cursor-y <- increment
195 }
196 set-cursor-position screen, cursor-x, cursor-y
197 }
198
199 fn draw-text-wrapping-right-then-down-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
200 var x2/eax: int <- copy 0
201 var y2/ecx: int <- copy 0
202 x2, y2 <- screen-size screen
203 x2, y2 <- draw-text-wrapping-right-then-down screen, text, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
204 return x2, y2
205 }
206
207 fn draw-text-wrapping-right-then-down-from-cursor screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int {
208 var cursor-x/eax: int <- copy 0
209 var cursor-y/ecx: int <- copy 0
210 cursor-x, cursor-y <- cursor-position screen
211 var end-x/edx: int <- copy cursor-x
212 end-x <- increment
213 compare end-x, xmax
214 {
215 break-if-<
216 cursor-x <- copy xmin
217 cursor-y <- increment
218 }
219 cursor-x, cursor-y <- draw-text-wrapping-right-then-down screen, text, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
220 }
221
222 fn draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int {
223 var width/eax: int <- copy 0
224 var height/ecx: int <- copy 0
225 width, height <- screen-size screen
226 draw-text-wrapping-right-then-down-from-cursor screen, text, 0/xmin, 0/ymin, width, height, color, background-color
227 }
228
229 fn draw-int32-hex-wrapping-right-then-down screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
230 var stream-storage: (stream byte 0x100)
231 var stream/esi: (addr stream byte) <- address stream-storage
232 write-int32-hex stream, n
233
234 var xcurr/edx: int <- copy x
235 var ycurr/ecx: int <- copy y
236 {
237 compare ycurr, ymax
238 break-if->=
239 var g/eax: grapheme <- read-grapheme stream
240 compare g, 0xffffffff/end-of-file
241 break-if-=
242 xcurr <- increment
243 compare xcurr, xmax
244 {
245 break-if-<
246 xcurr <- copy xmin
247 ycurr <- increment
248 }
249 loop
250 }
251 compare ycurr, ymax
252 {
253 break-if-<
254 return 0, 0
255 }
256
257 rewind-stream stream
258 xcurr <- copy x
259 ycurr <- copy y
260 {
261 var g/eax: grapheme <- read-grapheme stream
262 compare g, 0xffffffff/end-of-file
263 break-if-=
264 draw-grapheme screen, g, xcurr, ycurr, color, background-color
265 xcurr <- increment
266 compare xcurr, xmax
267 {
268 break-if-<
269 xcurr <- copy xmin
270 ycurr <- increment
271 }
272 loop
273 }
274 set-cursor-position screen, xcurr, ycurr
275 return xcurr, ycurr
276 }
277
278 fn draw-int32-hex-wrapping-right-then-down-over-full-screen screen: (addr screen), n: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
279 var x2/eax: int <- copy 0
280 var y2/ecx: int <- copy 0
281 x2, y2 <- screen-size screen
282 x2, y2 <- draw-int32-hex-wrapping-right-then-down screen, n, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
283 return x2, y2
284 }
285
286 fn draw-int32-hex-wrapping-right-then-down-from-cursor screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int {
287 var cursor-x/eax: int <- copy 0
288 var cursor-y/ecx: int <- copy 0
289 cursor-x, cursor-y <- cursor-position screen
290 var end-x/edx: int <- copy cursor-x
291 end-x <- increment
292 compare end-x, xmax
293 {
294 break-if-<
295 cursor-x <- copy xmin
296 cursor-y <- increment
297 }
298 cursor-x, cursor-y <- draw-int32-hex-wrapping-right-then-down screen, n, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
299 }
300
301 fn draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), n: int, color: int, background-color: int {
302 var width/eax: int <- copy 0
303 var height/ecx: int <- copy 0
304 width, height <- screen-size screen
305 draw-int32-hex-wrapping-right-then-down-from-cursor screen, n, 0/xmin, 0/ymin, width, height, color, background-color
306 }
307
308 fn draw-int32-decimal-wrapping-right-then-down screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
309 var stream-storage: (stream byte 0x100)
310 var stream/esi: (addr stream byte) <- address stream-storage
311 write-int32-decimal stream, n
312
313 var xcurr/edx: int <- copy x
314 var ycurr/ecx: int <- copy y
315 {
316 compare ycurr, ymax
317 break-if->=
318 var g/eax: grapheme <- read-grapheme stream
319 compare g, 0xffffffff/end-of-file
320 break-if-=
321 xcurr <- increment
322 compare xcurr, xmax
323 {
324 break-if-<
325 xcurr <- copy xmin
326 ycurr <- increment
327 }
328 loop
329 }
330 compare ycurr, ymax
331 {
332 break-if-<
333 return 0, 0
334 }
335
336 rewind-stream stream
337 xcurr <- copy x
338 ycurr <- copy y
339 {
340 var g/eax: grapheme <- read-grapheme stream
341 compare g, 0xffffffff/end-of-file
342 break-if-=
343 draw-grapheme screen, g, xcurr, ycurr, color, background-color
344 xcurr <- increment
345 compare xcurr, xmax
346 {
347 break-if-<
348 xcurr <- copy xmin
349 ycurr <- increment
350 }
351 loop
352 }
353 set-cursor-position screen, xcurr, ycurr
354 return xcurr, ycurr
355 }
356
357 fn draw-int32-decimal-wrapping-right-then-down-over-full-screen screen: (addr screen), n: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
358 var x2/eax: int <- copy 0
359 var y2/ecx: int <- copy 0
360 x2, y2 <- screen-size screen
361 x2, y2 <- draw-int32-decimal-wrapping-right-then-down screen, n, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
362 return x2, y2
363 }
364
365 fn draw-int32-decimal-wrapping-right-then-down-from-cursor screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int {
366 var cursor-x/eax: int <- copy 0
367 var cursor-y/ecx: int <- copy 0
368 cursor-x, cursor-y <- cursor-position screen
369 var end-x/edx: int <- copy cursor-x
370 end-x <- increment
371 compare end-x, xmax
372 {
373 break-if-<
374 cursor-x <- copy xmin
375 cursor-y <- increment
376 }
377 cursor-x, cursor-y <- draw-int32-decimal-wrapping-right-then-down screen, n, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
378 }
379
380 fn draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), n: int, color: int, background-color: int {
381 var width/eax: int <- copy 0
382 var height/ecx: int <- copy 0
383 width, height <- screen-size screen
384 draw-int32-decimal-wrapping-right-then-down-from-cursor screen, n, 0/xmin, 0/ymin, width, height, color, background-color
385 }
386
387
388
389
390
391
392 fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int {
393 var stream-storage: (stream byte 0x100)
394 var stream/esi: (addr stream byte) <- address stream-storage
395 write stream, text
396
397 var ycurr/ecx: int <- copy y
398 {
399 compare ycurr, ymax
400 break-if->
401 var g/eax: grapheme <- read-grapheme stream
402 compare g, 0xffffffff/end-of-file
403 break-if-=
404 ycurr <- increment
405 loop
406 }
407 compare ycurr, ymax
408 {
409 break-if-<=
410 return 0
411 }
412
413 rewind-stream stream
414 ycurr <- copy y
415 {
416 var g/eax: grapheme <- read-grapheme stream
417 compare g, 0xffffffff/end-of-file
418 break-if-=
419 draw-grapheme screen, g, x, ycurr, color, background-color
420 ycurr <- increment
421 loop
422 }
423 set-cursor-position screen, x, ycurr
424 return ycurr
425 }
426
427 fn draw-text-downward-from-cursor screen: (addr screen), text: (addr array byte), ymax: int, color: int, background-color: int {
428 var cursor-x/eax: int <- copy 0
429 var cursor-y/ecx: int <- copy 0
430 cursor-x, cursor-y <- cursor-position screen
431 var result/eax: int <- draw-text-downward screen, text, cursor-x, cursor-y, ymax, color, background-color
432 }
433
434
435
436
437
438 fn draw-text-wrapping-down-then-right screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
439 var stream-storage: (stream byte 0x100)
440 var stream/esi: (addr stream byte) <- address stream-storage
441 write stream, text
442
443 var xcurr/edx: int <- copy x
444 var ycurr/ecx: int <- copy y
445 {
446 compare xcurr, xmax
447 break-if->=
448 var g/eax: grapheme <- read-grapheme stream
449 compare g, 0xffffffff/end-of-file
450 break-if-=
451 ycurr <- increment
452 compare ycurr, ymax
453 {
454 break-if-<
455 xcurr <- increment
456 ycurr <- copy ymin
457 }
458 loop
459 }
460 compare xcurr, xmax
461 {
462 break-if-<
463 return 0, 0
464 }
465
466 rewind-stream stream
467 xcurr <- copy x
468 ycurr <- copy y
469 {
470 var g/eax: grapheme <- read-grapheme stream
471 compare g, 0xffffffff/end-of-file
472 break-if-=
473 draw-grapheme screen, g, xcurr, ycurr, color, background-color
474 ycurr <- increment
475 compare ycurr, ymax
476 {
477 break-if-<
478 xcurr <- increment
479 ycurr <- copy ymin
480 }
481 loop
482 }
483 set-cursor-position screen, xcurr, ycurr
484 return xcurr, ycurr
485 }
486
487 fn draw-text-wrapping-down-then-right-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
488 var x2/eax: int <- copy 0
489 var y2/ecx: int <- copy 0
490 x2, y2 <- screen-size screen
491 x2, y2 <- draw-text-wrapping-down-then-right screen, text, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
492 return x2, y2
493 }
494
495 fn draw-text-wrapping-down-then-right-from-cursor screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int {
496 var cursor-x/eax: int <- copy 0
497 var cursor-y/ecx: int <- copy 0
498 cursor-x, cursor-y <- cursor-position screen
499 var end-y/edx: int <- copy cursor-y
500 end-y <- increment
501 compare end-y, ymax
502 {
503 break-if-<
504 cursor-x <- increment
505 cursor-y <- copy ymin
506 }
507 cursor-x, cursor-y <- draw-text-wrapping-down-then-right screen, text, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
508 }
509
510 fn draw-text-wrapping-down-then-right-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int {
511 var width/eax: int <- copy 0
512 var height/ecx: int <- copy 0
513 width, height <- screen-size screen
514 draw-text-wrapping-down-then-right-from-cursor screen, text, 0/xmin, 0/ymin, width, height, color, background-color
515 }
516
517
518
519 fn abort e: (addr array byte) {
520 var dummy1/eax: int <- copy 0
521 var dummy2/ecx: int <- copy 0
522 dummy1, dummy2 <- draw-text-wrapping-right-then-down-over-full-screen 0/screen, e, 0/x, 0x2f/y, 0xf/fg=white, 0xc/bg=red
523 {
524 loop
525 }
526 }