:: commit 7506fcb8205e6947ec5c4b49af707c62e368335f

iiSaLMaN <slmanarendo1950@gmail.com> — 2019-06-01 21:34

parents: 77572b0df4

Add simple disk library (#2)

* Simple disk library

* Simple disk library

* add rm_seg and rm_off

* Make interrupt call per 128 sectors

* Matching code style + some modifies

* change max count to 127 + slight modifies 

max count of sectors to make a call with is 127 instead of 128

* make setup_dap static

* Matching actual code style + slight modifies
diff --git a/lib/disk.c b/lib/disk.c
new file mode 100644
index 00000000..911ea89e
--- /dev/null
+++ b/lib/disk.c
@@ -0,0 +1,73 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <lib/libc.h>
+#include <lib/disk.h>
+#include <lib/real.h>
+#include <lib/print.h>
+
+#define DAP_SIZE 16
+#define SECTOR_SIZE 512
+
+static struct {
+    unsigned short size;
+    unsigned short count;
+    unsigned short offset;
+    unsigned short segment;
+    unsigned long long lba;
+} dap = { DAP_SIZE, 0, 0, 0, 0 };
+
+static unsigned char sector_buf[512];
+
+static inline void setup_dap(int lba, int count, int off, int seg) {
+    dap.lba = lba;
+    dap.count = count;
+    dap.offset = off;
+    dap.segment = seg;
+}
+
+static int check_results(struct rm_regs *out) {
+    int ah = (out->eax >> 8) & 0xFF;
+    
+    if (ah) 
+        print("Disk error %x\n", ah);
+
+    return ah;
+} 
+
+int read_sector(int drive, int lba, int count, unsigned char *buffer) {
+    while (count--) {
+        setup_dap(lba++, 1, sector_buf, 0);
+        struct rm_regs r = {0};
+        r.eax = 0x4200;
+        r.edx = drive;
+        r.esi = (unsigned int)&dap;
+        rm_int(0x13, &r, &r);
+        if (check_results(&r)) 
+            return (r.eax >> 8) & 0xFF;
+
+        memcpy(buffer, sector_buf, SECTOR_SIZE);
+        
+        buffer += SECTOR_SIZE;
+    }
+        
+    return 0;
+}
+
+int write_sector(int drive, int lba, int count, const unsigned char *buffer) {
+    while (count--) {
+        memcpy(sector_buf, buffer, SECTOR_SIZE);
+
+        setup_dap(lba++, 1, sector_buf, 0);
+        struct rm_regs r = {0};
+        r.eax = 0x4300;
+        r.edx = drive;
+        r.esi = (unsigned int)&dap;
+        rm_int(0x13, &r, &r);
+        if (check_results(&r)) 
+            return (r.eax >> 8) & 0xFF;
+
+        buffer += SECTOR_SIZE;
+    }
+
+    return 0;
+}
diff --git a/lib/disk.h b/lib/disk.h
new file mode 100644
index 00000000..0fb0844c
--- /dev/null
+++ b/lib/disk.h
@@ -0,0 +1,7 @@
+#ifndef __DISK_H__
+#define __DISK_H__
+
+int read_sector(int drive, int lba, int count, unsigned char *buffer);
+int write_sector(int drive, int lba, int count, unsigned char *buffer);
+
+#endif
diff --git a/lib/real.h b/lib/real.h
index 12730ee1..352bfdfe 100644
--- a/lib/real.h
+++ b/lib/real.h
@@ -3,6 +3,9 @@
 
 #include <stdint.h>
 
+#define rm_seg(x) (unsigned short)(((int)x & 0xFFFF0) >> 4)
+#define rm_off(x) (unsigned short)(((int)x & 0x0000F) >> 0)
+
 struct rm_regs {
     uint32_t ebp;
     uint32_t edi;
tab: 248 wrap: offon