Page 1 of 1

Some floppy problems

Posted: Wed Apr 09, 2003 11:24 am
by Rootdown
Hello,

I've updated the therx floppy driver to my os. The problem comes when i want to read bootsector from a fat12 FD. Don't read well.

My struct for boot record is the same used by therx,

Code: Select all

typedef struct
{
        char  jump[3];
        char  oem_id[8];
   short bps;
        char  spc;
   short num_reserved;
        char  num_fats;
   short num_rootents;
   short total_sectors;
        char  media_ID_byte;
   short spf;
   short spt;
   short heads;
   short hidden_sectors;
   short total_sectors_large;
   short logical_drive_number;
        char extended_signature;
        long serial_number;
        char volume_name[11];
        char  boot_code[456];
        char  magic[2];
} __attribute__ ((packed)) bootsector_t;
My problems comes int this line: read_block(0, 1, &fat_fd0);
( I try to read only the boot sector ). I've proved many diferents call at the read_bock function. when i try to printf on screen the magic pos 0 and pos 1 ( boot sector mark ), i get 160 ( using %d ).

I atach my floppy.h file. I don't really know how to fix or what is happening. I'm not asking you to fix my error, i want to learn why i meka i mistake.

Thanks.

Re:Some floppy problems

Posted: Wed Apr 09, 2003 11:37 am
by _mark
By my calculation, you are missing 4 bytes somewhere.

_mark()

Re:Some floppy problems

Posted: Wed Apr 09, 2003 3:42 pm
by Rootdown
Yes,

i only have 508 bytes on the struct. But if i use an array of 512 pos and char, when I read 511-510 i don't get the boot signature, and when try to read the oem info, i get some weird characters on screen.

Thanks for answering mark.

Re:Some floppy problems

Posted: Wed Apr 09, 2003 10:31 pm
by _mark
It is kind of hard to help without the code. But it has to be one of three things, either read_block is not doing what you think, what is on the disk is not what you think, or everything is fine and there is something wrong with your printf. If your sure of your read_block routine, copy the boot sector to a file and look at it in a hex editor to see what is really there. Also verify your printf function is correctly printing numbers.

Post the code if you want me or someone else to take a look.

_mark()

Re:Some floppy problems

Posted: Thu Apr 10, 2003 11:26 am
by roquefeler
I can't atach it, i recieve an error:

2: Unable to create '/home3/mega-tokyo/www/forum/attachments/uploaded_files/rfdos.txt': Permission denied
(/home3/www/mega-tokyo/forum/Sources/Post.php ln 697)

Re:Some floppy problems

Posted: Thu Apr 10, 2003 4:52 pm
by roquefeler
As i can't post the file,

I show you my funcition:

Code: Select all

boolean write_block(dword lba, dword num_sectors, char* buffer)
{
   return floppy_rw(lba, num_sectors, buffer, FALSE);
}

