summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlejandro Sior <aho@sior.be>2022-05-21 12:05:07 +0200
committerAlejandro Sior <aho@sior.be>2022-05-21 12:05:07 +0200
commit35c9df451d4f415632a4a1f64b06d1de12340687 (patch)
treeeae162590c9087639ba20b000d357cfbdcd0ea6a
parent68e5c0c5c9dc26e9c7ce4bf5252719ee8dc4b3ae (diff)
bios::drive: fix the read function
-rw-r--r--bios/bios.ha2
-rw-r--r--bios/drive/drive.ha74
-rw-r--r--main.ha19
-rw-r--r--rt/abort.ha4
-rw-r--r--rt/hare.sc2
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;
+ };
+
+};
diff --git a/main.ha b/main.ha
index 75ccb98..e26fb26 100644
--- a/main.ha
+++ b/main.ha
@@ -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();
+};
diff --git a/rt/hare.sc b/rt/hare.sc
index 3de964c..ac8c4c5 100644
--- a/rt/hare.sc
+++ b/rt/hare.sc
@@ -21,7 +21,7 @@ SECTIONS {
_p1 = .;
. += 4096;
_ws = .;
- . += 512;
+ . += 4096;
. = 0x7c00;
stack_top = .;