The Place to Start for Operating System Developers
http://forum.osdev.org/
Code: Select all
int fdc_read(fdc_drive_t *fd, unsigned char *data, unsigned int sector, unsigned int offset, unsigned int length)
{
if(!fdc_motor_on(fd))
return 0;
//check if a disk is in the drive
unsigned char disk_not_changed = inportb(fd->ports.digital_input) & 0x80;
if(disk_not_changed)
{
write_string("DNC");
//this is gaurenteed to change the disk if it exists
if(!fdc_seek(fd, 79))
{
write_string(" failed seek! ");
return 0;
}
if(!fdc_seek(fd, 0))
{
write_string(" failed seek! ");
return 0;
}
}
disk_not_changed = inportb(fd->ports.digital_input) & 0x80;
if(disk_not_changed)
{
write_string(" No disk in drive. ");
//there is no disk in the drive
return 0;
}
if(!fdc_seek(fd, sector))
{
write_string(" failed seek! ");
return 0;
}
//send the read command
fdc_send_command(fd, FDC_READ_DATA);
//fdc_send_data(fd, fd->index | fd->current_head << 2); //head and drive
//fdc_send_data(fd, fd->current_cylinder);
//fdc_send_data(fd, fd->current_head);
//fdc_send_data(fd, fd->current_sector);
//fdc_send_data(fd, 2); // bytes per sector (2 = 512)
//fdc_send_data(fd, fd->current_sector + 1); // "end of track" the final sector of this track
//fdc_send_data(fd, 0x1B); //GAP3 length
//fdc_send_data(fd, 0xFF); //data length (0xFF because bytes per sector != 0)
// first read status information
unsigned char st0, st1, st2, rcy, rhe, rse, bps;
fdc_get_data(fd, &st0);
write_hex(st0);
halt();
fdc_get_data(fd, &st1);
fdc_get_data(fd, &st2);
/*
* These are cylinder/head/sector values, updated with some
* rather bizarre logic, that I would like to understand.
*
*/
fdc_get_data(fd, &rcy);
fdc_get_data(fd, &rhe);
fdc_get_data(fd, &rse);
// bytes per sector, should be what we programmed in
fdc_get_data(fd, &bps);
//get the data
int i = 0; unsigned char *tmp = data;
for(i = 0; i < 512; i++)
{
fdc_wait_interrupt(fd);
fdc_get_data(fd, tmp);
write_hex(*tmp);
tmp++;
}
if(!fdc_motor_off(fd))
return 0;
return 1;
}
Well that would have been my intuitive guess also but both the manual and the tutorial say differently.bewing wrote:I have not done PIO floppy stuff yet, but my initial guess is that you cannot send the read command until AFTER you have set up the CHS address.
I never though about this, I'll make sure that it's not zero.bewing wrote:The default sector is probably 0, which is illegal.
No, I'm not sure if that calculation is correct, that is part of why I asked here. :) fd->index is just the drive number (0, 1, 2, or 3) and fd->current_head << 2 is supposed to correctly set the head bit. I'll be sure to check this also.bewing wrote:Also I'm worried about the way you calculate one CHS value: fd->index | fd->current_head << 2
-- are you sure the precedence of that calculation is right?
Means: fd->index | (fd->current_head << 2)d->index is just the drive number (0, 1, 2, or 3) and fd->current_head << 2 is supposed to correctly set the head bit.
Well, it's better than no help at all. :wink:bewing wrote:Guess I'm not much help then. :D
I've checked. fd->current_sector equals 1 just before it is sent to the floppy controller.Stevo14 wrote:I never though about this, I'll make sure that it's not zero.bewing wrote:The default sector is probably 0, which is illegal.
This doesn't help either. :(bewing wrote:Means: fd->index | (fd->current_head << 2)
Code: Select all
fdc_send_data(fd, fd->current_sector + 1); // "end of track" the final sector of this track
Code: Select all
int fdc_read(fdc_drive_t *fd, unsigned char *data, unsigned int sector, unsigned int offset, unsigned int length)
{
unsigned char st0, st1, st2, rcy, rhe, rse, bps, cyl;
if(!fdc_motor_on(fd))
return 0;
//check if a disk is in the drive
unsigned char disk_not_changed = inportb(fd->ports.digital_input) & 0x80;
if(disk_not_changed)
{
//write_string("DNC");
//this is gaurenteed to change the disk if it exists
if(!fdc_seek(fd, 79))
{
write_string(" failed seek! ");
return 0;
}
if(!fdc_seek(fd, 0))
{
write_string(" failed seek! ");
return 0;
}
}
disk_not_changed = inportb(fd->ports.digital_input) & 0x80;
if(disk_not_changed)
{
write_string(" No disk in drive. ");
//there is no disk in the drive
return 0;
}
if(!fdc_seek(fd, sector))
{
write_string(" failed seek! ");
return 0;
}
//send the read command
fdc_send_command(fd, FDC_READ_DATA);
fdc_send_data(fd, fd->index | (fd->current_head << 2)); //head and drive
fdc_send_data(fd, fd->current_cylinder);
fdc_send_data(fd, fd->current_head);
fdc_send_data(fd, fd->current_sector);
fdc_send_data(fd, 2); // bytes per sector (2 = 512)
fdc_send_data(fd, 1); // "end of track" the final sector of this track (I have no idea what it does)
fdc_send_data(fd, 0x1B); //GAP3 length
fdc_send_data(fd, 0xFF); //data length (0xFF because bytes per sector != 0)
//get the data
fdc_wait_interrupt(fd);//wait for it...
//GO!
int i = 0; unsigned char *tmp = data;
for(i = 0; i < 512; i++)
{
fdc_get_data(fd, tmp);
write_hex(*tmp);
tmp++;
}
// read status information
fdc_get_data(fd, &st0);
write_hex(st0);
fdc_get_data(fd, &st1);
fdc_get_data(fd, &st2);
/*
* These are cylinder/head/sector values, updated with some
* rather bizarre logic, that I would like to understand.
*/
fdc_get_data(fd, &rcy);
fdc_get_data(fd, &rhe);
fdc_get_data(fd, &rse);
// bytes per sector, should be what we programmed in
fdc_get_data(fd, &bps);
if(!fdc_motor_off(fd))
return 0;
return 1;
}