shell: read initial expression from secondary disk

See shell/README.md for (extremely klunky) instructions.
This commit is contained in:
Kartik K. Agaram 2021-03-21 23:10:55 -07:00
parent 2718cb453c
commit e6b42204ef
6 changed files with 62 additions and 11 deletions

3
400.mu
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
```

View File

@ -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
}
}

View File

@ -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