diff --git a/boot.subx b/boot.subx index 5dc8e5bc..855d7f18 100644 --- a/boot.subx +++ b/boot.subx @@ -934,15 +934,10 @@ load-sector-string-from-primary-bus-secondary-drive: # LBAlo: byte, LBAmid: byt 50/push-eax 51/push-ecx 52/push-edx - # check for floating bus - { - 31/xor %eax 0/r32/eax - ba/copy-to-edx 0x1f7/imm32 - ec/read-port-dx-into-al - 81 7/subop/compare %eax 0xff/imm32 - 75/jump-if-!= break/disp8 - (abort "primary bus has no drives") - } + # check for drive + (secondary-drive-exists?) # => eax + 3d/compare-eax-and 0/imm32/false + 0f 84/jump-if-= $load-sector-string-from-primary-bus-secondary-drive:end/disp32 # kick off read (ata-drive-select 0xf0) # primary bus, secondary drive; 4 LSBs contain 4 upper bits of LBA (here 0) (clear-ata-error) @@ -982,6 +977,66 @@ $load-sector-string-from-primary-bus-secondary-drive:end: 5d/pop-to-ebp c3/return +secondary-drive-exists?: # -> _/eax: boolean + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 52/push-edx + # check for floating bus + { + 31/xor %eax 0/r32/eax + ba/copy-to-edx 0x1f7/imm32 + ec/read-port-dx-into-al + 3d/compare-eax-and 0xff/imm32 + # if eax is 0xff, primary bus has no drives + b8/copy-to-eax 0/imm32/false + 74/jump-if-= $secondary-drive-exists?:end/disp8 + } + # identify + (ata-drive-select 0xb0) # primary bus, secondary drive + (ata-sector-count 0) + (ata-lba 0 0 0) + (ata-command 0xec) # identify + # read status register + # TODO: might need to spin here for 400ns: https://wiki.osdev.org/index.php?title=ATA_PIO_Mode&oldid=25664#400ns_delays + 31/xor %eax 0/r32/eax + ba/copy-to-edx 0x1f7/imm32 + ec/read-port-dx-into-al + # if eax is 0, secondary drive does not exist + 3d/compare-eax-and 0/imm32 + { + 74/jump-if-= break/disp8 + b8/copy-to-eax 1/imm32/true + eb/jump $secondary-drive-exists?:complete-identify/disp8 + } + # TODO: might need to perform remaining steps at https://wiki.osdev.org/index.php?title=ATA_PIO_Mode&oldid=25664#IDENTIFY_command + b8/copy-to-eax 0/imm32/false +$secondary-drive-exists?:complete-identify: + 50/push-eax + # clear FIFO from the drive + ba/copy-to-edx 0x1f0/imm32 + b9/copy-to-ecx 0x200/imm32 + { + 81 7/subop/compare %ecx 0/imm32 + 74/jump-if-= break/disp8 + # read 4 bytes + ed/read-port-dx-into-eax + 49/decrement-ecx + 49/decrement-ecx + 49/decrement-ecx + 49/decrement-ecx + eb/jump loop/disp8 + } + 58/pop-to-eax +$secondary-drive-exists?:end: + # . restore registers + 5a/pop-to-edx + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + ata-drive-select: # n: byte # . prologue 55/push-ebp diff --git a/shell/README.md b/shell/README.md index 463f8e16..fce3fbd1 100644 --- a/shell/README.md +++ b/shell/README.md @@ -7,19 +7,24 @@ Currently runs a tiny subset of Lisp. Steps to run it from the top-level: $ ./translate shell/*.mu # generates disk.img ``` -2. Create a data disk: +2. Run it: +```sh +$ qemu-system-i386 disk.img +``` + +To save typing in a large s-expression, create a secondary disk for data: ```sh $ dd if=/dev/zero of=data.img count=20160 ``` -3. Optionally load an s-expression into the disk: +Load an s-expression into it: ```sh $ echo '(+ 1 1)' |dd of=data.img conv=notrunc ``` -4. Run it: +4. Now run with both code and data disks: ```sh -$ qemu-system-i386 disk.img +$ qemu-system-i386 -hda disk.img -hdb data.img ``` You can type in expressions, hit `ctrl-s` to see their results, and hit `Tab`