7542 - baremetal: support cursor on a grapheme

So far we've drawn a space implicitly at the cursor. Now I allow drawing
an arbitrary grapheme when drawing the cursor. But the caller has to
specify what to draw. (The alternative would be for layer 103 to
track every single grapheme on screen along with its color and any other
future attributes, just to be able to paint and unpaint the background
for a single character.)

I've modified existing helpers for drawing multiple graphemes to always
clear the final cursor position after they finish drawing. That seems
reasonable for terminal-like applications. Applications that need to
control the screen in a more random-access manner will need to track the
grapheme at the cursor for themselves.
This commit is contained in:
Kartik Agaram 2021-01-22 20:57:29 -08:00
parent a51bc7a1e0
commit 1b09418c60
4 changed files with 36 additions and 18 deletions

View File

@ -104,14 +104,16 @@ $cursor-position-on-real-screen:end:
5d/pop-to-ebp
c3/return
set-cursor-position-on-real-screen: # x: int, y: int
# Caller is responsible for tracking what was on the screen at this position
# before, and making sure the cursor continues to show the same grapheme.
set-cursor-position-on-real-screen: # x: int, y: int, g: grapheme
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# . save registers
50/push-eax
#
(draw-grapheme-on-real-screen 0x20 *(ebp+8) *(ebp+0xc) 0 7)
(draw-grapheme-on-real-screen *(ebp+0x10) *(ebp+8) *(ebp+0xc) 0 7)
# TODO: support fake screen; we currently assume 'screen' is always 0 (real)
8b/-> *(ebp+8) 0/r32/eax
89/<- *Real-screen-cursor-x 0/r32/eax

View File

@ -2,7 +2,7 @@
sig pixel-on-real-screen x: int, y: int, color: int
sig draw-grapheme-on-real-screen g: grapheme, x: int, y: int, color: int, background-color: int
sig cursor-position-on-real-screen -> _/eax: int, _/ecx: int
sig set-cursor-position-on-real-screen x: int, y: int
sig set-cursor-position-on-real-screen x: int, y: int, g: grapheme
# keyboard
sig read-key kbd: (addr keyboard) -> _/eax: byte

View File

