I always get 0xFF when I execute inb(0x1F7) under the real machine.
Code: Select all
#define IDE_BSY 0x80
#define IDE_DRDY 0x40
#define IDE_DF 0x20
#define IDE_ERR 0x01
ide_wait_ready(bool check_error)
{
int num = 0x10000;
int r;
while (((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY) {
if (--num == 0) {
return -1;
}
if (check_error && (r & (IDE_DF|IDE_ERR)) != 0)
return -1;
return 0;
}
Code: Select all
int
ide_read(uint32_t secno, void *dst, uint32_t driver ,size_t nsecs)
{
int r;
assert(nsecs <= 256);
ide_wait_ready(0);
outb(0x1F6, 0xE0 | (driver << 4) | ((secno >> 24) & 0x0F));
outb(0x1F1, 0x00);
outb(0x1F2, nsecs);
outb(0x1F3, secno & 0xFF);
outb(0x1F4, (secno >> 8) & 0xFF);
outb(0x1F5, (secno >> 16) & 0xFF);
outb(0x1F6, 0xE0 | ((driver&1)<<4) | ((secno>>24)&0x0F));
outb(0x1F7, 0x20); // CMD 0x20 means read sector
for (; nsecs > 0; nsecs--, dst += SECTSIZE) {
if ((r = ide_wait_ready(1)) < 0)
return r;
insl(0x1F0, dst, SECTSIZE/4);
}
return 0;
}