https://github.com/akkartik/mu/blob/master/405screen.mu
1
2
3
4
5
6
7
8
9 type screen {
10 num-rows: int
11 num-cols: int
12 data: (handle array screen-cell)
13 top-index: int
14 cursor-row: int
15 cursor-col: int
16 cursor-hide?: boolean
17 curr-attributes: screen-cell
18 }
19
20 type screen-cell {
21 data: grapheme
22 color: int
23 background-color: int
24 bold?: boolean
25 underline?: boolean
26 reverse?: boolean
27 blink?: boolean
28 }
29
30 fn initialize-screen screen: (addr screen), nrows: int, ncols: int {
31 var screen-addr/esi: (addr screen) <- copy screen
32 var tmp/eax: int <- copy 0
33 var dest/edi: (addr int) <- copy 0
34
35 dest <- get screen-addr, num-rows
36 tmp <- copy nrows
37 copy-to *dest, tmp
38
39 dest <- get screen-addr, num-cols
40 tmp <- copy ncols
41 copy-to *dest, tmp
42
43 {
44 var data-addr/edi: (addr handle array screen-cell) <- get screen-addr, data
45 tmp <- multiply nrows
46 populate data-addr, tmp
47 }
48
49 dest <- get screen-addr, cursor-row
50 copy-to *dest, 1
51
52 dest <- get screen-addr, cursor-col
53 copy-to *dest, 1
54
55 var tmp2/eax: (addr screen-cell) <- get screen-addr, curr-attributes
56 dest <- get tmp2, background-color
57 copy-to *dest, 7
58 }
59
60 fn screen-size screen: (addr screen) -> nrows/eax: int, ncols/ecx: int {
61 $screen-size:body: {
62 compare screen, 0
63 {
64 break-if-!=
65 nrows, ncols <- real-screen-size
66 break $screen-size:body
67 }
68 {
69 break-if-=
70
71 var screen-addr/esi: (addr screen) <- copy screen
72 var tmp/edx: (addr int) <- get screen-addr, num-rows
73 nrows <- copy *tmp
74 tmp <- get screen-addr, num-cols
75 ncols <- copy *tmp
76 }
77 }
78 }
79
80 fn clear-screen screen: (addr screen) {
81 $clear-screen:body: {
82 compare screen, 0
83 {
84 break-if-!=
85 clear-real-screen
86 break $clear-screen:body
87 }
88 {
89 break-if-=
90
91 var space/edi: grapheme <- copy 0x20
92 move-cursor screen, 1, 1
93 var screen-addr/esi: (addr screen) <- copy screen
94 var i/eax: int <- copy 1
95 var nrows/ecx: (addr int) <- get screen-addr, num-rows
96 {
97 compare i, *nrows
98 break-if->
99 var j/edx: int <- copy 1
100 var ncols/ebx: (addr int) <- get screen-addr, num-cols
101 {
102 compare j, *ncols
103 break-if->
104 print-grapheme screen, space
105 j <- increment
106 loop
107 }
108 i <- increment
109 loop
110 }
111 move-cursor screen, 1, 1
112 }
113 }
114 }
115
116 fn move-cursor screen: (addr screen), row: int, column: int {
117 $move-cursor:body: {
118 compare screen, 0
119 {
120 break-if-!=
121 move-cursor-on-real-screen row, column
122 break $move-cursor:body
123 }
124 {
125 break-if-=
126
127 var screen-addr/esi: (addr screen) <- copy screen
128
129 {
130 compare row, 0
131 break-if-< $move-cursor:body
132 }
133
134 {
135 compare row, 0
136 break-if-!=
137 copy-to row, 1
138 }
139
140 {
141 var nrows-addr/eax: (addr int) <- get screen-addr, num-rows
142 var nrows/eax: int <- copy *nrows-addr
143 compare row, nrows
144 break-if-<=
145 copy-to row, nrows
146 }
147
148 {
149 compare column, 0
150 break-if-< $move-cursor:body
151 }
152
153 {
154 compare column, 0
155 break-if-!=
156 copy-to column, 1
157 }
158
159 {
160 var ncols-addr/eax: (addr int) <- get screen-addr, num-cols
161 var ncols/eax: int <- copy *ncols-addr
162 compare column, ncols
163 break-if-<=
164 copy-to column, ncols
165 increment column
166 }
167
168 var dest/edi: (addr int) <- get screen-addr, cursor-row
169 var src/eax: int <- copy row
170 copy-to *dest, src
171
172 dest <- get screen-addr, cursor-col
173 src <- copy column
174 copy-to *dest, src
175 }
176 }
177 }
178
179 fn print-string screen: (addr screen), s: (addr array byte) {
180 $print-string:body: {
181 compare screen, 0
182 {
183 break-if-!=
184 print-string-to-real-screen s
185 break $print-string:body
186 }
187 {
188 break-if-=
189
190 var s2: (stream byte 0x100)
191 var s2-addr/esi: (addr stream byte) <- address s2
192 write s2-addr, s
193 var screen-addr/edi: (addr screen) <- copy screen
194 {
195 var done?/eax: boolean <- stream-empty? s2-addr
196 compare done?, 0
197 break-if-!=
198 var g/eax: grapheme <- read-grapheme s2-addr
199 print-grapheme screen, g
200 loop
201 }
202 }
203 }
204 }
205
206 fn print-grapheme screen: (addr screen), c: grapheme {
207 $print-grapheme:body: {
208 compare screen, 0
209 {
210 break-if-!=
211 print-grapheme-to-real-screen c
212 break $print-grapheme:body
213 }
214 {
215 break-if-=
216
217 var screen-addr/esi: (addr screen) <- copy screen
218 var cursor-col-addr/edx: (addr int) <- get screen-addr, cursor-col
219
220
221 {
222
223 var num-cols-addr/ecx: (addr int) <- get screen-addr, num-cols
224 var num-cols/ecx: int <- copy *num-cols-addr
225 compare *cursor-col-addr, num-cols
226 break-if-<=
227 copy-to *cursor-col-addr, 1
228 var cursor-row-addr/ebx: (addr int) <- get screen-addr, cursor-row
229 increment *cursor-row-addr
230
231 var num-rows-addr/eax: (addr int) <- get screen-addr, num-rows
232 var num-rows/eax: int <- copy *num-rows-addr
233 compare *cursor-row-addr, num-rows
234 break-if-<=
235 copy-to *cursor-row-addr, num-rows
236
237 $print-grapheme:perform-scroll: {
238 var top-index-addr/ebx: (addr int) <- get screen-addr, top-index
239 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
240 var data/eax: (addr array screen-cell) <- lookup *data-ah
241 var max-index/edi: int <- length data
242 compare *top-index-addr, max-index
243 {
244 break-if->=
245 add-to *top-index-addr, num-cols
246 break $print-grapheme:perform-scroll
247 }
248 {
249 break-if-<
250 copy-to *top-index-addr, 0
251 }
252 }
253 }
254 var idx/ecx: int <- current-screen-cell-index screen-addr
255
256
257
258 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
259 var data/eax: (addr array screen-cell) <- lookup *data-ah
260 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
261 var dest-cell/ecx: (addr screen-cell) <- index data, offset
262 var src-cell/eax: (addr screen-cell) <- get screen-addr, curr-attributes
263 copy-object src-cell, dest-cell
264 var dest/eax: (addr grapheme) <- get dest-cell, data
265 var c2/ecx: grapheme <- copy c
266
267
268 copy-to *dest, c2
269 increment *cursor-col-addr
270 }
271 }
272 }
273
274 fn current-screen-cell-index screen-on-stack: (addr screen) -> result/ecx: int {
275 var screen/esi: (addr screen) <- copy screen-on-stack
276 var cursor-row-addr/ecx: (addr int) <- get screen, cursor-row
277 var cursor-col-addr/eax: (addr int) <- get screen, cursor-col
278 result <- screen-cell-index screen, *cursor-row-addr, *cursor-col-addr
279 }
280
281 fn screen-cell-index screen-on-stack: (addr screen), row: int, col: int -> result/ecx: int {
282 var screen/esi: (addr screen) <- copy screen-on-stack
283 var num-cols-addr/eax: (addr int) <- get screen, num-cols
284 var num-cols/eax: int <- copy *num-cols-addr
285 result <- copy row
286 result <- subtract 1
287 result <- multiply num-cols
288 result <- add col
289 result <- subtract 1
290
291 var top-index-addr/eax: (addr int) <- get screen, top-index
292 result <- add *top-index-addr
293 var data-ah/eax: (addr handle array screen-cell) <- get screen, data
294 var data/eax: (addr array screen-cell) <- lookup *data-ah
295 var max-index/eax: int <- length data
296 compare result, max-index
297 {
298 break-if-<
299 result <- subtract max-index
300 }
301 }
302
303 fn screen-grapheme-at screen-on-stack: (addr screen), row: int, col: int -> result/eax: grapheme {
304 var screen-addr/esi: (addr screen) <- copy screen-on-stack
305 var idx/ecx: int <- screen-cell-index screen-addr, row, col
306 result <- screen-grapheme-at-idx screen-addr, idx
307 }
308
309 fn screen-grapheme-at-idx screen-on-stack: (addr screen), idx-on-stack: int -> result/eax: grapheme {
310 var screen-addr/esi: (addr screen) <- copy screen-on-stack
311 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
312 var data/eax: (addr array screen-cell) <- lookup *data-ah
313 var idx/ecx: int <- copy idx-on-stack
314 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
315 var cell/eax: (addr screen-cell) <- index data, offset
316 var src/eax: (addr grapheme) <- get cell, data
317 result <- copy *src
318 }
319
320 fn screen-color-at screen-on-stack: (addr screen), row: int, col: int -> result/eax: int {
321 var screen-addr/esi: (addr screen) <- copy screen-on-stack
322 var idx/ecx: int <- screen-cell-index screen-addr, row, col
323 result <- screen-color-at-idx screen-addr, idx
324 }
325
326 fn screen-color-at-idx screen-on-stack: (addr screen), idx-on-stack: int -> result/eax: int {
327 var screen-addr/esi: (addr screen) <- copy screen-on-stack
328 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
329 var data/eax: (addr array screen-cell) <- lookup *data-ah
330 var idx/ecx: int <- copy idx-on-stack
331 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
332 var cell/eax: (addr screen-cell) <- index data, offset
333 var src/eax: (addr int) <- get cell, color
334 result <- copy *src
335 }
336
337 fn screen-background-color-at screen-on-stack: (addr screen), row: int, col: int -> result/eax: int {
338 var screen-addr/esi: (addr screen) <- copy screen-on-stack
339 var idx/ecx: int <- screen-cell-index screen-addr, row, col
340 result <- screen-background-color-at-idx screen-addr, idx
341 }
342
343 fn screen-background-color-at-idx screen-on-stack: (addr screen), idx-on-stack: int -> result/eax: int {
344 var screen-addr/esi: (addr screen) <- copy screen-on-stack
345 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
346 var data/eax: (addr array screen-cell) <- lookup *data-ah
347 var idx/ecx: int <- copy idx-on-stack
348 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
349 var cell/eax: (addr screen-cell) <- index data, offset
350 var src/eax: (addr int) <- get cell, background-color
351 result <- copy *src
352 }
353
354 fn screen-bold-at? screen-on-stack: (addr screen), row: int, col: int -> result/eax: boolean {
355 var screen-addr/esi: (addr screen) <- copy screen-on-stack
356 var idx/ecx: int <- screen-cell-index screen-addr, row, col
357 result <- screen-bold-at-idx? screen-addr, idx
358 }
359
360 fn screen-bold-at-idx? screen-on-stack: (addr screen), idx-on-stack: int -> result/eax: boolean {
361 var screen-addr/esi: (addr screen) <- copy screen-on-stack
362 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
363 var data/eax: (addr array screen-cell) <- lookup *data-ah
364 var idx/ecx: int <- copy idx-on-stack
365 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
366 var cell/eax: (addr screen-cell) <- index data, offset
367 var src/eax: (addr boolean) <- get cell, bold?
368 result <- copy *src
369 }
370
371 fn screen-underline-at? screen-on-stack: (addr screen), row: int, col: int -> result/eax: boolean {
372 var screen-addr/esi: (addr screen) <- copy screen-on-stack
373 var idx/ecx: int <- screen-cell-index screen-addr, row, col
374 result <- screen-underline-at-idx? screen-addr, idx
375 }
376
377 fn screen-underline-at-idx? screen-on-stack: (addr screen), idx-on-stack: int -> result/eax: boolean {
378 var screen-addr/esi: (addr screen) <- copy screen-on-stack
379 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
380 var data/eax: (addr array screen-cell) <- lookup *data-ah
381 var idx/ecx: int <- copy idx-on-stack
382 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
383 var cell/eax: (addr screen-cell) <- index data, offset
384 var src/eax: (addr boolean) <- get cell, underline?
385 result <- copy *src
386 }
387
388 fn screen-reverse-at? screen-on-stack: (addr screen), row: int, col: int -> result/eax: boolean {
389 var screen-addr/esi: (addr screen) <- copy screen-on-stack
390 var idx/ecx: int <- screen-cell-index screen-addr, row, col
391 result <- screen-reverse-at-idx? screen-addr, idx
392 }
393
394 fn screen-reverse-at-idx? screen-on-stack: (addr screen), idx-on-stack: int -> result/eax: boolean {
395 var screen-addr/esi: (addr screen) <- copy screen-on-stack
396 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
397 var data/eax: (addr array screen-cell) <- lookup *data-ah
398 var idx/ecx: int <- copy idx-on-stack
399 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
400 var cell/eax: (addr screen-cell) <- index data, offset
401 var src/eax: (addr boolean) <- get cell, reverse?
402 result <- copy *src
403 }
404
405 fn screen-blink-at? screen-on-stack: (addr screen), row: int, col: int -> result/eax: boolean {
406 var screen-addr/esi: (addr screen) <- copy screen-on-stack
407 var idx/ecx: int <- screen-cell-index screen-addr, row, col
408 result <- screen-blink-at-idx? screen-addr, idx
409 }
410
411 fn screen-blink-at-idx? screen-on-stack: (addr screen), idx-on-stack: int -> result/eax: boolean {
412 var screen-addr/esi: (addr screen) <- copy screen-on-stack
413 var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
414 var data/eax: (addr array screen-cell) <- lookup *data-ah
415 var idx/ecx: int <- copy idx-on-stack
416 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
417 var cell/eax: (addr screen-cell) <- index data, offset
418 var src/eax: (addr boolean) <- get cell, blink?
419 result <- copy *src
420 }
421
422 fn print-code-point screen: (addr screen), c: code-point {
423 var g/eax: grapheme <- to-grapheme c
424 print-grapheme screen, g
425 }
426
427 fn print-int32-hex screen: (addr screen), n: int {
428 $print-int32-hex:body: {
429 compare screen, 0
430 {
431 break-if-!=
432 print-int32-hex-to-real-screen n
433 break $print-int32-hex:body
434 }
435 {
436 break-if-=
437
438 }
439 }
440 }
441
442 fn reset-formatting screen: (addr screen) {
443 $reset-formatting:body: {
444 compare screen, 0
445 {
446 break-if-!=
447 reset-formatting-on-real-screen
448 break $reset-formatting:body
449 }
450 {
451 break-if-=
452
453 var screen-addr/esi: (addr screen) <- copy screen
454 var dest/ecx: (addr screen-cell) <- get screen-addr, curr-attributes
455 var default-cell: screen-cell
456 var bg/eax: (addr int) <- get default-cell, background-color
457 copy-to *bg, 7
458 var default-cell-addr/eax: (addr screen-cell) <- address default-cell
459 copy-object default-cell-addr, dest
460 }
461 }
462 }
463
464 fn start-color screen: (addr screen), fg: int, bg: int {
465 $start-color:body: {
466 compare screen, 0
467 {
468 break-if-!=
469 start-color-on-real-screen fg, bg
470 break $start-color:body
471 }
472 {
473 break-if-=
474
475 var screen-addr/esi: (addr screen) <- copy screen
476 var attr/ecx: (addr screen-cell) <- get screen-addr, curr-attributes
477 var dest/edx: (addr int) <- get attr, color
478 var src/eax: int <- copy fg
479 copy-to *dest, src
480 var dest/edx: (addr int) <- get attr, background-color
481 var src/eax: int <- copy bg
482 copy-to *dest, src
483 }
484 }
485 }
486
487 fn start-bold screen: (addr screen) {
488 $start-bold:body: {
489 compare screen, 0
490 {
491 break-if-!=
492 start-bold-on-real-screen
493 break $start-bold:body
494 }
495 {
496 break-if-=
497
498 var screen-addr/esi: (addr screen) <- copy screen
499 var attr/ecx: (addr screen-cell) <- get screen-addr, curr-attributes
500 var dest/edx: (addr boolean) <- get attr, bold?
501 copy-to *dest, 1
502 }
503 }
504 }
505
506 fn start-underline screen: (addr screen) {
507 $start-underline:body: {
508 compare screen, 0
509 {
510 break-if-!=
511 start-underline-on-real-screen
512 break $start-underline:body
513 }
514 {
515 break-if-=
516
517 var screen-addr/esi: (addr screen) <- copy screen
518 var attr/ecx: (addr screen-cell) <- get screen-addr, curr-attributes
519 var dest/edx: (addr boolean) <- get attr, underline?
520 copy-to *dest, 1
521 }
522 }
523 }
524
525 fn start-reverse-video screen: (addr screen) {
526 $start-reverse-video:body: {
527 compare screen, 0
528 {
529 break-if-!=
530 start-reverse-video-on-real-screen
531 break $start-reverse-video:body
532 }
533 {
534 break-if-=
535
536 var screen-addr/esi: (addr screen) <- copy screen
537 var attr/ecx: (addr screen-cell) <- get screen-addr, curr-attributes
538 var dest/edx: (addr boolean) <- get attr, reverse?
539 copy-to *dest, 1
540 }
541 }
542 }
543
544 fn start-blinking screen: (addr screen) {
545 $start-blinking:body: {
546 compare screen, 0
547 {
548 break-if-!=
549 start-blinking-on-real-screen
550 break $start-blinking:body
551 }
552 {
553 break-if-=
554
555 var screen-addr/esi: (addr screen) <- copy screen
556 var attr/ecx: (addr screen-cell) <- get screen-addr, curr-attributes
557 var dest/edx: (addr boolean) <- get attr, blink?
558 copy-to *dest, 1
559 }
560 }
561 }
562
563 fn hide-cursor screen: (addr screen) {
564 $hide-cursor:body: {
565 compare screen, 0
566 {
567 break-if-!=
568 hide-cursor-on-real-screen
569 break $hide-cursor:body
570 }
571 {
572 break-if-=
573
574 var screen-addr/esi: (addr screen) <- copy screen
575 var hide?/ecx: (addr boolean) <- get screen-addr, cursor-hide?
576 copy-to *hide?, 1
577 }
578 }
579 }
580
581 fn show-cursor screen: (addr screen) {
582 $show-cursor:body: {
583 compare screen, 0
584 {
585 break-if-!=
586 show-cursor-on-real-screen
587 break $show-cursor:body
588 }
589 {
590 break-if-=
591
592 var screen-addr/esi: (addr screen) <- copy screen
593 var hide?/ecx: (addr boolean) <- get screen-addr, cursor-hide?
594 copy-to *hide?, 0
595 }
596 }
597 }
598
599
600
601
602
603 fn check-screen-row screen: (addr screen), row-idx: int, expected: (addr array byte), msg: (addr array byte) {
604 check-screen-row-from screen, row-idx, 1, expected, msg
605 }
606
607 fn check-screen-row-from screen-on-stack: (addr screen), row-idx: int, col-idx: int, expected: (addr array byte), msg: (addr array byte) {
608 var screen/esi: (addr screen) <- copy screen-on-stack
609 var idx/ecx: int <- screen-cell-index screen, row-idx, col-idx
610
611 var e: (stream byte 0x100)
612 var e-addr/edx: (addr stream byte) <- address e
613 write e-addr, expected
614 {
615 var done?/eax: boolean <- stream-empty? e-addr
616 compare done?, 0
617 break-if-!=
618 var g/eax: grapheme <- screen-grapheme-at-idx screen, idx
619 var g2/ebx: int <- copy g
620 var expected-grapheme/eax: grapheme <- read-grapheme e-addr
621 var expected-grapheme2/eax: int <- copy expected-grapheme
622
623 $check-screen-row-from:compare-graphemes: {
624
625 {
626 compare expected-grapheme2, 0x20
627 break-if-!=
628 compare g2, 0
629 break-if-= $check-screen-row-from:compare-graphemes
630 }
631 check-ints-equal g2, expected-grapheme2, msg
632 }
633 idx <- increment
634 loop
635 }
636 }
637
638
639
640 fn check-screen-row-in-color screen: (addr screen), fg: int, row-idx: int, expected: (addr array byte), msg: (addr array byte) {
641 check-screen-row-in-color-from screen, fg, row-idx, 1, expected, msg
642 }
643
644 fn check-screen-row-in-color-from screen-on-stack: (addr screen), fg: int, row-idx: int, col-idx: int, expected: (addr array byte), msg: (addr array byte) {
645 var screen/esi: (addr screen) <- copy screen-on-stack
646 var idx/ecx: int <- screen-cell-index screen, row-idx, col-idx
647
648 var e: (stream byte 0x100)
649 var e-addr/edx: (addr stream byte) <- address e
650 write e-addr, expected
651 {
652 var done?/eax: boolean <- stream-empty? e-addr
653 compare done?, 0
654 break-if-!=
655 var g/eax: grapheme <- screen-grapheme-at-idx screen, idx
656 var g2/ebx: int <- copy g
657 var expected-grapheme/eax: grapheme <- read-grapheme e-addr
658 var expected-grapheme2/edx: int <- copy expected-grapheme
659
660 $check-screen-row-in-color-from:compare-graphemes: {
661
662 {
663 compare expected-grapheme2, 0x20
664 break-if-!=
665 compare g2, 0
666 break-if-= $check-screen-row-in-color-from:compare-graphemes
667 }
668
669 {
670 compare expected-grapheme2, 0x20
671 break-if-!=
672 var color/eax: int <- screen-color-at-idx screen, idx
673 compare color, fg
674 break-if-!= $check-screen-row-in-color-from:compare-graphemes
675 }
676 check-ints-equal g2, expected-grapheme2, msg
677 var color/eax: int <- screen-color-at-idx screen, idx
678 check-ints-equal color, fg, msg
679 }
680 idx <- increment
681 loop
682 }
683 }
684
685
686
687 fn check-screen-row-in-background-color screen: (addr screen), bg: int, row-idx: int, expected: (addr array byte), msg: (addr array byte) {
688 check-screen-row-in-background-color-from screen, bg, row-idx, 1, expected, msg
689 }
690
691 fn check-screen-row-in-background-color-from screen-on-stack: (addr screen), bg: int, row-idx: int, col-idx: int, expected: (addr array byte), msg: (addr array byte) {
692 var screen/esi: (addr screen) <- copy screen-on-stack
693 var idx/ecx: int <- screen-cell-index screen, row-idx, col-idx
694
695 var e: (stream byte 0x100)
696 var e-addr/edx: (addr stream byte) <- address e
697 write e-addr, expected
698 {
699 var done?/eax: boolean <- stream-empty? e-addr
700 compare done?, 0
701 break-if-!=
702 var g/eax: grapheme <- screen-grapheme-at-idx screen, idx
703 var g2/ebx: int <- copy g
704 var expected-grapheme/eax: grapheme <- read-grapheme e-addr
705 var expected-grapheme2/edx: int <- copy expected-grapheme
706
707 $check-screen-row-in-background-color-from:compare-graphemes: {
708
709 {
710 compare expected-grapheme2, 0x20
711 break-if-!=
712 compare g2, 0
713 break-if-= $check-screen-row-in-background-color-from:compare-graphemes
714 }
715
716 {
717 compare expected-grapheme2, 0x20
718 break-if-!=
719 var color/eax: int <- screen-background-color-at-idx screen, idx
720 compare color, bg
721 break-if-!= $check-screen-row-in-background-color-from:compare-graphemes
722 }
723 check-ints-equal g2, expected-grapheme2, msg
724 var color/eax: int <- screen-background-color-at-idx screen, idx
725 check-ints-equal color, bg, msg
726 }
727 idx <- increment
728 loop
729 }
730 }
731
732 fn check-screen-row-in-bold screen: (addr screen), row-idx: int, expected: (addr array byte), msg: (addr array byte) {
733 check-screen-row-in-bold-from screen, row-idx, 1, expected, msg
734 }
735
736 fn check-screen-row-in-bold-from screen-on-stack: (addr screen), row-idx: int, col-idx: int, expected: (addr array byte), msg: (addr array byte) {
737 var screen/esi: (addr screen) <- copy screen-on-stack
738 var idx/ecx: int <- screen-cell-index screen, row-idx, col-idx
739
740 var e: (stream byte 0x100)
741 var e-addr/edx: (addr stream byte) <- address e
742 write e-addr, expected
743 {
744 var done?/eax: boolean <- stream-empty? e-addr
745 compare done?, 0
746 break-if-!=
747 var g/eax: grapheme <- screen-grapheme-at-idx screen, idx
748 var g2/ebx: int <- copy g
749 var expected-grapheme/eax: grapheme <- read-grapheme e-addr
750 var expected-grapheme2/edx: int <- copy expected-grapheme
751
752 $check-screen-row-in-bold-from:compare-graphemes: {
753
754 {
755 compare expected-grapheme2, 0x20
756 break-if-!=
757 compare g2, 0
758 break-if-= $check-screen-row-in-bold-from:compare-graphemes
759 }
760
761 {
762 compare expected-grapheme2, 0x20
763 break-if-!=
764 var bold?/eax: boolean <- screen-bold-at-idx? screen, idx
765 compare bold?, 1
766 break-if-!= $check-screen-row-in-bold-from:compare-graphemes
767 }
768 check-ints-equal g2, expected-grapheme2, msg
769 var bold?/eax: boolean <- screen-bold-at-idx? screen, idx
770 var bold/eax: int <- copy bold?
771 check-ints-equal bold, 1, msg
772 }
773 idx <- increment
774 loop
775 }
776 }
777
778 fn check-screen-row-in-underline screen: (addr screen), row-idx: int, expected: (addr array byte), msg: (addr array byte) {
779 check-screen-row-in-underline-from screen, row-idx, 1, expected, msg
780 }
781
782 fn check-screen-row-in-underline-from screen-on-stack: (addr screen), row-idx: int, col-idx: int, expected: (addr array byte), msg: (addr array byte) {
783 var screen/esi: (addr screen) <- copy screen-on-stack
784 var idx/ecx: int <- screen-cell-index screen, row-idx, col-idx
785
786 var e: (stream byte 0x100)
787 var e-addr/edx: (addr stream byte) <- address e
788 write e-addr, expected
789 {
790 var done?/eax: boolean <- stream-empty? e-addr
791 compare done?, 0
792 break-if-!=
793 var g/eax: grapheme <- screen-grapheme-at-idx screen, idx
794 var g2/ebx: int <- copy g
795 var expected-grapheme/eax: grapheme <- read-grapheme e-addr
796 var expected-grapheme2/edx: int <- copy expected-grapheme
797
798 $check-screen-row-in-underline-from:compare-graphemes: {
799
800 {
801 compare expected-grapheme2, 0x20
802 break-if-!=
803 compare g2, 0
804 break-if-= $check-screen-row-in-underline-from:compare-graphemes
805 }
806
807 {
808 compare expected-grapheme2, 0x20
809 break-if-!=
810 var underline?/eax: boolean <- screen-underline-at-idx? screen, idx
811 compare underline?, 1
812 break-if-!= $check-screen-row-in-underline-from:compare-graphemes
813 }
814 check-ints-equal g2, expected-grapheme2, msg
815 var underline?/eax: boolean <- screen-underline-at-idx? screen, idx
816 var underline/eax: int <- copy underline?
817 check-ints-equal underline, 1, msg
818 }
819 idx <- increment
820 loop
821 }
822 }
823
824 fn check-screen-row-in-reverse screen: (addr screen), row-idx: int, expected: (addr array byte), msg: (addr array byte) {
825 check-screen-row-in-reverse-from screen, row-idx, 1, expected, msg
826 }
827
828 fn check-screen-row-in-reverse-from screen-on-stack: (addr screen), row-idx: int, col-idx: int, expected: (addr array byte), msg: (addr array byte) {
829 var screen/esi: (addr screen) <- copy screen-on-stack
830 var idx/ecx: int <- screen-cell-index screen, row-idx, col-idx
831
832 var e: (stream byte 0x100)
833 var e-addr/edx: (addr stream byte) <- address e
834 write e-addr, expected
835 {
836 var done?/eax: boolean <- stream-empty? e-addr
837 compare done?, 0
838 break-if-!=
839 var g/eax: grapheme <- screen-grapheme-at-idx screen, idx
840 var g2/ebx: int <- copy g
841 var expected-grapheme/eax: grapheme <- read-grapheme e-addr
842 var expected-grapheme2/edx: int <- copy expected-grapheme
843
844 $check-screen-row-in-reverse-from:compare-graphemes: {
845
846 {
847 compare expected-grapheme2, 0x20
848 break-if-!=
849 compare g2, 0
850 break-if-= $check-screen-row-in-reverse-from:compare-graphemes
851 }
852
853 {
854 compare expected-grapheme2, 0x20
855 break-if-!=
856 var reverse?/eax: boolean <- screen-reverse-at-idx? screen, idx
857 compare reverse?, 1
858 break-if-!= $check-screen-row-in-reverse-from:compare-graphemes
859 }
860 check-ints-equal g2, expected-grapheme2, msg
861 var reverse?/eax: boolean <- screen-reverse-at-idx? screen, idx
862 var reverse/eax: int <- copy reverse?
863 check-ints-equal reverse, 1, msg
864 }
865 idx <- increment
866 loop
867 }
868 }
869
870 fn check-screen-row-in-blinking screen: (addr screen), row-idx: int, expected: (addr array byte), msg: (addr array byte) {
871 check-screen-row-in-blinking-from screen, row-idx, 1, expected, msg
872 }
873
874 fn check-screen-row-in-blinking-from screen-on-stack: (addr screen), row-idx: int, col-idx: int, expected: (addr array byte), msg: (addr array byte) {
875 var screen/esi: (addr screen) <- copy screen-on-stack
876 var idx/ecx: int <- screen-cell-index screen, row-idx, col-idx
877
878 var e: (stream byte 0x100)
879 var e-addr/edx: (addr stream byte) <- address e
880 write e-addr, expected
881 {
882 var done?/eax: boolean <- stream-empty? e-addr
883 compare done?, 0
884 break-if-!=
885 var g/eax: grapheme <- screen-grapheme-at-idx screen, idx
886 var g2/ebx: int <- copy g
887 var expected-grapheme/eax: grapheme <- read-grapheme e-addr
888 var expected-grapheme2/edx: int <- copy expected-grapheme
889
890 $check-screen-row-in-blinking-from:compare-graphemes: {
891
892 {
893 compare expected-grapheme2, 0x20
894 break-if-!=
895 compare g2, 0
896 break-if-= $check-screen-row-in-blinking-from:compare-graphemes
897 }
898
899 {
900 compare expected-grapheme2, 0x20
901 break-if-!=
902 var blinking?/eax: boolean <- screen-blink-at-idx? screen, idx
903 compare blinking?, 1
904 break-if-!= $check-screen-row-in-blinking-from:compare-graphemes
905 }
906 check-ints-equal g2, expected-grapheme2, msg
907 var blinking?/eax: boolean <- screen-blink-at-idx? screen, idx
908 var blinking/eax: int <- copy blinking?
909 check-ints-equal blinking, 1, msg
910 }
911 idx <- increment
912 loop
913 }
914 }
915
916 fn test-print-single-grapheme {
917 var screen-on-stack: screen
918 var screen/esi: (addr screen) <- address screen-on-stack
919 initialize-screen screen, 5, 4
920 var c/eax: grapheme <- copy 0x61
921 print-grapheme screen, c
922 check-screen-row screen, 1, "a", "F - test-print-single-grapheme"
923 }
924
925 fn test-print-multiple-graphemes {
926 var screen-on-stack: screen
927 var screen/esi: (addr screen) <- address screen-on-stack
928 initialize-screen screen, 5, 4
929 print-string screen, "Hello, 世界"
930 check-screen-row screen, 1, "Hello, 世界", "F - test-print-multiple-graphemes"
931 }
932
933 fn test-move-cursor {
934 var screen-on-stack: screen
935 var screen/esi: (addr screen) <- address screen-on-stack
936 initialize-screen screen, 5, 4
937 move-cursor screen, 1, 4
938 var c/eax: grapheme <- copy 0x61
939 print-grapheme screen, c
940 check-screen-row screen, 1, " a", "F - test-move-cursor"
941 }
942
943 fn test-move-cursor-zeroes {
944 var screen-on-stack: screen
945 var screen/esi: (addr screen) <- address screen-on-stack
946 initialize-screen screen, 5, 4
947 move-cursor screen, 0, 0
948 var c/eax: grapheme <- copy 0x61
949 print-grapheme screen, c
950 check-screen-row screen, 1, "a", "F - test-move-cursor-zeroes"
951 }
952
953 fn test-move-cursor-zero-row {
954 var screen-on-stack: screen
955 var screen/esi: (addr screen) <- address screen-on-stack
956 initialize-screen screen, 5, 4
957 move-cursor screen, 0, 2
958 var c/eax: grapheme <- copy 0x61
959 print-grapheme screen, c
960 check-screen-row screen, 1, " a", "F - test-move-cursor-zero-row"
961 }
962
963 fn test-move-cursor-zero-column {
964 var screen-on-stack: screen
965 var screen/esi: (addr screen) <- address screen-on-stack
966 initialize-screen screen, 5, 4
967 move-cursor screen, 4, 0
968 var c/eax: grapheme <- copy 0x61
969 print-grapheme screen, c
970 check-screen-row screen, 4, "a", "F - test-move-cursor-zero-column"
971 }
972
973 fn test-move-cursor-negative-row {
974 var screen-on-stack: screen
975 var screen/esi: (addr screen) <- address screen-on-stack
976 initialize-screen screen, 5, 3
977 move-cursor screen, -1, 2
978 var c/eax: grapheme <- copy 0x61
979 print-grapheme screen, c
980
981 check-screen-row screen, 1, "a", "F - test-move-cursor-negative-row"
982 }
983
984 fn test-move-cursor-negative-column {
985 var screen-on-stack: screen
986 var screen/esi: (addr screen) <- address screen-on-stack
987 initialize-screen screen, 5, 3
988 move-cursor screen, 2, -1
989 var c/eax: grapheme <- copy 0x61
990 print-grapheme screen, c
991
992 check-screen-row screen, 1, "a", "F - test-move-cursor-negative-column"
993 }
994
995 fn test-move-cursor-column-too-large {
996 var screen-on-stack: screen
997 var screen/esi: (addr screen) <- address screen-on-stack
998 initialize-screen screen, 5, 3
999 move-cursor screen, 1, 4
1000 var c/eax: grapheme <- copy 0x61
1001 print-grapheme screen, c
1002
1003 check-screen-row screen, 1, " ", "F - test-move-cursor-column-too-large"
1004
1005 check-screen-row screen, 2, "a", "F - test-move-cursor-column-too-large"
1006 }
1007
1008 fn test-move-cursor-column-too-large-saturates {
1009 var screen-on-stack: screen
1010 var screen/esi: (addr screen) <- address screen-on-stack
1011 initialize-screen screen, 5, 3
1012 move-cursor screen, 1, 6
1013 var c/eax: grapheme <- copy 0x61
1014 print-grapheme screen, c
1015
1016 check-screen-row screen, 1, " ", "F - test-move-cursor-column-too-large-saturates"
1017
1018 check-screen-row screen, 2, "a", "F - test-move-cursor-column-too-large-saturates"
1019 }
1020
1021 fn test-move-cursor-row-too-large {
1022 var screen-on-stack: screen
1023 var screen/esi: (addr screen) <- address screen-on-stack
1024 initialize-screen screen, 5, 3
1025 move-cursor screen, 6, 2
1026 var c/eax: grapheme <- copy 0x61
1027 print-grapheme screen, c
1028
1029 check-screen-row screen, 5, " a", "F - test-move-cursor-row-too-large"
1030 }
1031
1032 fn test-move-cursor-row-too-large-saturates {
1033 var screen-on-stack: screen
1034 var screen/esi: (addr screen) <- address screen-on-stack
1035 initialize-screen screen, 5, 3
1036 move-cursor screen, 9, 2
1037 var c/eax: grapheme <- copy 0x61
1038 print-grapheme screen, c
1039
1040 check-screen-row screen, 5, " a", "F - test-move-cursor-row-too-large-saturates"
1041 }
1042
1043 fn test-check-screen-row-from {
1044 var screen-on-stack: screen
1045 var screen/esi: (addr screen) <- address screen-on-stack
1046 initialize-screen screen, 5, 4
1047 move-cursor screen, 1, 4
1048 var c/eax: grapheme <- copy 0x61
1049 print-grapheme screen, c
1050 check-screen-row screen, 1, " a", "F - test-check-screen-row-from/baseline"
1051 check-screen-row-from screen, 1, 4, "a", "F - test-check-screen-row-from"
1052 }
1053
1054 fn test-print-string-overflows-to-next-row {
1055 var screen-on-stack: screen
1056 var screen/esi: (addr screen) <- address screen-on-stack
1057 initialize-screen screen, 5, 4
1058 print-string screen, "abcdefg"
1059 check-screen-row screen, 1, "abcd", "F - test-print-string-overflows-to-next-row"
1060 check-screen-row screen, 2, "efg", "F - test-print-string-overflows-to-next-row"
1061 }
1062
1063 fn test-check-screen-scrolls-on-overflow {
1064 var screen-on-stack: screen
1065 var screen/esi: (addr screen) <- address screen-on-stack
1066 initialize-screen screen, 5, 4
1067
1068 move-cursor screen, 5, 4
1069 var c/eax: grapheme <- copy 0x61
1070 print-grapheme screen, c
1071 check-screen-row-from screen, 5, 4, "a", "F - test-check-screen-scrolls-on-overflow/baseline"
1072
1073 move-cursor screen, 5, 4
1074 print-string screen, "ab"
1075
1076
1077
1078
1079
1080
1081 check-screen-row-from screen, 4, 4, "a", "F - test-check-screen-scrolls-on-overflow/1"
1082 check-screen-row-from screen, 5, 1, "b", "F - test-check-screen-scrolls-on-overflow/2"
1083 }
1084
1085 fn test-check-screen-color {
1086 var screen-on-stack: screen
1087 var screen/esi: (addr screen) <- address screen-on-stack
1088 initialize-screen screen, 5, 4
1089 var c/eax: grapheme <- copy 0x61
1090 print-grapheme screen, c
1091 start-color screen, 1, 0
1092 c <- copy 0x62
1093 print-grapheme screen, c
1094 start-color screen, 0, 0
1095 c <- copy 0x63
1096 print-grapheme screen, c
1097 check-screen-row-in-color screen, 0, 1, "a c", "F - test-check-screen-color"
1098 }
1099
1100 fn test-check-screen-background-color {
1101 var screen-on-stack: screen
1102 var screen/esi: (addr screen) <- address screen-on-stack
1103 initialize-screen screen, 5, 4
1104 var c/eax: grapheme <- copy 0x61
1105 print-grapheme screen, c
1106 start-color screen, 0, 1
1107 c <- copy 0x62
1108 print-grapheme screen, c
1109 start-color screen, 0, 7
1110 c <- copy 0x63
1111 print-grapheme screen, c
1112 check-screen-row-in-background-color screen, 7, 1, "a c", "F - test-check-screen-background-color"
1113 }
1114
1115 fn test-check-screen-bold {
1116 var screen-on-stack: screen
1117 var screen/esi: (addr screen) <- address screen-on-stack
1118 initialize-screen screen, 5, 4
1119 start-bold screen
1120 var c/eax: grapheme <- copy 0x61
1121 print-grapheme screen, c
1122 reset-formatting screen
1123 c <- copy 0x62
1124 print-grapheme screen, c
1125 start-bold screen
1126 c <- copy 0x63
1127 print-grapheme screen, c
1128 check-screen-row-in-bold screen, 1, "a c", "F - test-check-screen-bold"
1129 }
1130
1131 fn test-check-screen-underline {
1132 var screen-on-stack: screen
1133 var screen/esi: (addr screen) <- address screen-on-stack
1134 initialize-screen screen, 5, 4
1135 start-underline screen
1136 var c/eax: grapheme <- copy 0x61
1137 print-grapheme screen, c
1138 reset-formatting screen
1139 c <- copy 0x62
1140 print-grapheme screen, c
1141 start-underline screen
1142 c <- copy 0x63
1143 print-grapheme screen, c
1144 check-screen-row-in-underline screen, 1, "a c", "F - test-check-screen-underline"
1145 }
1146
1147 fn test-check-screen-reverse {
1148 var screen-on-stack: screen
1149 var screen/esi: (addr screen) <- address screen-on-stack
1150 initialize-screen screen, 5, 4
1151 start-reverse-video screen
1152 var c/eax: grapheme <- copy 0x61
1153 print-grapheme screen, c
1154 reset-formatting screen
1155 c <- copy 0x62
1156 print-grapheme screen, c
1157 start-reverse-video screen
1158 c <- copy 0x63
1159 print-grapheme screen, c
1160 check-screen-row-in-reverse screen, 1, "a c", "F - test-check-screen-reverse"
1161 }
1162
1163 fn test-check-screen-blinking {
1164 var screen-on-stack: screen
1165 var screen/esi: (addr screen) <- address screen-on-stack
1166 initialize-screen screen, 5, 4
1167 start-blinking screen
1168 var c/eax: grapheme <- copy 0x61
1169 print-grapheme screen, c
1170 reset-formatting screen
1171 c <- copy 0x62
1172 print-grapheme screen, c
1173 start-blinking screen
1174 c <- copy 0x63
1175 print-grapheme screen, c
1176 check-screen-row-in-blinking screen, 1, "a c", "F - test-check-screen-blinking"
1177 }
1178
1179
1180
1181
1182
1183