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 - Programmer "proprement"
(Article écrit par Max et extrait d'Amiga News Tech - mai 1990)
|
|
Permettez-moi une petite parenthèse pour aborder un problème qui, apparemment, vous tient à coeur : programmer "proprement".
Ça veut dire quoi, "proprement" ? Tout simplement ceci : respectez sinon les gugusses qui se sont emm... pendant des
années pour pondre un ordinateur fabuleux (n'ayons pas peur des mots), au moins cet ordinateur lui-même.
En d'autres termes, évitez la programmation sauvage qui consiste à implanter son programme en mémoire, sans
soucis de ce qui peut déjà s'y trouver. N'oubliez pas que l'Amiga est une machine multitâche, ce qui implique
que l'on se conforme à quelques règles, succinctes certes, mais indispensables.
Adresse absolue
Premièrement, et sans doute le plus important, ne logez jamais vos programmes à une adresse absolue ! Finis
les ORG préhistoriques de l'antédiluvien K-Seka. De nos jours, un programme est chargé n'importe
où en mémoire, selon la place disponible. Si vous forcez une adresse de chargement, rien ne dit que vous
n'irez pas écraser une tâche ou des données importantes ! Et que ceux qui prétendent que c'est le seul
moyen d'avoir des données en mémoire Chip me laissent me marrer deux minutes... Au moins deux moyens
permettent d'y parvenir.
Le premier, plutôt bénin et pro, consiste à réserver la mémoire grâce à la fonction AllocMem(), à
charger les données adéquates depuis le disque, et à restituer cette mémoire avec FreeMem()
lors de la sortie du programme. Le second, plus facile à mettre en oeuvre, consiste à forcer l'assemblage
du programme et/ou des données en mémoire Chip. Devpac II connaît les pseudo-directives SECTION CODE_C,
SECTION DATA_C et section BSS_C, tandis que K-Seka admet, tout du moins dans sa dernière version, une
option d'assemblage appropriée.
Vecteur
Deuxièmement, et à partir de maintenant, je m'adresserai plus particulièrement aux programmeurs de démos en
tous genres, lorsque l'on détourne un vecteur quelconque, il convient de le remettre en place. Dans le
même ordre d'idée, tous les registres matériels importants, au même titre que les toilettes, doivent être
laissés dans l'état où on les a trouvés en entrant. Ils ne sont pourtant pas nombreux : DMACON et INTENA.
Quant au Copper, il est réinitialisé tous les 1/50e de seconde par le système (registre COPxLCH et COPxLCL),
on peut donc, à la rigueur, ne pas s'en occuper.
Interruptions
Troisièmement, les interruptions. Ben oui, il arrive souvent, pour ne pas dire tout le temps, que l'on ai besoin
de s'installer une routine d'interruption propre (n'est-pas, m'sieur SoundTracker ?). Le moyen le plus couramment
utilisé est le suivant : on place en $6c l'adresse de notre propre routine, et le tour est joué. Ben oui, mais
non : si on ne rétablit pas ce vecteur en quittant, l'Amiga se trouvera fort embêté lorsque la bise sera venue...
Le multitâche
Quatrièmement, le multitâche. Là encore, on s'en passe quasiment tout le temps. Il existe plusieurs manières de
le désactiver, depuis l'appel à Forbid() - suivi de l'inévitable Permit() - au passage en mode superviseur - par
SuperState, trap #x, etc.
Tout ça pour introduire les deux routines suivantes, baptisées, de manière fort judicieuse
d'ailleurs, Sauve et Restaure. Un simple appel à ces routines respectivement en début et fin de votre propre programme,
résoudra tous les problèmes évoqués plus haut. On en reparle tout de suite après lesdites routines.
Sauve
Restaure
Voyons d'abord Sauve : comme expliqué en long, en large, en travers et plus haut, cette routine sauvegarde quelque
part en mémoire les valeurs des registres matériels les plus importants pour le système. Premièrement, le vecteur
IRQ (vecteur d'interruption de niveau 3, celle exécutée à chaque VBL) que l'on trouve à l'adresse $6c) est copié en
OldIRQ. Même si vous n'utilisez pas d'interruption, ou d'une autre manière, deux précautions valent toujours mieux
qu'une.
Viennent ensuite les registres DMACON et INTENA qui contrôlent respectivement les canaux DMA à activer (Copper, Blitter,
sprites...) et les interruptions à autoriser parmi les six niveaux que connaît le 68000 (rappel : en fait, 8 niveaux sont
à distinguer, mais le niveau 0 correspond à l'état "pas d'interruption" et le niveau 7, dit "non masquable", n'est pas
utilisé dans l'Amiga). Une fois sauvegardés, ces deux registres sont "vidés", c'est-à-dire que tous les canaux DMA sont
bloqués et toutes les interruptions interdites. Seul le 68000 continue à fonctionner. Heureusement d'ailleurs, sinon on
ne pourrait pas appeler la fonction Exec SuperState(), qui a pour but de le commuter en mode superviseur (ce qui a
pour effet de bloquer le multitâche). A partir de là, plus rien ne viendra disturber le bon fonctionnement de votre programme.
Restaure : remet tout dans l'état initial. L'ancien vecteur IRQ est remis à sa place en $6c, ainsi que les anciens
DMACON et INTENA, en ayant bien entendu pris soin de positionner le bit SET/CLR (le bit 15, quoi) à un avant - d'où
l'utilité des or.w #$8000,d0.
Une remarque au passage : Sauve ayant interdit tout canal DMA et toute interruption, vous devrez, dans votre programme,
initialiser ces registres d'après vos propres besoins.
Après ces deux routines, il ne vous reste plus qu'à gérer vous-même l'utilisation de la mémoire. De manière aussi
propre, j'espère...
|