// funcion real para leer o escribir segun bool read
boolean floppy_rw(dword lba, dword num_sectors, byte* buffer, boolean read)
{
   int head,track,sector,tries, copycount = 0;
   byte* p_tbaddr = (byte*)FLOPPY_DMA_PHYSICAL_ADDRESS;
   byte* p_blockbuff = buffer;

   // convert logical address into physical address
   block2hts(lba, &head, &track, &sector);


   motoron();

   if (!read && buffer)
   {

      for(copycount=0; copycount< (num_sectors*512); copycount++)
      {
         *p_tbaddr = *p_blockbuff;
         p_blockbuff++;
         p_tbaddr++;
      }
   }

   for (tries = 0; tries < 3; tries++)
   {

      if (inportb(FDC_DIR) & 0x80)
      {
         fd_stat[0].dc = TRUE;
         seek(1);   // Borra el estado
         recalibra();
         motoroff();
         return floppy_rw(lba, num_sectors, buffer, read);
      }

      if (!seek(track))
      {
         motoroff();
         return FALSE;
      }

      outportb(FDC_CCR,0);
      

      if (read)
      {

         dma_setup(floppy_tbaddr, FALSE,num_sectors*512 );
         sendbyte(CMD_READ);
      }
      else
      {
         dma_setup(floppy_tbaddr, TRUE,num_sectors*512 );

         sendbyte(CMD_WRITE);
      }
      sendbyte(head << 2);
      sendbyte(track);
      sendbyte(head);
      sendbyte(sector);
      sendbyte(2);            
      sendbyte(geometry.spt);
      if (geometry.spt == DG144_SPT)
      {
         sendbyte(DG144_GAP3RW);      
      }
      else
      {
         sendbyte(DG168_GAP3RW);      
      }
      sendbyte(0xff);            

      // Espera a q se complete el comando
      if (!fdwait(TRUE))
      {
         reset();
         return floppy_rw(lba, num_sectors, buffer, read);
      }
      if ((fd_stat[0].buf[0] & 0xc0) == 0)
      {
         // si funciono, fuera de aqui.
         break;
      }
      recalibra();   
   }
   // Para el motor
   motoroff();
   if (read && buffer)
   {
      
      p_blockbuff = buffer;

      p_tbaddr = (byte*)FLOPPY_DMA_PHYSICAL_ADDRESS;
      for(copycount=0; copycount< (num_sectors*512); copycount++)
      {
         *p_blockbuff = *p_tbaddr;
         p_blockbuff++;
         p_tbaddr++;
      }
   }
   return (tries != 3);
}

/*
FLOPPY_DMA_PHYSICAL_ADDRESS = 0x80000-65280 ( is a define )

And the str i use for control de FD:

Code: Select all

typedef struct fd_disk{
   //char *label;
   //unsigned short cyls;
   unsigned short heads;
   unsigned short tracks;
   unsigned short spt;
}fd_disk;

typedef struct FD_ctrl{
   boolean fdcok;
   boolean motor_st;
   char *name;
   char type;
   boolean dc;
   unsigned char GAP3;
   unsigned char DR;
   fd_disk *disk;
   int fdstop;
   int tout;
   int cbuf;
   byte buf[7];
   byte sr0;
   byte track;

}FD_ctrl;
Don't know if you need something more.

Re:Some floppy problems

Posted: Fri Apr 11, 2003 10:46 am
by eL JeDi
Hi,

if you want send me your file my mail, and i try to post it and fix it. I'm not an expert, but i will do what i can :)

Re:Some floppy problems

Posted: Fri Apr 11, 2003 12:14 pm
by eL JeDi
I can't post the file. I get the same error. Try to post the code by parts

Re:Some floppy problems

Posted: Sat Apr 12, 2003 4:50 am
by roquefeler
/* this turns the motor on */
void motoron(void)
{
if (!fd_stat[0].motor_st) {
fd_stat[0].fdstop=-1; /* stop motor kill countdown */
outportb(FDC_DOR,0x1c);
delay(500); /* delay 500ms for motor to spin up */
fd_stat[0].motor_st = TRUE;
}
}
//////////////////////////////////////////////////////////////////////////////////////
/* this turns the motor off */
void motoroff(void)
{
if (fd_stat[0].motor_st) {
fd_stat[0].fdstop=36; /* start motor kill countdown: 36 ticks ~ 2s */
}
}


