HD low level : What is wrong in this code ???

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.
Post Reply
jcmatias

HD low level : What is wrong in this code ???

Post by jcmatias »

/*
  this is the code to  input data from HD

  It works only with the comand Identify

  When a try to read a sector it fails...

  Sameone cand get a help ??

  Note :  This DOS version, but is easy to port to any other

*/

#include <dos.h>
#include <stdio.h>



#define BSY( status )   ( ( status & 0x80 ) != 0 )
#define DRDY( status )  ( ( status & 0x40 ) != 0 )
#define DRQ( status )   ( ( status & 0x08 ) != 0 )
#define ERROR( status ) ( ( status & 0x01 ) != 0 )


#define ASTATUS         0x3F6  // Device Control
#define CONTROL         0x3F6  // Device Control
#define DRIVE_ADDRESS   0x3F7  // Not Used
#define DATA            0x1F0 //Data Port
#define ERROREG         0x1F1 // Error Register  Precomp
#define SECTOR_COUNT    0x1F2
#define SECTOR_NUMBER   0x1F3
#define CYLINDER_LOW    0x1F4
#define CYLINDER_HIGH   0x1F5
#define DEVICE_HEAD     0x1F6
#define COMMAND         0x1F7
#define PRISTATUS       0x1F7

#define RESET_PIC { outportb(0xA0,0x20); outportb(0x20,0x20);}

#define inportw( p ) inport( p )

// from Hale Davis
#define DELAY400NS {inportb(ASTATUS);inportb(ASTATUS);inportb(ASTATUS);inportb(ASTATUS);}



typedef unsigned int word ;
typedef unsigned long int dword ;
typedef unsigned char byte ;


static byte ErrorCode = 0 ;

typedef struct SAtaCmd
{
word    SectorCount,
SectorNumber,
CylinderLow,
CylinderHigh,
DeviceHead,
        Command,
        *Buffer;
word    DataSize;
byte  Result;
} TAtaCmd;





void CmdIn(TAtaCmd *Cmd )
{
   byte Status , PriStatus  ;
   int i;

  do   Status = inportb( ASTATUS);
  while ( BSY( Status ) );


  // set device
  outportb( DEVICE_HEAD , 0 ) ; // device 0 in lba mode

   do Status = inportb( ASTATUS );
  while ( BSY( Status ) & !DRDY( Status ) );

  outportb( SECTOR_COUNT , Cmd->SectorCount );

  outportb( SECTOR_NUMBER , Cmd->SectorNumber );

  outportb( CYLINDER_HIGH , Cmd->CylinderHigh );

  outportb( CYLINDER_LOW , Cmd->CylinderLow );

  outportb( DEVICE_HEAD , Cmd->DeviceHead ) ;

  outportb( COMMAND, Cmd->Command );

  RESET_PIC ;

  do Status =inportb( ASTATUS ) ;
while ( BSY( Status ) & !DRDY( Status ) );

  // check error
if ( ERROR( Status ) )
   {
   ErrorCode = 3 ; // COMMAND_EXECUTION_ERROR

       return ;
   }

  // wait Command completion poolling status reg...
    DELAY400NS;

  do Status =inportb( ASTATUS );
  while ( BSY( Status )  );


  // clear intrq reading the PrimaryStatusReg
  Status = inportb( PRISTATUS );
  RESET_PIC ;

  DELAY400NS;

  for ( i = 0 ; i < Cmd->DataSize ; i++) Cmd->Buffer[ i ] = inportw( DATA ) ; // INPUT IN WORDS !!!

  Status =inportb( ASTATUS ) ;

  if ( ERROR( Status ) )
   {
   ErrorCode = 4 ; // DATA_IN_ERROR

       return ;
    }
}


void main(void)
{
   TAtaCmd Cmd ;

   byte SectorBuffer[512];
  
   int i;

   dword LbaSector = 1 ;

   byte Device = 0 ;

   Cmd.SectorCount = 1 ;
   Cmd.SectorNumber = (byte)LbaSector ;
   Cmd.CylinderLow = (byte)(LbaSector>>8)  ;
   Cmd.CylinderHigh = (byte)(LbaSector>>16 ) ;
   Cmd.DeviceHead = (Device | 0xE0) | (byte)( LbaSector >> 24)    ;
   Cmd.Command = 0x20 ;                    // read sector
   Cmd.Buffer = SectorBuffer ;
   Cmd.DataSize = 512 ;
   Cmd.Result = 0 ;

   CmdIn(&Cmd ) ;

   for ( i = 0 ; i <= 512 ; i++) printf("%c",SectorBuffer[i]);

   // ...always buffer is full of  0x0....

}
Post Reply