about summary refs log tree commit diff stats
path: root/baremetal
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2021-01-15 20:30:07 -0800
committerKartik Agaram <vc@akkartik.com>2021-01-15 20:30:07 -0800
commit6e36ce06dd035408d43a6599b75b933a0709cc78 (patch)
treeb5b90ee59b5387036d311096fed1c96aa588cacb /baremetal
parent20d6be52405130930fde9ca5bb5e95131ba4e659 (diff)
downloadmu-6e36ce06dd035408d43a6599b75b933a0709cc78.tar.gz
7521 - new plan for tests
It's not really manageable to make the fake screen pixel-oriented. Feels
excessive to compare things pixel by pixel when we will mostly be
writing text to screen. It'll also make expected screen assertions
more difficult to manage.

So I'm not sure how to make assertions about pixels for now. Instead
we'll introduce fake screens at draw-grapheme.
Diffstat (limited to 'baremetal')
-rw-r--r--baremetal/101screen.subx56
-rw-r--r--baremetal/102keyboard.subx3
-rw-r--r--baremetal/103grapheme.subx28
-rw-r--r--baremetal/400.mu8
-rw-r--r--baremetal/500clear-screen.mu17
-rw-r--r--baremetal/500text-screen.mu64
-rw-r--r--baremetal/503manhattan-line.mu18
-rw-r--r--baremetal/ex2.mu2
-rw-r--r--baremetal/ex3.mu2
-rw-r--r--baremetal/ex6.mu2
-rw-r--r--baremetal/mu-init.subx2
11 files changed, 124 insertions, 78 deletions
diff --git a/baremetal/101screen.subx b/baremetal/101screen.subx
index 225efeec..5a26a86a 100644
--- a/baremetal/101screen.subx
+++ b/baremetal/101screen.subx
@@ -1,44 +1,38 @@
 # Primitives for screen control.
+#
+# We need to do this in machine code because Mu doesn't have global variables
+# yet (for the start of video memory).
 
 == code
 
-pixel:  # screen: (addr screen), x: int, y: int, color: int
+pixel-on-real-screen:  # x: int, y: int, color: int
     # . prologue
     55/push-ebp
     89/<- %ebp 4/r32/esp
     # . save registers
     50/push-eax
     51/push-ecx
-    # ecx = screen
-    8b/-> *(ebp+8) 1/r32/ecx
-    81 7/subop/compare %ecx 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) 1/r32/ecx
-      88/byte<- *eax 1/r32/CL
-      # return
-      eb $pixel:end/disp8
-    }
-    # TODO: fake screen
-$pixel:end:
+    # bounds checks
+    8b/-> *(ebp+8) 0/r32/eax
+    3d/compare-eax-and 0/imm32
+    7c/jump-if-< $pixel-on-real-screen:end/disp8
+    3d/compare-eax-and 0x400/imm32/1024
+    7d/jump-if->= $pixel-on-real-screen:end/disp8
+    8b/-> *(ebp+0xc) 0/r32/eax
+    3d/compare-eax-and 0/imm32
+    7c/jump-if-< $pixel-on-real-screen:end/disp8
+    3d/compare-eax-and 0x300/imm32/768
+    7d/jump-if->= $pixel-on-real-screen:end/disp8
+    # eax = y*1024 + x
+    8b/-> *(ebp+0xc) 0/r32/eax
+    c1/shift 4/subop/left %eax 0xa/imm8
+    03/add-> *(ebp+8) 0/r32/eax
+    # eax += location of frame buffer
+    03/add-> *0x7f28 0/r32/eax  # unsafe
+    # *eax = color
+    8b/-> *(ebp+0x10) 1/r32/ecx
+    88/byte<- *eax 1/r32/CL
+$pixel-on-real-screen:end:
     # . restore registers
     59/pop-to-ecx
     58/pop-to-eax
diff --git a/baremetal/102keyboard.subx b/baremetal/102keyboard.subx
index b047a7c2..f2c22339 100644
--- a/baremetal/102keyboard.subx
+++ b/baremetal/102keyboard.subx
@@ -1,5 +1,8 @@
 # check keyboard for a key
 # return 0 on no keypress or unrecognized key
+#
+# We need to do this in machine code because Mu doesn't have global variables
+# yet (for the keyboard buffer).
 
 == code
 
diff --git a/baremetal/103grapheme.subx b/baremetal/103grapheme.subx
index 9b19884f..4ee423d7 100644
--- a/baremetal/103grapheme.subx
+++ b/baremetal/103grapheme.subx
@@ -1,8 +1,11 @@
-# Use the built-in font to draw a grapheme to screen.
+# Use the built-in font to draw a grapheme to real screen.
+#
+# We need to do this in machine code because Mu doesn't have global variables
+# yet (for the start of video memory).
 
 == code
 
-draw-grapheme:  # screen: (addr screen), g: grapheme, x: int, y: int, color: int
+draw-grapheme-on-real-screen:  # g: grapheme, x: int, y: int, color: int
     # . prologue
     55/push-ebp
     89/<- %ebp 4/r32/esp
