about summary refs log tree commit diff stats
path: root/baremetal
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2021-01-13 16:57:04 -0800
committerKartik Agaram <vc@akkartik.com>2021-01-13 16:57:04 -0800
commitec0d5bb17e22e31c0edfc1b9b1e95ef363d690e7 (patch)
tree0dd6b1dd1b9358f0e9495545bf6679f777706bbd /baremetal
parentf6fd7e1be0780b5b6dee042bef1c4f0264069787 (diff)
downloadmu-ec0d5bb17e22e31c0edfc1b9b1e95ef363d690e7.tar.gz
7510 - baremetal: a game of snake
Diffstat (limited to 'baremetal')
-rw-r--r--baremetal/501draw-text.mu61
-rw-r--r--baremetal/ex7.mu46
2 files changed, 107 insertions, 0 deletions
diff --git a/baremetal/501draw-text.mu b/baremetal/501draw-text.mu
index 5ddb4bf5..fa284d68 100644
--- a/baremetal/501draw-text.mu
+++ b/baremetal/501draw-text.mu
@@ -1,3 +1,64 @@
+# some primitives for moving the cursor without making assumptions about
+# raster order
+fn cursor-left screen: (addr screen) {
+  var cursor-x/eax: int <- copy 0
+  var cursor-y/ecx: int <- copy 0
+  cursor-x, cursor-y <- cursor-position screen
+  compare cursor-x, 0
+  {
+    break-if->
+    return
+  }
+  cursor-x <- subtract 8  # font-width
+  set-cursor-position screen, cursor-x, cursor-y
+}
+
+fn cursor-right screen: (addr screen) {
+  var cursor-x/eax: int <- copy 0
+  var cursor-y/ecx: int <- copy 0
+  cursor-x, cursor-y <- cursor-position screen
+  compare cursor-x, 0x400  # screen-width
+  {
+    break-if-<
+    return
+  }
+  cursor-x <- add 8  # font-width
+  set-cursor-position screen, cursor-x, cursor-y
+}
+
+fn cursor-up screen: (addr screen) {
+  var cursor-x/eax: int <- copy 0
+  var cursor-y/ecx: int <- copy 0
+  cursor-x, cursor-y <- cursor-position screen
+  compare cursor-y, 0
+  {
+    break-if->
+    return
+  }
+  cursor-y <- subtract 0x10  # screen-height
+  set-cursor-position screen, cursor-x, cursor-y
+}
+
+fn cursor-down screen: (addr screen) {
+  var cursor-x/eax: int <- copy 0
+  var cursor-y/ecx: int <- copy 0
+  cursor-x, cursor-y <- cursor-position screen
+  compare cursor-y, 0x300  # screen-height
+  {
+    break-if-<
+    return
+  }
+  cursor-y <- add 0x10  # screen-height
+  set-cursor-position screen, cursor-x, cursor-y
+}
+
+fn draw-grapheme-at-cursor screen: (addr screen), g: grapheme, color: int {
+  var cursor-x/eax: int <- copy 0
+  var cursor-y/ecx: int <- copy 0
+  cursor-x, cursor-y <- cursor-position screen
+  draw-grapheme screen, g, cursor-x, cursor-y, color
+}
+
 # draw a single line of text from x, y to xmax
 # return the next 'x' coordinate
 # if there isn't enough space, return 0 without modifying the screen
diff --git a/baremetal/ex7.mu b/baremetal/ex7.mu
new file mode 100644
index 00000000..6beac7aa
--- /dev/null
+++ b/baremetal/ex7.mu
@@ -0,0 +1,46 @@
+# Cursor-based motions.
+#
+# To build a disk image:
+#   ./translate_mu_baremetal baremetal/ex7.mu     # emits disk.img
+# To run:
+#   qemu-system-i386 disk.img
+# Or:
+#   bochs -f baremetal/boot.bochsrc               # boot.bochsrc loads disk.img
+#
+# Expected output: an interactive game a bit like "snakes". Try pressing h, j,
+# k, l.
+
+fn main {
+  {
+    var key/eax: byte <- read-key 0
+    {
+      compare key, 0x68  # 'h'
+      break-if-!=
+      var g/eax: grapheme <- copy 0x2d  # '-'
+      draw-grapheme-at-cursor 0, g, 0x31
+      cursor-left 0
+    }
+    {
+      compare key, 0x6a  # 'j'
+      break-if-!=
+      var g/eax: grapheme <- copy 0x7c  # '|'
+      draw-grapheme-at-cursor 0, g, 0x31
+      cursor-down 0
+    }
+    {
+      compare key, 0x6b  # 'k'
+      break-if-!=
+      var g/eax: grapheme <- copy 0x7c  # '|'
+      draw-grapheme-at-cursor 0, g, 0x31
+      cursor-up 0
+    }
+    {
+      compare key, 0x6c  # 'l'
+      break-if-!=
+      var g/eax: grapheme <- copy 0x2d  # '-'
+      draw-grapheme-at-cursor 0, g, 0x31
+      cursor-right 0
+    }
+    loop
+  }
+}