IDE ATA Ports for {Primary/Secundary , Master/Slave} Serial IDE devices - How to read/write one LBA/CHS sector

Reading IDE ATA sector in LBA mode
Function pioreadide(ide As UByte, typ As UByte,sector As UInteger,counts As UShort,where As Any ptr)As uinteger
If counts = 0 Then Exit Function
typ And=&h01
typ Shl= 4 'select which cannel ... Master(0) / Slave(1)
If ide = 0 then
Asm
pushf
cli
pushad
movzx ecx,Word Ptr [counts]
mov ebx,[sector]
mov edi,[where]
mov dx,&H1f1
in al,dx
mov dx,&H1f7
r_wait_busybus:
in al,dx
And al,&b10000000
jne r_wait_busybus
r_wait_until_Drdy1:
in al,dx
And al,&b01000000
je r_wait_until_Drdy1

MOV DX, &h3f6'Device Control register
MOV AL, &b00001010 'nIEN is the second bit from the right here
Out DX, AL 'nIEN is now one!

mov ax,0
cmp cx,256
cmove ax,ax
cmovne ax,cx
mov dx,&H1f2
out dx,al
mov al,bl
mov dx,&H1f3
out dx,al
mov al,bh
mov dx,&H1f4
out dx,al
shr ebx,16
mov al,bl
mov dx,&H1f5
out dx,al
mov al,bh
or al,&H70
and al,&Hef
Or al,Byte Ptr [typ]
mov dx,&H1f6
out dx,al
'btr ax,4 ;0 master
'bts ax,5 ;1 512bytes sector size
'bts ax,6 ;1 LBA mode
'bts ax,7 ;1 ... bla
mov dx,&H1f1
in al,dx
mov dx,&H1f7
r_wbvevemunte:
in al,dx
And al,&b10000000
jne r_wbvevemunte

mov al,&H20 ';20 read with retry / 21 read without retry
mov dx,&H1f7
out dx,al

mov dx,&h1f7
rcampieiepur:
in al,dx
And al,&b01000
je rcampieiepur
cld

_read_me:
mov dx,&H1f0
mov ecx,256
rep insw '; for di=di to di+cx-1 : word ptr [es:di] = in[dx]: next di
mov dx,&H1f1
in al,dx
mov dx,&H1f7

rdealpopand2:
in al,dx
And al,&b10000000
jne rdealpopand2
cmp dword Ptr [counts],1
je r_donememe2
rcampieiepur2:
in al,dx
And al,&b01000
je rcampieiepur2
loop _read_me
r_donememe2:
mov dx,&h3f6
MOV AL, &b00001000 'nIEN is the second bit from the right here
Out DX, AL 'nIEN is now on!
sti
popad
popf
End Asm
Else 'secundary ide ... PIO
Asm
pushf
cli
pushad
movzx ecx,Word Ptr [counts]
mov ebx,[sector]
mov edi,[where]
mov dx,&h177
r_wait_busybus2:
in al,dx
And al,&b10000000
jne r_wait_busybus2
r_wait_until_Drdy12:
in al,dx
And al,&b01000000
je r_wait_until_Drdy12

MOV DX, &h376'Device Control register
MOV AL, &b00001010 'nIEN is the second bit from the right here
Out DX, AL 'nIEN is now one!
mov ax,0
cmp cx,256
cmove ax,ax
cmovne ax,cx
mov dx,&H172
out dx,al
mov al,bl
mov dx,&H173
out dx,al
mov al,bh
mov dx,&H174
out dx,al
shr ebx,16
mov al,bl
mov dx,&H175
out dx,al
mov al,bh
or al,&H70
and al,&Hef
Or al,Byte Ptr [typ]
mov dx,&H176
out dx,al
'btr ax,4 ;0 master
'bts ax,5 ;1 512bytes sector size
'bts ax,6 ;1 LBA mode
'bts ax,7 ;1 ... bla
mov dx,&H171
in al,dx
mov dx,&H177
r_wbvevemunte2:
in al,dx
And al,&b10000000
jne r_wbvevemunte2

mov al,&H20 ';20 read with retry / 21 read without retry
mov dx,&H177
out dx,al
mov dx,&h177
rcampieiepur23:
in al,dx
And al,&b01000
je rcampieiepur23
cld
_read_meqwe2:
mov dx,&H170
mov ecx,256
rep insw '; for di=di to di+cx-1 : word ptr [es:di] = in[dx]: next di
mov dx,&H171
in al,dx
mov dx,&H177

