|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Voici une nouvelle série qui commence au sein de notre initiation à l'assembleur sur Amiga, dédiée à AmigaDOS. On va commencer doucement par quelques généralités... heu... générales. Tu fichier ! Alors puisqu'il faut bien commencer par quelque chose, et que jusqu'à preuve du contraire, c'est à moi que revient la décision de commencer par ce dont j'ai envie, on va causer un peu des fichiers. La première chose à faire, on s'en doute, c'est d'ouvrir la dos.library. On distingue alors deux possibilités : soit le fichier existe déjà, soit on le crée. Dans les deux cas, on utilise qu'une seule et même fonction, baptisée Open() et de décalage -30. Elle attend deux paramètres : dans D1, l'adresse du nom du fichier, et dans D2, le mode d'ouverture : Une fois le fichier ouvert, on va essayer de lire son contenu. On utilise pour cela la fonction Read(), de décalage -42. Les paramètres sont aussi logiques qu'attendus : le handle du fichier ouvert dans D1, l'adresse où les données lues doivent être logées dans D2, et le nombre d'octets à lire dans D3. Ce qui nous donne en gros : L'inverse de Read() est Write(), qui permet d'écrire des données dans un fichier. Son décalage est -48 et les paramètres qu'elle attend sont exactement identiques à ceux de Read() : Pour se déplacer dans le fichier, ce qui permet par exemple de relire une information qu'on a écrite quelques instants auparavant, ou au contraire pour aller lire le énième octet précisément, on dispose de la fonction Seek(), de décalage -66. Elle attend comme paramètre dans D1, le handle du fichier, dans D2, l'intervalle de déplacement et dans D3, le mode de déplacement. Spécifier le début du fichier, la position actuelle du pointeur et la fin du fichier. L'intervalle, quant à lui, peut-être soit positif (déplacement "vers l'avant") soit négatif (déplacement "vers l'arrière"). Reste à fermer le fichier, ce qui se fait tout naturellement grâce à la fonction Close() de décalages -36. Le seul paramètre à lui fournir est le handle du fichier, dans D1 toujours :
Tout ça ne vous rappelle rien ? Bien sûr que si : la commande Why du CLI. La plupart de ces erreurs sont signalées par un "system requester" qu'AmigaDOS affiche sur l'écran du Workbench. Mais voilà qui ne conclut pas pour autant les fonctions dédiées à la gestion des fichiers. Vous n'êtes pas sans savoir qu'il est possible d'ouvrir une fenêtre CON:, RAW: ou NewCON: de la même manière qu'on ouvre un fichier standard. Dans l'exemple ci-dessous : Pour écrire un texte dans cette fenêtre, on emploie encore la fonction Write() : De la même manière, on peut lire dans cette fenêtre, grâce à la fonction Read() : Enfin, on ferme la fenêtre, encore une fois de la même manière qu'un fichier standard, avec la fonction Close() : Chance de répertoire ! Si vous n'êtes pas bêtes, vous aurez remarqué que les fichiers ne sont pas les seuls éléments que l'on trouve sur une disquette. Il existe aussi les répertoires. Il me semble logique que l'on n'ouvre pas un répertoire comme on ouvre un fichier normal ; il y a certaines règles à respecter. Commençons par le commencement, si vous voulez bien, et imaginons que nous voulions créer un nouveau répertoire sur la disquette placée en DF0: (ce que fait la commande CLI MakeDir, soit dit en passant). Nous appelons pour ce faire la fonction CreateDir de décalage -120, qui attend dans D1 l'adresse du nom du nouveau répertoire : CreateDir() renvoie dans D0 un pointeur sur ce qu'on appelle une structure Lock (verrou), ce que l'on pourrait traduire par "clé d'accès au répertoire". De la même manière que le handle des fichiers, le verrou sera utilisé par la suite pour tout accès au répertoire auquel il est associé. Cette structure est longue de 20 octets, et se présente comme suit :
Le "Type d'accès" peut prendre les valeurs -1 (accès exclusif, c'est-à-dire qu'un seul programme peut avoir accès au répertoire à ce moment donné) ou -2 (accès général, toutes les applications ont accès au répertoire). Dans le cas où le répertoire existe déjà sur la disquette, il est inutile de le créer avec CreateDir(), qui d'ailleurs échouerait lamentablement. On utilise dans ce cas la fonction Lock() de décalage -84, qui attend deux paramètres, à savoir dans D1, l'adresse du nom du répertoire et dans D2, le type d'accès : "ACCESS_WRITE" signifie au contraire qu'on y accède en écriture, donc qu'on est susceptible d'en modifier le contenu, et donc que les autres applications ne peuvent y accéder également (imaginez Deluxe Paint en train de charger une image et vous l'effaçant avant qu'il ait terminé...). Le contraire de Lock(), c'est UnLock(). Son décalage est -90 et le seul paramètre qu'elle attend est le verrou à libérer dans D1: On peut également examiner le contenu d'un répertoire grâce aux fonctions Examine() et ExNext(). Leurs décalages respectifs sont -102 et -108, et elles réclament les mêmes paramètres, c'est-à-dire dans D1 le pointeur sur la structure Lock et dans D2, le pointeur sur une zone de mémoire de 260 octets qui sera remplie d'informations toutes plus utiles les unes que les autres et qu'on appelle FileInfoBlock. Ces deux fonctions permettent d'examiner dans le détail le contenu d'un répertoire, en d'autres termes, d'en obtenir la liste (commande List du CLI). Examine() sert à se brancher sur la première entrée du répertoire (en fait, elle renvoie le nom du répertoire lui-même), ExNext() recherhe les suivantes, une à une. Pour illustrer cela, voici une routine semblable à la commande List, qui se contente toutefois d'afficher le nom des fichiers qu'elle trouve, donc sans leur taille, attribut, commentaire, etc. Son utilisation - sous CLI ou Shell uniquement - est très simple puisqu'il suffit d'entrer :
...pour qu'une liste de son contenu soit affichée. Tant qu'on y est et avant que j'oublie, voici tout de suite le contenu et l'organisation de ce fameux FileInfoBlock :
Comme on le voit, 108 octets sont réservés au nom du fichier, alors qu'AmigaDOS n'en permet que 32, et 116 au commentaire, alors qu'on n'a droit qu'à 80. Les futures versions du système d'exploitation permettront peut-être d'exploiter tous ces espaces. Car l'inconvénient de la fonction Write() lorsqu'on l'utilise pour écrire du texte, est qu'elle a besoin de connaître le nombre de caractères à sortir. Les noms de fichiers sous AmigaDOS pouvant être de longueur variable, il faut compter un à un tous les caractères jusqu'au 0 final. On initialise donc le registre D3 - celui qui doit justement indiquer la longueur du texte à Write() - à 0, et on l'incrémente au fur et à mesure que l'on teste les caractères composant le nom du fichier. A ce test s'ajoute le fait qu'un nom de fichier ne peut, dans la version actuelle d'AmigaDOS, excéder 32 caractères de long. On utilise donc le registre D0 comme compteur de boucle dans l'instruction DBcc. En gros, cela se résume à : "tant que l'on n'a pas testé 32 caractères au maximum ou que l'un des caractères testés n'est pas 0, incrémente D3". Puissant, comme instruction, non ? Par la suite, on insère un Line Feed (code ASCII $0a) à la suite du nom du fichier, histoire que le prochain aille s'afficher une ligne plus bas et non collé au premier, avant d'appeler Write() et de boucler sur ExNext(). Les plus pointilleux d'entre vous trouveront certainement que je me suis embêté pour pas grand-chose en écrivant ce programme (emploi de l'instruction Link, etc,) ; c'est vrai, mais ainsi il est entièrement relogeable, c'est-à-dire que vous pouvez, par exemple, l'inclure tel quel dans un programme en GFA Basic avec l'instruction Inline. Et puis après tout, c'est un de ces exercices de style dont je suis assez friand. Un dernier mot pour en terminer avec ce programme : rien ne vous empêche de l'améliorer en y insérant une routine de tri alphabétique sur les noms, de sortie de la longueur des fichiers (en hexa ou, plus difficile, en décimal) et de leur commentaire, etc. Si ces routines vous intéressent, je vous les proposerai un de ces quatre. En attendant, on se retrouve le mois prochain pour la suite de nos investigations au sein (oh oui !) d'AmigaDOS.
|