I have been following the wiki article about floppy drivers and also mystran's tutorial thread, but I keep getting errors when I calibrate the floppy drive.
I first do a reset by clearing and then setting bit 2 in the DOR reg.
Then I clear the CCR register to set the drive for 500kb/s operation.
The function floppy_fix_drive_data() sets up function 0x03 with appropriate (i think) timings for the drive.
Then when I get to the recalibration function, I get errors from the check_interrupt_status function. It fails all 4 times with the same issues.
Here's the code for the critical parts, if you want to see more just ask.
Code: Select all
#define base_address 0x03f0
#define DOR_register 0x03f2
#define status_register 0x03f4
#define data_register 0x03f5
#define CCR_register 0x03f7
/* -- DOR Register Bits -- */
#define DR0 0x01
#define DR1 0x02
#define REST 0x04
#define DMA 0x08
#define MOTA 0x10
#define MOTB 0x20
#define MOTC 0x40
#define MATD 0x80
/* -- Main Status Register Bits -- */
#define ACTA 0x01
#define ACTB 0x02
#define ACTC 0x04
#define ACTD 0x08
#define BUSY 0x10
#define NDMA 0x20
#define DIO 0x40
#define MRQ 0x80
void wait_for_data()
{
int timeout = 1000;
while((inportb(status_register) & BUSY) != 0)
{if(timeout){timeout--;wait(5);}else{break;}}
if(!timeout){printf("fdc - wait_for_data timeout! \n");}
}
unsigned short floppy_check_interrupt_status()
{
unsigned short ret_val = 0;
while(1)
{
floppy_write_cmd(0x08);
wait_for_data();
ret_val = ((read_controller() << 8) & 0xFF00);
if((ret_val & 0xFF00) != 0x8000)
{
wait_for_data();
ret_val |= (read_controller() & 0xFF);
break;
}
}
printf("fdc - interrupt_status: %x \n", ret_val);
return ret_val;
}
void floppy_recalibrate()
{
int timeout = 4;
turn_floppy_motor_on();
while(timeout--)
{
floppy_write_cmd(0x07); // recalibrate cmd
floppy_write_cmd(0x00);
if((floppy_check_interrupt_status() & 0x1000) == 0){break;} // check the UC bit in ST0
}
turn_floppy_motor_off();
}
void floppy_fix_drive_data()
{
turn_floppy_motor_on();
floppy_write_cmd(0x03); // fix drive data cmd
floppy_write_cmd(0x8f); /* steprate = 8ms, unload time = 240ms */
floppy_write_cmd(0x0B); /* load time = 10ms, no-DMA = 1 */
int timeout = 1000;
while((inportb(status_register) & BUSY) != 0 || (inportb(DOR_register) & REST) == 0)
{if(timeout){timeout--;wait(1);}else{break;}}
if(!timeout){printf("fdc - fix_drive_data timeout! \n");}
turn_floppy_motor_off();
}
void floppy_reset()
{
outportb(DOR_register, 0x00);
outportb(DOR_register, REST);
int timeout = 1000;
while((inportb(status_register) & BUSY) != 0 || (inportb(DOR_register) & REST) == 0)
{if(timeout){timeout--;wait(5);}else{break;}}
if(!timeout){printf("fdc - reset timeout! \n");}
outportb(CCR_register, 0x00); // 500kbits/s transfer rate
floppy_fix_drive_data();
floppy_recalibrate();
floppy_check_drive_status();
}
any help is appreciated.