rdealpopand22:
in al,dx
And al,&b10000000
jne rdealpopand22
cmp dword Ptr [counts],1
je r_donememe22
rcampieiepur22:
in al,dx
And al,&b01000
je rcampieiepur22
loop _read_meqwe2
r_donememe22:
mov dx,&h376
MOV AL, &b00001000 'nIEN is the second bit from the right here
Out DX, AL 'nIEN is now on!
sti
popad
popf
End asm
End If
Function = 1
End Function

Writing IDE ATA sector in LBA mode
Function piowriteide(ide As UByte, typ As UByte,sector As UInteger,counts As UShort,where As Any ptr)As uinteger
If counts = 0 Then Exit Function
typ And=&h01
typ Shl= 4 'select which cannel ... Master(0) / Slave(1)
If ide = 0 then
Asm
pushf
cli
pushad
movzx ecx,Word Ptr [counts]
mov ebx,[sector]
mov esi,[where]
mov dx,&h1f7
_wait_busybus:
in al,dx
And al,&b10000000
jne _wait_busybus

_wait_until_Drdy1:
in al,dx
And al,&b01000000
je _wait_until_Drdy1

MOV DX, &h3f6'Device Control register
MOV AL, &b00001010 'nIEN is the second bit from the right here
Out DX, AL 'nIEN is now one!

mov ax,0
cmp cx,256
cmove ax,ax
cmovne ax,cx
mov dx,&H1f2
out dx,al
mov al,bl
mov dx,&H1f3
out dx,al
mov al,bh
mov dx,&H1f4
out dx,al
shr ebx,16
mov al,bl
mov dx,&H1f5
out dx,al
mov al,bh
or al,&H70
and al,&Hef
Or al,Byte Ptr [typ]
mov dx,&H1f6
out dx,al
'btr ax,4 ;0 master
'bts ax,5 ;1 512bytes sector size
'bts ax,6 ;1 LBA mode
'bts ax,7 ;1 ... bla
mov dx,&H1f7
_wbvevemunte:
in al,dx
And al,&b10000000
jne _wbvevemunte
w_stillnotpos:
mov al,&H30 ';0x30 write with retry / 0x31 write without retry
mov dx,&H1f7
out dx,al

mov dx,&h1f7
campieiepur:
in al,dx
And al,&b01000
je campieiepur
cld
w_read_me:
mov dx,&H1f0
mov ecx,256
rep outsw '; for di=di to di+cx-1 : word ptr [es:di] = in[dx]: next di

mov dx,&h1f7
dealpopand2:
in al,dx
And al,&b10000000
jne dealpopand2
cmp dword Ptr [counts],1
je _donememe2
campieiepur2:
in al,dx
And al,&b01000
je campieiepur2
loop w_read_me
_donememe2:
mov dx,&h3f6
MOV AL, &b00001000 'nIEN is the second bit from the right here
Out DX, AL 'nIEN is now on!
sti
popad
popf
End Asm
Else 'secundary ide ... PIO
Asm
pushf
cli
pushad
movzx ecx,Word Ptr [counts]
mov ebx,[sector]
mov esi,[where]

w_waitqwe__:
mov dx,&H177
in al,dx
And al,&b10000000
jne w_waitqwe__
w_doobido:
mov dx,&h177
in al,dx
And al,&b01000000
je w_doobido
MOV DX, &h376'Device Control register
MOV AL, &b00001010 'nIEN is the second bit from the right here
Out DX, AL 'nIEN is now one!

mov ax,0
cmp cx,256
cmove ax,ax
cmovne ax,cx
mov dx,&H172
out dx,al
mov al,bl
mov dx,&H173
out dx,al
mov al,bh
mov dx,&H174
out dx,al
shr ebx,16
mov al,bl
mov dx,&H175
out dx,al
mov al,bh
or al,&H70
and al,&Hef
Or al,Byte Ptr [typ]
mov dx,&H176
out dx,al
'btr ax,4 ;0 master
'bts ax,5 ;1 512bytes sector size
'bts ax,6 ;1 LBA mode
'bts ax,7 ;1 ... bla

mov dx,&H177
w_waitqwe__22:
in al,dx
And al,&b10000000
jne w_waitqwe__22

mov al,&H30 ';30 read with retry / 31 read without retry
mov dx,&H177
out dx,al