@ -112,11 +112,11 @@ fn cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int {
return *cursor-x-addr, *cursor-y-addr
}
fn set-cursor-position screen: (addr screen), x: int, y: int {
fn set-cursor-position screen: (addr screen), x: int, y: int, g: grapheme {
{
compare screen, 0
break-if-!=
set-cursor-position-on-real-screen x, y
set-cursor-position-on-real-screen x, y, g
return
}
# fake screen
@ -157,6 +157,11 @@ fn set-cursor-position screen: (addr screen), x: int, y: int {
dest <- get screen-addr, cursor-y
src <- copy y
copy-to *dest, src
#
var cursor-x/eax: int <- copy 0
var cursor-y/ecx: int <- copy 0
cursor-x, cursor-y <- cursor-position screen-addr
draw-grapheme screen-addr, g, cursor-x, cursor-y, 0 # cursor color not tracked for fake screen
}
fn clear-screen screen: (addr screen) {
@ -168,7 +173,7 @@ fn clear-screen screen: (addr screen) {
}
# fake screen
var space/edi: grapheme <- copy 0x20
set-cursor-position screen, 0, 0
set-cursor-position screen, 0, 0, space
var screen-addr/esi: (addr screen) <- copy screen
var y/eax: int <- copy 1
var height/ecx: (addr int) <- get screen-addr, height
@ -187,7 +192,7 @@ fn clear-screen screen: (addr screen) {
y <- increment
loop
}
set-cursor-position screen, 0, 0
set-cursor-position screen, 0, 0, space
}
# there's no grapheme that guarantees to cover every pixel, so we'll bump down

View File

@ -10,7 +10,8 @@ fn cursor-left screen: (addr screen) {
return
}
cursor-x <- decrement
set-cursor-position screen, cursor-x, cursor-y
var space/esi: grapheme <- copy 0x20
set-cursor-position screen, cursor-x, cursor-y, space
}
fn cursor-right screen: (addr screen) {
@ -27,7 +28,8 @@ fn cursor-right screen: (addr screen) {
return
}
cursor-x <- increment
set-cursor-position screen, cursor-x, cursor-y
var space/esi: grapheme <- copy 0x20
set-cursor-position screen, cursor-x, cursor-y, space
}
fn cursor-up screen: (addr screen) {
@ -40,7 +42,8 @@ fn cursor-up screen: (addr screen) {
return
}
cursor-y <- decrement
set-cursor-position screen, cursor-x, cursor-y
var space/esi: grapheme <- copy 0x20
set-cursor-position screen, cursor-x, cursor-y, space
}
fn cursor-down screen: (addr screen) {
@ -57,7 +60,8 @@ fn cursor-down screen: (addr screen) {
return
}
cursor-y <- increment
set-cursor-position screen, cursor-x, cursor-y
var space/esi: grapheme <- copy 0x20
set-cursor-position screen, cursor-x, cursor-y, space
}
fn draw-grapheme-at-cursor screen: (addr screen), g: grapheme, color: int {
@ -101,7 +105,8 @@ fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, x
xcurr <- increment
loop
}
set-cursor-position screen, xcurr, y
var space/esi: grapheme <- copy 0x20
set-cursor-position screen, xcurr, y, space # we'll assume it's ok to clear the next grapheme
return xcurr
}
@ -162,7 +167,8 @@ fn draw-text-wrapping-right-then-down screen: (addr screen), text: (addr array b
}
loop
}
set-cursor-position screen, xcurr, ycurr
var space/esi: grapheme <- copy 0x20
set-cursor-position screen, xcurr, ycurr, space # we'll assume it's ok to clear the next grapheme
return xcurr, ycurr
}
@ -177,7 +183,8 @@ fn move-cursor-rightward-and-downward screen: (addr screen), xmin: int, xmax: in
cursor-x <- copy xmin
cursor-y <- increment
}
set-cursor-position screen, cursor-x, cursor-y
var space/esi: grapheme <- copy 0x20
set-cursor-position screen, cursor-x, cursor-y, space # we'll assume it's ok to clear the grapheme at the cursor
}
fn draw-text-wrapping-right-then-down-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int -> _/eax: int, _/ecx: int {
@ -255,7 +262,8 @@ fn draw-int32-hex-wrapping-right-then-down screen: (addr screen), n: int, xmin:
}
loop
}
set-cursor-position screen, xcurr, ycurr
var space/esi: grapheme <- copy 0x20
set-cursor-position screen, xcurr, ycurr, space # we'll assume it's ok to clear the next grapheme
return xcurr, ycurr
}
@ -334,7 +342,8 @@ fn draw-int32-decimal-wrapping-right-then-down screen: (addr screen), n: int, xm
}
loop
}
set-cursor-position screen, xcurr, ycurr
var space/esi: grapheme <- copy 0x20
set-cursor-position screen, xcurr, ycurr, space # we'll assume it's ok to clear the next grapheme
return xcurr, ycurr
}
@ -404,7 +413,8 @@ fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y:
ycurr <- increment
loop
}
set-cursor-position screen, x, ycurr
var space/esi: grapheme <- copy 0x20
set-cursor-position screen, x, ycurr, space # we'll assume it's ok to clear the next grapheme
return ycurr
}
@ -464,7 +474,8 @@ fn draw-text-wrapping-down-then-right screen: (addr screen), text: (addr array b
}
loop
}
set-cursor-position screen, xcurr, ycurr
var space/esi: grapheme <- copy 0x20
set-cursor-position screen, xcurr, ycurr, space # we'll assume it's ok to clear the next grapheme
return xcurr, ycurr
}