@@ -12,28 +15,27 @@ draw-grapheme:  # screen: (addr screen), g: grapheme, x: int, y: int, color: int
     52/push-edx
     53/push-ebx
     56/push-esi
-    # TODO: support fake screen; we currently assume 'screen' is always 0 (real)
     # var letter-bitmap/esi = font[g]
-    8b/-> *(ebp+0xc) 6/r32/esi
+    8b/-> *(ebp+8) 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
+    8b/-> *(ebp+0x10) 2/r32/edx
     # var ymax/ebx: int = y + 16
-    8b/-> *(ebp+0x14) 3/r32/ebx
+    8b/-> *(ebp+0x10) 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
+      8b/-> *(ebp+0xc) 0/r32/eax
       81 0/subop/add %eax 7/imm32
       # var xmin/ecx: int = x
-      8b/-> *(ebp+0x10) 1/r32/ecx
+      8b/-> *(ebp+0xc) 1/r32/ecx
       # var row-bitmap/ebx: int = *letter-bitmap
       53/push-ebx
       8b/-> *esi 3/r32/ebx
@@ -46,7 +48,7 @@ draw-grapheme:  # screen: (addr screen), g: grapheme, x: int, y: int, color: int
         # if LSB, draw a pixel
         {
           73/jump-if-not-CF break/disp8
-          (pixel *(ebp+8) %eax %edx *(ebp+0x18))
+          (pixel-on-real-screen %eax %edx *(ebp+0x14))
         }
         # --x
         48/decrement-eax
@@ -74,7 +76,7 @@ $draw-grapheme:end:
     5d/pop-to-ebp
     c3/return
 
-cursor-position:  # screen: (addr screen) -> _/eax: int, _/ecx: int
+cursor-position-on-real-screen:  # -> _/eax: int, _/ecx: int
     # . prologue
     55/push-ebp
     89/<- %ebp 4/r32/esp
@@ -87,16 +89,16 @@ $cursor-position:end:
     5d/pop-to-ebp
     c3/return
 
-set-cursor-position:  # screen: (addr screen), x: int, y: int
+set-cursor-position-on-real-screen:  # x: int, y: int
     # . prologue
     55/push-ebp
     89/<- %ebp 4/r32/esp
     # . save registers
     50/push-eax
     # TODO: support fake screen; we currently assume 'screen' is always 0 (real)
-    8b/-> *(ebp+0xc) 0/r32/eax
+    8b/-> *(ebp+8) 0/r32/eax
     89/<- *Default-next-x 0/r32/eax
-    8b/-> *(ebp+0x10) 0/r32/eax
+    8b/-> *(ebp+0xc) 0/r32/eax
     89/<- *Default-next-y 0/r32/eax
 $set-cursor-position:end:
     # . restore registers
diff --git a/baremetal/400.mu b/baremetal/400.mu
index ff84a643..5025a51c 100644
--- a/baremetal/400.mu
+++ b/baremetal/400.mu
@@ -1,8 +1,8 @@
 # screen
-sig pixel screen: (addr screen), x: int, y: int, color: int
-sig draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int
-sig cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int
-sig set-cursor-position screen: (addr screen), x: int, y: int
+sig pixel-on-real-screen x: int, y: int, color: int
+sig draw-grapheme-on-real-screen g: grapheme, x: int, y: int, color: int
+sig cursor-position-on-real-screen -> _/eax: int, _/ecx: int
+sig set-cursor-position-on-real-screen x: int, y: int
 
 # keyboard
 sig read-key kbd: (addr keyboard) -> _/eax: byte
