Thank you for answer, I write while for busy. My code is:
Code:
#define ATA_PORT_DATA 0x000
#define ATA_PORT_ERROR 0x001
#define ATA_PORT_FEATURES 0x001
#define ATA_PORT_SCT_COUNT 0x002
#define ATA_PORT_SCT_NUMBER 0x003
#define ATA_PORT_CYL_LOW 0x004
#define ATA_PORT_CYL_HIGH 0x005
#define ATA_PORT_DRV 0x006
#define ATA_PORT_STATUS 0x007
#define ATA_PORT_COMMAND 0x007
uint16_t buffer[256];
void ata_pio28(uint16_t base, uint8_t type, uint64_t addr, uint8_t drive) {
if(drive==ATA_MASTER) {
outb(base+ATA_PORT_DRV, 0xE0);
}
else { // ATA_SLAVE
outb(base+ATA_PORT_DRV, 0xF0);
}
if ((inb(base+ATA_PORT_STATUS) & 0x01)) {
system_ata_pio_error();
return;
}
//PIO28
outb(base+ATA_PORT_FEATURES, 0x00);
outb(base+ATA_PORT_SCT_COUNT, 0x01);
outb(base+ATA_PORT_SCT_NUMBER, (unsigned char)addr);
outb(base+ATA_PORT_CYL_LOW, (unsigned char)(addr >> 8));
outb(base+ATA_PORT_CYL_HIGH, (unsigned char)(addr >> 16));
//type
if(type==ATA_READ) {
outb(base+ATA_PORT_COMMAND, 0x20); // Send command
}
else {
outb(base+ATA_PORT_COMMAND, 0x30);
}
//wait
while (!(inb(base+ATA_PORT_STATUS) & 0x80)) {} //BSY bit
while (!(inb(base+ATA_PORT_STATUS) & 0x08)) {} //DRQ bit
for (int idx = 0; idx < 256; idx++)
{
if(type==ATA_READ) {
buffer[idx] = inw(base + ATA_PORT_DATA);
}
else {
outw(base + ATA_PORT_DATA, buffer[idx]);
}
}
}
Hard disc is in Primary Master.