Suivez-nous sur X

|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : Assembleur - disk.resource et cia.resource
(Article écrit par Max et extrait d'Amiga News Tech - mai 1991)
|
|
Le système d'exploitation de l'Amiga offre un moyen à la fois simple, efficace et pratique, au travers des bibliothèques
et des devises, de gérer les différents périphériques de la machine. Il y a pourtant des cas dans lesquels l'on peut
avoir besoin d'accéder directement au matériel.
Le problème reste toujours le même : l'Amiga étant multitâche, accéder aux registres matériels sans prendre de
précautions peut entraîner des situations, heu... disons délicates. Que diriez-vous si, alors que
votre traitement de texte préféré imprime votre superbe document que vous avez passé trois heures à réaliser, un
autre programme venait à s'approprier sauvagement le port parallèle pour ses propres besoins ?
C'est pour éviter ce genre d'incidents que les petits malins de chez Commodore-Amiga ont introduit
la notion de "resource", ou, en français dans le texte, de... ressource, mais oui madame, c'est
encore un militaire qui gagne une tringle à rideaux.
Le principe est fort simple : avant d'attaquer le matériel, on demande poliment à l'Amiga
si personne d'autre n'est en train de l'utiliser, et si c'est le cas, on se l'approprie égoïstement,
interdisant par la suite aux autres tâches d'y accéder. Ce qui me fait préciser tout de suite
qu'évidemment, il ne faudra pas oublier de le libérer après usage, sinon pan-pan cul-cul.
Il n'existe pour l'instant que quatre ressources officiellement gérées : la disk.resource,
la cia.resource, la misc.resource et la potgo.resource.
Ouverture d'une ressource
Tout comme une bibliothèque ou un périphérique logique, une ressource doit être ouverte au moyen d'une
fonction d'Exec appropriée, qui s'appelle devinez comment ? OpenResource(), oui.
Son synopsis est le suivant :
Résultat = OpenResource(ResourceName,Version)
d0.L -498 a1 d0.L
|
Avec :
- Résultat : adresse de base de la ressource, ou 0 si erreur.
- ResourceName : pointeur sur son nom, terminé par 0.
- Version : numéro de version de la ressource.
Remarquez la similitude à peine voulue avec OpenLibrary()...
Note : dans la suite de cet article, tous les exemples seront donnés en assembleur,
qui reste tout de même le langage le plus pratique pour accéder aux ressources.
On accède ensuite aux fonctions de chaque ressource via son adresse de base, comme pour
une bibliothèque standard. Par contre, à la différence d'une bibliothèque, on ne referme
pas une ressource (la fonction CloseResource() n'existe pas !). La raison en est simple :
une et une seule tâche peut à un moment donné, posséder une ressource ; il est donc inutile,
comme c'est le cas pour une bibliothèque, de maintenir un compteur de "clients" avec des
variables et des zones de données propres à chacun d'entre eux. L'ouverture d'une
ressource consiste simplement pour celle-ci à vérifier que personne ne la possède déjà et
à retourner le cas échéant son adresse de base, un point c'est tout.
Attention : ouvrir une ressource ne suffit pas pour y accéder ! Il faut ensuite se
l'approprier grâce à ses fonctions propres.
Re-attention : une ressource n'est finalement rien d'autre qu'un protocole d'utilisation
du matériel dans un environnement multitâche. Rien de physique n'interdit l'accès aux registres
matériels (adresses $DFFxxx) directement par un programme. C'est de la responsabilité du programmeur,
que de respecter ou non ce protocole.
Disk.resource
En voilà une qui n'est que rarement utilisée. Non pas qu'elle ne présente pas
d'intérêt particulier, mais bon, la gestion directe des lecteurs de disquette sur
l'Amiga étant un tel bordel, autant laisser cela au trackdisk.device, qui
s'en débrouille d'ailleurs fort bien.
Le premier problème vient du fait que le trackdisk.device s'appropria lui-même la
ressource de chaque lecteur connecté, et ne la libère jamais, chaque lecteur étant,
théoriquement, en permanence disponible pour le système. Néanmoins, la disk.resource
offre deux paires de fonctions pour s'approprier/libérer une unité donnée. Le couple
AllocUnit() et FreeUnit() est utilisé lorsque le lecteur en question n'est pas encore
reconnu par le système. Un exemple typique est un périphérique logique devant gérer un lecteur
particulier (5,25" ou 3" par exemple) : le périphérique logique est chargé par la commande
Mount de la startup-sequence, il réserve la ressource, et le système, par cette
même commande Mount, prend connaissance de la présence de ce lecteur particulier.
D'un autre côté, GetUnit() et GiveUnit() sont utilisées pour momentanément
piquer la ressource au trackdisk.device. J'insiste sur le mot "momentanément",
parce que d'autres tâches (le Shell en particulier) peuvent vouloir accéder au lecteur
concerné. Cette solution est vivement déconseillée au profit de celle utilisée
par Frédéric Mazué dans son programme anti-clic
d'octobre 1990 (inhibition du lecteur au moyen d'un DosPacket de ACTION_INHIBIT et
utilisation du trackdisk.device). Cette seconde solution garantit de plus une
compatibilité totale avec d'éventuelles futures extensions du matériel dans le domaine des disquettes.
La cia.resource
Les deux circuits 8520, plus connus sous le nom de CIA A et CIA B, qui équipent
l'Amiga fournissent chacun trois chronomètres (timers) de grande précision. Là encore, le
timer.device se charge d'établir une passerelle entre vous et le matériel.
Cependant, une utilisation en multitâche peut conduire à des chronomètres
erronés, notamment lorsque le système est très occupé (beaucoup de tâches tournant
simultanément, dont certaines avec une priorité élevée). Cette relative imprécision
est bien entendu inacceptable pour certaines applications, qui devront alors
recourir à la cia.resource.
L'avantage est qu'un programme utilisant cette ressource à directement accès
aux interruptions provoquées par les chronomètres des CIA. Il s'agit là
d'interruptions matérielles, et non logicielles, comme celles provoquées - et
chaînées - par le timer.device.
Les fonctions offertes sont AddICRVector(), qui installe le vecteur
d'interruption, SetICR() et AbleICR(), qui accèdent au registre ICR
des CIA (note : le propos n'étant pas ici de faire un cours complet sur
le 8520, reportez-vous à la littérature spécialisée, à savoir le Hardware
Manual ou La Bible de l'Amiga), et RemICRVector(), qui enlève le vecteur
d'interruption lorsqu'on n'en a plus besoin.
Note : en réalité, seul le CIA B est disponible, le CIA A étant
intensivement utilisé par le système. La tableau ci-dessous résume l'emploi
de chacun des deux CIA par l'Amiga (rappel : le CIA A déclenche une interruption
de niveau 2 et le CIA B, une interruption de niveau 6) :
|
CIA A (IRQ 2) |
CIA B (IRQ 6) |
Timer A |
Handshake clavier |
Non utilisé |
Timer B |
timer.device MICROHZ |
Non utilisé |
TOD |
timer.device VBLANK |
graphics.library |
L'exemple
Le programme assembleur qui suit utilise la cia.resource pour s'approprier le
chronomètre B du CIA B, et changer la couleur 1 suivant une palette prédéfinie
tous les 1/50e de seconde. Ce type de programme est évidemment plus
adapté avec l'interruption VBLANK (IRQ 3), mais c'est la seule idée qu j'ai
eue, en dehors de l'inévitable et très banal chronomètre. Le source est
suffisamment commenté pour que je puisse me permettre de vous quitter sans
de plus amples explications et vous donner rendez-vous au mois prochain
pour la suite (et la fin) de notre tour d'horizon des ressources.
|