7521 - new plan for tests

It's not really manageable to make the fake screen pixel-oriented. Feels
excessive to compare things pixel by pixel when we will mostly be
writing text to screen. It'll also make expected screen assertions
more difficult to manage.

So I'm not sure how to make assertions about pixels for now. Instead
we'll introduce fake screens at draw-grapheme.
This commit is contained in:
Kartik Agaram 2021-01-15 20:30:07 -08:00
parent 20d6be5240
commit 6e36ce06dd
11 changed files with 124 additions and 78 deletions

View File

@ -1,44 +1,38 @@
# Primitives for screen control.
#
# We need to do this in machine code because Mu doesn't have global variables
# yet (for the start of video memory).
== code
pixel: # screen: (addr screen), x: int, y: int, color: int
pixel-on-real-screen: # x: int, y: int, color: int
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# . save registers
50/push-eax
51/push-ecx
# ecx = screen
8b/-> *(ebp+8) 1/r32/ecx
81 7/subop/compare %ecx 0/imm32
{
75/jump-if-!= break/disp8
# bounds checks
8b/-> *(ebp+0xc) 0/r32/eax
3d/compare-eax-and 0/imm32
7c/jump-if-< $pixel:end/disp8
3d/compare-eax-and 0x400/imm32/1024
7d/jump-if->= $pixel:end/disp8
8b/-> *(ebp+0x10) 0/r32/eax
3d/compare-eax-and 0/imm32
7c/jump-if-< $pixel:end/disp8
3d/compare-eax-and 0x300/imm32/768
7d/jump-if->= $pixel:end/disp8
# eax = y*1024 + x
8b/-> *(ebp+0x10) 0/r32/eax
c1/shift 4/subop/left %eax 0xa/imm8
03/add-> *(ebp+0xc) 0/r32/eax
# eax += location of frame buffer
03/add-> *0x7f28 0/r32/eax
# *eax = color
8b/-> *(ebp+0x14) 1/r32/ecx
88/byte<- *eax 1/r32/CL
# return
eb $pixel:end/disp8
}
# TODO: fake screen
$pixel:end:
# bounds checks
8b/-> *(ebp+8) 0/r32/eax
3d/compare-eax-and 0/imm32
7c/jump-if-< $pixel-on-real-screen:end/disp8
3d/compare-eax-and 0x400/imm32/1024
7d/jump-if->= $pixel-on-real-screen:end/disp8
8b/-> *(ebp+0xc) 0/r32/eax
3d/compare-eax-and 0/imm32
7c/jump-if-< $pixel-on-real-screen:end/disp8
3d/compare-eax-and 0x300/imm32/768
7d/jump-if->= $pixel-on-real-screen:end/disp8
# eax = y*1024 + x
8b/-> *(ebp+0xc) 0/r32/eax
c1/shift 4/subop/left %eax 0xa/imm8
03/add-> *(ebp+8) 0/r32/eax
# eax += location of frame buffer
03/add-> *0x7f28 0/r32/eax # unsafe
# *eax = color
8b/-> *(ebp+0x10) 1/r32/ecx
88/byte<- *eax 1/r32/CL
$pixel-on-real-screen:end:
# . restore registers
59/pop-to-ecx
58/pop-to-eax

View File

@ -1,5 +1,8 @@
# check keyboard for a key
# return 0 on no keypress or unrecognized key
#
# We need to do this in machine code because Mu doesn't have global variables
# yet (for the keyboard buffer).
== code

View File

