about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ex10.mu8
-rw-r--r--ex2.mu2
-rw-r--r--ex3.mu4
-rw-r--r--ex4.mu4
-rw-r--r--ex5.mu6
-rw-r--r--ex6.mu22
-rw-r--r--ex7.mu16
-rw-r--r--ex8.mu2
-rw-r--r--ex9.mu2
-rw-r--r--life.mu4
-rw-r--r--mu-init.subx6
-rw-r--r--mu.md27
-rw-r--r--rpn.mu16
-rw-r--r--shell/main.mu8
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:
 
 <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 `{`
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