explicitly pass screen and keyboard to main

This commit is contained in:
Kartik K. Agaram 2021-03-26 22:47:44 -07:00
parent 9f71d7248c
commit 1a43d12b15
14 changed files with 76 additions and 51 deletions

View File

@ -11,7 +11,7 @@
# Values between -256 and +255 as you move the mouse over the window.
# You might need to click on the window once.
fn main {
fn main screen: (addr screen), keyboard: (addr keyboard) {
# repeatedly print out mouse driver results if non-zero
$main:event-loop: {
var dx/eax: int <- copy 0
@ -27,15 +27,15 @@ fn main {
{
var dummy1/eax: int <- copy 0
var dummy2/ecx: int <- copy 0
dummy1, dummy2 <- draw-text-wrapping-right-then-down-over-full-screen 0/screen, " ", 0/x, 0x10/y, 0x31/fg, 0/bg
dummy1, dummy2 <- draw-text-wrapping-right-then-down-over-full-screen screen, " ", 0/x, 0x10/y, 0x31/fg, 0/bg
}
{
var dummy/ecx: int <- copy 0
dx, dummy <- draw-int32-decimal-wrapping-right-then-down-over-full-screen 0/screen, dx, 0/x, 0x10/y, 0x31/fg, 0/bg
dx, dummy <- draw-int32-decimal-wrapping-right-then-down-over-full-screen screen, dx, 0/x, 0x10/y, 0x31/fg, 0/bg
}
{
var dummy/eax: int <- copy 0
dummy, dy <- draw-int32-decimal-wrapping-right-then-down-over-full-screen 0/screen, dy, 5/x, 0x10/y, 0x31/fg, 0/bg
dummy, dy <- draw-int32-decimal-wrapping-right-then-down-over-full-screen screen, dy, 5/x, 0x10/y, 0x31/fg, 0/bg
}
loop
}

2
ex2.mu
View File

@ -7,7 +7,7 @@
# Or:
# bochs -f bochsrc # bochsrc loads disk.img
fn main {
fn main screen: (addr screen), keyboard: (addr keyboard) {
var y/eax: int <- copy 0
{
compare y, 0x300/screen-height=768

4
ex3.mu
View File

@ -11,11 +11,11 @@
# Expected output: a new green pixel starting from the top left corner of the
# screen every time you press a key (letter or digit)
fn main {
fn main screen: (addr screen), keyboard: (addr keyboard) {
var x/ecx: int <- copy 0
var y/edx: int <- copy 0
{
var key/eax: byte <- read-key 0/keyboard
var key/eax: byte <- read-key keyboard
compare key, 0
loop-if-= # busy wait
pixel-on-real-screen x, y, 0x31/green

4
ex4.mu
View File

@ -9,6 +9,6 @@
#
# Expected output: letter 'A' in green near the top-left corner of screen
fn main {
draw-codepoint 0/screen, 0x41/A, 2/row, 1/col, 0xa/fg, 0/bg
fn main screen: (addr screen), keyboard: (addr keyboard) {
draw-codepoint screen, 0x41/A, 2/row, 1/col, 0xa/fg, 0/bg
}

6
ex5.mu
View File

@ -10,7 +10,7 @@
#
# Expected output: text in green near the top-left corner of screen
fn main {
var dummy/eax: int <- draw-text-rightward 0/screen, "hello from baremetal Mu!", 0x10/x, 0x400/xmax, 0x10/y, 0xa/color
dummy <- draw-text-rightward 0/screen, "you shouldn't see this", 0x10/x, 0xa0/xmax, 0x30/y, 0x3/color # xmax is too narrow
fn main screen: (addr screen), keyboard: (addr keyboard) {
var dummy/eax: int <- draw-text-rightward screen, "hello from baremetal Mu!", 0x10/x, 0x400/xmax, 0x10/y, 0xa/color
dummy <- draw-text-rightward screen, "you shouldn't see this", 0x10/x, 0xa0/xmax, 0x30/y, 0x3/color # xmax is too narrow
}

22
ex6.mu
View File

@ -9,24 +9,24 @@
#
# Expected output: a box and text that doesn't overflow it
fn main {
fn main screen: (addr screen), keyboard: (addr keyboard) {
# drawing text within a bounding box
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/screen, "hello ", 0x10/xmin, 0x20/ymin, 0x78/xmax, 0x50/ymax, x, y, 0xa/color
x, y <- draw-text-wrapping-right-then-down 0/screen, "from ", 0x10/xmin, 0x20/ymin, 0x78/xmax, 0x50/ymax, x, y, 0xa/color
x, y <- draw-text-wrapping-right-then-down 0/screen, "baremetal ", 0x10/xmin, 0x20/ymin, 0x78/xmax, 0x50/ymax, x, y, 0xa/color
x, y <- draw-text-wrapping-right-then-down 0/screen, "Mu!", 0x10/xmin, 0x20/ymin, 0x78/xmax, 0x50/ymax, x, y, 0xa/color
x, y <- draw-text-wrapping-right-then-down screen, "hello ", 0x10/xmin, 0x20/ymin, 0x78/xmax, 0x50/ymax, x, y, 0xa/color
x, y <- draw-text-wrapping-right-then-down screen, "from ", 0x10/xmin, 0x20/ymin, 0x78/xmax, 0x50/ymax, x, y, 0xa/color
x, y <- draw-text-wrapping-right-then-down screen, "baremetal ", 0x10/xmin, 0x20/ymin, 0x78/xmax, 0x50/ymax, x, y, 0xa/color
x, y <- draw-text-wrapping-right-then-down screen, "Mu!", 0x10/xmin, 0x20/ymin, 0x78/xmax, 0x50/ymax, x, y, 0xa/color
# drawing at the cursor in multiple directions
draw-text-wrapping-down-then-right-from-cursor-over-full-screen 0/screen, "abc", 0xa
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "def", 0xa
draw-text-wrapping-down-then-right-from-cursor-over-full-screen screen, "abc", 0xa
draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "def", 0xa
# test drawing near the edge
x <- draw-text-rightward 0/screen, "R", 0x3f8/x, 0x400/xmax=screen-width, 0x100/y, 0xa/color
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "wrapped from R", 0xa
x <- draw-text-rightward screen, "R", 0x3f8/x, 0x400/xmax=screen-width, 0x100/y, 0xa/color
draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "wrapped from R", 0xa
x <- draw-text-downward 0/screen, "D", 0x100/x, 0x2f0/y, 0x300/ymax=screen-height, 0xa/color
draw-text-wrapping-down-then-right-from-cursor-over-full-screen 0/screen, "wrapped from D", 0xa
x <- draw-text-downward screen, "D", 0x100/x, 0x2f0/y, 0x300/ymax=screen-height, 0xa/color
draw-text-wrapping-down-then-right-from-cursor-over-full-screen screen, "wrapped from D", 0xa
}

16
ex7.mu
View File

@ -10,35 +10,35 @@
# Expected output: an interactive game a bit like "snakes". Try pressing h, j,
# k, l.
fn main {
fn main screen: (addr screen), keyboard: (addr keyboard) {
var space/eax: grapheme <- copy 0x20
set-cursor-position 0/screen, 0, 0
set-cursor-position screen, 0, 0
{
draw-cursor 0/screen, space
var key/eax: byte <- read-key 0/keyboard
draw-cursor screen, space
var key/eax: byte <- read-key keyboard
{
compare key, 0x68/h
break-if-!=
draw-code-point-at-cursor 0/screen, 0x2d/dash, 0x31/fg, 0/bg
draw-code-point-at-cursor screen, 0x2d/dash, 0x31/fg, 0/bg
move-cursor-left 0
}
{
compare key, 0x6a/j
break-if-!=
draw-code-point-at-cursor 0/screen, 0x7c/vertical-bar, 0x31/fg, 0/bg
draw-code-point-at-cursor screen, 0x7c/vertical-bar, 0x31/fg, 0/bg
move-cursor-down 0
}
{
compare key, 0x6b/k
break-if-!=
draw-code-point-at-cursor 0/screen, 0x7c/vertical-bar, 0x31/fg, 0/bg
draw-code-point-at-cursor screen, 0x7c/vertical-bar, 0x31/fg, 0/bg
move-cursor-up 0
}
{
compare key, 0x6c/l
break-if-!=
var g/eax: code-point <- copy 0x2d/dash
draw-code-point-at-cursor 0/screen, 0x2d/dash, 0x31/fg, 0/bg
draw-code-point-at-cursor screen, 0x2d/dash, 0x31/fg, 0/bg
move-cursor-right 0
}
loop

2
ex8.mu
View File

@ -6,7 +6,7 @@
# bochs -f bochsrc # bochsrc loads disk.img
# Set a breakpoint at 0x7c00 and start stepping.
fn main {
fn main screen: (addr screen), keyboard: (addr keyboard) {
var n/eax: int <- copy 0
var result/xmm0: float <- convert n
}

2
ex9.mu
View File

@ -15,7 +15,7 @@
# 6. Notice that the data disk now contains the word count of the original text.
# xxd data.img |head
fn main {
fn main screen: (addr screen), keyboard: (addr keyboard) {
var text-storage: (stream byte 0x200)
var text/esi: (addr stream byte) <- address text-storage
load-first-sector-from-primary-bus-secondary-drive text

View File

@ -211,7 +211,7 @@ fn render grid: (addr array boolean) {
}
}
fn main {
fn main screen: (addr screen), keyboard: (addr keyboard) {
#? # allocate on the stack
#? var grid1-storage: (array boolean 0xc000) # width * height
#? var grid1/esi: (addr array boolean) <- address grid1-storage
@ -237,7 +237,7 @@ fn main {
# render grid1
render grid1
{
var key/eax: byte <- read-key 0/keyboard
var key/eax: byte <- read-key keyboard
compare key, 0
#? loop-if-= # press key to step
break-if-!= # press key to quit # comment this out to run under bochs; I'm not sure why there's a newline in the keyboard buffer

View File

@ -2,7 +2,9 @@
#
# See translate for how this file is used.
#
# Mu programs start at a function called 'main' without inouts or outputs.
# Mu programs start at a function called 'main' with this signature:
# fn main screen: (addr screen), keyboard: (addr keyboard)
#
# All tests must pass first (the "power-on unit test").
== code
@ -20,7 +22,7 @@ Entry:
(clear-real-screen)
c7 0/subop/copy *Real-screen-cursor-x 0/imm32
c7 0/subop/copy *Real-screen-cursor-y 0/imm32
(main)
(main 0 0)
}
# hang indefinitely

27
mu.md
View File

@ -44,8 +44,7 @@ and [vocabulary.md](vocabulary.md).
## Functions and calls
Zooming out from single statements, here's a complete sample program in Mu
that runs in Linux (Mu programs without an OS need `main` to have a different
signature):
that runs in Linux:
<img alt='ex2.mu' src='html/ex2.mu.png' width='400px'>
@ -104,6 +103,30 @@ documentation).
Variables can't currently accept unchecked metadata for documentation.
(Perhaps this should change.)
The function `main` is special. It's where Mu programs start executing. It has
a different signature depending on whether a Mu program requires Linux or can
run without an OS. On Linux, the signature looks like this:
```
fn main args: (addr array addr array byte) -> _/ebx: int
```
It takes an array of strings and returns a status code to Linux in register
`ebx`.
Without an OS, the signature looks like this:
```
fn main screen: (addr screen), keyboard: (addr keyboard)
```
A screen and keyboard are explicitly passed in. The goal is for all hardware
dependencies to always be explicit. However there are currently gaps:
* The mouse is accessed implicitly
* The disk is accessed implicitly
* The screen argument only supports text-mode graphics. Pixel graphics rely
on implicit access to the screen.
## Blocks
Blocks are useful for grouping related statements. They're delimited by `{`

16
rpn.mu
View File

@ -15,7 +15,7 @@
#
# Error handling is non-existent. This is just a prototype.
fn main {
fn main screen: (addr screen), keyboard: (addr keyboard) {
var in-storage: (stream byte 0x80)
var in/esi: (addr stream byte) <- address in-storage
var y/ecx: int <- copy 0
@ -23,13 +23,13 @@ fn main {
# read-eval-print loop
{
# print prompt
var x/eax: int <- draw-text-rightward 0/screen, "> ", 0/x, 0x80/xmax, y, 3/fg/cyan, 0/bg
set-cursor-position 0/screen, x, y
var x/eax: int <- draw-text-rightward screen, "> ", 0/x, 0x80/xmax, y, 3/fg/cyan, 0/bg
set-cursor-position screen, x, y
# read line from keyboard
clear-stream in
{
draw-cursor 0/screen, space
var key/eax: byte <- read-key 0/keyboard
draw-cursor screen, space
var key/eax: byte <- read-key keyboard
compare key, 0xa/newline
break-if-=
compare key, 0
@ -37,17 +37,17 @@ fn main {
var key2/eax: int <- copy key
append-byte in, key2
var g/eax: grapheme <- copy key2
draw-grapheme-at-cursor 0/screen, g, 0xf/fg, 0/bg
draw-grapheme-at-cursor screen, g, 0xf/fg, 0/bg
move-cursor-right 0
loop
}
# clear cursor
draw-grapheme-at-cursor 0/screen, space, 3/fg/never-used, 0/bg
draw-grapheme-at-cursor screen, space, 3/fg/never-used, 0/bg
# parse and eval
var out/eax: int <- simplify in
# print
y <- increment
out, y <- draw-int32-decimal-wrapping-right-then-down 0/screen, out, 0/xmin, y, 0x80/xmax, 0x30/ymax, 0/x, y, 7/fg, 0/bg
out, y <- draw-int32-decimal-wrapping-right-then-down screen, out, 0/xmin, y, 0x80/xmax, 0x30/ymax, 0/x, y, 7/fg, 0/bg
# newline
y <- increment
#

View File

@ -1,18 +1,18 @@
# Experimental Mu shell
# A Lisp with indent-sensitivity and infix, no macros. Commas are ignored.
fn main {
fn main screen: (addr screen), keyboard: (addr keyboard) {
var sandbox-storage: sandbox
var sandbox/esi: (addr sandbox) <- address sandbox-storage
initialize-sandbox sandbox
load-sandbox-from-secondary-disk sandbox
var width/eax: int <- copy 0
var height/ecx: int <- copy 0
width, height <- screen-size 0/screen
width, height <- screen-size screen
{
render-sandbox 0/screen, sandbox, 2/x, 2/y, width, height
render-sandbox screen, sandbox, 2/x, 2/y, width, height
{
var key/eax: byte <- read-key 0/keyboard
var key/eax: byte <- read-key keyboard
compare key, 0
loop-if-=
# no way to quit right now; just reboot