pata read write
Posted: Sun Nov 25, 2012 12:46 pm
I'm having some problems with the code below.
Read will put out garbage, but always the same garbage.
So I can't check if write is working.
I'm using virtualbox for testing.
Read will put out garbage, but always the same garbage.
So I can't check if write is working.
I'm using virtualbox for testing.
Code: Select all
void read(uint32 LBA){
unsigned short port = 0x1F0;
unsigned short te;
int teller = 0;
outb(port + HDD_DRIVE_PORT, HDD_ADDRESSING_MODE);//Modo LBA addressing
outb(port + HDD_ERROR_PORT, 0x00);
outb(port + HDD_SECTORCOUNT_PORT, 1);//Sector count
outb(port + HDD_SECTORNUMBER_PORT, (uint8)LBA);//Sector to read
outb(port + HDD_CYLINDERLOW_PORT, (uint8)(LBA >> 8));//Cylinder low
outb(port + HDD_CYLINDERHIGH_PORT, (uint8)(LBA >> 16));//Cylinder high
outb(port + HDD_COMMAND_PORT, HDD_SINGLEREAD_COMMAND);//Read Sector(s) command
printf("Reading bytes...\n");
while ((inb(port+7)&0x08)!=0x08) ; // 0x08 <-- wait until DRQ bit is set : Data ReQuest bit
while(teller != 256){
te = inw(0x1F0);
readar[teller*2] = (unsigned char) te;
readar[(teller*2)+1] = (unsigned char) (te>>8);
teller++;
while ((inb(port+7)&0x80)==0x80) ; //wait until BUS BUSY bit to be cleared
while ((inb(port+7)&0x40)!=0x40) ; // wait for DRIVE READY bit to be set
}
while ((inb(port+7)&0x80)==0x80) ; //wait until BUS BUSY bit to be cleared
while ((inb(port+7)&0x40)!=0x40) ; // wait for DRIVE READY bit to be set
}
void write(uint32 LBA){
unsigned short port = 0x1F0;
int teller = 0;
outb(port + HDD_DRIVE_PORT, HDD_ADDRESSING_MODE);//LBA addressing
outb(port + HDD_ERROR_PORT, 0x00);
outb(port + HDD_SECTORCOUNT_PORT, 1);//Sector count
outb(port + HDD_SECTORNUMBER_PORT, (uint8)LBA);//Sector to read
outb(port + HDD_CYLINDERLOW_PORT, (uint8)(LBA >> 8));//Cylinder low
outb(port + HDD_CYLINDERHIGH_PORT, (uint8)(LBA >> 16));//Cylinder high
outb(port + HDD_COMMAND_PORT, HDD_SINGLEWRITE_COMMAND);//Write Sector(s) command
printf("Writing bytes\n");
while(teller != 256){
while ((inb(port+7)&0x40)!=0x40) ; // wait for DRIVE READY bit to be set
outw(0x1F0, (unsigned short)writear[teller*2]+(writear[(teller*2)+1]<<8));
teller++;
while ((inb(port+7)&0x80)==0x80) ; //wait until BUS BUSY bit to be cleared
outb(0x1F0 + HDD_COMMAND_PORT, HDD_COMMAND_FLUSH);
}
while ((inb(port+7)&0x80)==0x80) ; //wait until BUS BUSY bit to be cleared
while ((inb(port+7)&0x40)!=0x40) ; // wait for DRIVE READY bit to be set
the defines are higher in the code obviously.
#define HDD_PRIMARY_CONTROLLER 0x1F0
#define HDD_SECONDARY_CONTROLLER 0x170
#define HDD_PRIMARY_ALTERNATE_STATUS 0x3F6
#define HDD_SECONDARY_ALTERNATE_STATUS 0x376
#define HDD_DATA_PORT 0x000
#define HDD_ERROR_PORT 0x001
#define HDD_SECTORCOUNT_PORT 0x002
#define HDD_SECTORNUMBER_PORT 0x003
#define HDD_CYLINDERLOW_PORT 0x004
#define HDD_CYLINDERHIGH_PORT 0x005
#define HDD_DRIVE_PORT 0x006
#define HDD_COMMAND_PORT 0x007
#define HDD_COMMAND_FLUSH 0xE7
#define HDD_SINGLEREAD_COMMAND 0x20
#define HDD_SINGLEWRITE_COMMAND 0x30
#define HDD_ADDRESSING_MODE 0xE0
}