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 +#include +#include +#include +#include +#include + +#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 +#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;