about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--apps/sigils.subx2
-rw-r--r--baremetal/103grapheme.subx70
-rw-r--r--baremetal/400.mu1
-rw-r--r--baremetal/ex4.mu15
4 files changed, 88 insertions, 0 deletions
diff --git a/apps/sigils.subx b/apps/sigils.subx
index 05efe305..31d074af 100644
--- a/apps/sigils.subx
+++ b/apps/sigils.subx
@@ -34,6 +34,8 @@
 #   $ echo '*Foo'  |  ./bootstrap run apps/sigils
 #   0/mod 5/rm32/.disp32 Foo/disp32
 #
+# TODO: *(Foo+ecx<<2)
+#
 # Addition isn't commutative here. Template must always be (base+index<<scale+disp),
 # though some components are optional as described above.
 # In particular, global variables like 'Foo' above don't support displacement
diff --git a/baremetal/103grapheme.subx b/baremetal/103grapheme.subx
new file mode 100644
index 00000000..934aac51
--- /dev/null
+++ b/baremetal/103grapheme.subx
@@ -0,0 +1,70 @@
+draw-grapheme:  # screen: (addr screen), g: grapheme, x: int, y: int, color: int
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    50/push-eax
+    51/push-ecx
+    52/push-edx
+    53/push-ebx
+    56/push-esi
+    # var letter-bitmap/esi = font[g]
+    8b/-> *(ebp+0xc) 6/r32/esi
+    c1 4/subop/shift-left %esi 4/imm8
+    8d/copy-address *(esi+0x8800) 6/r32/esi  # font-start
+    # if (letter-bitmap >= 0x9000) return  # characters beyond ASCII currently not supported
+    81 7/subop/compare %esi 0x9000/imm32
+    7d/jump-if->= $draw-grapheme:end/disp8
+    # edx = y
+    8b/-> *(ebp+0x14) 2/r32/edx
+    # var ymax/ebx: int = y + 16
+    8b/-> *(ebp+0x14) 3/r32/ebx
+    81 0/subop/add %ebx 0x10/imm32
+    {
+      # if (y >= ymax) break
+      39/compare %edx 3/r32/ebx
+      7d/jump-if->= break/disp8
+      # eax = x + 7
+      8b/-> *(ebp+0x10) 0/r32/eax
+      81 0/subop/add %eax 7/imm32
+      # var xmin/ecx: int = x
+      8b/-> *(ebp+0x10) 1/r32/ecx
+      # var row-bitmap/ebx: int = *letter-bitmap
+      53/push-ebx
+      8b/-> *esi 3/r32/ebx
+      {
+        # if (x < xmin) break
+        39/compare %eax 1/r32/ecx
+        7c/jump-if-< break/disp8
+        # shift LSB from row-bitmap into carry flag (CF)
+        c1 5/subop/shift-right-logical %ebx 1/imm8
+        # if LSB, draw a pixel
+        {
+          73/jump-if-not-CF break/disp8
+          (pixel *(ebp+8) %eax %edx *(ebp+0x18))
+        }
+        # --x
+        48/decrement-eax
+        #
+        eb/jump loop/disp8
+      }
+      # reclaim row-bitmap
+      5b/pop-to-ebx
+      # ++y
+      42/increment-edx
+      # next bitmap row
+      46/increment-esi
+      #
+      eb/jump loop/disp8
+    }
+$draw-grapheme:end:
+    # . restore registers
+    5e/pop-to-esi
+    5b/pop-to-ebx
+    5a/pop-to-edx
+    59/pop-to-ecx
+    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
index 0f36e3fe..016204c5 100644
--- a/baremetal/400.mu
+++ b/baremetal/400.mu
@@ -1,2 +1,3 @@
 sig pixel screen: (addr screen), x: int, y: int, color: int
 sig read-key kbd: (addr keyboard) -> _/eax: byte
+sig draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int
diff --git a/baremetal/ex4.mu b/baremetal/ex4.mu
new file mode 100644
index 00000000..52b681bc
--- /dev/null
+++ b/baremetal/ex4.mu
@@ -0,0 +1,15 @@
+# Draw a character using the built-in font (GNU unifont)
+#
+# To build a disk image:
+#   ./translate_mu_baremetal baremetal/ex4.mu     # emits disk.img
+# To run:
+#   qemu-system-i386 disk.img
+# Or:
+#   bochs -f baremetal/boot.bochsrc               # boot.bochsrc loads disk.img
+#
+# Expected output: letter 'A' in green near the top-left corner of screen
+
+fn main {
+  var g/eax: grapheme <- copy 0x41  # 'A'
+  draw-grapheme 0, g, 0x10, 0x10, 0xa
+}