Add cached read function + some slight updates
diff --git a/drivers/disk.c b/drivers/disk.c
index 98c91a71..b4f12e9a 100644
--- a/drivers/disk.c
+++ b/drivers/disk.c
@@ -7,6 +7,7 @@
#define SECTOR_SIZE 512
+static uint64_t last_sector = -1;
static uint8_t sector_buf[512];
static struct {
@@ -17,11 +18,11 @@ static struct {
uint64_t lba;
} dap = { 16, 1, 0, 0, 0 };
-int read_sector(int drive, int lba, int count, void *buffer) {
+int read_sector(int drive, void *buffer, uint64_t lba, size_t count) {
dap.offset = (uint16_t)(size_t)sector_buf;
while (count--) {
- dap.lba = lba++;
+ dap.lba = lba;
struct rm_regs r = {0};
r.eax = 0x4200;
r.edx = drive;
@@ -35,9 +36,38 @@ int read_sector(int drive, int lba, int count, void *buffer) {
}
memcpy(buffer, sector_buf, SECTOR_SIZE);
+ last_sector = lba++;
buffer += SECTOR_SIZE;
}
return 0;
}
+
+int read(int drive, void *buffer, int offset, size_t count) {
+ int res;
+
+ if (last_sector == (uint64_t)-1)
+ if ((res = read_sector(drive, sector_buf, 0, 1)))
+ return res;
+
+ uint64_t cur_sector = last_sector + (offset / SECTOR_SIZE);
+ offset %= SECTOR_SIZE;
+
+ size_t sectors_count = 1 + ((offset + count) / SECTOR_SIZE);
+
+ while (sectors_count--) {
+ if (cur_sector != last_sector)
+ if ((res = read_sector(drive, sector_buf, cur_sector, 1)))
+ return res;
+
+ size_t limited_count = ((offset + count) > SECTOR_SIZE) ? (size_t)(SECTOR_SIZE - offset) : count;
+ memcpy(buffer, §or_buf[offset], limited_count);
+
+ offset = (offset + limited_count) % SECTOR_SIZE;
+ buffer += limited_count;
+ cur_sector++;
+ }
+
+ return 0;
+}
