7548 - baremetal: better cursor management
This commit is contained in:
parent
0f73127ef1
commit
63be7b7d0d
|
@ -104,17 +104,13 @@ $cursor-position-on-real-screen:end:
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
# Caller is responsible for tracking what was on the screen at this position
|
set-cursor-position-on-real-screen: # x: int, y: int
|
||||||
# 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
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
# . save registers
|
# . save registers
|
||||||
50/push-eax
|
50/push-eax
|
||||||
#
|
#
|
||||||
(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
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
89/<- *Real-screen-cursor-x 0/r32/eax
|
89/<- *Real-screen-cursor-x 0/r32/eax
|
||||||
8b/-> *(ebp+0xc) 0/r32/eax
|
8b/-> *(ebp+0xc) 0/r32/eax
|
||||||
|
@ -127,17 +123,47 @@ $set-cursor-position-on-real-screen:end:
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
|
# Draw cursor at current location. But this is rickety:
|
||||||
|
# - does not clear previous location cursor was shown at.
|
||||||
|
# - does not preserve what was at the cursor. Caller is responsible for
|
||||||
|
# tracking what was on the screen at this position before and passing it
|
||||||
|
# in again.
|
||||||
|
show-cursor-on-real-screen: # g: grapheme
|
||||||
|
# . prologue
|
||||||
|
55/push-ebp
|
||||||
|
89/<- %ebp 4/r32/esp
|
||||||
|
# . save registers
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
#
|
||||||
|
(cursor-position-on-real-screen) # => eax, ecx
|
||||||
|
(draw-grapheme-on-real-screen *(ebp+8) %eax %ecx 0 7)
|
||||||
|
$show-cursor-on-real-screen:end:
|
||||||
|
# . restore registers
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
# . epilogue
|
||||||
|
89/<- %esp 5/r32/ebp
|
||||||
|
5d/pop-to-ebp
|
||||||
|
c3/return
|
||||||
|
|
||||||
== data
|
== data
|
||||||
|
|
||||||
# The cursor is where certain Mu functions (usually of the form
|
# The cursor is where certain Mu functions (usually of the form
|
||||||
# 'draw*cursor*') print to by default. It becomes visible on
|
# 'draw*cursor*') print to by default.
|
||||||
# set-cursor-position, but further drawing might overwrite it.
|
|
||||||
# We don't bother displaying the cursor when drawing text. It's up to
|
|
||||||
# applications to display the cursor before waiting for a key, and to ensure
|
|
||||||
# its location appropriately suggests the effect keystrokes will have.
|
|
||||||
#
|
#
|
||||||
# There's no low-level support for blinking, etc. We aren't using any
|
# We don't bother displaying the cursor when drawing. It only becomes visible
|
||||||
# hardware-supported text mode here.
|
# on show-cursor, which is quite rickety (see above)
|
||||||
|
#
|
||||||
|
# It's up to applications to manage cursor display:
|
||||||
|
# - clean up where it used to be
|
||||||
|
# - display the cursor before waiting for a key
|
||||||
|
# - ensure its location appropriately suggests the effect keystrokes will have
|
||||||
|
# - ensure its contents (and colors) appropriately reflect the state of the
|
||||||
|
# screen
|
||||||
|
#
|
||||||
|
# There's no blinking, etc. We aren't using any hardware-supported text mode
|
||||||
|
# here.
|
||||||
Real-screen-cursor-x:
|
Real-screen-cursor-x:
|
||||||
0/imm32
|
0/imm32
|
||||||
Real-screen-cursor-y:
|
Real-screen-cursor-y:
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
sig pixel-on-real-screen x: int, y: int, color: int
|
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 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 cursor-position-on-real-screen -> _/eax: int, _/ecx: int
|
||||||
sig set-cursor-position-on-real-screen x: int, y: int, g: grapheme
|
sig set-cursor-position-on-real-screen x: int, y: int
|
||||||
|
sig show-cursor-on-real-screen g: grapheme
|
||||||
|
|
||||||
# keyboard
|
# keyboard
|
||||||
sig read-key kbd: (addr keyboard) -> _/eax: byte
|
sig read-key kbd: (addr keyboard) -> _/eax: byte
|
||||||
|
|
|
@ -112,11 +112,11 @@ fn cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int {
|
||||||
return *cursor-x-addr, *cursor-y-addr
|
return *cursor-x-addr, *cursor-y-addr
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set-cursor-position screen: (addr screen), x: int, y: int, g: grapheme {
|
fn set-cursor-position screen: (addr screen), x: int, y: int {
|
||||||
{
|
{
|
||||||
compare screen, 0
|
compare screen, 0
|
||||||
break-if-!=
|
break-if-!=
|
||||||
set-cursor-position-on-real-screen x, y, g
|
set-cursor-position-on-real-screen x, y
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
# fake screen
|
# fake screen
|
||||||
|
@ -157,11 +157,20 @@ fn set-cursor-position screen: (addr screen), x: int, y: int, g: grapheme {
|
||||||
dest <- get screen-addr, cursor-y
|
dest <- get screen-addr, cursor-y
|
||||||
src <- copy y
|
src <- copy y
|
||||||
copy-to *dest, src
|
copy-to *dest, src
|
||||||
#
|
}
|
||||||
|
|
||||||
|
fn show-cursor screen: (addr screen), g: grapheme {
|
||||||
|
{
|
||||||
|
compare screen, 0
|
||||||
|
break-if-!=
|
||||||
|
show-cursor-on-real-screen g
|
||||||
|
return
|
||||||
|
}
|
||||||
|
# fake screen
|
||||||
var cursor-x/eax: int <- copy 0
|
var cursor-x/eax: int <- copy 0
|
||||||
var cursor-y/ecx: int <- copy 0
|
var cursor-y/ecx: int <- copy 0
|
||||||
cursor-x, cursor-y <- cursor-position screen-addr
|
cursor-x, cursor-y <- cursor-position screen
|
||||||
draw-grapheme screen-addr, g, cursor-x, cursor-y, 0 # cursor color not tracked for fake screen
|
draw-grapheme screen, g, cursor-x, cursor-y, 0 # cursor color not tracked for fake screen
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear-screen screen: (addr screen) {
|
fn clear-screen screen: (addr screen) {
|
||||||
|
@ -173,7 +182,7 @@ fn clear-screen screen: (addr screen) {
|
||||||
}
|
}
|
||||||
# fake screen
|
# fake screen
|
||||||
var space/edi: grapheme <- copy 0x20
|
var space/edi: grapheme <- copy 0x20
|
||||||
set-cursor-position screen, 0, 0, space
|
set-cursor-position screen, 0, 0
|
||||||
var screen-addr/esi: (addr screen) <- copy screen
|
var screen-addr/esi: (addr screen) <- copy screen
|
||||||
var y/eax: int <- copy 1
|
var y/eax: int <- copy 1
|
||||||
var height/ecx: (addr int) <- get screen-addr, height
|
var height/ecx: (addr int) <- get screen-addr, height
|
||||||
|
@ -192,7 +201,7 @@ fn clear-screen screen: (addr screen) {
|
||||||
y <- increment
|
y <- increment
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
set-cursor-position screen, 0, 0, space
|
set-cursor-position screen, 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# there's no grapheme that guarantees to cover every pixel, so we'll bump down
|
# there's no grapheme that guarantees to cover every pixel, so we'll bump down
|
||||||
|
|
|
@ -10,8 +10,7 @@ fn cursor-left screen: (addr screen) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cursor-x <- decrement
|
cursor-x <- decrement
|
||||||
var space/esi: grapheme <- copy 0x20
|
set-cursor-position screen, cursor-x, cursor-y
|
||||||
set-cursor-position screen, cursor-x, cursor-y, space
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cursor-right screen: (addr screen) {
|
fn cursor-right screen: (addr screen) {
|
||||||
|
@ -28,8 +27,7 @@ fn cursor-right screen: (addr screen) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cursor-x <- increment
|
cursor-x <- increment
|
||||||
var space/esi: grapheme <- copy 0x20
|
set-cursor-position screen, cursor-x, cursor-y
|
||||||
set-cursor-position screen, cursor-x, cursor-y, space
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cursor-up screen: (addr screen) {
|
fn cursor-up screen: (addr screen) {
|
||||||
|
@ -42,8 +40,7 @@ fn cursor-up screen: (addr screen) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cursor-y <- decrement
|
cursor-y <- decrement
|
||||||
var space/esi: grapheme <- copy 0x20
|
set-cursor-position screen, cursor-x, cursor-y
|
||||||
set-cursor-position screen, cursor-x, cursor-y, space
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cursor-down screen: (addr screen) {
|
fn cursor-down screen: (addr screen) {
|
||||||
|
@ -60,8 +57,7 @@ fn cursor-down screen: (addr screen) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cursor-y <- increment
|
cursor-y <- increment
|
||||||
var space/esi: grapheme <- copy 0x20
|
set-cursor-position screen, cursor-x, cursor-y
|
||||||
set-cursor-position screen, cursor-x, cursor-y, space
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw-grapheme-at-cursor screen: (addr screen), g: grapheme, color: int {
|
fn draw-grapheme-at-cursor screen: (addr screen), g: grapheme, color: int {
|
||||||
|
@ -105,8 +101,7 @@ fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, x
|
||||||
xcurr <- increment
|
xcurr <- increment
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
var space/esi: grapheme <- copy 0x20
|
set-cursor-position screen, xcurr, y
|
||||||
set-cursor-position screen, xcurr, y, space # we'll assume it's ok to clear the next grapheme
|
|
||||||
return xcurr
|
return xcurr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,8 +162,7 @@ fn draw-text-wrapping-right-then-down screen: (addr screen), text: (addr array b
|
||||||
}
|
}
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
var space/esi: grapheme <- copy 0x20
|
set-cursor-position screen, xcurr, ycurr
|
||||||
set-cursor-position screen, xcurr, ycurr, space # we'll assume it's ok to clear the next grapheme
|
|
||||||
return xcurr, ycurr
|
return xcurr, ycurr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,8 +177,7 @@ fn move-cursor-rightward-and-downward screen: (addr screen), xmin: int, xmax: in
|
||||||
cursor-x <- copy xmin
|
cursor-x <- copy xmin
|
||||||
cursor-y <- increment
|
cursor-y <- increment
|
||||||
}
|
}
|
||||||
var space/esi: grapheme <- copy 0x20
|
set-cursor-position screen, cursor-x, cursor-y
|
||||||
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 {
|
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 {
|
||||||
|
@ -262,8 +255,7 @@ fn draw-int32-hex-wrapping-right-then-down screen: (addr screen), n: int, xmin:
|
||||||
}
|
}
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
var space/esi: grapheme <- copy 0x20
|
set-cursor-position screen, xcurr, ycurr
|
||||||
set-cursor-position screen, xcurr, ycurr, space # we'll assume it's ok to clear the next grapheme
|
|
||||||
return xcurr, ycurr
|
return xcurr, ycurr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,8 +334,7 @@ fn draw-int32-decimal-wrapping-right-then-down screen: (addr screen), n: int, xm
|
||||||
}
|
}
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
var space/esi: grapheme <- copy 0x20
|
set-cursor-position screen, xcurr, ycurr
|
||||||
set-cursor-position screen, xcurr, ycurr, space # we'll assume it's ok to clear the next grapheme
|
|
||||||
return xcurr, ycurr
|
return xcurr, ycurr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,8 +404,7 @@ fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y:
|
||||||
ycurr <- increment
|
ycurr <- increment
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
var space/esi: grapheme <- copy 0x20
|
set-cursor-position screen, x, ycurr
|
||||||
set-cursor-position screen, x, ycurr, space # we'll assume it's ok to clear the next grapheme
|
|
||||||
return ycurr
|
return ycurr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,8 +464,7 @@ fn draw-text-wrapping-down-then-right screen: (addr screen), text: (addr array b
|
||||||
}
|
}
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
var space/esi: grapheme <- copy 0x20
|
set-cursor-position screen, xcurr, ycurr
|
||||||
set-cursor-position screen, xcurr, ycurr, space # we'll assume it's ok to clear the next grapheme
|
|
||||||
return xcurr, ycurr
|
return xcurr, ycurr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,9 @@
|
||||||
|
|
||||||
fn main {
|
fn main {
|
||||||
var space/eax: grapheme <- copy 0x20
|
var space/eax: grapheme <- copy 0x20
|
||||||
set-cursor-position 0, 0, 0, space
|
set-cursor-position 0, 0, 0
|
||||||
{
|
{
|
||||||
|
show-cursor 0, space
|
||||||
var key/eax: byte <- read-key 0
|
var key/eax: byte <- read-key 0
|
||||||
{
|
{
|
||||||
compare key, 0x68 # 'h'
|
compare key, 0x68 # 'h'
|
||||||
|
|
|
@ -26,10 +26,11 @@ fn main -> _/ebx: int {
|
||||||
{
|
{
|
||||||
# print prompt
|
# print prompt
|
||||||
var x/eax: int <- draw-text-rightward 0, "> ", 0, 0x80, y, 3
|
var x/eax: int <- draw-text-rightward 0, "> ", 0, 0x80, y, 3
|
||||||
set-cursor-position 0, x, y, space
|
set-cursor-position 0, x, y
|
||||||
# read line from keyboard
|
# read line from keyboard
|
||||||
clear-stream in
|
clear-stream in
|
||||||
{
|
{
|
||||||
|
show-cursor 0, space
|
||||||
var key/eax: byte <- read-key 0
|
var key/eax: byte <- read-key 0
|
||||||
compare key, 0xa # newline
|
compare key, 0xa # newline
|
||||||
break-if-=
|
break-if-=
|
||||||
|
@ -42,6 +43,8 @@ fn main -> _/ebx: int {
|
||||||
cursor-right 0
|
cursor-right 0
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
|
# clear cursor
|
||||||
|
draw-grapheme-at-cursor 0, space, 3 # 3=foreground color, which is never used
|
||||||
# parse and eval
|
# parse and eval
|
||||||
var out/eax: int <- simplify in
|
var out/eax: int <- simplify in
|
||||||
# print
|
# print
|
||||||
|
|
Loading…
Reference in New Issue