shell: read initial expression from secondary disk
See shell/README.md for (extremely klunky) instructions.
This commit is contained in:
parent
2718cb453c
commit
e6b42204ef
3
400.mu
3
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
|
||||
|
|
30
boot.subx
30
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue