Page 1 of 1

HD :  Why this code does not work  ?

Posted: Fri Jul 16, 2004 11:00 pm
by jcmatias
This code is done to read a ata hd in pio mode, but don't work
it performs drive ID fine , but  don't read a sector. WHY?????
Some one can help me ?

Use borland c to compile


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

#define ASTATUS         0x3F6  // Device Control
#define CONTROL         0x3F6  // Device Control
#define DRIVE_ADDRESS   0x3F7  // Not Used    
#define DATA_PORT       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

typedef unsigned char byte ; // 8 bits
typedef unsigned int word ;  // 16 bits

#define inportw inport

void WaitReady(void);
void WaitDRQ(void);
void Lba2Chs(int block,int *head,int *Track,int *sector);
void Command( byte Cmd );
void ReadSector(int sector , byte *buffer);
void Init(void);

typedef struct SAtaId
{
word
  DevTipe ,
  Cylinders,
  Reserved1,
  Heads,
  Obsolete1,
  Obsolet2,
  SectorsPerTrack,
  VendorEspecific1,
  VendorEspecific2,
  VendorId,
  SerialNumber[10], //20 bytes
  Obsoler3,
  Obsolet4,
  NumBytesRWLong,
  Revison[4];
  ModelNumber[10]; // 20 bytes
int  MaxSectPerInt,
   Reserved2;
} TAtaId ;

int HEADS, SPT ,CYL;

byte DRIVE = 0;

void WaitReady(void)
{
while  ( inportb( COMMAND ) & 0x80  );
}

void WaitDRQ(void)
{
while  ( inportb( COMMAND ) & 0x08 != 0 );
}


void Command( byte Cmd )
{
WaitReady();

outportb(COMMAND , Cmd );
}


void ReadSector(int sector , byte *buffer)
{
int  c ,h , s ,i ,j,w,*ibuffer;

ibuffer = (int*)buffer;

Lba2Chs(sector,&h,&c,&s);

outportb(SECTOR_COUNT, 1);

outportb(SECTOR_NUMBER , s ) ;

outportb(CYLINDER_LOW , (byte)c  );

outportb(CYLINDER_HIGH , (byte) ( c >> 8 ));

outportb(DEVICE_HEAD ,DRIVE + 0xA0 + (byte)h );

Command( 0x20 );

for ( i = 0 ; i <= 511 ; i++)
  ibuffer[i] = inportw(DATA_PORT) ;
  

}


void Identify( byte *buffer)
{
int i,  *ibuffer ;

Command(  0xEC );
inportb( COMMAND ); // clear irq
ibuffer=(int*)buffer ;
  for ( i = 0 ; i < 128 ; i++)
      ibuffer[i] = inportw(DATA_PORT);
}

void Init(void)
{
outportb( CONTROL, 0x06 ); // reset
delay(10);
outportb( CONTROL , 0x02 );
outportb( SECTOR_COUNT , SPT);
outportb( DEVICE_HEAD , 0xA0 + (byte)HEADS );
outportb( COMMAND ,0x91);

};

void Lba2Chs(int block,int *head,int *Track,int *sector)
{
   *head = (block % (SPT* HEADS)) / (SPT);
   *Track = block / (SPT * HEADS);
   *sector = block % SPT + 1;
}




void main(int argc, char **argv )
{
byte buffer[1024];
int i ,s, *pint ;
char *pchar ;

TAtaId AtaId ;

for ( i = 0 ; i <= 1024; i++) buffer[i] = 0;

if ( argc > 1 ) s = atoi(argv[1]);
else s = 1;

if ( argc > 2 ) DRIVE = 0x10;
else DRIVE = 0;

Identify((byte*)&AtaId);

SPT = (int)AtaId.SectorsPerTrack ;
HEADS =(int)AtaId.Heads ;

pchar = (char*)&AtaId.ModelNumber[0] ;
pint = (int*)&AtaId;

printf("\n Drive ID: ["); for ( i = 0 ; i <= 19; i++) printf("%c",pchar[i]);
printf("]\n");

printf("\n Cylinders = %i \n Spt = %i \nHeads = %i",AtaId.Cylinders, SPT, HEADS);

// printf("\n ==>");
// for( i = 0 ; i < sizeof(TAtaId) ; i++) printf(" %i ",pint[i]);
// for( i = 0 ; i < sizeof(TAtaId) ; i++) printf("%c",(char)pint[i]);

while (! getch() ) ;

// Init();



do {

    clrscr();

    pchar = (char*)buffer ;

    for ( i = 0 ; i < 1024; i++) buffer[i] = '0';

    ReadSector(s,buffer);

    printf("\nSector: %i \n",s);

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

    printf("\n DUMP %i \n",s);

   for ( i = 0 ; i <= 255 ; i++) printf("%x",(unsigned int)buffer[i]);

s++ ;

} while ( getch() != 'f');


}

