Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
int waituntilbusy(unsigned int base)
{
unsigned int maxtry = 300000;
unsigned char r;
while(((r = inb(base + 0x07)) & 0x80) || !(r & 0x40))
{
maxtry--;
if (maxtry == 0)
{
puts("Error: read time-out.\n");
return 0;
}
}
return 1;
}
int GetSector(unsigned char ide, unsigned long drive, unsigned long sector)
{
unsigned char buffer[512];
unsigned int idx;
unsigned short tmpword;
unsigned short base;
if (ide == 0)
base = 0x1F0;
else
if (ide == 1)
base = 0x170;
else
return 0;
// first set the read parameters
outb(base + 1, 0x0); // reset the error flag
outb(base + 2, 0x1); // read 1 sector
outb(base + 3, (unsigned char)sector); // first address byte
outb(base + 4, (unsigned char)(sector >> 8)); // second address byte
outb(base + 5, (unsigned char)(sector >> 16)); // third address byte
outb(base + 6, 0xE0 | (drive << 4) | ((sector >> 24) & 0x0F)); // select drive
outb(base + 7, 0x20); // read with retry
if (!waituntilbusy(base))
return 0;
for (idx = 0; idx < 256; idx++)
{
tmpword = inw(base); // read a word
buffer[idx * 2] = (unsigned char)tmpword;
buffer[idx * 2 + 1] = (unsigned char)(tmpword >> 8);
}
for (idx = 0; idx < 512; idx++)
putch(buffer[idx]);
return 1;
}
Oddly, when I use 0xA0 instead of 0xE0, I get a good result, but only for the first sector. I haven't got a clue where to look for the error, I've tried so many things. Have you got an idea?
Heh. Clearly Laksen has read ATA_PIO_Mode -- it would be wise for you to see it, too, Revelation.
The 0xE0 vs. 0x40 should not cause problems. The extra bits are for compatibility with legacy disks.
I am more likely to guess that you are calling this funtion with bad values for your LBA sector number. Do you understand that LBAs start at 0?
(And you should also test that "drive" is never anything other than 0 or 1.)
Edit: and what is your waituntilbusy function supposed to do? You are supposed to wait until bsy=0 and drq=1. not until bsy!=1 and drdy!=0
Are you sure the code is wrong? It looks fine to me.
Heh. Clearly Laksen has read ATA_PIO_Mode -- it would be wise for you to see it, too, Revelation.
I have read it.
I am more likely to guess that you are calling this funtion with bad values for your LBA sector number. Do you understand that LBAs start at 0?
(And you should also test that "drive" is never anything other than 0 or 1.)
I'm starting to wonder if my code is using LBA, because when I enter 1 as the sector, I get the first block, like with CHS. How can I make sure my code uses LBA?
edit: I just read the specs, and it says that the E0 should do the trick...
I've found the problem: once again it's bochs. My code works fine if I test it on my real computer. Now I have to figure out why bochs doesn't like LBA.