Read your HD witout bios - Now it works fine !

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

Read your HD witout bios - Now it works fine !

Post by jcmatias »

//
// is easy that read floppy , small and fast
// I will a WRITE  function  near
//

#include <dos.h> // only inputb(port) outputb(port,byte) inportw(port) outportw(port ,word)
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

// you must implement :
//inputb(port) outputb(port,byte) inportw(port) outportw(port ,word)

#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

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

word SPT,HEADS ;

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 ;


byte DRIVE = 0;

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

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


void Command( byte Cmd )
{
WaitReady();

outportb(COMMAND , Cmd );

WaitDRQ();
}


void ReadSector(int sector , word *buffer , byte device)
{

int i ,j,w,*ibuffer;

int  c ,h , s ;

ibuffer = (int*)buffer;

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

outportb(0x20,0x20);

outportb(0xA0,0x20);

outportb(SECTOR_COUNT, 1);

outportb(SECTOR_NUMBER , (byte)s) ;

outportb(CYLINDER_LOW , (byte)c  );

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

outportb(DEVICE_HEAD , 0xA0 | ( (byte)device | (byte)h ) );

inportb( COMMAND ); // clear irq

outportb(0x20,0x20);

outportb(0xA0,0x20);

Command( 0x20 );

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


void Identify( word *buffer)
{
int i,  input_word ;

Command(  0xEC );

inportb( COMMAND ); // clear irq

for ( i = 0  ; i <= 127 ; i++)

buffer[i] = inportw(DATA_PORT);  // <<<< ATTENTION >>>> input in WORDS
}

void Init(void)
{
outportb( CONTROL, 0x06 ); // reset

outportb( CONTROL , 0x02 );

outportb( SECTOR_COUNT , SPT);

outportb( DEVICE_HEAD , 0xA0 + (byte)HEADS - 1 );

outportb( COMMAND ,0x91);
};


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


// example app: USAGE:  HD sector device ---  Exemple : HD 0 0 or HD 0 160  
void main(int argc, char **argv )
{
byte device,*pchar;

word buffer[1024] ;
int *pint, i, lba,cyl,sector,head;
TAtaId AtaId ;

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

// first arg is the sector number in lba
if ( argc > 1 ) lba = atoi(argv[1]); else lba = 0;

// the second arg is 0 or is 160 (0xA0)
if ( argc > 2 ) device = (byte)atoi(argv[2]); else device = 0;
  
Identify((word*)&AtaId);

SPT = (int)AtaId.SectorsPerTrack ;

HEADS =(int)AtaId.Heads ;

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

printf("\nDevice %i Drive ID :", device);
for ( i = 0 ; i <= 19; i++) printf("%c%c",(char)(pint[i]>>8),(char)pint[i]);

printf("\nCylinders = %i Spt = %i Heads = %i \nPress Any Key",AtaId.Cylinders, SPT, HEADS);

while( ! getch() ) ;

Init();

do {
    clrscr();

    pchar = (char*)buffer ;

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

Lba2Chs(lba,&head,&cyl,&sector);

printf("\nLBA Sector =  %i \nCHS : C = %i , H = %i , S= %i \n \n",lba,head,cyl,sector);

    ReadSector(lba,buffer,device);

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

    printf("\n\n   < q to Quit > < Any Key continue > ");
lba++; // next sector

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

}
hartyl

RE:Read your HD witout bios - Now it works fine !

Post by hartyl »

great work!
thank you for sharing your code.
i've saved it to my harddisk, i think i can make use of it somewhen.

greets, hartyl
SystemHalted

RE:Read your HD witout bios - Now it works fine !

Post by SystemHalted »

Sorry for not replying to your first message jcmatias, I was on vacation. :)
Post Reply