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 }
21
22 fn initialize-screen screen: (addr screen), width: int, height: int {
23 var screen-addr/esi: (addr screen) <- copy screen
24 var tmp/eax: int <- copy 0
25 var dest/edi: (addr int) <- copy 0
26
27 dest <- get screen-addr, width
28 tmp <- copy width
29 copy-to *dest, tmp
30
31 dest <- get screen-addr, height
32 tmp <- copy height
33 copy-to *dest, tmp
34
35 {
36 var data-addr/edi: (addr handle array screen-cell) <- get screen-addr, data
37 tmp <- multiply width
38 populate data-addr, tmp
39 }
40
41 dest <- get screen-addr, cursor-x
42 copy-to *dest, 0
43
44 dest <- get screen-addr, cursor-y
45 copy-to *dest, 0
46 }
47
48
49 fn screen-size screen: (addr screen) -> _/eax: int, _/ecx: int {
50 var width/eax: int <- copy 0
51 var height/ecx: int <- copy 0
52 compare screen, 0
53 {
54 break-if-!=
55 return 0x80, 0x30
56 }
57
58 var screen-addr/esi: (addr screen) <- copy screen
59 var tmp/edx: (addr int) <- get screen-addr, width
60 width <- copy *tmp
61 tmp <- get screen-addr, height
62 height <- copy *tmp
63 return width, height
64 }
65
66
67
68 fn draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int {
69 {
70 compare screen, 0
71 break-if-!=
72 draw-grapheme-on-real-screen g, x, y, color, 0
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 color2/edx: grapheme <- copy color
87 copy-to *dest-color, color2
88 }
89
90 fn screen-cell-index screen-on-stack: (addr screen), x: int, y: int -> _/ecx: int {
91 var screen/esi: (addr screen) <- copy screen-on-stack
92 var height-addr/eax: (addr int) <- get screen, height
93 var result/ecx: int <- copy y
94 result <- multiply *height-addr
95 result <- add x
96 return result
97 }
98
99 fn cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int {
100 {
101 compare screen, 0
102 break-if-!=
103 var x/eax: int <- copy 0
104 var y/ecx: int <- copy 0
105 x, y <- cursor-position-on-real-screen
106 return x, y
107 }
108
109 var screen-addr/esi: (addr screen) <- copy screen
110 var cursor-x-addr/eax: (addr int) <- get screen-addr, cursor-x
111 var cursor-y-addr/ecx: (addr int) <- get screen-addr, cursor-y
112 return *cursor-x-addr, *cursor-y-addr
113 }
114
115 fn set-cursor-position screen: (addr screen), x: int, y: int {
116 {
117 compare screen, 0
118 break-if-!=
119 set-cursor-position-on-real-screen x, y
120 return
121 }
122
123 var screen-addr/esi: (addr screen) <- copy screen
124
125 {
126 compare x, 0
127 break-if->=
128 return
129 }
130
131 {
132 var width-addr/eax: (addr int) <- get screen-addr, width
133 var width/eax: int <- copy *width-addr
134 compare x, width
135 break-if-<=
136 return
137 }
138
139 {
140 compare y, 0
141 break-if->=
142 return
143 }
144
145 {
146 var height-addr/eax: (addr int) <- get screen-addr, height
147 var height/eax: int <- copy *height-addr
148 compare y, height
149 break-if-<
150 return
151 }
152
153 var dest/edi: (addr int) <- get screen-addr, cursor-x
154 var src/eax: int <- copy x
155 copy-to *dest, src
156
157 dest <- get screen-addr, cursor-y
158 src <- copy y
159 copy-to *dest, src
160 }
161
162 fn show-cursor screen: (addr screen), g: grapheme {
163 {
164 compare screen, 0
165 break-if-!=
166 show-cursor-on-real-screen g
167 return
168 }
169
170 var cursor-x/eax: int <- copy 0
171 var cursor-y/ecx: int <- copy 0
172 cursor-x, cursor-y <- cursor-position screen
173 draw-grapheme screen, g, cursor-x, cursor-y, 0
174 }
175
176 fn clear-screen screen: (addr screen) {
177 {
178 compare screen, 0
179 break-if-!=
180 clear-real-screen
181 return
182 }
183
184 var space/edi: grapheme <- copy 0x20
185 set-cursor-position screen, 0, 0
186 var screen-addr/esi: (addr screen) <- copy screen
187 var y/eax: int <- copy 1
188 var height/ecx: (addr int) <- get screen-addr, height
189 {
190 compare y, *height
191 break-if->
192 var x/edx: int <- copy 1
193 var width/ebx: (addr int) <- get screen-addr, width
194 {
195 compare x, *width
196 break-if->
197 draw-grapheme screen, space, x, y, 0
198 x <- increment
199 loop
200 }
201 y <- increment
202 loop
203 }
204 set-cursor-position screen, 0, 0
205 }
206
207
208
209 fn clear-real-screen {
210 var y/eax: int <- copy 0
211 {
212 compare y, 0x300
213 break-if->=
214 var x/edx: int <- copy 0
215 {
216 compare x, 0x400
217 break-if->=
218 pixel-on-real-screen x, y, 0
219 x <- increment
220 loop
221 }
222 y <- increment
223 loop
224 }
225 }
226
227 fn screen-grapheme-at screen-on-stack: (addr screen), x: int, y: int -> _/eax: grapheme {
228 var screen-addr/esi: (addr screen) <- copy screen-on-stack
229 var idx/ecx: int <- screen-cell-index screen-addr, x, y
230 var result/eax: grapheme <- screen-grapheme-at-idx screen-addr, idx
231 return result
232 }
233
234 fn screen-grapheme-at-idx screen-on-stack: (addr screen), idx-on-stack: int -> _/eax: grapheme {
235 var screen-addr/esi: (addr screen) <- copy screen-on-stack
236 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
237 var data/eax: (addr array screen-cell) <- lookup *data-ah
238 var idx/ecx: int <- copy idx-on-stack
239 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
240 var cell/eax: (addr screen-cell) <- index data, offset
241 var src/eax: (addr grapheme) <- get cell, data
242 return *src
243 }
244
245 fn screen-color-at screen-on-stack: (addr screen), x: int, y: int -> _/eax: int {
246 var screen-addr/esi: (addr screen) <- copy screen-on-stack
247 var idx/ecx: int <- screen-cell-index screen-addr, x, y
248 var result/eax: int <- screen-color-at-idx screen-addr, idx
249 return result
250 }
251
252 fn screen-color-at-idx screen-on-stack: (addr screen), idx-on-stack: int -> _/eax: int {
253 var screen-addr/esi: (addr screen) <- copy screen-on-stack
254 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
255 var data/eax: (addr array screen-cell) <- lookup *data-ah
256 var idx/ecx: int <- copy idx-on-stack
257 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
258 var cell/eax: (addr screen-cell) <- index data, offset
259 var src/eax: (addr int) <- get cell, color
260 var result/eax: int <- copy *src
261 return result
262 }