about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--400.mu3
-rw-r--r--boot.subx30
-rw-r--r--mu-init.subx1
-rw-r--r--shell/README.md17
-rw-r--r--shell/main.mu20
-rw-r--r--vocabulary.md2
6 files changed, 62 insertions, 11 deletions
diff --git a/400.mu b/400.mu
index c60f17ca..391ca57d 100644
--- a/400.mu
+++ b/400.mu
@@ -8,6 +8,9 @@ sig draw-cursor-on-real-screen g: grapheme
 # keyboard
 sig read-key kbd: (addr keyboard) -> _/eax: byte
 
+# disk
+sig load-sector-string-from-primary-bus-secondary-drive LBAlo: byte, LBAmid: byte, LBAhi: byte, out: (addr stream byte)
+
 # tests
 sig count-test-failure
 sig num-test-failures -> _/eax: int
diff --git a/boot.subx b/boot.subx
index 0573d19e..5dc8e5bc 100644
--- a/boot.subx
+++ b/boot.subx
@@ -916,20 +916,23 @@ Font:
 # offset 1800 (address 0x9400)
 == code 0x9400
 
-# Use 28-bit PIO mode to transfer one sector from the primary drive on the
-# primary bus.
+# Use 28-bit PIO mode to transfer a string spanning at most one sector (512
+# bytes) of data.
 # Inspired by https://colorforth.github.io/ide.html
 #
 # Resources:
 #   https://wiki.osdev.org/ATA_PIO_Mode
 #   https://forum.osdev.org/viewtopic.php?f=1&p=167798
 #   read-sector, according to https://www.scs.stanford.edu/11wi-cs140/pintos/specs/ata-3-std.pdf
-read-a-sector:
+#
+# Currently assumes top 4 bits of the 28-bit LBA coordinate are 0.
+load-sector-string-from-primary-bus-secondary-drive:  # LBAlo: byte, LBAmid: byte, LBAhi: byte, out: (addr stream byte)
   # . prologue
   55/push-ebp
   89/<- %ebp 4/r32/esp
   # . save registers
   50/push-eax
+  51/push-ecx
   52/push-edx
   # check for floating bus
   {
@@ -944,26 +947,35 @@ read-a-sector:
   (ata-drive-select 0xf0)  # primary bus, secondary drive; 4 LSBs contain 4 upper bits of LBA (here 0)
   (clear-ata-error)
   (ata-sector-count 1)
-  (ata-lba 0 0 0)  # lower 24 bits of LBA
+  (ata-lba *(ebp+8) *(ebp+0xc) *(ebp+0x10))  # lower 24 bits of LBA
   (ata-command 0x20)  # read sectors with retries
   # poll for results
   (poll-ata-primary-bus-primary-drive-regular-status-word)
   # print out results
   ba/copy-to-edx 0x1f0/imm32
-  b9/copy-to-ecx 0x10/imm32
+  b9/copy-to-ecx 0x200/imm32  # 512 bytes per sector
   {
     81 7/subop/compare %ecx 0/imm32
     74/jump-if-= break/disp8
     ed/read-port-dx-into-eax
-    (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %eax)
-    (move-cursor-to-left-margin-of-next-line 0)  # 0=screen
+    # write 4 bytes to stream one at a time
+    (append-byte *(ebp+0x14) %eax)
+    49/decrement-ecx
+    c1/shift 5/subop/right-padding-zeroes %eax 8/imm8
+    (append-byte *(ebp+0x14) %eax)
+    49/decrement-ecx
+    c1/shift 5/subop/right-padding-zeroes %eax 8/imm8
+    (append-byte *(ebp+0x14) %eax)
+    49/decrement-ecx
+    c1/shift 5/subop/right-padding-zeroes %eax 8/imm8
+    (append-byte *(ebp+0x14) %eax)
     49/decrement-ecx
     eb/jump loop/disp8
   }
-  (abort "success")
-$read-256-sectors:end:
+$load-sector-string-from-primary-bus-secondary-drive:end:
   # . restore registers
   5a/pop-to-edx
+  59/pop-to-ecx
   58/pop-to-eax
   # . epilogue
   89/<- %esp 5/r32/ebp
diff --git a/mu-init.subx b/mu-init.subx
index 7857a8a1..bf9e5b0d 100644
--- a/mu-init.subx
+++ b/mu-init.subx
@@ -10,7 +10,6 @@
 Entry:
   # initialize stack
   bd/copy-to-ebp 0/imm32
-  (read-a-sector)
   # always first run tests
   (run-tests)
   (num-test-failures)  # => eax
diff --git a/shell/README.md b/shell/README.md
index 7a6600c2..463f8e16 100644
--- a/shell/README.md
+++ b/shell/README.md
@@ -1,9 +1,24 @@
 ### A prototype shell for the Mu computer
 
-Currently runs a tiny subset of Lisp. To build and run it from the top-level:
+Currently runs a tiny subset of Lisp. Steps to run it from the top-level:
 
+1. Build it:
 ```sh
 $ ./translate shell/*.mu      # generates disk.img
+```
+
+2. Create a data disk:
+```sh
+$ dd if=/dev/zero of=data.img count=20160
+```
+
+3. Optionally load an s-expression into the disk:
+```sh
+$ echo '(+ 1 1)' |dd of=data.img conv=notrunc
+```
+
+4. Run it:
+```sh
 $ qemu-system-i386 disk.img
 ```
 
diff --git a/shell/main.mu b/shell/main.mu
index eb437b67..38683293 100644
--- a/shell/main.mu
+++ b/shell/main.mu
@@ -5,6 +5,7 @@ fn main {
   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
@@ -20,3 +21,22 @@ fn main {
     loop
   }
 }
+
+# Read a null-terminated sequence of keys from secondary disk and load them
+# into sandbox.
+fn load-sandbox-from-secondary-disk _self: (addr sandbox) {
+  var self/esi: (addr sandbox) <- copy _self
+  var s-storage: (stream byte 0x200)
+  var s/ebx: (addr stream byte) <- address s-storage
+  load-sector-string-from-primary-bus-secondary-drive 0/lbalo, 0/lbamid, 0/lbahi, s
+  {
+    var done?/eax: boolean <- stream-empty? s
+    compare done?, 0/false
+    break-if-!=
+    var key/eax: byte <- read-byte s
+    compare key, 0/null
+    break-if-=
+    edit-sandbox self, key
+    loop
+  }
+}
diff --git a/vocabulary.md b/vocabulary.md
index 1ecbdf8d..badf6b02 100644
--- a/vocabulary.md
+++ b/vocabulary.md
@@ -112,6 +112,8 @@ The most useful functions from 400.mu and later .mu files. Look for definitions
 - `append-byte-hex`: writes textual representation of lowest byte in hex to
   a stream of bytes. Does not write a '0x' prefix.
 - `read-byte`: reads a single byte from a stream of bytes.
+- `read-grapheme`: reads a single unicode grapheme (up to 4 bytes containing a
+  single code-point encoded in utf-8) from a stream of bytes.
 
 #### reading/writing hex representations of integers