//////////////////////////////////////////////////////////////////////////////////////
void fdc_st_ini()
{
   int n;
   for (n=0;n<NUMFDS;n++)
   {
      fd_stat[n].fdcok=0;
      fd_stat[n].motor_st=0;
      fd_stat[n].type=0;
      fd_stat[n].dc=0;
      fd_stat[n].GAP3=0;
      fd_stat[n].DR=0;
      fd_stat[n].disk=NULL;
      fd_stat[n].fdstop=0;
      fd_stat[n].tout=0;
      fd_stat[n].sr0=0;
      fd_stat[n].track=0xff;
   }
}
//////////////////////////////////////////////////////////////////////////////////////
/* sendbyte() routine from intel manual */
void sendbyte(int byte)
{
volatile int msr;
int tmo;

for (tmo = 0;tmo < 128;tmo++) {
msr = inportb(FDC_MSR);
if ((msr & 0xc0) == 0x80) {
    outportb(FDC_DATA,byte);
    return;
}
inportb(0x80); /* delay */
}
}
//////////////////////////////////////////////////////////////////////////////////////
/* getbyte() routine from intel manual */
int getbyte()
{
volatile int msr;
int tmo;

for (tmo = 0;tmo < 128;tmo++) {
msr = inportb(FDC_MSR);
if ((msr & 0xd0) == 0xd0) {
    return inportb(FDC_DATA);
}
inportb(0x80); /* delay */
}

return -1; /* read timeout */
}

//////////////////////////////////////////////////////////////////////////////////////
int detect_fd()
{
   char a,b,c;

   unsigned char gs[]= {27,42,42,27,27,27};
   // selecionamos en la BIOS el byte q indica el tipo de Unidad
   outportb(0x70, 0x10);
   a = inportb(0x71);

   b=a>>4;
   c=a & 0x0F;

   fd_stat[0].type=b;
   fd_stat[0].name="fda";
   fd_stat[0].GAP3=gs;

   fd_stat[1].type=c;
   fd_stat[1].name="fdb";
   fd_stat[1].GAP3=gs[c];


}
//////////////////////////////////////////////////////////////////////////////////////
void fdc()
{
   fd_stat[1].fdcok=TRUE;
   fd_stat[2].fdcok=TRUE;
}



//////////////////////////////////////////////////////////////////////////////////////
boolean fdwait(boolean estao)
{
   // Timeout = 1seg
   fd_stat[0].tout=1000;
   
   while ( !(fd_stat[0].fdcok) && fd_stat[0].tout);

   fd_stat[0].cbuf=0;
   while ((inportb(FDC_MSR) & (1<<4)) && (fd_stat[0].cbuf < 7))
   {
      fd_stat[0].buf[fd_stat[0].cbuf] = getbyte();
      fd_stat[0].cbuf++;
   }

   if (estao)
   {
      // Mana SENSEI al controlador de la Disquetera.
      sendbyte(CMD_SENSEI);
      fd_stat[0].sr0 = getbyte();
      fd_stat[0].track = getbyte();
   }
   
   fd_stat[0].fdcok = FALSE;

   if (!fd_stat[0].tout)
   {
      // time out
      if (inportb(FDC_DIR) & 0x80)
      {
         fd_stat[0].dc = TRUE;
      }
      return FALSE;
   }else{
      return TRUE;
   }

}

//////////////////////////////////////////////////////////////////////////////////////
boolean seek(int trk)
{
// Comprobamos si ya estamos en la posicion trk
if (fd_stat[0].track == trk) { return TRUE; } // si ya estamos posicionados, devuelve TRUE

motoron();

// Mandamos comando al controlador.
sendbyte(CMD_SEEK);
sendbyte(0);
sendbyte(trk);

// ESperamos a que acabe la disquetera
if (!fdwait(TRUE)) { return FALSE; } // Devuelve FALSE si TIMED OUT

/* now let head settle for 15ms */
delay(15);

motoroff();

/* check that seek worked */
if ((fd_stat[0].track != trk)||(fd_stat[0].sr0 != 0x20)) { return FALSE; }
else { return TRUE; }
}

Re:Some floppy problems