@ -1,8 +1,11 @@
# Use the built-in font to draw a grapheme to screen.
# Use the built-in font to draw a grapheme to real screen.
#
# We need to do this in machine code because Mu doesn't have global variables
# yet (for the start of video memory).
== code
draw-grapheme: # screen: (addr screen), g: grapheme, x: int, y: int, color: int
draw-grapheme-on-real-screen: # g: grapheme, x: int, y: int, color: int
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
@ -12,28 +15,27 @@ draw-grapheme: # screen: (addr screen), g: grapheme, x: int, y: int, color: int
52/push-edx
53/push-ebx
56/push-esi
# TODO: support fake screen; we currently assume 'screen' is always 0 (real)
# var letter-bitmap/esi = font[g]
8b/-> *(ebp+0xc) 6/r32/esi
8b/-> *(ebp+8) 6/r32/esi
c1 4/subop/shift-left %esi 4/imm8
8d/copy-address *(esi+0x8800) 6/r32/esi # font-start
# if (letter-bitmap >= 0x9000) return # characters beyond ASCII currently not supported
81 7/subop/compare %esi 0x9000/imm32
7d/jump-if->= $draw-grapheme:end/disp8
# edx = y
8b/-> *(ebp+0x14) 2/r32/edx
8b/-> *(ebp+0x10) 2/r32/edx
# var ymax/ebx: int = y + 16
8b/-> *(ebp+0x14) 3/r32/ebx
8b/-> *(ebp+0x10) 3/r32/ebx
81 0/subop/add %ebx 0x10/imm32
{
# if (y >= ymax) break
39/compare %edx 3/r32/ebx
7d/jump-if->= break/disp8
# eax = x + 7
8b/-> *(ebp+0x10) 0/r32/eax
8b/-> *(ebp+0xc) 0/r32/eax
81 0/subop/add %eax 7/imm32
# var xmin/ecx: int = x
8b/-> *(ebp+0x10) 1/r32/ecx
8b/-> *(ebp+0xc) 1/r32/ecx
# var row-bitmap/ebx: int = *letter-bitmap
53/push-ebx
8b/-> *esi 3/r32/ebx
@ -46,7 +48,7 @@ draw-grapheme: # screen: (addr screen), g: grapheme, x: int, y: int, color: int
# if LSB, draw a pixel
{
73/jump-if-not-CF break/disp8
(pixel *(ebp+8) %eax %edx *(ebp+0x18))
(pixel-on-real-screen %eax %edx *(ebp+0x14))
}
# --x
48/decrement-eax
@ -74,7 +76,7 @@ $draw-grapheme:end:
5d/pop-to-ebp
c3/return
cursor-position: # screen: (addr screen) -> _/eax: int, _/ecx: int
cursor-position-on-real-screen: # -> _/eax: int, _/ecx: int
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
@ -87,16 +89,16 @@ $cursor-position:end:
5d/pop-to-ebp
c3/return
set-cursor-position: # screen: (addr screen), x: int, y: int
set-cursor-position-on-real-screen: # x: int, y: int
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# . save registers
50/push-eax
# TODO: support fake screen; we currently assume 'screen' is always 0 (real)
8b/-> *(ebp+0xc) 0/r32/eax
8b/-> *(ebp+8) 0/r32/eax
89/<- *Default-next-x 0/r32/eax
8b/-> *(ebp+0x10) 0/r32/eax
8b/-> *(ebp+0xc) 0/r32/eax
89/<- *Default-next-y 0/r32/eax
$set-cursor-position:end:
# . restore registers

View File

@ -1,8 +1,8 @@
# screen
sig pixel screen: (addr screen), x: int, y: int, color: int
sig draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int
sig cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int
sig set-cursor-position screen: (addr screen), x: int, y: 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
sig cursor-position-on-real-screen -> _/eax: int, _/ecx: int
sig set-cursor-position-on-real-screen x: int, y: int
# keyboard
sig read-key kbd: (addr keyboard) -> _/eax: byte

View File

@ -1,17 +0,0 @@
fn clear-screen screen: (addr screen) {
var y/eax: int <- copy 0
{
compare y, 0x300 # 768
break-if->=
var x/edx: int <- copy 0
{
compare x, 0x400 # 1024
break-if->=
pixel 0, x, y, 0 # black
x <- increment
loop
}
y <- increment
loop
}
}

View File

@ -0,0 +1,64 @@
# Screen primitives for character-oriented output.
#
# Unlike the top-level, this text mode has no scrolling.
fn draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int {
{
compare screen, 0
break-if-!=
draw-grapheme-on-real-screen g, x, y, color
return
}
# TODO: fake screen
}
fn cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int {
{
compare screen, 0
break-if-!=
var x/eax: int <- copy 0
var y/ecx: int <- copy 0
x, y <- cursor-position-on-real-screen
return x, y
}
# TODO: fake screen
return 0, 0
}
fn set-cursor-position screen: (addr screen), x: int, y: int {
{
compare screen, 0
break-if-!=
set-cursor-position-on-real-screen x, y
return
}
# TODO: fake screen
}
fn clear-screen screen: (addr screen) {
{
compare screen, 0
break-if-!=
clear-real-screen
return
}
# TODO: fake screen
}
fn clear-real-screen {
var y/eax: int <- copy 0
{
compare y, 0x300 # 768
break-if->=
var x/edx: int <- copy 0
{
compare x, 0x400 # 1024
break-if->=
pixel-on-real-screen x, y, 0 # black
x <- increment
loop
}
y <- increment
loop
}
}

View File

@ -1,27 +1,27 @@
fn draw-box screen: (addr screen), x1: int, y1: int, x2: int, y2: int, color: int {
draw-horizontal-line screen, x1, x2, y1, color
draw-vertical-line screen, x1, y1, y2, color
draw-horizontal-line screen, x1, x2, y2, color
draw-vertical-line screen, x2, y1, y2, color
fn draw-box-on-real-screen x1: int, y1: int, x2: int, y2: int, color: int {
draw-horizontal-line-on-real-screen x1, x2, y1, color
draw-vertical-line-on-real-screen x1, y1, y2, color
draw-horizontal-line-on-real-screen x1, x2, y2, color
draw-vertical-line-on-real-screen x2, y1, y2, color
}
fn draw-horizontal-line screen: (addr screen), x1: int, x2: int, y: int, color: int {
fn draw-horizontal-line-on-real-screen x1: int, x2: int, y: int, color: int {
var x/eax: int <- copy x1
{
compare x, x2
break-if->=
pixel screen, x, y, color
pixel-on-real-screen x, y, color
x <- increment
loop
}
}
fn draw-vertical-line screen: (addr screen), x: int, y1: int, y2: int, color: int {
fn draw-vertical-line-on-real-screen x: int, y1: int, y2: int, color: int {
var y/eax: int <- copy y1
{
compare y, y2
break-if->=
pixel screen, x, y, color
pixel-on-real-screen x, y, color
y <- increment
loop
}

View File

@ -21,7 +21,7 @@ fn main {
break-if->=
var color/ecx: int <- copy x
color <- and 0xff
pixel 0, x, y, color
pixel-on-real-screen x, y, color
x <- increment
loop
}

View File

@ -18,7 +18,7 @@ fn main {
var key/eax: byte <- read-key 0 # real keyboard
compare key, 0
loop-if-= # busy wait
pixel 0, x, y, 0x31 # green
pixel-on-real-screen x, y, 0x31 # green
x <- increment
compare x, 0x400
{

View File

@ -11,7 +11,7 @@
fn main {
# drawing text within a bounding box
draw-box 0, 0xf, 0x1f, 0x79, 0x51, 0x4
draw-box-on-real-screen 0xf, 0x1f, 0x79, 0x51, 0x4
var x/eax: int <- copy 0x20
var y/ecx: int <- copy 0x20
x, y <- draw-text-wrapping-right-then-down 0, "hello ", 0x10, 0x20, 0x78, 0x50, x, y, 0xa # (0x10, 0x20) -> (0x78, 0x50)

View File

@ -17,7 +17,7 @@ bd/copy-to-ebp 0/imm32
{
3d/compare-eax-and 0/imm32
75/jump-if-!= break/disp8
(clear-screen)
(clear-real-screen)
(main)
}