Par Forthman - Forthman@Wanadoo.fr
Un disque est constitué de plusieurs faces ( on parle de têtes pour les disques durs ), chaque face recoit un certain nombre de cylindres ou pistes ( suivant que l'on parle de disque dur ou de disquette ), chaque cylindre est découpé en secteurs, pour les disquettes 1.44Mo il y a 18 secteurs/piste, pour les 720Ko 9 secteurs/piste et pour la majorité des disques durs modernes, 63 secteurs/cylindre ( c'est le maximum que le bios supporte ) et enfin, chaque secteur se compose de 512 octets.
Donc pour accéder à un secteur de 512 octets, nous avons besoin de connaitre :
Il faut savoir que :
A utilier après une erreur.Entrée :
AH = 0
DL = Numéro du lecteurSortie :
AH = Etat
Renvoie la dernière erreur d'un lecteur.Entrée :
AH = 1
DL = Numéro du lecteurSortie :
AH = Etat
C'est l'une des fonction les plus utilisées, elle permet de lire directement des secteurs d'un disque et de les placer en mémoire.Entrée :
AH = 2
DL = Numéro du lecteur
AL = Nombre de secteurs à lire
DH = Numéro de tête
CH = 8 bits de poids faible du numéro de cylindre ( ou piste )
CL :ES:BX = Adresse du buffer dans lequel les secteurs seront placés
- Bits 6 et 7 = 2 bits de poids fort du cylindre
- Bits 0 à 5 = Numéro du premier secteur àlire
Sortie :
AH = Etat
C'est l'une des fonction les plus utilisées, elle permet d'écrire directement des secteurs d'un disque à partir de données en mémoire.Entree :
AH = 3
DL = Numéro du lecteur
AL = Nombre de secteurs à écrire
DH = Numéro de tête
CH = 8 bits de poids faible du numéro de cylindre ( ou piste )
CL :
- Bits 6 et 7 = 2 bits de poids fort du cylindre
- Bits 0 à 5 = numéro du premier secteur à lire
ES:BX = Adresse du buffer a écrire dans les secteursSortie :
AH = Etat
Renvoie les informations du lecteur spécifié.Entrée :
AH = 8
DL = numéro du lecteurSortie :
AL = non défini
DL = nombre de contrôleurs ( le CD-ROM peut avoir son contrôleur )
DH = Nombre de têtes-1 ( 256 têtes maximum )
CH = bits de poids faible du nombre de cylindres
CL :
- Bits 0 à 5 = nombre de secteurs/piste
- Bits 6 et 7 = bits de poids fort du nombre de cylindres
premiere piste * ( nombre de têtes -1 ) * nombre de secteurs/piste + premiere tête * nombre de secteurs/piste + premier secteur - 1
C'est un peu long mais c'est ça.
Pour connaitre le nombre de secteur d'une partition, il suffit d'appliquer
ce calcul avec la derniere tête, derniere piste et dernier secteur,
de soustraire au résultat l'adresse relative, et d'ajouter 1 au
résultat.
Le calcul inverse, càd à partir de l'adresse sous forme
de secteurs, retrouver les piste, tête et secteur :
Adresse relative MOD secteurs/piste = n°
secteur-1
Adresse relative / secteurs/piste MOD nombre
de tetes = n° tête
Adresse relative / secteurs/piste / nombre
de têtes = n° piste
En clair, voici 2 programmes Forth :
Variable TETES ( nombre de tetes de l'unite )
Variable Sect/piste ( nombre de secteurs par piste )
>ADR
----
Convertit 3 valeurs ( Piste Tete Secteur ) en une adresse relative
:
>ADR ( Piste Tete Secteur --- Adresse )
1- >R
Swap
Tetes @ *
+
Sect/piste @
*
R> +
;
ADR>
----
Convertit une adresse relative en 3 valeurs ( Piste Tete Secteur )
:
ADR> ( Adresse32 --- Piste Tete Secteur )
Sect/piste @ MU/Mod
Tetes @ UM/Mod
;
Si le programme ADR> marche parfaitement, en contrepartie, le programme >ADR ne fonctionne que sur de très petites valeurs, car le résultat doit tenir sur 16 bits alors qu'une adresse est codée sur 32 bits. Ceci est dû au fait qu'il n'existe pas de mot Forth permettant de multiplier deux nombres 32bits entre eux. Voici donc un nouveau mot à ajouter au vocabulaire : D*
En entrée : 2 nombres 32 bits
En sortie : 1 nombre 32 bits = à la multiplication des deux
précédents
Ce programme ne fonctionne que sur processeurs 386 minimum et avec TF386.COM
ou TFX386.EXE
Code D* ( d1 d2 --- d3 )
EAX Pop
EDX Pop
16 # EAX Rol
16 # EDX Rol
EDX Mul
16 # EAX Rol
EAX Push
Next
End-code
Et voici la nouvelle definition de >ADR :
>ADR
----
Convertit 3 valeurs ( Secteur-1 Tete Piste ) en une adresse relative
:
>ADR ( Secteur-1 Tete Piste --- Adresse )
0 Swap
Tetes @ *D
D+
Sect/piste @ 0
D*
Rot 0 D+
;
La suite peut être copiée/collée dirrectement dans un fichier *.FTH pour être compilée en turbo Forth ( je laisse le soin a Jacques de faire les quelques modifs pour l'utiliser en WForth, à moins qu'il n'ait pas le temps).
Pour lire un secteur ( 512 octets ) il nous faut une zone mémoire definie : Create Sector_buffer 512 Allot on passe en Hexadécimal Hex Un mot en assembleur pour initialiser le lecteur au cas ou ... Code Init_HD 0 # AH Mov Fonction 0 80 # DL Mov Lecteur 80h ( 1er disque dur ) 13 Int 10 # AX Shr Décale les 8 bits de AH vers AL en effacant AH 1Push on renvoie l'etat du lecteur sur la pile 1Push est équivalent à "AX Push Next" End-code Puis un petit bout de programme en assembleur pour lire le secteur MBR Code Read_MBR 2 # AH Mov Fonction de lecture 80 # DL Mov Lecteur 80h = Disque dur 1 # AL Mov Nombre de secteurs à lire 0 # DH Mov Tête "0" 0 # CH Mov Cylindre "0" 1 # CL Mov Cylindre "0", secteur "1" DS Push Envoie DS sur la pile ES Pop Recupère cette valeur dans ES ( DS ES Mov n'est pas possible ) Sector_buffer # BX Mov Adresse du buffer dans ES:BX 13 Int lance l'interruption 13h 10 # AX Shr Décale les 8 bits de AH vers AL en effacant AH 1Push on renvoie l'état du lecteur sur la pile End-code Un mot qui affiche un message d'erreur et arrête le programme si une erreur se produit avec le lecteur : Erreur? If Si valeur sur la pile <> 0 alors il y a erreur ." Erreur d'acces au disue dur !" Beep J'aime bien le bruit ;-) Abort Then ; Il Faut maintenant "traduire" les infos contenues dans le buffer Juste celles qui nous interressent en fait : MBR? Decimal Force le passage en décimal pour afficher les valeurs Init_HD Erreur? initialise le disque dur, pas d'erreurs ? Read_MBR Erreur? lecture du MBR, pas d'erreurs ? 4 0 Do Cr Sector_buffer 1BE + I 10 * + calcule l'adresse pour chaque partition ." Partition " I . Dup C@ 80 = If ." Amorcable" Then 10 Spaces Dup 4 + C@ 0= If ." Non attribuee" Cr Else ." nø systeme :" Dup 4 + C@ . Cr ." Tete de debut : " Dup 1+ C@ 5 .R ." Tete de fin : " Dup 5 + C@ . Cr ." Cylindre de debut : " Dup 2+ C@ Over 3 + C@ 64 / 256 * + 5 .R ." Cylindre de fin : " Dup 6 + C@ Over 7 + C@ 64 / 256 * + . Cr ." Secteur de debut : " Dup 3 + C@ 63 And 5 .R ." Secteur de fin : " Dup 7 + C@ 63 And . Cr Then Drop Loop ;
Libre reproduction et diffusion autorisée - modifications interdites sans autorisation de l'auteur