Posted: Sat Apr 12, 2003 4:53 am
by roquefeler
void recalibra()
{
// Ponemos en marcha el motor de la disquetera
motoron();

// Envia comando al controlador
sendbyte(CMD_RECAL);
sendbyte(0);

// Esperar a que finalice el comando.
fdwait(TRUE);

// Apagar el motor
motoroff();
}
//////////////////////////////////////////////////////////////////////////////////////
void reset(void)
{
// Para el motor y desactiva IRQ/DMA
outportb(FDC_DOR,0);

fd_stat[0].fdstop=0;
fd_stat[0].motor_st = FALSE;

// data rate= 500K/s
outportb(FDC_DRS,0);

// Rehabilita IRQs
outportb(FDC_DOR,0x0c);


fd_stat[0].fdcok = TRUE;
fdwait(TRUE);

// Tiempos para la disquetera, los saca de la BIOS
sendbyte(CMD_SPECIFY);
sendbyte(0xdf); /* SRT = 3ms, HUT = 240ms */
sendbyte(0x02); /* HLT = 16ms, ND = 0 */

// Borra el estado de cambio de disco
seek(1);
recalibra();

// Cambio de disco = falso
fd_stat[0].dc = FALSE;

}

//////////////////////////////////////////////////////////////////////////////////////

void fdc_ini()
{
   


   // Instalamos el Handle del Floppy
   set_idt_entry((unsigned long)&irq6, 0x26);
   EnableIRQ(6);
   // Handle del timerpara apagar el floppy
   //set_idt_entry((unsigned long)&timer0, 0x20);
   //EnableIRQ(6);

   //Inicializamos la estructura de contrl del floppy.
   fdc_st_ini(fd_stat);

   //Detectando Unidades:
   detect_fd(fd_stat);
   printf("Unidades de Disco:\n");
   printf("Unidad A: %s \n",fd_type[fd_stat[0].type]);
   printf("Unidad B: %s \n",fd_type[fd_stat[1].type]);
   
   motoron();
   motoroff();
}



// Convierte direccion lineal en formato pista, cilindro...
void block2hts(int block,int *head,int *track,int *sector)
{
*head = (block % (geometry.spt * geometry.heads)) / (geometry.spt);
*track = block / (geometry.spt * geometry.heads);
*sector = block % geometry.spt + 1;
}



////////////////////////////////////////////////////////////
// read block (blockbuff is 512 byte buffer)
boolean read_block(dword lba, dword num_sectors, char* buffer)
{
   int track=0, sector=0, head=0, track2=0, result=0, loop=0;

   // The FDC can read multiple sides at once but not multiple tracks
   block2hts(lba, &head, &track, &sector);
   block2hts(lba+num_sectors, &head, &track2, &sector);

   if (track!=track2)
   {
      for(loop=0; loop < num_sectors; loop++)
      {
         result = floppy_rw(lba+loop, 1, buffer+(loop*512), TRUE);
      }
      return result;
   }
   return floppy_rw(lba, num_sectors, buffer, TRUE);
}
/*
void read_block(int block,unsigned char *blockbuff, int size)
{
printf("Floppy");
log_disk(0);
block = (int)(block / 512);
fdc_rw(block,blockbuff,TRUE);
}*/
////////////////////////////////////////////////////////////
// write block (blockbuff is 512 byte buffer) */
boolean write_block(dword lba, dword num_sectors, char* buffer)
{
   return floppy_rw(lba, num_sectors, buffer, FALSE);
}

Re:Some floppy problems

Posted: Sat Apr 12, 2003 4:55 am
by roquefeler

Code: Select all