w_waitqwe__223:
in al,dx
And al,&b10000000
jne w_waitqwe__223

_veve2ups:
in al,dx
And al,&b01000
je _veve2ups
cld

w_read_meqwe:
mov dx,&H170
mov ecx,256
rep outsw '; for di=di to di+cx-1 : word ptr [es:di] = in[dx]: next di
' in al,&H64' ;for error we still preserve this func
' in al,&H60
' cmp al,&H40
'je _next_pqwe
mov dx,&H177
popandau2:
in al,dx
And al,&b10000000
jne popandau2
cmp dword Ptr [counts],1
je _donebebe
popandou3:
in al,dx
And al,&b01000
je popandou3
loop w_read_meqwe
_donebebe:
mov dx,&h376
MOV AL, &b00001000 'nIEN is the second bit from the right here
Out DX, AL 'nIEN is now on!
sti
popad
popf
End asm
End If
Function = 1
End Function

IDE data received by SENDING : ATA IDENTIFY DEVICE
[WORD]id1
[WORD]cylinders
[WORD]id2
[WORD]heads
[WORD]id3[2]
[WORD]sect_per_track
[WORD]id4[3]
[BYTE]serial_number[((19-10+1)*2)]
[WORD]controller_type
[WORD]controller_buffer_size
[WORD]ecc_transferred
[BYTE]controller_number[((26-23+1)*2)]
[BYTE]model_number[((46-27+1)*2)]
[WORD]num_sect_per_int
[WORD]word_trasfer_flag

IDE ATA Identify HardDisk - Good to find out disk geometry : size and manufacturer
Function get_ide_info(ide As Integer,typ As Integer,buf As ide_prop Ptr) As Integer
Dim As Integer i
Dim As UShort ptr dd=callocate(256*2)
dim as ubyte w
Dim As Any Ptr p
If ide = 0 Then
w = (&h0a+cast(ubyte,typ))*&h10+&h40
p = dd
Asm
push ax
push dx
push ecx
mov ecx,10000
mov dx,&h1f7
_redo_f1:
mov dx,&H1f1
in al,dx
mov dx,&H1f7
in al,dx
dec ecx
jecxz _ok_time_to_go_OUT
in al,dx
cmp al,&h50 '{wait until controller not busy}
jne _redo_f1
_ok_time_to_go_OUT: ':))
mov al,[w]
mov dx,&h1f6
Out dx,al
mov al,&hec
mov dx,&h1f7
Out dx,al
mov ecx,10000
_redo_f2:
mov dx,&H1f1
in al,dx
mov dx,&H1f7
in al,dx
dec ecx
jecxz _OK_now_realy_is_time_to_END
in al,dx
cmp al,&h58 ' {wait for data ready} :))
jne _redo_f2
_OK_now_realy_is_time_to_END:
mov dx,&h1f0
mov edi,[p]
mov ecx,255
cld
push edi
rep insw ' finally read :)
pop edi
pop ecx
pop dx
pop ax
End asm
movsb1(dd,buf,SizeOf(ide_prop)) ':))
Function = 1
dealloc2 @dd
ElseIf ide=1 Then
w = (&h0a+cast(ubyte,typ))*&h10+&h40
p = dd
Asm
push ax
push dx
push ecx
mov ecx,10000
_redo_f12:
mov dx,&H171
in al,dx
mov dx,&H177
in al,dx
dec ecx
cmp ecx,1
jbe _ok_time_to_go_OUT2
'jecxz _ok_time_to_go_OUT2
in al,dx
cmp al,&h50 '{wait until controller not busy}
jne _redo_f12
_ok_time_to_go_OUT2: ':))
mov al,[w]
mov dx,&h176
Out dx,al
mov al,&hec
mov dx,&h177
Out dx,al
mov ecx,10000
_redo_f22:
mov dx,&H171
in al,dx
mov dx,&H177
in al,dx
dec ecx
cmp ecx,1
jbe _OK_now_realy_is_time_to_END2
'jecxz _OK_now_realy_is_time_to_END2
in al,dx
cmp al,&h58 ' {wait for data ready} :))
jne _redo_f22
_OK_now_realy_is_time_to_END2:
mov dx,&h170
mov edi,[p]
mov ecx,255
cld
push edi
rep insw ' finally read :)
pop edi
pop ecx
pop dx
pop ax
End asm
movsb1(dd,buf,SizeOf(ide_prop)) ':))
Function = 1
dealloc2 @dd
endif
End function