FDC doesn't work on real PC

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
hunter

FDC doesn't work on real PC

Post by hunter »

Hello,

My FDC works on Bochs,VM-Ware,... but if I try it on a real PC it doesn't work ... Here is the FDC code, maybe somebody could tell me the error in the code:

Code: Select all

void start_motor()
{
   
   if( !motor_on )
   {
      outport((base_used + 0x2), 0x1C);
      delay(500);
    }
    text( "Floppy Motor Ein\n" );
    motor_on = 1;
}   


void stop_motor()
{
   
   if( motor_on != 0 )
   {
      outport((base_used + 0x2), 0x00);
      delay(200);
   }
   text( "Floppy Motor Aus\n" );
    motor_on = 0;
}


void sendbyte(char byte)
{
    volatile int msr;
    int tmo;
    for(tmo = 0; tmo < 128; tmo++)
    {
        msr = inport((base_used + 0x04));
        if ((msr & 0xC0) == 0x80)
        {
            outport((base_used + 0x05), byte);
            return;
        }
        inport(0x80);
    }   
}



int getbyte()
{
    volatile int msr;
    int tmo;
    for (tmo = 0; tmo < 128; tmo++)
    {
        msr = inport((base_used + 0x04));
        if ((msr & 0xd0) == 0xd0)
           return inport((base_used + 0x05));
        inport(0x80);
    }
    return -1;
}


void waitfdc()
{
    //wait_irq6();
    statsz = 0;
    while ((statsz < 7) && (inb(base_used+0x4) & (1<<4)))
    {
      status[statsz++] = getbyte();
    }
   
    sendbyte(0x08);
    sr0 = getbyte();
    current_track = getbyte();
}

int fdc_seek(int track)
{
    if(current_track == track)
    {
      text_XY( floppy_x,text_Y() );
      text( "Track bereits ausgew?hlt!!!" );
        return 0;
    }
   
    start_motor();
       
    text( "Track Suchvorgang gestartet\n" );
       
    sendbyte(0x0F);
    sendbyte(0x00);
    sendbyte(track);
   
    text( "Floppy Wartet\n" );
    waitfdc();
    delay(1000);
   
    stop_motor();
   
    if(sr0 != 0x20)
    {
        text( "\n\nFehler: Track suchvorgang abgebrochen!!!\n\n" );
        return error;
    }
   
    text( "SR0 = 0x20\n" );
   
    current_track = track;
    return 0;
}

void fdc_recalibrate()
{
   text( "Floppy Rekalibrieren\n" );
    start_motor();
    sendbyte(0x07);
    sendbyte(0x00);
    waitfdc();
    stop_motor();
}


void fdc_reset()
{
   text( "Floppy wird resetet\n" );
   
    outport((base_used + 0x02), 0);    // stop everything
   
    motor_on = 0;
   
    outport((base_used + 0x04), 0);     // data rate (500K/s)
    outport((base_used + 0x02), 0x0C);  // restart ints
   
    text( "Floppy wartet auf IRQ\n" );
   
    waitfdc();
   
    sendbyte(0x03);                     // timing
    sendbyte(0xDF);                     // timing
    sendbyte(0x02);                     // timing
   
    while(fdc_seek(1) == error);        // set track
   
    fdc_recalibrate();
}


void Floppy_Laden()
{
   floppy_x = text_X();
   text( "Floppy Treiber wird initialisiert\n" );
   
    base_used = 0x3F0;
    //Floppy_typ();
    fdc_reset();
}


void readsector( unsigned char *buffer, int position )
{
   int sektor, track, head, a = 0;
   unsigned char *p_tbaddr = (unsigned char *)0x80000;
   
   sektor    =  (position % 18) + 1;
   track    =  (position / 18) / 2;
   head     =  (position / 18) % 2;
   
   start_motor();
   
   if( fdc_seek(track) == error )
   {
      stop_motor();
      return;
   }
   
   outport( (base_used + 0x7),0 );
   
   DMA_laden( (unsigned char *)tbaddr,512,0,2 );
   sendbyte( 0xE6 );
   
   sendbyte( head << 2 );
    sendbyte( track );
    sendbyte( head );
    sendbyte( sektor );
   
    sendbyte( 0x02 );               /* 512 bytes/sector */
    sendbyte( 0x12 );
    sendbyte( 0x1B );
    sendbyte( 0xFF );
   
   waitfdc();
   
   if( (status[0] & 0xC0) == 0 ) a = 1;   /* worked! outta here! */

   if( !a )
   {
      text( "Ouch!!" );
      fdc_recalibrate();
   }
   
   stop_motor();
   
   memcpy2( (unsigned char *)(buffer),(unsigned char *)tbaddr,128 );

   return;
}
elderK

Re:FDC doesn't work on real PC

Post by elderK »

I take it, that you are NOT using DMA?
hunter

Re:FDC doesn't work on real PC

Post by hunter »

I use DMA ... In the readsector function I use DMA_laden (it sets the DMA) ...

Code: Select all