boolean floppy_rw(dword lba, dword num_sectors, byte* buffer, boolean read)
{
   int head,track,sector,tries, copycount = 0;
   byte* p_tbaddr = (byte*)FLOPPY_DMA_PHYSICAL_ADDRESS;
   byte* p_blockbuff = buffer;

   // convert logical address into physical address
   block2hts(lba, &head, &track, &sector);

   // enciende el motor de la disquetera
   motoron();

   if (!read && buffer)
   {
      // Copia datos del buffer al buffer de la disquetera
      for(copycount=0; copycount< (num_sectors*512); copycount++)
      {
         *p_tbaddr = *p_blockbuff;
         p_blockbuff++;
         p_tbaddr++;
      }
   }

   for (tries = 0; tries < 3; tries++)
   {
      // cambio de disco??
      if (inportb(FDC_DIR) & 0x80)
      {
         fd_stat[0].dc = TRUE;
         seek(1);   // Borra el estado
         recalibra();
         motoroff();
         return floppy_rw(lba, num_sectors, buffer, read);
      }
      // Posiciona el cabezal
      if (!seek(track))
      {
         motoroff();
         return FALSE;
      }
      // data rate =500K/s
      outportb(FDC_CCR,0);
      
      // Envia se?al al controlador DMA
      if (read)
      {
         //dma_xfer(2, floppy_tbaddr, num_sectors*512, FALSE);
         dma_setup(floppy_tbaddr, FALSE,num_sectors*512 );
         sendbyte(CMD_READ);
      }
      else
      {
         dma_setup(floppy_tbaddr, TRUE,num_sectors*512 );
         //dma_xfer(2, floppy_tbaddr, num_sectors*512, TRUE);
         sendbyte(CMD_WRITE);
      }
      sendbyte(head << 2);
      sendbyte(track);
      sendbyte(head);
      sendbyte(sector);
      sendbyte(2);            // 512 bytes/sector
      sendbyte(geometry.spt);
      if (geometry.spt == DG144_SPT)
      {
         sendbyte(DG144_GAP3RW);      // gap 3 para 1.44M read/write
      }
      else
      {
         sendbyte(DG168_GAP3RW);      // gap 3 para 1.68M read/write
      }
      sendbyte(0xff);            // DTL

      // Espera a q se complete el comando
      if (!fdwait(TRUE))
      {
         reset();
         return floppy_rw(lba, num_sectors, buffer, read);
      }
      if ((fd_stat[0].buf[0] & 0xc0) == 0)
      {
         // si funciono, fuera de aqui.
         break;
      }
      recalibra();   // si no, vuelva a intertarlo cu?aaao
   }
   // Para el motor
   motoroff();
   if (read && buffer)
   {
      // Mete datos dentro del buffer.
      p_blockbuff = buffer;

      p_tbaddr = (byte*)FLOPPY_DMA_PHYSICAL_ADDRESS;
      for(copycount=0; copycount< (num_sectors*512); copycount++)
      {
         *p_blockbuff = *p_tbaddr;
         p_blockbuff++;
         p_tbaddr++;
      }
   }
   return (tries != 3);
}
And my DMA SETUP FUNCTION:

Code: Select all

void dma_setup(long address, char mode, int size)
{
   asm("cli");
   outportb(0x0A, 2 | 4);                     //Set channel Mask Bit
   outportb(0x0C, 0);                         //Reset Flip-flop
   if(mode == 1)                          //Memory to Device ( DEV_READ )
      outportb(0x0B, 0x5A);
   else                                       //Device to Memory
      outportb(0x0B, 0x56);
   outportb(0x81, address >> 16);             //Set Page
   outportb(0x04,(address & 0xFFFF) & 0xFF);  //Output Lo Byte of offset
   outportb(0x04,(address & 0xFFFF) >> 8);    //Output Hi Byte of offset
   outportb(0x05,size & 0xff);                //Output Lo Byte of length
   outportb(0x05,size >> 8);                  //Output Hi Byte of length
   outportb(0x0A, 2);                         //Clear Channel Mask
}
Thanks

Re:Some floppy problems

Posted: Tue Apr 15, 2003 10:37 am
by Roquefeler_
Please,

anyone can tell what i'm doing wrong?? Or why it doesn't works??

When i do a read_block() function, and i do a printf of the array i get the same output before and after.

Could it be my dam_setup function?? ( is the therx OS one)