I was working on my floppy driver this week, and I managed to reinitialize the floppy drive, so I tried working on a function that would read a sector and I follow the steps from the wiki, and made a prototype function, but this one does not work great: On Bochs, I don't get an error, I just don't receive an interrupt. On Qemu I get an error: "FLOPPY ERROR: fdctrl_start_transfer: dma_mode=2 direction=1". I think I didn't do something I was supposed to do with my ISA DMA code, but I don't know what because I can't find a good explanation on how to program the DMA.
Here's my code:
Code: Select all
void setup_dma2(void)
{
dissable(); // Dissable interupts
outb(0x0A, 0x06); // Mask DMA channel 2.
outb(0x0C, 0xFF); // Reset the master flip-flop.
outb(0x04, 0x00); // Address to 0x1000 (low byte).
outb(0x04, 0x10); // Address to 0x1000 (high byte).
outb(0x0C, 0xFF); // Reset the master flip-flop (send any value).
outb(0x05, 0xFF); // Count to 0x23ff (low byte).
outb(0x05, 0x23); // Count to 0x23ff (high byte),
outb(0x81, 0x00); // External page register to 0 for total address of 00 10 00
outb(0x0a, 0x01); // Unmask DMA channel 2
enable(); // Enable interupts.
}
void setup_dma2_read(void)
{
outb(0x0A, 0x06); // Mask DMA channel 2.
outb(0x0B, 0x5A); // 01 0 1 10 10
// Single transfer, address increment, autoinit, read, channel2
outb(0x0a, 0x01); // Unmask DMA channel 2
}
Code: Select all
void ReadFloppy(u8int drive, u8int head, u8int cyl, u8int sect, u8int n)
{
outb(DOR, 0x1C);
delay(500);
setup_dma2_read();
ReceivedIRQ = 0;
outb(DATA_FIFO, 0x80 | 0x40 | 0x6);
outb(DATA_FIFO, (( head << 2) | drive));
outb(DATA_FIFO, cyl);
outb(DATA_FIFO, head);
outb(DATA_FIFO, sect);
outb(DATA_FIFO, 0x02);
outb(DATA_FIFO, n);
outb(DATA_FIFO, 0x1b);
outb(DATA_FIFO, 0xff);
int i = 0;
for(i=0; i < 7; i++)
{
printf("\nWaiting for result byte %d...", i);
while(!(inb(MSR) & (0x1 << 7)));
printf("0x%x Done.", inb(DATA_FIFO));
}
printf("\n Waiting for IRQ...");
FloppyWaitIRQ();
printf(" Done.");
}