diff --git a/baremetal/500clear-screen.mu b/baremetal/500clear-screen.mu
deleted file mode 100644
index 0dbcdee2..00000000
--- a/baremetal/500clear-screen.mu
+++ /dev/null
@@ -1,17 +0,0 @@
-fn clear-screen screen: (addr screen) {
-  var y/eax: int <- copy 0
-  {
-    compare y, 0x300  # 768
-    break-if->=
-    var x/edx: int <- copy 0
-    {
-      compare x, 0x400  # 1024
-      break-if->=
-      pixel 0, x, y, 0  # black
-      x <- increment
-      loop
-    }
-    y <- increment
-    loop
-  }
-}
diff --git a/baremetal/500text-screen.mu b/baremetal/500text-screen.mu
new file mode 100644
index 00000000..525ddb03
--- /dev/null
+++ b/baremetal/500text-screen.mu
@@ -0,0 +1,64 @@
+# Screen primitives for character-oriented output.
+#
+# Unlike the top-level, this text mode has no scrolling.
+
+fn draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int {
+  {
+    compare screen, 0
+    break-if-!=
+    draw-grapheme-on-real-screen g, x, y, color
+    return
+  }
+  # TODO: fake screen
+}
+
+fn cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int {
+  {
+    compare screen, 0
+    break-if-!=
+    var x/eax: int <- copy 0
+    var y/ecx: int <- copy 0
+    x, y <- cursor-position-on-real-screen
+    return x, y
+  }
+  # TODO: fake screen
+  return 0, 0
+}
+
+fn set-cursor-position screen: (addr screen), x: int, y: int {
+  {
+    compare screen, 0
+    break-if-!=
+    set-cursor-position-on-real-screen x, y
+    return
+  }
+  # TODO: fake screen
+}
+
+fn clear-screen screen: (addr screen) {
+  {
+    compare screen, 0
+    break-if-!=
+    clear-real-screen
+    return
+  }
+  # TODO: fake screen
+}
+
+fn clear-real-screen {
+  var y/eax: int <- copy 0
+  {
+    compare y, 0x300  # 768
+    break-if->=
+    var x/edx: int <- copy 0
+    {
+      compare x, 0x400  # 1024
+      break-if->=
+      pixel-on-real-screen x, y, 0  # black
+      x <- increment
+      loop
+    }
+    y <- increment
+    loop
+  }
+}
diff --git a/baremetal/503manhattan-line.mu b/baremetal/503manhattan-line.mu
index 0351fcb6..5c51473d 100644
--- a/baremetal/503manhattan-line.mu
+++ b/baremetal/503manhattan-line.mu
@@ -1,27 +1,27 @@
-fn draw-box screen: (addr screen), x1: int, y1: int, x2: int, y2: int, color: int {
-  draw-horizontal-line screen, x1, x2, y1, color
-  draw-vertical-line screen, x1, y1, y2, color
-  draw-horizontal-line screen, x1, x2, y2, color
-  draw-vertical-line screen, x2, y1, y2, color
+fn draw-box-on-real-screen x1: int, y1: int, x2: int, y2: int, color: int {
+  draw-horizontal-line-on-real-screen x1, x2, y1, color
+  draw-vertical-line-on-real-screen x1, y1, y2, color
+  draw-horizontal-line-on-real-screen x1, x2, y2, color
+  draw-vertical-line-on-real-screen x2, y1, y2, color
 }
 
-fn draw-horizontal-line screen: (addr screen), x1: int, x2: int, y: int, color: int {
+fn draw-horizontal-line-on-real-screen x1: int, x2: int, y: int, color: int {
   var x/eax: int <- copy x1
   {
     compare x, x2
     break-if->=
-    pixel screen, x, y, color
+    pixel-on-real-screen x, y, color
     x <- increment
     loop
   }
 }
 
-fn draw-vertical-line screen: (addr screen), x: int, y1: int, y2: int, color: int {
+fn draw-vertical-line-on-real-screen x: int, y1: int, y2: int, color: int {
   var y/eax: int <- copy y1
   {
     compare y, y2
     break-if->=
-    pixel screen, x, y, color
+    pixel-on-real-screen x, y, color
     y <- increment
     loop
   }
diff --git a/baremetal/ex2.mu b/baremetal/ex2.mu
index b386fe5b..d7a5e0c4 100644
--- a/baremetal/ex2.mu
+++ b/baremetal/ex2.mu
@@ -21,7 +21,7 @@ fn main {
       break-if->=
       var color/ecx: int <- copy x
       color <- and 0xff
-      pixel 0, x, y, color
+      pixel-on-real-screen x, y, color
       x <- increment
       loop
     }
diff --git a/baremetal/ex3.mu b/baremetal/ex3.mu
index 21e30466..206e22b3 100644
--- a/baremetal/ex3.mu
+++ b/baremetal/ex3.mu
@@ -18,7 +18,7 @@ fn main {
     var key/eax: byte <- read-key 0  # real keyboard
     compare key, 0
     loop-if-=  # busy wait
-    pixel 0, x, y, 0x31  # green
+    pixel-on-real-screen x, y, 0x31  # green
     x <- increment
     compare x, 0x400
     {
diff --git a/baremetal/ex6.mu b/baremetal/ex6.mu
index 5e47a57c..72d21f2e 100644
--- a/baremetal/ex6.mu
+++ b/baremetal/ex6.mu
@@ -11,7 +11,7 @@
 
 fn main {
   # drawing text within a bounding box
-  draw-box 0, 0xf, 0x1f, 0x79, 0x51, 0x4
+  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, "hello ",     0x10, 0x20, 0x78, 0x50, x, y, 0xa  # (0x10, 0x20) -> (0x78, 0x50)
diff --git a/baremetal/mu-init.subx b/baremetal/mu-init.subx
index 77e62ede..a1aa4e99 100644
--- a/baremetal/mu-init.subx
+++ b/baremetal/mu-init.subx
@@ -17,7 +17,7 @@ bd/copy-to-ebp 0/imm32
 {
   3d/compare-eax-and 0/imm32
   75/jump-if-!= break/disp8
-  (clear-screen)
+  (clear-real-screen)
   (main)
 }