7529 - baremetal: fake screen
This commit is contained in:
parent
3d6c6e5286
commit
6efc1ebed7
|
@ -0,0 +1,25 @@
|
|||
# 2-arg version of allocate-array.
|
||||
# Really only intended to be called from code generated by mu.subx.
|
||||
|
||||
== code
|
||||
|
||||
allocate-array2: # ad: (addr allocation-descriptor), array-len: int, elem-size: int, out: (addr handle array _)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
# . save registers
|
||||
50/push-eax
|
||||
52/push-edx
|
||||
#
|
||||
8b/-> *(ebp+0xc) 0/r32/eax
|
||||
f7 4/subop/multiply-into-edx-eax *(ebp+0x10)
|
||||
# TODO: check edx for overflow
|
||||
(allocate-array *(ebp+8) %eax *(ebp+0x14))
|
||||
$allocate-array2:end:
|
||||
# . restore registers
|
||||
5a/pop-to-edx
|
||||
58/pop-to-eax
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
c3/return
|
|
@ -2,6 +2,67 @@
|
|||
#
|
||||
# Unlike the top-level, this text mode has no scrolling.
|
||||
|
||||
# coordinates here don't match top-level
|
||||
# Here we're consistent with graphics mode. Top-level is consistent with
|
||||
# terminal emulators.
|
||||
type screen {
|
||||
width: int
|
||||
height: int
|
||||
data: (handle array screen-cell)
|
||||
cursor-x: int
|
||||
cursor-y: int
|
||||
}
|
||||
|
||||
type screen-cell {
|
||||
data: grapheme
|
||||
color: int
|
||||
}
|
||||
|
||||
fn initialize-screen screen: (addr screen), width: int, height: int {
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var tmp/eax: int <- copy 0
|
||||
var dest/edi: (addr int) <- copy 0
|
||||
# screen->width = width
|
||||
dest <- get screen-addr, width
|
||||
tmp <- copy width
|
||||
copy-to *dest, tmp
|
||||
# screen->height = height
|
||||
dest <- get screen-addr, height
|
||||
tmp <- copy height
|
||||
copy-to *dest, tmp
|
||||
# screen->data = new screen-cell[width*height]
|
||||
{
|
||||
var data-addr/edi: (addr handle array screen-cell) <- get screen-addr, data
|
||||
tmp <- multiply width
|
||||
populate data-addr, tmp
|
||||
}
|
||||
# screen->cursor-x = 0
|
||||
dest <- get screen-addr, cursor-x
|
||||
copy-to *dest, 0
|
||||
# screen->cursor-y = 0
|
||||
dest <- get screen-addr, cursor-y
|
||||
copy-to *dest, 0
|
||||
}
|
||||
|
||||
fn screen-size screen: (addr screen) -> _/eax: int, _/ecx: int {
|
||||
var width/eax: int <- copy 0
|
||||
var height/ecx: int <- copy 0
|
||||
compare screen, 0
|
||||
{
|
||||
break-if-!=
|
||||
width <- copy 0x30 # 768/16
|
||||
height <- copy 0x80 # 1024/8
|
||||
return width, height
|
||||
}
|
||||
# fake screen
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var tmp/edx: (addr int) <- get screen-addr, width
|
||||
width <- copy *tmp
|
||||
tmp <- get screen-addr, height
|
||||
height <- copy *tmp
|
||||
return width, height
|
||||
}
|
||||
|
||||
fn draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int {
|
||||
{
|
||||
compare screen, 0
|
||||
|
@ -9,7 +70,28 @@ fn draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int
|
|||
draw-grapheme-on-real-screen g, x, y, color
|
||||
return
|
||||
}
|
||||
# TODO: fake screen
|
||||
# fake screen
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var idx/ecx: int <- screen-cell-index screen-addr, x, y
|
||||
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 dest-cell/ecx: (addr screen-cell) <- index data, offset
|
||||
var dest-grapheme/eax: (addr grapheme) <- get dest-cell, data
|
||||
var g2/edx: grapheme <- copy g
|
||||
copy-to *dest-grapheme, g2
|
||||
var dest-color/eax: (addr int) <- get dest-cell, color
|
||||
var color2/edx: grapheme <- copy color
|
||||
copy-to *dest-color, color2
|
||||
}
|
||||
|
||||
fn screen-cell-index screen-on-stack: (addr screen), x: int, y: int -> _/ecx: int {
|
||||
var screen/esi: (addr screen) <- copy screen-on-stack
|
||||
var height-addr/eax: (addr int) <- get screen, height
|
||||
var result/ecx: int <- copy y
|
||||
result <- multiply *height-addr
|
||||
result <- add x
|
||||
return result
|
||||
}
|
||||
|
||||
fn cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int {
|
||||
|
@ -21,8 +103,11 @@ fn cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int {
|
|||
x, y <- cursor-position-on-real-screen
|
||||
return x, y
|
||||
}
|
||||
# TODO: fake screen
|
||||
return 0, 0
|
||||
# fake screen
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var cursor-x-addr/eax: (addr int) <- get screen-addr, cursor-x
|
||||
var cursor-y-addr/ecx: (addr int) <- get screen-addr, cursor-y
|
||||
return *cursor-x-addr, *cursor-y-addr
|
||||
}
|
||||
|
||||
fn set-cursor-position screen: (addr screen), x: int, y: int {
|
||||
|
@ -32,7 +117,44 @@ fn set-cursor-position screen: (addr screen), x: int, y: int {
|
|||
set-cursor-position-on-real-screen x, y
|
||||
return
|
||||
}
|
||||
# TODO: fake screen
|
||||
# fake screen
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
# ignore x < 0
|
||||
{
|
||||
compare x, 0
|
||||
break-if->=
|
||||
return
|
||||
}
|
||||
# ignore x >= width
|
||||
{
|
||||
var width-addr/eax: (addr int) <- get screen-addr, width
|
||||
var width/eax: int <- copy *width-addr
|
||||
compare x, width
|
||||
break-if-<=
|
||||
return
|
||||
}
|
||||
# ignore y < 0
|
||||
{
|
||||
compare y, 0
|
||||
break-if->=
|
||||
return
|
||||
}
|
||||
# ignore y >= height
|
||||
{
|
||||
var height-addr/eax: (addr int) <- get screen-addr, height
|
||||
var height/eax: int <- copy *height-addr
|
||||
compare y, height
|
||||
break-if-<
|
||||
return
|
||||
}
|
||||
# screen->cursor-x = x
|
||||
var dest/edi: (addr int) <- get screen-addr, cursor-x
|
||||
var src/eax: int <- copy x
|
||||
copy-to *dest, src
|
||||
# screen->cursor-y = y
|
||||
dest <- get screen-addr, cursor-y
|
||||
src <- copy y
|
||||
copy-to *dest, src
|
||||
}
|
||||
|
||||
fn clear-screen screen: (addr screen) {
|
||||
|
@ -42,9 +164,32 @@ fn clear-screen screen: (addr screen) {
|
|||
clear-real-screen
|
||||
return
|
||||
}
|
||||
# TODO: fake screen
|
||||
# fake screen
|
||||
var space/edi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, 0, 0
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var y/eax: int <- copy 1
|
||||
var height/ecx: (addr int) <- get screen-addr, height
|
||||
{
|
||||
compare y, *height
|
||||
break-if->
|
||||
var x/edx: int <- copy 1
|
||||
var width/ebx: (addr int) <- get screen-addr, width
|
||||
{
|
||||
compare x, *width
|
||||
break-if->
|
||||
draw-grapheme screen, space, x, y, 0 # color=black
|
||||
x <- increment
|
||||
loop
|
||||
}
|
||||
y <- increment
|
||||
loop
|
||||
}
|
||||
set-cursor-position screen, 0, 0
|
||||
}
|
||||
|
||||
# there's no grapheme that guarantees to cover every pixel, so we'll bump down
|
||||
# to pixels for a real screen
|
||||
fn clear-real-screen {
|
||||
var y/eax: int <- copy 0
|
||||
{
|
||||
|
@ -62,3 +207,40 @@ fn clear-real-screen {
|
|||
loop
|
||||
}
|
||||
}
|
||||
|
||||
fn screen-grapheme-at screen-on-stack: (addr screen), x: int, y: int -> _/eax: grapheme {
|
||||
var screen-addr/esi: (addr screen) <- copy screen-on-stack
|
||||
var idx/ecx: int <- screen-cell-index screen-addr, x, y
|
||||
var result/eax: grapheme <- screen-grapheme-at-idx screen-addr, idx
|
||||
return result
|
||||
}
|
||||
|
||||
fn screen-grapheme-at-idx screen-on-stack: (addr screen), idx-on-stack: int -> _/eax: grapheme {
|
||||
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 grapheme) <- get cell, data
|
||||
return *src
|
||||
}
|
||||
|
||||
fn screen-color-at screen-on-stack: (addr screen), x: int, y: int -> _/eax: int {
|
||||
var screen-addr/esi: (addr screen) <- copy screen-on-stack
|
||||
var idx/ecx: int <- screen-cell-index screen-addr, x, y
|
||||
var result/eax: int <- screen-color-at-idx screen-addr, idx
|
||||
return result
|
||||
}
|
||||
|
||||
fn screen-color-at-idx screen-on-stack: (addr screen), idx-on-stack: int -> _/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
|
||||
var result/eax: int <- copy *src
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -58,13 +58,13 @@
|
|||
# calls, so we don't need to initialize the stack.
|
||||
|
||||
# 0e:
|
||||
# load second sector from disk
|
||||
# load some sectors from disk
|
||||
b4 02 # ah <- 2 # read sectors from disk
|
||||
# dl comes conveniently initialized at boot time with the index of the device being booted
|
||||
b5 00 # ch <- 0 # cylinder 0
|
||||
b6 00 # dh <- 0 # track 0
|
||||
b1 02 # cl <- 2 # second sector, 1-based
|
||||
b0 20 # al <- 32 # number of sectors to read; all sectors must be in a single track
|
||||
b0 3e # al <- 62 # number of sectors to read; all sectors must be in a single track
|
||||
# address to write sectors to = es:bx = 0x7e00, contiguous with boot segment
|
||||
bb 00 00 # bx <- 0
|
||||
8e c3 # es <- bx
|
||||
|
|
Loading…
Reference in New Issue