From 1a43d12b15c11c1fb1686369665f48d87f350f37 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Fri, 26 Mar 2021 22:47:44 -0700 Subject: [PATCH] explicitly pass screen and keyboard to main --- ex10.mu | 8 ++++---- ex2.mu | 2 +- ex3.mu | 4 ++-- ex4.mu | 4 ++-- ex5.mu | 6 +++--- ex6.mu | 22 +++++++++++----------- ex7.mu | 16 ++++++++-------- ex8.mu | 2 +- ex9.mu | 2 +- life.mu | 4 ++-- mu-init.subx | 6 ++++-- mu.md | 27 +++++++++++++++++++++++++-- rpn.mu | 16 ++++++++-------- shell/main.mu | 8 ++++---- 14 files changed, 76 insertions(+), 51 deletions(-) diff --git a/ex10.mu b/ex10.mu index adc58d87..4d30ac70 100644 --- a/ex10.mu +++ b/ex10.mu @@ -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 } diff --git a/ex2.mu b/ex2.mu index 0d6e91cf..e47b3add 100644 --- a/ex2.mu +++ b/ex2.mu @@ -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 diff --git a/ex3.mu b/ex3.mu index c05a2f47..b4014dbd 100644 --- a/ex3.mu +++ b/ex3.mu @@ -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 diff --git a/ex4.mu b/ex4.mu index 8f0cbd7a..eb3fc899 100644 --- a/ex4.mu +++ b/ex4.mu @@ -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 } diff --git a/ex5.mu b/ex5.mu index cb0ec063..287b1148 100644 --- a/ex5.mu +++ b/ex5.mu @@ -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 } diff --git a/ex6.mu b/ex6.mu index bd0978fe..65a5da7a 100644 --- a/ex6.mu +++ b/ex6.mu @@ -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 } diff --git a/ex7.mu b/ex7.mu index 5b53dbdc..0b84d584 100644 --- a/ex7.mu +++ b/ex7.mu @@ -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 diff --git a/ex8.mu b/ex8.mu index eb013eeb..1be5dfc9 100644 --- a/ex8.mu +++ b/ex8.mu @@ -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 } diff --git a/ex9.mu b/ex9.mu index 711b2e48..003eeb4c 100644 --- a/ex9.mu +++ b/ex9.mu @@ -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 diff --git a/life.mu b/life.mu index c93a8afb..af69c589 100644 --- a/life.mu +++ b/life.mu @@ -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 diff --git a/mu-init.subx b/mu-init.subx index bf9e5b0d..399a9a3f 100644 --- a/mu-init.subx +++ b/mu-init.subx @@ -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 diff --git a/mu.md b/mu.md index 34149a29..09856068 100644 --- a/mu.md +++ b/mu.md @@ -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: ex2.mu @@ -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 `{` diff --git a/rpn.mu b/rpn.mu index f7a56bd1..719fd03d 100644 --- a/rpn.mu +++ b/rpn.mu @@ -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 # diff --git a/shell/main.mu b/shell/main.mu index 07ba00c6..87ad0893 100644 --- a/shell/main.mu +++ b/shell/main.mu @@ -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