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;
