ports,harddisk....
ports,harddisk....
Hi,
I'm trying to read sector 64 at cylinder 1 , head 0 of the harddisk.
That works fine if I first read sector 63 at cylinder 0, head 0.
But if I don't read sector 63 at cy l 0, head 0 then
sector 64 (cyl 1,head 0) doesn't get the right info...
Any ideas why?
I thought it was something with seek... so I tried to do a seek...
I setted the same variables then outputed 0x70,
and then setted the same variables again and outputed a read, but that didn't change a thing...
So how di I fix this?
Also I output the sector number using my outportdd function which sends 2 bytes which is 66536 bytes big... but my disk has more sectors than 66536, so should I make a function called outportw (which sends 4 bytes) instead?
Best,
Frank
I'm trying to read sector 64 at cylinder 1 , head 0 of the harddisk.
That works fine if I first read sector 63 at cylinder 0, head 0.
But if I don't read sector 63 at cy l 0, head 0 then
sector 64 (cyl 1,head 0) doesn't get the right info...
Any ideas why?
I thought it was something with seek... so I tried to do a seek...
I setted the same variables then outputed 0x70,
and then setted the same variables again and outputed a read, but that didn't change a thing...
So how di I fix this?
Also I output the sector number using my outportdd function which sends 2 bytes which is 66536 bytes big... but my disk has more sectors than 66536, so should I make a function called outportw (which sends 4 bytes) instead?
Best,
Frank
Re:ports,harddisk....
What do you expect to see? How do you know it's not the right info? You should be seeing the boot sector of the first partition. Any code?frank wrote:I'm trying to read sector 64 at cylinder 1 , head 0 of the harddisk.
That works fine if I first read sector 63 at cylinder 0, head 0.
But if I don't read sector 63 at cy l 0, head 0 then
sector 64 (cyl 1,head 0) doesn't get the right info...
Any ideas why?
Look up LBA in the ATA reference you're using; the sector number gets split across the cylinder and sector registers. Alternatively, write a simple sector number to cylinder-head-sector function and program the CHS values into the drive.Also I output the sector number using my outportdd function which sends 2 bytes which is 66536 bytes big... but my disk has more sectors than 66536, so should I make a function called outportw (which sends 4 bytes) instead?
BTW: outportw sounds like it outputs a word, which is 2 bytes and ranges from 0 to 65535. outportd sounds like it outputs a doubleword, which is 4 bytes and ranges from 0 to 2[sup]32[/sup] - 1 (about 4 billion).
Re:ports,harddisk....
well, I wrote it to sector 64... I've also written it to 63,15,14 (all work fine) except for 64...Tim Robinson wrote:What do you expect to see? How do you know it's not the right info? You should be seeing the boot sector of the first partition. Any code?frank wrote:I'm trying to read sector 64 at cylinder 1 , head 0 of the harddisk.
That works fine if I first read sector 63 at cylinder 0, head 0.
But if I don't read sector 63 at cy l 0, head 0 then
sector 64 (cyl 1,head 0) doesn't get the right info...
Any ideas why?
Look up LBA in the ATA reference you're using; the sector number gets split across the cylinder and sector registers. Alternatively, write a simple sector number to cylinder-head-sector function and program the CHS values into the drive.Also I output the sector number using my outportdd function which sends 2 bytes which is 66536 bytes big... but my disk has more sectors than 66536, so should I make a function called outportw (which sends 4 bytes) instead?
BTW: outportw sounds like it outputs a word, which is 2 bytes and ranges from 0 to 65535. outportd sounds like it outputs a doubleword, which is 4 bytes and ranges from 0 to 2[sup]32[/sup] - 1 (about 4 billion).
(i'm using dd for it at the moment)
Normally, yes, I should see the start of the partition...
the thing is, I'm not using partitions right now.. (I boot my os the windows way now)
so I should see the data... it works fine with sector 63,15,14 (at head 0, cyl 0)
but when I read sector 64 (without reading 63 before) it outputs the wrong data...
if I do read sec 63 before it outputs the right data..
Code: Select all
int ATAreadsec(int drive,char head,char sec,int cylinder,unsigned char * buf)
{
unsigned char c=0x0,c2=0x00;
unsigned short int b;
int cylinderlow,cylinderhigh;
int i=0;
int dh=0;
cylinderlow = (cylinder & 255);
cylinderhigh = (cylinder >> 8 & 255);
dh = dh+(prisec & 255);
dh = dh+(head >> 8 & 255);
if (ATA[drive]){
ATAsetdrive(drive); /* set drive ports. */
outportdd(diskport,dh);
outportdd(nrsecport,1);
outportdd(secport,sec);
outportdd(lcylport,cylinderlow);
outportdd(hcylport,cylinderhigh);
outportdd(commandport,0x20); /* Read with retry */
ATAdiskready();
while (i<512)
{
b = inportdd(dataport);
asm volatile("movw %%ax,%%bx"::"b" (b));
asm volatile("mov %%al,%%bh":"=b" (c));
asm volatile("mov %%ah,%%bl":"=b" (c2));
buf[i] = c;
buf[i+1] = c2;
i = i+2;
}
ATAdiskready();
} else {
printf("\nTrying to read an non ATA disk");
}
return * buf;
}
I have to read sector 63 for some reason, else it doesn't put the sector..
(sectors before 63 don't work)...
yes reading does, but when I want to read 64,65 only 63 works..
I don't know what I did wrong, reading sectors lower than 63 work directly...
( I have 63 sec per track, new cylinder starts at 64 )
I didn't do a seek, should I? (also, how?)
Any examples/codes of the disk from other os-es? (language doesn't really matter, I prefer C)
Re:ports,harddisk....
When you write to the 64th sector, it is actually Cyl1, Sec0, Hd0... Not Cyl1, Sec 64... You only have 64(0-63) Sectors per cylinder.
Re:ports,harddisk....
Warmaster199 is right... LBA sector 64 is actually head 0 cylinder 1 sector 0. Sector 65 is C/H/S = 1/0/1, etc.
By the way, you should probably learn some boolean algebra.
AND operator (& in C): masks bits.
value & mask clears the 1 bits in value that are 0 in mask, and leaves the bits in value that are 1 in mask alone.
OR operator (| in C): combines bits
value | bits combines the bits in mask with the bits in value, so that the 1's in mask become 1's in value, and the 0s in mask are ignored.
Left and right shift operators (<< and >> in C): move bits
value << count moves the bits in value count bits to the left. The bottom bits are cleared.
value >> count moves the bits in value count bits to the right. The top bits are cleared.
To obtain the high and low bytes of a 16-bit number:
When working with sets of bits, you should use OR and shifts instead of + and *. If you add together two bit patterns, and some bits that are set in one pattern are set in the other, you won't get the right result. If you OR them, everything will be fine.
That was just a quick reference; see pretty much any computer science text for more detail.
By the way, you should probably learn some boolean algebra.
AND operator (& in C): masks bits.
value & mask clears the 1 bits in value that are 0 in mask, and leaves the bits in value that are 1 in mask alone.
OR operator (| in C): combines bits
value | bits combines the bits in mask with the bits in value, so that the 1's in mask become 1's in value, and the 0s in mask are ignored.
Left and right shift operators (<< and >> in C): move bits
value << count moves the bits in value count bits to the left. The bottom bits are cleared.
value >> count moves the bits in value count bits to the right. The top bits are cleared.
To obtain the high and low bytes of a 16-bit number:
Code: Select all
bh = (bx >> 8) & 0xff; /* shift right 8 bits and mask bottom 8 bits */
bl = (bx >> 0) & 0xff; /* don't shift at all; mask bottom 8 bits */
That was just a quick reference; see pretty much any computer science text for more detail.
Re:ports,harddisk....
cylinder 1, head 0, sec 0 works ,
but I still have to read cylinder 0-head 0-sector 63 (end of cylinder 0) before I can read cylinder 1-head 0-sec 0.
(else it outputs data from another sector)
Any ideas why?
but I still have to read cylinder 0-head 0-sector 63 (end of cylinder 0) before I can read cylinder 1-head 0-sec 0.
(else it outputs data from another sector)
Any ideas why?
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:ports,harddisk....
what a fool am i to fight the legendary Tim Robinson on the block addressing battle field ... Grand Gods of Assembly, i pray for mercy ...Tim Robinson wrote: Warmaster199 is right... LBA sector 64 is actually head 0 cylinder 1 sector 0. Sector 65 is C/H/S = 1/0/1, etc.
That was just a quick reference; see pretty much any computer science text for more detail.
this been said, i remembered the sector after C=0/H=0/S=63 was C=0/H=1/S=1 rather than C=1/H=0/S=1. This mainly make sense because moving to the next head requires absolutely no rw heads moves (the slowest part of disk IO) and thus contiguous sectors can be read far quickly than if it has to change the heads position every single track.
Assuming (as tim said) sector 64 is 1/0/1 (remember: no sector #0) would mean that you need nb_heads*nb_cylinders heads moves to sweep your entire disk while assuming it is 0/1/1 does only require nb_cylinders moves ...
now, i leave my fate in the hands of BIOS ...
Re:ports,harddisk....
Tried it using assembly, doesn't work
I still have to read sec 63-head 0-cyl 0 before I can read sec 0-head 0-cyl 1...
(else it outputs wrong sector data, probably sector data of another sector)
But it doesn't work without reading sec 63 (end of cyl 0) before reading sec 0... (Cyl 1)
code:
I still have to read sec 63-head 0-cyl 0 before I can read sec 0-head 0-cyl 1...
(else it outputs wrong sector data, probably sector data of another sector)
But it doesn't work without reading sec 63 (end of cyl 0) before reading sec 0... (Cyl 1)
code:
Code: Select all
bits 32
jmp t
t: mov ebx,0xb8000
mov byte[es:ebx],'f'
jmp set
set: mov dx,0x1f6
mov ax,176 ; head+drive, second drive
out dx,al
mov dx,0x1f2
mov ax,1 ; 1 sector
out dx,al
mov dx,0x1f3
mov ax,63 ; sector 63
out dx,al
mov dx,0x1f4
mov ax,0 ; cylinder 0
out dx,ax
mov dx,0x1f5
mov ax,0 ; high cylinder = 0
out dx,ax
mov dx,0x1f7
mov ax,0x20 ; read with retry :]
out dx,ax
f: in al,dx
test al,8 ; are we still busy?
jz f
mov cx,0
mov ebx,0xB8000
jmp re
re: mov dx,0x1f0
in ax,dx
mov dl,al
mov dh,ah
mov byte[es:ebx],dl
inc ebx
mov byte[es:ebx],0x1F
inc ebx
mov byte[es:ebx],dh
inc ebx
mov byte[es:ebx],0x1F
inc ebx
inc cx
cmp cx,512
jne re
jmp k
;
; do the same stuff again...
;
k: mov dx,0x1f6
mov ax,176 ; head+drive, second drive
out dx,al
mov dx,0x1f2
mov ax,1 ; 1 sector
out dx,al
mov dx,0x1f3
mov ax,0 ; sector 1
out dx,al
mov dx,0x1f4
mov ax,1 ; cylinder 1
out dx,ax
mov dx,0x1f5
mov ax,0 ; high cylinder = 0
out dx,ax
mov dx,0x1f7
mov ax,0x20 ; read with retry :]
out dx,ax
f2: in al,dx
test al,8 ; are we still busy?
jz f2
mov cx,0
jmp re2
re2: mov dx,0x1f0
in ax,dx
mov dl,al
mov dh,ah
mov byte[es:ebx],dl
inc ebx
mov byte[es:ebx],0x1F
inc ebx
mov byte[es:ebx],dh
inc ebx
mov byte[es:ebx],0x1F
inc ebx
inc cx
cmp cx,512
jne re2
hang: jmp hang ; hang
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:ports,harddisk....
as long as i remember, there is *no* sector #0 on any track: sectors are numbered from 1 to 63, not from 0 to 63 !!
Re:ports,harddisk....
doesn't change much...
outputs no data at all...
hmmm, no errors at all...
head 0, cyl 1,sector 0, = sec 64, 65 is the sec 1...
outputs no data at all...
Code: Select all
bits 32
jmp k
;============================
; do the stuff again...
;============================
k: mov dx,0x1f6
mov ax,176 ; head+drive, second drive
out dx,al
mov dx,0x1f2
mov ax,1 ; 1 sector
out dx,al
mov dx,0x1f3
mov ax,1 ; sector 1
out dx,al
mov dx,0x1f4
mov ax,1 ; cylinder 1
out dx,ax
mov dx,0x1f5
mov ax,0 ; high cylinder = 0
out dx,ax
mov dx,0x1f7
mov ax,0x20 ; read with retry :]
out dx,ax
f2: in al,dx
test al,8 ; are we still busy?
jz f2
mov cx,0
mov ebx,0xB8000
jmp re2
re2: mov dx,0x1f0
in ax,dx
mov dl,al
mov dh,ah
mov byte[es:ebx],dl
inc ebx
mov byte[es:ebx],0x1F
inc ebx
mov byte[es:ebx],dh
inc ebx
mov byte[es:ebx],0x1F
inc ebx
inc cx
cmp cx,512
jne re2
jmp hang
hang: jmp hang ; hang
hmmm, no errors at all...
head 0, cyl 1,sector 0, = sec 64, 65 is the sec 1...
Code: Select all
bits 32
jmp set
err: mov ebx,0xb8000
mov byte[es:ebx],'E'
inc ebx
mov byte[es:ebx],0x1F
jmp hang
set: mov dx,0x1f7
in al,dx
or al,1
je err
or al,7 ; ready to accept commands ? :)
jz set
mov dx,0x1f6
mov ax,176 ; head+drive, second drive
out dx,al
mov dx,0x1f2
mov ax,1 ; 1 sector
out dx,al
mov dx,0x1f3
mov ax,0 ; sector 1
out dx,al
mov dx,0x1f4
mov ax,1 ; cylinder 1
out dx,ax
mov dx,0x1f5
mov ax,0 ; high cylinder = 0
out dx,ax
mov dx,0x1f7
mov ax,0x20 ; read with retry :]
out dx,ax
f: in al,dx
or al,1 ; error?
je err
test al,8 ; are we still busy?
jz f
mov cx,0
mov ebx,0xB8000
jmp re
re: mov dx,0x1f0
in ax,dx
mov dl,al
mov dh,ah
mov byte[es:ebx],dl
inc ebx
mov byte[es:ebx],0x1F
inc ebx
mov byte[es:ebx],dh
inc ebx
mov byte[es:ebx],0x1F
inc ebx
inc cx
cmp cx,512
jne re
jmp hang
hang: jmp hang ; hang
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:ports,harddisk....
maybe displaying the status result on screen might help ... maybe it says "ready" but its seek is not yet complete or maybe an error occured ...
Re:ports,harddisk....
hmmmm... it outputs 1e00 when I read sec 0 - head 0 - cyl 1...
(checked that in vi, I've put a part of the disk in a file )
1e00 is sector 6 at head 0 - cylinder 0
(checked that in vi, I've put a part of the disk in a file )
1e00 is sector 6 at head 0 - cylinder 0
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:ports,harddisk....
i think we're not talking about the same thing: i was suggesting that you display the disk status port on screen with something like
Code: Select all
hexs db '0123456789abcdef'
mov [0xb8000],0x073e073e ; displays ..
xor ebx,ebx
f2: in al,dx
mov bl,al
shr bl,4
mov ah,[hexs+ebx]
mov [0xb8000],ah ; display higher nible
mov bl,al
and bl,0x0f
mov ah,[hexs+ebx]
mov [0xb8002],ah ; display lower nible
test al,0x20 ; is there a flaw
err:
jne err ; if there is, stops working
test al,0x8 ; are we still busy?
jz f2
...
Re:ports,harddisk....
What do you mean?
I read the status port (see f: in ax,dx)...
dx still contains the status port,
I see no errors at all, only the output of the wrong sector.
(just checked the error register (0x1f1), doesn't output errors either.
I checked if the are bits using: or al,number)
[edit]
It always outputs that sector, no matter if I change the sector.
So cylinder 1021 outputs the same as 567...
see source:
changing the cylinder to 0 (or any other number) does no matter, it doesn't output the right output...
but when I select cylinder 0 and a number < 63 for the sector it works fine...
[/edi]
I read the status port (see f: in ax,dx)...
dx still contains the status port,
I see no errors at all, only the output of the wrong sector.
(just checked the error register (0x1f1), doesn't output errors either.
I checked if the are bits using: or al,number)
[edit]
It always outputs that sector, no matter if I change the sector.
So cylinder 1021 outputs the same as 567...
see source:
Code: Select all
bits 32
jmp s
err: mov ebx,0xb8000
mov byte[es:ebx],'E'
inc ebx
mov byte[es:ebx],0x1F
jmp hang
s: mov dx,0x1f7 ; recalibrate
mov al,0x10
out dx,al
f2: in al,dx
test al,7
jz f2
;===============================================
; read
;===============================================
mov dx,0x1f6
mov ax,176 ; head+drive, second drive
out dx,ax
mov dx,0x1f2
mov ax,1 ; 1 sector
out dx,ax
mov dx,0x1f3
mov ax,0 ;0 ; sector 0
out dx,ax
mov dx,0x1f4
mov ax,1007 ; cylinder 1
out dx,ax
mov dx,0x1f5
mov ax,5343 ; high cylinder = 0
out dx,ax
mov dx,0x1f7
mov ax,0x20 ; read with retry :]
out dx,ax
; Check for errors
mov dx,0x1f1
in al,dx
or al,1
je err
or al,2
je err
or al,3
je err
or al,5
je err
or al,7
je err
or al,8
je err
f: mov dx,0x1f7
in ax,dx
or ax,1 ; error?
je err
test ax,8 ; are we still busy?
jz f
mov cx,0
mov ebx,0xB8000
jmp re
re: mov dx,0x1f0
in ax,dx
mov dl,al
mov dh,ah
mov byte[es:ebx],dl
inc ebx
mov byte[es:ebx],0x1F
inc ebx
mov byte[es:ebx],dh
inc ebx
mov byte[es:ebx],0x1F
inc ebx
inc cx
cmp cx,512
jne re
jmp hang
hang: jmp hang ; hang
but when I select cylinder 0 and a number < 63 for the sector it works fine...
[/edi]