HD : Why this code does not work ?
HD : Why this code does not work ?
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');
}
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 ?
Are you run it from dos as , it will not work in win98, xp etc ? .
ASHLEY4.
ASHLEY4.
RE:HD : Why this code does not work ?
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 ?
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);
}
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 ?
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.
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 ?
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 ??
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 ?
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 ?
I can give you links for code, but they are in asm like this.
http://www.humboldt1.com/~doors/idework/idework.htm
ASHLEY4.
http://www.humboldt1.com/~doors/idework/idework.htm
ASHLEY4.
RE:HD : Why this code does not work ?
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.
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.