6742 - support for formatting in fake screens
We still need a few primitives, but we can implement these as needed. I'm ready to call the fake screen done.
This commit is contained in:
parent
9f293fef05
commit
5462619d96
|
@ -879,7 +879,7 @@ zero-out: # start: (addr byte), size: int
|
|||
# curr/esi = start
|
||||
# i/ecx = 0
|
||||
# while true
|
||||
# if (i >= len) break
|
||||
# if (i >= size) break
|
||||
# *curr = 0
|
||||
# ++curr
|
||||
# ++i
|
||||
|
@ -896,10 +896,10 @@ zero-out: # start: (addr byte), size: int
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# var i/ecx: int = 0
|
||||
31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx
|
||||
# edx = len
|
||||
# edx = size
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
|
||||
$zero-out:loop:
|
||||
# if (i >= len) break
|
||||
# if (i >= size) break
|
||||
39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx
|
||||
7d/jump-if->= $zero-out:end/disp8
|
||||
# *curr = 0
|
||||
|
@ -929,7 +929,7 @@ test-zero-out:
|
|||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# zero-out(ecx, 3)
|
||||
# . . push args
|
||||
68/push 3/imm32/len
|
||||
68/push 3/imm32/size
|
||||
51/push-ecx
|
||||
# . . call
|
||||
e8/call zero-out/disp32
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# 2-arg version of allocate-array.
|
||||
|
||||
== code
|
||||
|
||||
allocate-array2: # ad: (addr allocation-descriptor), array-len: int, elem-size: int, out: (addr handle array _)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# Some unsafe methods not intended to be used directly in SubX, only through
|
||||
# Mu after proper type-checking.
|
||||
|
||||
== code
|
||||
|
||||
stream-empty?: # s: (addr stream _) -> result/eax: boolean
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
# Fill a region of memory with zeroes.
|
||||
|
||||
== code
|
||||
|
||||
copy-bytes: # src: (addr byte), dest: (addr byte), size: int
|
||||
# pseudocode:
|
||||
# curr-src/esi = src
|
||||
# curr-dest/edi = dest
|
||||
# i/ecx = 0
|
||||
# while true
|
||||
# if (i >= size) break
|
||||
# *curr-dest = *curr-src
|
||||
# ++curr-src
|
||||
# ++curr-dest
|
||||
# ++i
|
||||
#
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
# . save registers
|
||||
50/push-eax
|
||||
51/push-ecx
|
||||
52/push-edx
|
||||
56/push-esi
|
||||
57/push-edi
|
||||
# curr-src/esi = src
|
||||
8b/-> *(ebp+8) 6/r32/esi
|
||||
# curr-dest/edi = dest
|
||||
8b/-> *(ebp+0xc) 7/r32/edi
|
||||
# var i/ecx: int = 0
|
||||
b9/copy-to-ecx 0/imm32
|
||||
# edx = size
|
||||
8b/-> *(ebp+0x10) 2/r32/edx
|
||||
{
|
||||
# if (i >= size) break
|
||||
39/compare %ecx 2/r32/edx
|
||||
7d/jump-if->= break/disp8
|
||||
# *curr-dest = *curr-src
|
||||
8a/byte-> *esi 0/r32/AL
|
||||
88/byte<- *edi 0/r32/AL
|
||||
# update
|
||||
46/increment-esi
|
||||
47/increment-edi
|
||||
41/increment-ecx
|
||||
eb/jump loop/disp8
|
||||
}
|
||||
$copy-bytes:end:
|
||||
# . restore registers
|
||||
5f/pop-to-edi
|
||||
5e/pop-to-esi
|
||||
5a/pop-to-edx
|
||||
59/pop-to-ecx
|
||||
58/pop-to-eax
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
c3/return
|
2
400.mu
2
400.mu
|
@ -162,3 +162,5 @@ sig open filename: (addr array byte), write?: boolean, out: (addr handle buffere
|
|||
|
||||
sig stream-empty? s: (addr stream _) -> result/eax: boolean
|
||||
sig stream-full? s: (addr stream _) -> result/eax: boolean
|
||||
|
||||
sig copy-bytes src: (addr byte), dest: (addr byte), n: int
|
||||
|
|
118
405screen.mu
118
405screen.mu
|
@ -258,8 +258,10 @@ $print-grapheme:body: {
|
|||
var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
|
||||
var data/eax: (addr array screen-cell) <- lookup *data-ah
|
||||
var offset/ecx: (offset screen-cell) <- compute-offset data, idx
|
||||
var cell/eax: (addr screen-cell) <- index data, offset
|
||||
var dest/eax: (addr grapheme) <- get cell, data
|
||||
var dest-cell/ecx: (addr screen-cell) <- index data, offset
|
||||
var src-cell/eax: (addr screen-cell) <- get screen-addr, curr-attributes
|
||||
copy-object src-cell, dest-cell
|
||||
var dest/eax: (addr grapheme) <- get dest-cell, data
|
||||
var c2/ecx: grapheme <- copy c
|
||||
#? print-grapheme-to-real-screen c2
|
||||
#? print-string-to-real-screen "\n"
|
||||
|
@ -315,6 +317,23 @@ fn screen-grapheme-at-idx screen-on-stack: (addr screen), idx-on-stack: int -> r
|
|||
result <- copy *src
|
||||
}
|
||||
|
||||
fn screen-color-at screen-on-stack: (addr screen), row: int, col: int -> result/eax: int {
|
||||
var screen-addr/esi: (addr screen) <- copy screen-on-stack
|
||||
var idx/ecx: int <- screen-cell-index screen-addr, row, col
|
||||
result <- screen-color-at-idx screen-addr, idx
|
||||
}
|
||||
|
||||
fn screen-color-at-idx screen-on-stack: (addr screen), idx-on-stack: int -> result/eax: int {
|
||||
var screen-addr/esi: (addr screen) <- copy screen-on-stack
|
||||
var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
|
||||
var data/eax: (addr array screen-cell) <- lookup *data-ah
|
||||
var idx/ecx: int <- copy idx-on-stack
|
||||
var offset/ecx: (offset screen-cell) <- compute-offset data, idx
|
||||
var cell/eax: (addr screen-cell) <- index data, offset
|
||||
var src/eax: (addr int) <- get cell, color
|
||||
result <- copy *src
|
||||
}
|
||||
|
||||
fn print-code-point screen: (addr screen), c: code-point {
|
||||
var g/eax: grapheme <- to-grapheme c
|
||||
print-grapheme screen, g
|
||||
|
@ -346,6 +365,11 @@ $reset-formatting:body: {
|
|||
{
|
||||
break-if-=
|
||||
# fake screen
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var dest/ecx: (addr screen-cell) <- get screen-addr, curr-attributes
|
||||
var empty-cell: screen-cell
|
||||
var empty-cell-addr/eax: (addr screen-cell) <- address empty-cell
|
||||
copy-object empty-cell-addr, dest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -361,6 +385,14 @@ $start-color:body: {
|
|||
{
|
||||
break-if-=
|
||||
# fake screen
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var attr/ecx: (addr screen-cell) <- get screen-addr, curr-attributes
|
||||
var dest/edx: (addr int) <- get attr, color
|
||||
var src/eax: int <- copy fg
|
||||
copy-to *dest, src
|
||||
var dest/edx: (addr int) <- get attr, background-color
|
||||
var src/eax: int <- copy bg
|
||||
copy-to *dest, src
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,6 +408,10 @@ $start-bold:body: {
|
|||
{
|
||||
break-if-=
|
||||
# fake screen
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var attr/ecx: (addr screen-cell) <- get screen-addr, curr-attributes
|
||||
var dest/edx: (addr boolean) <- get attr, bold?
|
||||
copy-to *dest, 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -391,6 +427,10 @@ $start-underline:body: {
|
|||
{
|
||||
break-if-=
|
||||
# fake screen
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var attr/ecx: (addr screen-cell) <- get screen-addr, curr-attributes
|
||||
var dest/edx: (addr boolean) <- get attr, underline?
|
||||
copy-to *dest, 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -406,6 +446,10 @@ $start-reverse-video:body: {
|
|||
{
|
||||
break-if-=
|
||||
# fake screen
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var attr/ecx: (addr screen-cell) <- get screen-addr, curr-attributes
|
||||
var dest/edx: (addr boolean) <- get attr, reverse?
|
||||
copy-to *dest, 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -421,6 +465,10 @@ $start-blinking:body: {
|
|||
{
|
||||
break-if-=
|
||||
# fake screen
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var attr/ecx: (addr screen-cell) <- get screen-addr, curr-attributes
|
||||
var dest/edx: (addr boolean) <- get attr, blink?
|
||||
copy-to *dest, 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -436,6 +484,9 @@ $hide-cursor:body: {
|
|||
{
|
||||
break-if-=
|
||||
# fake screen
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var hide?/ecx: (addr boolean) <- get screen-addr, cursor-hide?
|
||||
copy-to *hide?, 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -451,6 +502,9 @@ $show-cursor:body: {
|
|||
{
|
||||
break-if-=
|
||||
# fake screen
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var hide?/ecx: (addr boolean) <- get screen-addr, cursor-hide?
|
||||
copy-to *hide?, 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -479,14 +533,13 @@ fn check-screen-row-from screen-on-stack: (addr screen), row-idx: int, col-idx:
|
|||
var expected-grapheme/eax: grapheme <- read-grapheme e-addr
|
||||
var expected-grapheme2/eax: int <- copy expected-grapheme
|
||||
# compare graphemes
|
||||
$check-screen-row:compare-graphemes: {
|
||||
$check-screen-row-from:compare-graphemes: {
|
||||
# if expected-grapheme is space, null grapheme is also ok
|
||||
{
|
||||
compare expected-grapheme2, 0x20
|
||||
break-if-!=
|
||||
compare g2, 0
|
||||
break-if-!=
|
||||
break $check-screen-row:compare-graphemes
|
||||
break-if-= $check-screen-row-from:compare-graphemes
|
||||
}
|
||||
check-ints-equal g2, expected-grapheme2, msg
|
||||
}
|
||||
|
@ -497,10 +550,47 @@ fn check-screen-row-from screen-on-stack: (addr screen), row-idx: int, col-idx:
|
|||
|
||||
# various variants by screen-cell attribute; spaces in the 'expected' data should not match the attribute
|
||||
|
||||
fn check-screen-row-in-color screen-on-stack: (addr screen), fg: color, row-idx: int, expected: (addr array byte), msg: (addr array byte) {
|
||||
fn check-screen-row-in-color screen: (addr screen), fg: color, row-idx: int, expected: (addr array byte), msg: (addr array byte) {
|
||||
check-screen-row-in-color-from screen, fg, row-idx, 1, expected, msg
|
||||
}
|
||||
|
||||
fn check-screen-row-in-color-from screen-on-stack: (addr screen), fg: color, row-idx: int, col-idx: int, expected: (addr array byte), msg: (addr array byte) {
|
||||
var screen/esi: (addr screen) <- copy screen-on-stack
|
||||
var idx/ecx: int <- screen-cell-index screen, row-idx, col-idx
|
||||
# compare 'expected' with the screen contents starting at 'idx', grapheme by grapheme
|
||||
var e: (stream byte 0x100)
|
||||
var e-addr/edx: (addr stream byte) <- address e
|
||||
write e-addr, expected
|
||||
{
|
||||
var done?/eax: boolean <- stream-empty? e-addr
|
||||
compare done?, 0
|
||||
break-if-!=
|
||||
var g/eax: grapheme <- screen-grapheme-at-idx screen, idx
|
||||
var g2/ebx: int <- copy g
|
||||
var expected-grapheme/eax: grapheme <- read-grapheme e-addr
|
||||
var expected-grapheme2/edx: int <- copy expected-grapheme
|
||||
# compare graphemes
|
||||
$check-screen-row-in-color-from:compare-graphemes: {
|
||||
# if expected-grapheme is space, null grapheme is also ok
|
||||
{
|
||||
compare expected-grapheme2, 0x20
|
||||
break-if-!=
|
||||
compare g2, 0
|
||||
break-if-= $check-screen-row-in-color-from:compare-graphemes
|
||||
}
|
||||
# if expected-grapheme is space, a different color is ok
|
||||
{
|
||||
compare expected-grapheme2, 0x20
|
||||
break-if-!=
|
||||
var color/eax: int <- screen-color-at-idx screen, idx
|
||||
compare color, fg
|
||||
break-if-!= $check-screen-row-in-color-from:compare-graphemes
|
||||
}
|
||||
check-ints-equal g2, expected-grapheme2, msg
|
||||
}
|
||||
idx <- increment
|
||||
loop
|
||||
}
|
||||
}
|
||||
|
||||
# background color is visible even for spaces, so 'expected' behaves as an array of booleans.
|
||||
|
@ -704,7 +794,23 @@ fn test-check-screen-scrolls-on-overflow {
|
|||
check-screen-row-from screen, 5, 1, "b", "F - test-check-screen-scrolls-on-overflow/2"
|
||||
}
|
||||
|
||||
fn test-check-screen-color {
|
||||
var screen-on-stack: screen
|
||||
var screen/esi: (addr screen) <- address screen-on-stack
|
||||
initialize-screen screen, 5, 4
|
||||
var c/eax: grapheme <- copy 0x61 # 'a'
|
||||
print-grapheme screen, c
|
||||
start-color screen, 1, 0 # foreground=1
|
||||
c <- copy 0x62 # 'b'
|
||||
print-grapheme screen, c
|
||||
start-color screen, 0, 0 # back to default
|
||||
c <- copy 0x63 # 'c'
|
||||
print-grapheme screen, c
|
||||
check-screen-row-in-color screen, 0, 1, "a c", "F - test-check-screen-color"
|
||||
}
|
||||
|
||||
#? fn main -> exit-status/ebx: int {
|
||||
#? #? test-check-screen-color
|
||||
#? run-tests
|
||||
#? exit-status <- copy 0
|
||||
#? }
|
||||
|
|
61
apps/mu.subx
61
apps/mu.subx
|
@ -12695,6 +12695,10 @@ has-primitive-name?: # stmt: (addr stmt) -> result/eax: boolean
|
|||
(string-equal? %esi "compute-offset") # => eax
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-!= $has-primitive-name?:end/disp32
|
||||
# if (name == "copy-object") return true
|
||||
(string-equal? %esi "copy-object") # => eax
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-!= $has-primitive-name?:end/disp32
|
||||
# if (name == "allocate") return true
|
||||
(string-equal? %esi "allocate") # => eax
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
|
@ -12820,6 +12824,14 @@ check-mu-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffer
|
|||
(check-mu-compute-offset-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
|
||||
e9/jump $check-mu-primitive:end/disp32
|
||||
}
|
||||
# if (op == "copy-object") check-mu-copy-object-stmt
|
||||
{
|
||||
(string-equal? %ecx "copy-object") # => eax
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-= break/disp8
|
||||
(check-mu-copy-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
|
||||
e9/jump $check-mu-primitive:end/disp32
|
||||
}
|
||||
# if (op == "allocate") check-mu-allocate-stmt
|
||||
{
|
||||
(string-equal? %ecx "allocate") # => eax
|
||||
|
@ -13786,6 +13798,18 @@ $check-mu-compute-offset-stmt:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
check-mu-copy-object-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
# . save registers
|
||||
$check-mu-copy-object-stmt:end:
|
||||
# . restore registers
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
check-mu-allocate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
|
@ -16039,6 +16063,15 @@ emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (ad
|
|||
(translate-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18))
|
||||
e9/jump $emit-subx-stmt:end/disp32
|
||||
}
|
||||
# copy-object
|
||||
{
|
||||
# if (!string-equal?(stmt->operation, "copy-object")) break
|
||||
(string-equal? %ecx "copy-object") # => eax
|
||||
3d/compare-eax-and 0/imm32
|
||||
0f 84/jump-if-= break/disp32
|
||||
(translate-mu-copy-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18))
|
||||
e9/jump $emit-subx-stmt:end/disp32
|
||||
}
|
||||
# allocate array
|
||||
{
|
||||
# if (!string-equal?(stmt->operation, "populate")) break
|
||||
|
@ -16810,6 +16843,34 @@ $translate-mu-get-stmt:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
translate-mu-copy-object-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
# . save registers
|
||||
50/push-eax
|
||||
#
|
||||
(emit-indent *(ebp+8) *Curr-block-depth)
|
||||
(write-buffered *(ebp+8) "(copy-bytes")
|
||||
# eax = stmt
|
||||
8b/-> *(ebp+0xc) 0/r32/eax
|
||||
# var first-inout/eax: (addr stmt-var) = stmt->inouts[0]
|
||||
(lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax
|
||||
(emit-subx-call-operand *(ebp+8) %eax)
|
||||
(lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
|
||||
(emit-subx-call-operand *(ebp+8) %eax)
|
||||
(write-buffered *(ebp+8) Space)
|
||||
(addr-payload-size %eax *(ebp+0x10) *(ebp+0x14)) # => eax
|
||||
(write-int32-hex-buffered *(ebp+8) %eax)
|
||||
(write-buffered *(ebp+8) ")\n")
|
||||
$translate-mu-copy-object-stmt:end:
|
||||
# . restore registers
|
||||
58/pop-to-eax
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
translate-mu-allocate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
|
|
Loading…
Reference in New Issue