Page 1 of 1

problem with FDC

Posted: Tue Jun 22, 2010 4:48 am
by pegasus
I'm write code for reading sector from floppy disk. In the virtual machine(Bochs, qemu and VirtualBox) it works. But in the real machine memory at address 0x1000 contains 512 zeros. Why? And how to fix it?

My code:

Code: Select all

u32int read_sector(u8int head, u8int track, u8int sector)
{
       u32int st0, cyl;
        
      init_dma();
      dma_read();
      send_command(FDC_CMD_READ_SECT | FDC_CMD_EXT_MULTITRACK | FDC_CMD_EXT_SKIP | FDC_CMD_EXT_DENSITY);
      
       send_command(head << 2 | 0 );
       send_command(track);
       send_command(head);
       send_command(sector);
       send_command(FLPYDSK_SECTOR_DTL_512);
       send_command(FLPY_SECTORS_PER_TRACK);
       send_command(FLPYDSK_GAP3_LENGTH_3_5);
       send_command(0xFF);
       wait_irq();
       u32int retVal;
       u8int j;
       for (j=0; j<7; ++j)
        {   
                u32int val = flpydsk_read_data();
                if ((j==6) && (val==2)) 
                       retVal = 0;
                else
                       retVal = -1;  
        }
        check_int(&st0,&cyl); 
        return retVal;
}
void init_dma () 
{
        outb (0x0a,0x06);  
        outb (0x0c,0xff);  
        outb (0x04, 0);   
        outb (0x04, 0x10);
        outb (0x0c, 0xff);  
        outb (0x05, 0xff);  
        outb (0x05, 0x23);
        outb (0x81, 0);    
        outb (0x0a, 0x02);  
}

void dma_read ()
 {
        outb (0x0a, 0x06);
        outb (0x0b, 0x46);
        outb (0x0a, 0x02);
}

Re: problem with FDC

Posted: Tue Jun 22, 2010 6:21 am
by bewing
Try removing FDC_CMD_EXT_MULTITRACK, and let us know what happens.

Re: problem with FDC

Posted: Tue Jun 22, 2010 6:57 am
by pegasus
I tried removed FDC_CMD_EXT_MULTITRACK. It did not help.

Re: problem with FDC

Posted: Wed Jun 23, 2010 1:27 pm
by bewing
OK, then the first thing to be concerned about is that, on real hardware, your first one or two tries at reading will often fail. The floppy drive is not a reliable device. You really need to put your code in a loop that retries at least twice more, if the first try fails. Emulators will always "succeed" if the command is formatted properly, but real hardware will not.

The next things to look at will be timing questions in your send_command() and flpydsk_read_data() functions, which you did not post. Real floppy controllers are slow, and need "handshaking". You cannot just blast bytes at their IO ports, or they will fail.

Re: problem with FDC

Posted: Thu Jun 24, 2010 2:59 am
by pegasus
I put a call read_sector() in a loop. And as I have added a sleep() function in my code.

Code: Select all

u8int read_status ()  
{
        u8int ret = inb (FLPYDSK_MSR);
        sleep(50);
        return ret;
}

u32int read_data ()  
{
        int i = 0;
        for (i = 0; i < 500; i++ )
        {   
                if ( read_status () & FLPYDSK_MSR_MASK_DATAREG )
                {   
                        u32int ret = inb (FLPYDSK_FIFO);
                        sleep(50);
                        return ret;
                }   
        }   
        return 0;
}
void send_command (u8int cmd)
{
        int i = 0;
        for (i = 0; i < 500; i++ )
        {
                if ( read_status () & FLPYDSK_MSR_MASK_DATAREG )
                {
                        outb (FLPYDSK_FIFO, cmd);
                        sleep(50);
                        break;
                }
        }
}

void check_int (u32int* st0, u32int* cyl) {

        send_command (FDC_CMD_CHECK_INT);

        *st0 = read_data ();
        *cyl = read_data ();
}
But it's still not working.

Re: problem with FDC

Posted: Thu Jun 24, 2010 8:48 pm
by bewing
Do you actually get the IRQ6 after doing this command, or not? Do you know?

Re: problem with FDC

Posted: Fri Jun 25, 2010 12:16 am
by pegasus
I get IRQ6.