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 - Démarrer un programme du Shell ou du Workbench
(Article écrit par Max et extrait d'Amiga News Tech - décembre 1989)
|
|
Ça y est, les temps d'Intuition sont révolus. On a vu tout (ou presque) ce qu'il était possible de voir
concernant l'interface graphique de l'Amiga, sans pour autant être arrivés au bout de nos peines.
Surtout que, comble du paradoxe, tous les programmes que nous avons pu étudier ensemble jusqu'ici,
refusaient absolument de se lancer à partir du Workbench, sous peine de plantage. En d'autres termes,
il est impossible de leur associer une icône sur laquelle il suffirait de double-cliquer pour les exécuter.
Un comble que, vous vous en doutez certainement, nous allons tout de suite réparer.
Un peu de théorie
Voyons pour commencer le cas le plus simple, l'appel à partir du Shell. Vous savez sans doute, pour
avoir déjà utilisé des commandes telles que Dir ou Rename, qu'il est possible de transmettre des
paramètres à un programme. Par exemple, lorsque vous écrivez :
...Dir est le nom de la commande (programme), et la chaîne "DF0:" est le paramètre dont se servira
Dir pour déterminer de quel disque ou dossier elle devra fournir la liste.
Dans un tel cas, le programme appelé possède un moyen très simple de récupérer ses paramètres :
AmigaDOS lui transmet dans a0 l'adresse de l'emplacement en mémoire où se trouve le texte
(dans notre exemple : DF0:) et dans d0, la longueur (en nombre de caractères +1) de ce texte
(ici, ce serait 5). Pourquoi la valeur contenue dans d0 est-elle supérieure d'une unité à la
longueur réelle du texte ? Tout simplement parce qu'AmigaDOS considère le code ASCII 10
(Line Feed) correspondant à l'appui sur la touche "Entrée" comme faisant partie intégrante de la
liste des paramètres.
Le seul inconvénient de cette méthode au demeurant fort pratique, est qu'elle ne permet la transmission
que de chaînes ASCII. Si votre programme a besoin d'un nombre comme paramètre (par exemple, une adresse),
il faudra lui inclure une routine transformant la chaîne ASCII en nombre binaire.
Voici, pour les plus fainéants, telle routine :
Attention toutefois, cette routine ne teste en aucune manière la validité du paramètre ;
que vous entriez "Tonton-Max", "=D446xw" ou "15.63.40", le résultat sera tout de même évalué,
avec les bogues pouvant en découler.
Avouez que c'est hyper-simple. Pour illustrer tout cela, je vous propose une nouvelle petite
commande Shell qui attend un paramètre (en l'occurrence, un nombre décimal quelconque)
qu'elle convertira d'abord en hexadécimal puis en binaire. Les programmeurs apprécieront.
Tous les matins, mon icône et moi... clic, clic !
Reste maintenant à voir comment se présente la situation lorsque le programme est lancé
depuis le Workbench. Là encore, il peut recevoir des paramètres, mais pas de la même manière.
Il existe deux moyens distincts pour passer des paramètres à un programme par l'intermédiaire du
Workbench :
- Dans le cas où le paramètre est le nom d'un fichier, il faut d'abord cliquer une fois sur son icône,
puis ensuite double-cliquer sur celle du programme, tout en maintenant la touche "Shift" appuyée.
- Si les paramètres concernent des options de configuration, il faut les entrer dans la partie
"ToolTypes" (types d'outils) de la fenêtre "Info" (l'exemple le plus connu étant la taille, position et nom de la fenêtre
CLI ou Shell - voir votre manuel de l'Amiga pour en savoir plus là-dessus).
Il faut là encore distinguer les deux cas. Dans le premier, le programme concerné reçoit ses paramètres
par l'intermédiaire de messages. La procédure minimale à suivre consiste à :
- Attendre le message au moyen de la fonction WaitPort() d'Exec.
- Aller le chercher avec GetMsg().
- Exécuter le programme proprement dit.
- Prévenir le Workbench, au moyen de ReplyMsg(), qu'on n'a plus besoin de son message.
Dans le deuxième cas, c'est-à-dire celui où les paramètres sont transmis par l'intermédiaire du gadget
"ToolTypes" de la fenêtre "Info", il faut utiliser certaines fonctions de l'icon.library, car
n'oublions pas que ces types d'outils sont stockés dans le fichier de l'icône elle-même. La procédure
à suivre est donc légèrement plus complexe, surtout qu'il faut de toute manière procéder à la recherche
du message Workbench. La routine qui suit devra donc être insérée au label "GetToolTypes" du listing précédent.
Arrivé à ce stade-là, le plus gros est fait. a1 contient un pointeur sur ce qu'on appelle le
"ToolTypesArray", qui est en fait un pointeur sur une liste de pointeurs sur les textes des types d'outils
et se terminant par un pointeur NULL(0). Pour lire les types d'outils un à un, il faut donc utiliser une
routine du genre (ne pas l'insérer à la suite du listing ci-dessus !) :
Vous imaginez aisément la galère pour tester un à un tous les types d'outils que le programme attend ?
C'est pourquoi l'icon.library met deux fonctions à notre dis position pour nous simplifier la
tâche (ah, quand même !), ce sont "FindToolType" (décalage -96) et "Match ToolType" (décalage -102).
Voici comment elles fonctionnent.
FindToolType() attend dans a0 un pointeur le ToolTypesArray évoqué plus haut, et dans a1
un pointeur sur un texte ASCII terminé par 0 décrivant le type d'outils à rechercher. Imaginons pour
les besoins d'un exemple que nous attendions un type d'outils du style WINDOW=ON/OFF (qui signifie
que le type d'outils "WINDOW" peut prendre les valeurs "ON" ou "OFF"). On écrit alors (en assumant
que a0 pointe déjà sur le ToolTypesArray et que a6 contienne déjà IconBase) :
En retour, si un type d'outils du nom de "WINDOW" est trouvé, d0 contiendra un pointeur sur le texte
se trouvant après le signe égal (ici, soit "ON", soit "OFF") et 0 dans le cas contraire. Il revient
alors au programme de vérifier la conformité des arguments précisés.
MatchToolType() peut justement y aider. Elle attend comme argument le pointeur renvoyé par FindToolType()
transféré dans a0, et dans a1 un pointeur sur le texte à comparer (n'oubliez jamais que les types d'outils
sont toujours exprimés en ASCII, même s'ils représentent des nombres). Pour continuer notre exemple du
type d'outils "WINDOW" :
Vous pouvez maintenant terminer la routine GetToolTypes à votre guise, en utilisant FindToolType()
et MatchToolType() suivant vos besoins. N'oubliez pas simplement de refermer l'icon.library avant
le label "Main", à moins que vous n'en ayez besoin ailleurs dans votre programme.
Tiens, pour la forme, je vais vous donner le contenu complet de la structure DiskObject dont
l'adresse est renvoyée per la fonction GetDiskObject().
Décalage |
Nom standard |
Signification |
$00 |
do-Magic |
Validation du fichier |
$02 |
do-Version |
Numéro de version |
$04 |
do-Gadget |
Structure Gadget de l'icône |
$30 |
do-Type |
Type d'objet (outil, etc.) |
$32 |
do-DefaultTool |
Idem fenêtre Info |
$36 |
do-ToolTypes |
Pointeur sur les types d'outils |
$3A |
do-CurrentX |
Position X de l'icône |
$3E |
do-CurrentY |
Position Y de l'icône |
$42 |
do-DrawerData |
Pointeur sur la fenêtre |
$46 |
do-ToolWindow |
Fenêtre pour les outils (tools) |
$4A |
do-StackSize |
Taille de la pile |
D'où viens-je ?
Je sais, c'est assez inhabituel de finir par le commencement, mais il faut encore que notre
programme soit capable de déterminer s'il a été appelé à partir du Shell ou du Workbench.
Heureusement, c'est hyper-simple.
Voici donc une routine Startup complète, qui détermine si le programme a été appelé depuis le
Shell ou le Workbench, exécute le programme principal, puis retourne à l'appelant.
Vous pouvez soit l'inclure à votre source principal par la directive Include "startup.s",
soit l'assembler en fichier objet dans la perspective d'un lien ultérieur.
Cette routine possède tout de même deux limitations, qui fort heureusement ne sont pas trop contraignantes.
Primo, votre programme doit commencer par le label "Main" (à moins que vous ne changiez ce nom dans
la routine de Startup), et secondo, il doit se terminer par l'instruction "RTS", en étant sûr d'avoir
remis la pile dans l'état où il l'a trouvée en entrant.
Le passage concernant l'icon.library et les fonctions GetDiskObjet(), FindToolType() et
MatchToolType() n'est pas inclus, c'est à vous de vous en occuper si vous en avez réellement besoin.
Insistons encore sur un dernier point : si vous désirez que votre programme puisse être indifféremment
appelé du Shell ou du Workbench, il faut que vous prévoyiez les deux éventualités lorsque vous
récupérerez les paramètres ; n'oubliez pas que dans le cas du Shell, a0 pointe la liste des paramètres
et d0 contient la longueur de la ligne de commande plus 1, alors que dans le cas du Workbench, a0
pointe le premier paramètre, et d0 contient le nombre total de paramètres.
On se retrouve le mois prochain pour une nouvelle série portant sur la gestion des fichiers en
assembleur, et par là-même, sur AmigaDOS en général.
|