RE:HD :  Why this code does not work  ?

Posted: Fri Jul 16, 2004 11:00 pm
by ASHLEY4
Are you run it from dos as , it will not work in win98, xp etc ? .

ASHLEY4.

RE:HD :  Why this code does not work  ?

Posted: Sat Jul 17, 2004 11:00 pm
by jcmatias
I run from DOS and fail to, The core routines, i try with no OS, but fails to read data from HD. I don't know why. I used the ATA/IDE  algorithms and nothing.

RE:HD :  Why this code does not work  ?

Posted: Wed Jul 21, 2004 11:00 pm
by SystemHalted
I found a problem the data you get is in words not bytes so:
void ReadSector(int sector , /*byte*/word *buffer)
{
int  c ,h , s ,i ,j,w,*ibuffer;

ibuffer = (int*)buffer;

Lba2Chs(sector,&h,&c,&s);

outportb(SECTOR_COUNT, 1);

outportb(SECTOR_NUMBER , s ) ;

outportb(CYLINDER_LOW , (byte)c  );

outportb(CYLINDER_HIGH , (byte) ( c >> 8 ));

outportb(DEVICE_HEAD ,DRIVE + 0xA0 + (byte)h );

Command( 0x20 );

for ( i = 0 ; i < 256 /*<= 511*/ ; i++)
  ibuffer[i] = inportw(DATA_PORT) ;
}
thats one problem i found there. oh and
try this too
void Command( byte Cmd )
{
WaitReady();

outportb(COMMAND , Cmd );

WaitDRQ(void);
}

RE:HD :  Why this code does not work  ?

Posted: Fri Jul 23, 2004 11:00 pm
by jcmatias
  These changes fails.
  Does it works in your system ?  
  In Bochs I get the corect HD identification ( bytes in reverse order ), but
in real PC this fails, I get garbage.

RE:HD :  Why this code does not work  ?

Posted: Sat Jul 24, 2004 11:00 pm
by SystemHalted
Maybe its your computer?

RE:HD :  Why this code does not work  ?

Posted: Sat Jul 24, 2004 11:00 pm
by jcmatias
     I try in 3 mchines with  Western Digital , Maxtor and Hitachi HDs
The best result is with Bochs emulator, ( I  get a driver ID string " Generic 1234 " ).
  This code works to you ??

RE:HD :  Why this code does not work  ?

Posted: Sat Jul 24, 2004 11:00 pm
by SystemHalted
I havent tried it. But i have similar code. What drive are you tring to read from? Primary Master?

RE:HD :  Why this code does not work  ?

Posted: Sun Jul 25, 2004 11:00 pm
by jcmatias
primary master .
Can I see your code ?
[email protected]

RE:HD :  Why this code does not work  ?

Posted: Sun Jul 25, 2004 11:00 pm
by ASHLEY4
I can give you links for code, but they are in asm like this.
   http://www.humboldt1.com/~doors/idework/idework.htm

ASHLEY4.

RE:HD :  Why this code does not work  ?

Posted: Mon Jul 26, 2004 11:00 pm
by jcmatias
Thanks ASHLEY4
I get the code of site, its looks like mine, but in nasm - small and simple .
I get the Hale Davis code in C too, but its is very large and had a lots of redundant code but compreensible. But I wan't know whi my code doesn't work.
It's simple and feels ATA data input protocol. I want see C codes that works to compare with mine.