diff options
| author | Alejandro Sior <aho@sior.be> | 2022-05-21 12:05:07 +0200 |
|---|---|---|
| committer | Alejandro Sior <aho@sior.be> | 2022-05-21 12:05:07 +0200 |
| commit | 35c9df451d4f415632a4a1f64b06d1de12340687 (patch) | |
| tree | eae162590c9087639ba20b000d357cfbdcd0ea6a | |
| parent | 68e5c0c5c9dc26e9c7ce4bf5252719ee8dc4b3ae (diff) | |
bios::drive: fix the read function
| -rw-r--r-- | bios/bios.ha | 2 | ||||
| -rw-r--r-- | bios/drive/drive.ha | 74 | ||||
| -rw-r--r-- | main.ha | 19 | ||||
| -rw-r--r-- | rt/abort.ha | 4 | ||||
| -rw-r--r-- | rt/hare.sc | 2 |
5 files changed, 82 insertions, 19 deletions
diff --git a/bios/bios.ha b/bios/bios.ha index aa69f8a..5a3c1aa 100644 --- a/bios/bios.ha +++ b/bios/bios.ha @@ -15,7 +15,7 @@ export let regs: state; // The address of a 512 bytes workspace that is located below 0xFFFFF and can be used to store the results // of various bios calls -export const @symbol("_ws") ws: u16; +export const @symbol("_ws") ws: [4096]u8; // The boot drive number as given by the BIOS at boot time export const @symbol("drive_no") drive_number: u8; diff --git a/bios/drive/drive.ha b/bios/drive/drive.ha index 35cccca..a2992b8 100644 --- a/bios/drive/drive.ha +++ b/bios/drive/drive.ha @@ -1,5 +1,71 @@ -export let @symbol("drive_no") drive_no: u8; -export let @symbol("drive_spt") drive_spt: u8; -export let @symbol("drive_heads") drive_heads: u8; +use bios; -export fn read() void; +def sector_size: u32 = 512; + +export type error = !void; + +// Converts lba to the CHS format +fn lbatochs(lba: u32) (u16, u16, u16) = { + const temp = lba / bios::drive_sectors_per_track; + const sector = (lba % bios::drive_sectors_per_track) + 1; + const head = temp % bios::drive_heads; + const cylinder = temp / bios::drive_heads; + + return (cylinder: u16, head: u16, sector: u16); +}; + +// Reads the sector at lba and place it into the workspace buffer +fn bios_read(lba: u32) (void | error) = { + const chs = lbatochs(lba); + const readcount = len(bios::ws): u32 / sector_size; + + // AH=0x2 (read disk) AL=1 (read 1 sector) + bios::regs.eax = 0x2 << 8 | readcount; + + // CH=cylinder CL=sector + bios::regs.ecx = chs.0 << 8 | chs.2; + + // DH=head DL=driveno + bios::regs.edx = chs.1 << 8 | bios::drive_number; + + let ws = (&bios::ws): uintptr; + bios::regs.es = (ws / 16): u16; + bios::regs.ebx = (ws % 16): u32; + + bios::call(0x13); + + if (bios::regs.eax != readcount) { + return error; + }; +}; + +export fn read(addr: u32, count: size, dest: *[*]u8) (void | error) = { + // the amount of sectors fitting in the workspace (cannot be make a global constant yet, an assertion fails) + const readcount = len(bios::ws): u32 / sector_size; + + // the starting lba + let lba = addr / sector_size; + // the reading head (for starting to read bytes not aligned with the sector) + let head = addr % len(bios::ws); + + let cursor = 0z; + + for (true) { + bios_read(lba)?; + + for (head < len(bios::ws)) { + // XXX: use memmove + dest[cursor] = bios::ws[head]; + + head += 1; + cursor += 1; + if (cursor >= count) { + return; + }; + }; + + head = 0; + lba += readcount; + }; + +}; @@ -15,17 +15,10 @@ export fn main() void = { term::print(&text, "a"); }; - bios::regs.eax = 6 << 8 | 1; - bios::regs.ebx = 0x43 << 8; - bios::regs.ecx = 0; - bios::regs.edx = 5 << 8 | 5; - bios::call(0x10); - bios::regs.eax = 0x2 << 8; - bios::regs.ebx = 0; - bios::regs.edx = 0 << 8 | 0; - bios::call(0x10); - bios::regs.eax = 0x9 << 8 | 'A': u16; - bios::regs.ebx = 0 << 8 | 0xd; - bios::regs.ecx = 8; - bios::call(0x10); + //bios::drive::read(0, 512, bios::ws: uintptr); + let dest = 0x100000: uintptr: *[*]u8; + bios::drive::read(0, 512, dest)!; + if (dest[511] == 0xaa) { + term::print(&text, "\nnice!"); + }; }; diff --git a/rt/abort.ha b/rt/abort.ha index dbe5d76..798c26f 100644 --- a/rt/abort.ha +++ b/rt/abort.ha @@ -1,3 +1,7 @@ export @noreturn fn abort_fixed() void = { halt(); }; + +export @noreturn @symbol("rt.abort") fn abort_() void = { + halt(); +}; @@ -21,7 +21,7 @@ SECTIONS { _p1 = .; . += 4096; _ws = .; - . += 512; + . += 4096; . = 0x7c00; stack_top = .; |
