about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--baremetal/101screen.subx46
-rw-r--r--baremetal/400.mu1
-rw-r--r--baremetal/ex2.mu31
-rw-r--r--baremetal/mu-init.subx17
-rwxr-xr-xtranslate_mu_baremetal9
5 files changed, 104 insertions, 0 deletions
diff --git a/baremetal/101screen.subx b/baremetal/101screen.subx
new file mode 100644
index 00000000..3e98d96b
--- /dev/null
+++ b/baremetal/101screen.subx
@@ -0,0 +1,46 @@
+# Primitives for screen control.
+
+pixel:  # screen: (addr screen), x: int, y: int, color: int
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    50/push-eax
+    56/push-esi
+    # esi = screen
+    8b/-> *(ebp+8) 6/r32/esi
+    81 7/subop/compare %esi 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) 6/r32/esi
+      88/byte<- *eax 6/r32/esi
+      # return
+      eb $pixel:end/disp8
+    }
+    # TODO: fake screen
+$pixel:end:
+    # . restore registers
+    5e/pop-to-esi
+    58/pop-to-eax
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
diff --git a/baremetal/400.mu b/baremetal/400.mu
new file mode 100644
index 00000000..1121a00a
--- /dev/null
+++ b/baremetal/400.mu
@@ -0,0 +1 @@
+sig pixel screen: (addr screen), x: int, y: int, color: int
diff --git a/baremetal/ex2.mu b/baremetal/ex2.mu
new file mode 100644
index 00000000..091cb1d0
--- /dev/null
+++ b/baremetal/ex2.mu
@@ -0,0 +1,31 @@
+# Test out the video mode by filling in the screen with pixels.
+#
+# To build a disk image:
+#   ./translate_subx_baremetal baremetal/ex2.subx    # emits disk.img
+# To run:
+#   qemu-system-i386 disk.img
+# Or:
+#   bochs -f baremetal/boot.bochsrc  # boot.bochsrc loads disk.img
+#
+# Expected output:
+#   html/baremetal.png
+
+fn main {
+  var y/eax: int <- copy 0
+  {
+    compare y, 0x300  # 768
+    break-if->=
+    var color/ecx: int <- copy y
+    color <- and 0xff
+    var x/edx: int <- copy 0
+    {
+      compare x, 0x400  # 1024
+      break-if->=
+      pixel 0, x, y, color
+      x <- increment
+      loop
+    }
+    y <- increment
+    loop
+  }
+}
diff --git a/baremetal/mu-init.subx b/baremetal/mu-init.subx
new file mode 100644
index 00000000..232b3b49
--- /dev/null
+++ b/baremetal/mu-init.subx
@@ -0,0 +1,17 @@
+# Initialize the minimal runtime for Mu programs.
+#
+# See translate_mu_baremetal for how this file is used.
+#
+# Mu baremetal programs start at a function called 'main' without inouts or outputs.
+
+== code
+
+# initialize stack
+bd/copy-to-ebp 0/imm32
+# no heap yet
+(main)
+
+# hang indefinitely
+{
+  eb/jump loop/disp8
+}
diff --git a/translate_mu_baremetal b/translate_mu_baremetal
new file mode 100755
index 00000000..66b27b23
--- /dev/null
+++ b/translate_mu_baremetal
@@ -0,0 +1,9 @@
+#!/bin/sh
+# Translate a given Mu program to 'baremetal', a raw disk image that can boot
+# and run without any OS.
+
+set -e
+
+cat $* baremetal/[0-9]*.mu    |apps/mu    > a.subx
+
+./translate_subx_baremetal baremetal/mu-init.subx baremetal/[0-9]*.subx a.subx