void readsector( unsigned char *buffer, int position )
{
   int sektor, track, head, a = 0;
   unsigned char *p_tbaddr = (unsigned char *)0x80000;
   
   sektor    =  (position % 18) + 1;
   track    =  (position / 18) / 2;
   head     =  (position / 18) % 2;
   
   start_motor();
   
   if( fdc_seek(track) == error )
   {
      stop_motor();
      return;
   }
   
   outport( (base_used + 0x7),0 );
   
   DMA_laden( (unsigned char *)tbaddr,512,0,2 );   // <---- Here I use DMA
   sendbyte( 0xE6 );
   
   sendbyte( head << 2 );
    sendbyte( track );
    sendbyte( head );
    sendbyte( sektor );
   
    sendbyte( 0x02 );              /* 512 bytes/sector */
    sendbyte( 0x12 );
    sendbyte( 0x1B );
    sendbyte( 0xFF );
   
   waitfdc();
   
   if( (status[0] & 0xC0) == 0 ) a = 1;  /* worked! outta here! */

   if( !a )
   {
      text( "Ouch!!" );
      fdc_recalibrate();
   }
   
   stop_motor();
   
   memcpy2( (unsigned char *)(buffer),(unsigned char *)tbaddr,128 );

   return;
}



If I test it on real PC I get an error (DMA Bit wasn't set) ...
hunter

Re:FDC doesn't work on real PC

Post by hunter »

Can nobody help me ?? I read lots of tutorials but I couldn't find the error ...

1. How long must be the delay times?
2. Where I have to put delay times?

On real PC somtimes the Floppy IRQ doesn't request ...
paulbarker

Re:FDC doesn't work on real PC

Post by paulbarker »

The only thing I can suggest is if the problem can't be found in this code try posting your DMA code.

Why are you now asking about delay times? Are you getting 1 correct read and then none after that? If you don't even get the first read then delay times probably aren't the problem.
Dex4u

Re:FDC doesn't work on real PC

Post by Dex4u »

I do not use C, but if you understand asm, you can take a look at my floppy code, it is commented to go with the intel fdd controler pdfs, pudo code.
http://www.dex4u.com/images/FloppyDriver.zip

PS: I would try a bigger delay for motor on spin up time, as mine is twice yours, you can alway cut delays back, once waying right.
hunter

Re:FDC doesn't work on real PC

Post by hunter »

Thank you ... I have solved the problem ;D... Now I make a recalibrate() ( at the readsector() funktion ) and then I start the motor ...

But there is another problem ... the FDC is to slowly ...
Dex4u

Re:FDC doesn't work on real PC

Post by Dex4u »

hunter wrote:Thank you ... I have solved the problem ;D... Now I make a recalibrate() ( at the readsector() funktion ) and then I start the motor ...

But there is another problem ... the FDC is to slowly ...

Good that you got it working, here some things i found with speed, First once you have your floppy code working, start making the delays smaller, until it stop working, than increase it a bit, then you know the best delay.
Next i think BIOS floppy int 13h knows some special tricks, as going back to realmode from pmode, doing int 13h, every 512bytes,
is about the same speed as using my pmode floppy driver.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven
Contact:

Re:FDC doesn't work on real PC

Post by Candy »

Dex4u wrote:Next i think BIOS floppy int 13h knows some special tricks, as going back to realmode from pmode, doing int 13h, every 512bytes,
is about the same speed as using my pmode floppy driver.


I think mainly that the floppy drive transfer speed (500kbps) is so much slower than the processor you're testing it on (expecting a p3+ system) that you can't notice a difference in the speed because the fdd is so d*mn slow.
hunter

Re:FDC doesn't work on real PC

Post by hunter »

Hello,

Now I have an other question ... if I want to load more sectors, is there a better way to do that faster ... if I want to load more sektores I load ther first sector, the second sector,... but there are big loading times ...
Dex4u

Re:FDC doesn't work on real PC

Post by Dex4u »

The sad thing is floppys are slow, but have you made a fat12 driver yet, if not you will need to make one, for code to do this you can take a look at Dex4u source code it got drivers for fdd, hdd, atapi. fat12, fat16, fat32,You will find the source on this page:
http://www.dex4u.com/download.htm

Note reading from HDD is a lot easier that FDD so once you happy with your fdd code you will find HDD easier.
If you down load Dex4U you can see the speed compeared too yours.
@Candy, There is still little differance on a p2 233.
rootel77

Re:FDC doesn't work on real PC

Post by rootel77 »

But there is another problem ... the FDC is to slowly ...


i've just started learning on fdc. but i've noticed that in your code, in seeK() function you stop the motor after the seek is finished. so if you look at the following code from readSector


Code: Select all

start_motor();


you start the motor, but

Code: Select all

  if( fdc_seek(track) ...


fdc_seek stop the motor at the end.

You should keep the motor on at least until the readSector is finished. Ideally, you should keep the motor on some more times after the read/write operation so if another read/write occurs a few time later you dont have to restart the motor.
hunter

Re:FDC doesn't work on real PC

Post by hunter »

No, I had already corrected the mistakes with start_motor and stop_motor ...

@Dex4u: I have already written a FAT12 driver ... file loading is no problem but the speed ...

thank you all...
Dex4u

Re:FDC doesn't work on real PC

Post by Dex4u »

First is your driver slower then other Drivers like linux, xp, dex4u, dos, or any other hobby OS if so then let me know and i will see if i can find any bottle-necks in your code.
rootel77

Re:FDC doesn't work on real PC

Post by rootel77 »

Now I have an other question ... if I want to load more sectors, is there a better way to do that faster ... if I want to load more sektores I load ther first sector, the second sector,... but there are big loading times ...


you can read a complete track instead of a single sector, and use a cache of one or more tracks for read operations.
Post Reply