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
|
# keyboard
|
||||||
sig read-key kbd: (addr keyboard) -> _/eax: byte
|
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
|
# tests
|
||||||
sig count-test-failure
|
sig count-test-failure
|
||||||
sig num-test-failures -> _/eax: int
|
sig num-test-failures -> _/eax: int
|
||||||
|
|
30
boot.subx
30
boot.subx
|
@ -916,20 +916,23 @@ Font:
|
||||||
# offset 1800 (address 0x9400)
|
# offset 1800 (address 0x9400)
|
||||||
== code 0x9400
|
== code 0x9400
|
||||||
|
|
||||||
# Use 28-bit PIO mode to transfer one sector from the primary drive on the
|
# Use 28-bit PIO mode to transfer a string spanning at most one sector (512
|
||||||
# primary bus.
|
# bytes) of data.
|
||||||
# Inspired by https://colorforth.github.io/ide.html
|
# Inspired by https://colorforth.github.io/ide.html
|
||||||
#
|
#
|
||||||
# Resources:
|
# Resources:
|
||||||
# https://wiki.osdev.org/ATA_PIO_Mode
|
# https://wiki.osdev.org/ATA_PIO_Mode
|
||||||
# https://forum.osdev.org/viewtopic.php?f=1&p=167798
|
# 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-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
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
# . save registers
|
# . save registers
|
||||||
50/push-eax
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
52/push-edx
|
52/push-edx
|
||||||
# check for floating bus
|
# 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)
|
(ata-drive-select 0xf0) # primary bus, secondary drive; 4 LSBs contain 4 upper bits of LBA (here 0)
|
||||||
(clear-ata-error)
|
(clear-ata-error)
|
||||||
(ata-sector-count 1)
|
(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
|
(ata-command 0x20) # read sectors with retries
|
||||||
# poll for results
|
# poll for results
|
||||||
(poll-ata-primary-bus-primary-drive-regular-status-word)
|
(poll-ata-primary-bus-primary-drive-regular-status-word)
|
||||||
# print out results
|
# print out results
|
||||||
ba/copy-to-edx 0x1f0/imm32
|
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
|
81 7/subop/compare %ecx 0/imm32
|
||||||
74/jump-if-= break/disp8
|
74/jump-if-= break/disp8
|
||||||
ed/read-port-dx-into-eax
|
ed/read-port-dx-into-eax
|
||||||
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %eax)
|
# write 4 bytes to stream one at a time
|
||||||
(move-cursor-to-left-margin-of-next-line 0) # 0=screen
|
(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
|
49/decrement-ecx
|
||||||
eb/jump loop/disp8
|
eb/jump loop/disp8
|
||||||
}
|
}
|
||||||
(abort "success")
|
$load-sector-string-from-primary-bus-secondary-drive:end:
|
||||||
$read-256-sectors:end:
|
|
||||||
# . restore registers
|
# . restore registers
|
||||||
5a/pop-to-edx
|
5a/pop-to-edx
|
||||||
|
59/pop-to-ecx
|
||||||
58/pop-to-eax
|
58/pop-to-eax
|
||||||
# . epilogue
|
# . epilogue
|
||||||
89/<- %esp 5/r32/ebp
|
89/<- %esp 5/r32/ebp
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
Entry:
|
Entry:
|
||||||
# initialize stack
|
# initialize stack
|
||||||
bd/copy-to-ebp 0/imm32
|
bd/copy-to-ebp 0/imm32
|
||||||
(read-a-sector)
|
|
||||||
# always first run tests
|
# always first run tests
|
||||||
(run-tests)
|
(run-tests)
|
||||||
(num-test-failures) # => eax
|
(num-test-failures) # => eax
|
||||||
|
|
|
@ -1,9 +1,24 @@
|
||||||
### A prototype shell for the Mu computer
|
### 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
|
```sh
|
||||||
$ ./translate shell/*.mu # generates disk.img
|
$ ./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
|
$ qemu-system-i386 disk.img
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ fn main {
|
||||||
var sandbox-storage: sandbox
|
var sandbox-storage: sandbox
|
||||||
var sandbox/esi: (addr sandbox) <- address sandbox-storage
|
var sandbox/esi: (addr sandbox) <- address sandbox-storage
|
||||||
initialize-sandbox sandbox
|
initialize-sandbox sandbox
|
||||||
|
load-sandbox-from-secondary-disk sandbox
|
||||||
var width/eax: int <- copy 0
|
var width/eax: int <- copy 0
|
||||||
var height/ecx: int <- copy 0
|
var height/ecx: int <- copy 0
|
||||||
width, height <- screen-size 0/screen
|
width, height <- screen-size 0/screen
|
||||||
|
@ -20,3 +21,22 @@ fn main {
|
||||||
loop
|
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
|
- `append-byte-hex`: writes textual representation of lowest byte in hex to
|
||||||
a stream of bytes. Does not write a '0x' prefix.
|
a stream of bytes. Does not write a '0x' prefix.
|
||||||
- `read-byte`: reads a single byte from a stream of bytes.
|
- `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
|
#### reading/writing hex representations of integers
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue