summaryrefslogtreecommitdiff
path: root/drive/drive.ha
diff options
context:
space:
mode:
authorAlejandro Sior <aho@sior.be>2022-05-19 08:45:26 +0200
committerAlejandro Sior <aho@sior.be>2022-05-19 08:45:26 +0200
commit776a3710652f78b44718450406d0683974aef72a (patch)
tree84f1b70e07b831d13db8c53c0ab0030ec0d85c09 /drive/drive.ha
parente50cbe8eb763cf63fb44b047d5164f6fbf07eb39 (diff)
bios: stub calls interrupt number; simplified bios.ha main interface
Instead of having the bios.call stub calling a function, make it directly call an interrupt that is changed dynamically by modifying the code at runtime. Simplify the bios.ha interface and document it. Next up: implementing a high level drive interface for the BIOS using BIOS interrupts
Diffstat (limited to 'drive/drive.ha')
-rw-r--r--drive/drive.ha20
1 files changed, 20 insertions, 0 deletions
diff --git a/drive/drive.ha b/drive/drive.ha
new file mode 100644
index 0000000..42cef43
--- /dev/null
+++ b/drive/drive.ha
@@ -0,0 +1,20 @@
+use bios;
+use bios::drive;
+
+fn lba_to_chs(lba: u16) (u16, u16, u16) = {
+ let temp = lba / bios::drive::drive_spt;
+ let sector = (lba % bios::drive::drive_spt) + 1;
+ let head = temp % bios::drive::drive_heads;
+ let cylinder = temp / bios::drive::drive_heads;
+
+ return (cylinder, head, sector);
+};
+
+export fn read(sector: u16, dest: uintptr) void = {
+ let chs = lba_to_chs(sector);
+
+ bios::regs.eax = 1 | 0x2 << 8;
+ bios::regs.ebx = ws;
+ bios::regs.ecx = chs.2 | chs.0 << 8;
+ bios::regs.edx = bios::drive::drive_no | chs.1 << 8;
+};