Sponsors

FacebookTwitterGoogle Bookmarks

L’AMIGA, UNE CONSOLE DE JEU ? On pourrait le croire... Voyez la revue de presse dans les news : les seuls journaux à parler de l’Amiga sont Micro Mag et Micro News, deux “multi-dédiés” ludiques. Pour des gens comme L’Ordinateur Individuel, Soft & Micro ou SVM, l’Amiga n’existe même pas. Il faut s’appeller Mac ou compatible PC. A croire que jamais rien de professionnel n’a été développé sur Amiga. C’est oublier des logiciels comme DeluxePaint, Word Perfect, ou encore Professional Page. C’est oublier l’ampleur qu’à pris le phénomène “Domaine Public". C’est oublier que l’Amiga possède un environnement multi-tâche, qu’on ne retrouve sur aucun microordinateur de sa catégorie, qui lui confère une souplesse d’utilisation inégalée jusqu’ici. C’est oublier le développement de hardware, de plus en plus performant, poussant l’Amiga à un niveau sinon supérieur, au moins égal aux systèmes cités plus haut. Il est vrai que sur six Amiga vendus, cinq sont des 500, contre un seul 2000. Il est vrai aussi, et maintenant plus que jamais, qu’au prix où il est proposé pour ses possibilités, l’Amiga 500 met toutes les chances de son côté dans la “lutte sanglante" qui l’oppose aux Atari, Archimèdes et autres 8 bits dépassés. On comprend qu’il se vende. Le problème est que le développement ludique du 500 nuit à l’image “sérieuse” du 2000: comment voulez- vous qu'un professionnel soit attiré par un micro-ordinateur dont tout ce qu’il a entendu dire est : “ouah, c’est génial, il possède les meilleurs jeux du moment !’’. Celà dit, ne crachons pas dans la soupe; l’Amiga est partout reconnu pour ses qualités graphiques et sonores, autant le 500 que le 2000. Il est normal, voire inévitable, que le jeu profite lui.aussi de ces capacités. Et certains, de véritables petits chefs-d’œuvres, ne se gênent pas. Le 500 possède en plus un côté hobbyste, celui du “bidouilleur fou" rivé à son clavier 26 heures par jour. Celui à qui s’adresse principalement cet ANT, d’ailleurs. Un côté beaucoup moins développé sur le 2000. Il ne reste plus qu’à espérer que le côté sérieux de l’Amiga se développe autant que son côté ludique, ce qui est en passe de se produire. INITIATION A LAMIGA-BASIC

Click image to download PDF

AMIGA NEWS TECH numero 05 (10-1989)

Document sans nom EDITO
SOMMAIRE
Edito : Ça commence très fort...
ExecBase : L'Amiga, une console de jeu ? Transactor : Suite et fin de l’article de John Toe- bes sur les techniques d’optimisation des programmes en assembleur.
L’assembleur 68000 : Fainéant de Max ! Mais un listing conséquent pour le pardonner...
La Tube-lntro : Conclusion en beauté de la superbe démo de Little Zeus, avec un ciel étoilé d’enfer !
L’Amiga-Basic : Michel Descoins fait lui aussi assez court ce mois-ci. Au programme, les sauts et les branchements.
Rescues : Grâce à Little Zeus, Milenium 2.2 et FOFT n’auront plus aucun secret pour personne. Requester : Le courrier des programmeurs explique tout sur les fichiers IFF ILBM (entre autres). ViewPort : Finalement, il est là, le listing de la routine de ciel étoile d'Eagle's Rider. Enfin, la première partie est là...
Vous avez pu le constater, le premier numéro de l’Amiga News Tech nouvelle formule n’est pas exactement parti sur les chapeaux de roues... Avouons-le sans honte, ce n’est pas sans quelque précipitation que nous l’avons bouclé. Ce numéro devrait être légèrement meilleur...
Tiens, pendant que j’y pense, je vous rappelle que dorénavant et à partir de maintenant, l'Amiga News Tech est votre journal. Ce qui signifie que tout le monde peut y participer, il suffit de prendre la plume et nous envoyer tout article, sur quelque sujet que ce soit (à condition bien entendu de rester dans le domaine de la programmation sur Amiga). Tout article suffisamment intéressant sera publié dans la rubrique Transactor et, est-il réellement besoin de le préciser, sera rémunéré. Si, grâce à TANT, on arrivait à créer une véritable chaîne d’entraide entre tous les programmeurs de France et de Navarre, notre but serait pleinement atteint. La balle est dans votre camp, à vous de jouer.
Stéphane Schreiber
ExecBase
L’AMIGA, UNE CONSOLE DE JEU ?
On pourrait le croire... Voyez la revue de presse dans les news : les seuls journaux à parler de l’Amiga sont Micro Mag et Micro News, deux “multi-dédiés” ludiques. Pour des gens comme L’Ordinateur Individuel, Soft & Micro ou SVM, l’Amiga n’existe même pas. Il faut s’appeller Mac ou compatible PC. A croire que jamais rien de professionnel n’a été développé sur Amiga.
C’est oublier des logiciels comme DeluxePaint, Word Perfect, ou encore Professional Page.
C’est oublier l’ampleur qu’à pris le phénomène “Domaine Public".
C’est oublier que l’Amiga possède un environnement multi-tâche, qu’on ne retrouve sur aucun microordinateur de sa catégorie, qui lui confère une souplesse d’utilisation inégalée jusqu’ici.
C’est oublier le développement de hardware, de plus en plus performant, poussant l’Amiga à un niveau sinon supérieur, au moins égal aux systèmes cités plus haut.
Il est vrai que sur six Amiga vendus, cinq sont des 500, contre un seul 2000. Il est vrai aussi, et maintenant plus que jamais, qu’au prix où il est proposé pour ses possibilités, l’Amiga 500 met toutes les chances de son côté dans la “lutte sanglante" qui l’oppose aux Atari, Archimèdes et autres 8 bits dépassés. On comprend qu’il se vende.
Le problème est que le développement ludique du 500 nuit à l’image “sérieuse” du 2000: comment voulez- vous qu'un professionnel soit attiré par un micro-ordinateur dont tout ce qu’il a entendu dire est : “ouah, c’est génial, il possède les meilleurs jeux du moment !’’.
Celà dit, ne crachons pas dans la soupe; l’Amiga est partout reconnu pour ses qualités graphiques et sonores, autant le 500 que le 2000. Il est normal, voire inévitable, que le jeu profite lui.aussi de ces capacités. Et certains, de véritables petits chefs-d’œuvres, ne se gênent pas.
Le 500 possède en plus un côté hobbyste, celui du “bidouilleur fou" rivé à son clavier 26 heures par jour. Celui à qui s’adresse principalement cet ANT, d’ailleurs. Un côté beaucoup moins développé sur le 2000.
Il ne reste plus qu’à espérer que le côté sérieux de l’Amiga se développe autant que son côté ludique, ce qui est en passe de se produire.
INITIATION A LAMIGA-BASIC
Où en étions-nous restés, le mois dernier ? Ah oui, ça me revient : aux boucles et aux sauts. Ça tombe bien, il y a encore quelques petites choses à approfondir de ce côté-là...
Avant de commencer, je voudrais savoir ceux qui, dans la salle, ont tout compris au petit programme du mois dernier ? M’enfin, il est pourtant très simple : nous avons défini ce que l’on appelle “un label”, c’est-à-dire une marque dans notre programme, à laquelle nous pourrons nous référer plus tard, pour effectuer, justement, des sauts. Si j’osais une comparaison hardie, je dirais que le label est au programme ce que le code postal est à la lettre : il permet au préposé aux PTT de savoir à quelle agglomération la missive est destinée. Lorsqu’il rencontre par exemple 42160, le facteur sait qu’il doit déposer le courrier à Grézolles, dans la Loire (vous pouvez vérifier!). Dans un programme, c’est la même chose : lorsqu’il rencontre un “GOTO”, l’interpréteur effectue un saut, le label étant la destination de ce saut.
Mais revenons à nous moutons. Notre label était ici dénommé “Menu”. On reconnaît que c’est un label parce qu’il est suivi du double-pont Vient alors l’affichage des différentes options que notre menu propose, puis l’attente de la réponse de l’utilisateur. Bien que nous n’avons pas explicitement effectué un test de la validité de cette réponse, les lignes suivantes permettent de détecter une éventuelle erreur.
Lesdites lignes sont donc destinés à tester le choix effectué, et à se brancher (sauter) à l’option correspondante. Les tests sont bien entendus réalisés par l’instruction IF... THEN.
Si le nombre entré n'était ni 1, ni 2, ni 3, ni 4, ni 5, on retourne alors au menu.
Le reste du programme, c’est-à-dire le corps des options lui-même, est laissé à votre discrétion.
BRANCHEMENTS MULTIPLES
Cette méthode est claire et nette; mais imaginez qu’au lieu de cinq options, le programme en propose 20, voire 30 ou même 40... Celà représenterait un certain nombre de lignes de programme à écrire, toutes de la forme : IF x = y THEN GOTO Label. Il doit y avoir plus simple.
Le “plus simple” en question, c’est l’instruction ON... GOTO. Elle permet de tester une valeur quelconque, soit explicite, soit implicite (c’est-à-dire calculée), et de se brancher, suivant le résultat de ce test, à l’un des labels dont elle est suivie. Reprenons le même exemple, pour plus de clarté :
Menu :
PRINT “1 - Première option”
PRINT “2 - Seconde option”
PRINT ”3 - Troisième option”
PRINT “4 - Quatrième option”
PRINT ”5 - Cinquième option”
INPUT “Votre choix : “Choix
9
REM : attention la ligne qui suit REM : est une seule et même ligne!! ON Choix GOTO Optionl, Option2 Option3, Option4, Option5 GOTO Menu
9
Optionl:
’ Ici, on fait plein de choses
’ Et on retourne au menu GOTO Menu
9
Option2:
’Suite du programme ici
’avec les autres options__
Si vous comparez ce programme avec celpi du mois dernier, vous ne trouverez que peu de différence... Pour être tout-à-fait objectif, elle ne tient qu'à une seule ligne, celle où figure l’instruction ON... GOTO.
L’utilisation même de cette instruction renseigne plus avant sur son utilité et son emploi. Dans notre exemple, la valeur de la variable Choix est testée; si cette valeur est égale à 1, on se branche au label Optionl, sinon, si elle est égale à 2, on se branche au label Option2, sinon... Et ainsi de suite tant qu’il y a des labels spécifiés (et il peut y en avoir jusqu’à 255!). Pratique, non ?
Avant que de voir un type particulier de branchement, les sous-programmes pour ne pas les nommer, il me faut signaler, mais vous vous en étiez sans doute déjà aperçu, que GOTO peut servir à réaliser des boucles infinies. Le programme suivant qui est totalement idiot, ne le tapez pas en est l’illustration vivante (ou presque) :
Bouclelnfinie GOTO Bouclelnfinie Ridicule, non ?
LES SOUS-PROGRAMMES
Qu'est-ce donc qu’un sous-programme ? Pour simplifier, il s’agit d’une portion du programme que l’on peut appeler à maintes reprises depuis divers endroits du programme, et qui possède la particularité de "retourner à l’envoyeur”.
X = 2 Boucle
GOSUB Carre ’ le “é” est interdit! IF x 256 THEN END GOTO Boucle
)
Carre:
PRINT x x = x 2 RETURN
Si vous exécutez ce programme, vous verrez s’afficher à l’écran les nombres 2, 4, 16 et 256. Le sous-programme “Carre” est appelé par l’instruction GOSUB Carre : il calcule le carré du nombre x, avant de retourner continuer l’exécution du programme juste après l’instruction GOSUB qui l’a appelé.
Vous vous en doutez certainement, les sous- programmes simplifient énormément la programmation. Ils permettent de rendre un programme structuré, c’est-à-dire composé de modules pour ainsi dire indépendants, avant chacun une tâche particulière à accomplir (calcul, attente d’une entrée au clavier, graphisme, musique, etc.).
D’ailleurs, l’usage veut que l’on proscrive tant que possible l’instruction GOTO, considérée, à juste titre à mon avis, comme le symbole de la programmation “spaghetti” (comme les westerns du même nom). Cela n’a bien sûr rien d’obligatoire, mais c’est un bon exercice que de l’éviter chaque fois que vous le pouvez. On s’en sort toujours par un WHILE ou un GOSUB.
LES SOUS-BRANCHEMENTS MULTIPLES
Hé oui, il fallait s’en douter; de même que GOTO, GOSUB permet la programmation de branchements multiples, grâce à l’instruction ON... GOSUB. Reprenons une fois de plus notre menu :
Menu:
PRINT “1 • Première option”
PRINT ”2 - Seconde option”
PRINT ”3 - Troisième option” PRINT “4 - Quatrième option” PRINT ”5 • Cinquième option” INPUT “Votre choix : ‘“Choix REM : attention : la ligne qui suit REM : est une seule et même ligne! ON Choix GOSUB Optionl, Option2, Option3, Option4, Option5 GOTO Menu
i
Optionl:
’ Ici, on fait plein de choses
’ Et on retourne au menu RETURN
I
Option2:
’ Suite du programme ici ’ avec les autres options
Le résultat est le même, mais la programmation est “plus propre". De plus, il sera toujours plus facile d’apporter d’éventuelle modifications au programme par la suite (ajout ou retrait d’option(s).
A BIENTOT
Celà suffit pour aujourd’hui (j’ai entendu dire que mon éminent confrère Max avait besoin de beaucoup de place pour son listing... Je lui en cède volontiers un peu de la mienne). Nous aborderons dès le mois prochain le délicat problème des paramètres (transmission, variables locales et globales, etc.). Un sujet conséquent mais ô combien passionnant.
Michel Descoins
Tube-lntro de Little Zeus
COMPLEMENT : ROUTINE D’ANIMATION D’ETOILES
Après de longs mois de dur labeur, nous avons enfin, dans le dernier numéro, achevé la Tube-lntro. Néanmoins, et ce dans un désir de perfection, implantons dans le background un multiscrolllng d’étoiles différentiel, autrement dit, en arrière plan de notre scrolling de caractères en forme de tube et de notre divin logo perpétuellement animé. Mais attention, ce scrolling se fait sur plusieurs plans de vitesses différentes.
Cessons de vous mettre l’eau à la bouche et commençons. Rappelons quelque peu le début de théorie que nous nous avions vu au sujet des Sprites dans le précédent numéro. Le sprite est un élément graphique d’une largeur maximale de 16 pixels et d’une hauteur de votre choix. Le nombre de canaux Sprites est de huit. Habituellement les Sprites comportent trois couleurs; cependant, en combinant les Sprites deux à deux, nous pouvons obtenir des Sprites de quinze couleurs.
Les couleurs des Sprites correspondent aux registres-couleurs allant du 16 au 31. Il faut tout de
même tenir compte du fait que deux Sprites successifs possèdent les mêmes couleurs. Nous avons alors 16 couleurs à répartir sur quatre fois deux Sprites. Il en découle qu’à chaque paire de Sprites, correspondent quatre couleurs dont la première, en dépit de la couleur pré-programmée dans la palette, correspond au transparent.
Pour afficher un Sprite, il faut préalablement définir une liste le concernant. Celle-ci se divise en trois parties : une première définissant les coordonnées de début et de fin du lieu sur l’écran où doit s’afficher le Sprite, une deuxième contenant ses données bitmap et enfin une dernière composée d’un long mot nul, qui spécifie la fin de la Sprite-list.
Nous passerons outre les détails de ces parties. Pour de plus amples informations, il vous suffira de vous reporter au numéro précédent.
Notez que lorsque nous parlons de Sprite, parfois, nous faisons d’une certaine manière un abus de langage. Il est dit que l’Amiga ne possède que huit Sprites, il serait plus juste de dire que ce dernier possède huit canaux DMA Sprites. Cependant, par cause de simplification on parle de Sprite autant pour canal DMA Sprite que pour Sprite. D’ailleurs, nous aurions été bien ennuyé de n’avoir que huit étoiles à l’écran...
Enfin, pour activer les canaux DMA Sprites, il suffit de pocker les addresses de bases respectives de chaque Sprite-list dans les régistres SPRXPTHL. De plus, il ne faut absolument pas oublier de lancer le DMA Sprite par un MOVE.W $ 8220,$ DFF096.
LES SPRITES EN MOUVEMENT
Le secret permettant l’animation des Sprites n’en est certainement plus un pour vous. Nous ne doutons pas que vous avez déjà pensé à changer la valeur des deux mots de contrôle, de manière a donner de nouvelles coordonnées au Sprite et de ce fait de le bouger. Mais soyons tout de même prudent, car des pièges s’annoncent.
C’est-à-dire qu’il ne faut absolument pas changer ces valeurs à tout vent. Pensez au cas dans lequel vous avez uniquement changé le premier mot de contrôle et malheureusement, à ce même instant, le DMA lit les deux mots de contrôle. La valeur lue est par conséquent erronée et ce pour la simple et bonne raison que le premier mot appartient aux nouvelles coordonnées alors que le second appartient aux anciennes coordonnées. Il n’y a néanmoins pas lieu de s’inquiéter.
Pour éviter de tels désagréments, il suffit de modifier les valeurs pendant que le Raster balaie l’écran invisible. C’est à dire la partie supérieure de votre moniteur. On parle aussi de “temps mort vertical”.
PRIORITES DES PUVYFIELDS PAR RAPPORT AUX SPRITES
Parlons d’un sujet qui a une incidence directe sur notre routine. Il s'agit des priorités des Sprites par rapport aux Playfields et celles qui existent au sein même des Sprites, c’est-à-dire quel Sprite se placera devant quel autre.
Nous ne nous éterniserons pas sur cette question des priorités; nous ferons simplement un survol des différents bits du registre concerné, en l’occurence BPLCON2. Celui-ci est situé à l’offset $ 104 et compte 16 bits :
Bit
numéro
15141312111009080706050403020100
aaaaaaaaaabbbccc
A) les bits inutilisés
B) bits correspondant à la position du Playfield composé des bitplanes impairs, par rapport aux quatre paires de Sprites
C) Idem pour la position du Playfield composé des Bitplanes pairs
Nous remarquons que nous avons à notre disposition deux fois trois bits, soit deux fois cinq possibilités. Voici sous forme d’un petit tableau ce à quoi correspond chaque chiffre.
Chiffre Priorités d’affichage
00 Playfield Sprites0&1 Sprites2&3 Sprites4&5 Sprites6&7
01 Sprites0&1 Playfield Sprites2&3Sprites4&5Sprites6&7
02 Sprites0&1 Sprites0&1 Playfield Sprites4&5Sprites6&7
03 Sprites0&1 Sprites0&1 Sprites2&3 Playfield Sprites6&7
04 Sprites0&1 Sprites0&1 Sprites2&3Sprites4&5 Playfield
Ainsi que vous pouvez le constater, plus le chiffre s’accroît, plus la priorité du Playfield est faible. Le tableau précédent peut s’appliquer de manière analogue aux deux Playfields. Ensuite, il vous revient de combiner à bon escient les bits B et C.
PRINCIPE DE LA ROUTINE
Après ce complément de théorie sur les Sprites, nous pouvons assurément aborder le principe de notre routine. D’une manière assez astucieuse, nous allons animer des Sprites d’étoiles de vitesses et de couleurs différentes en n’utilisant qu’un seul canal Sprite DMA. Tout d’abord, nous devons nécessairement insérer dans le début de Copper- List (rappelez-vous ce qui a été précédemment dit au sujet du “temps mort”) la ligne suivante : SpriteO : dc.w $ 0120.0000,$ 0122,0000
L’explication de cette ligne est simple : il s’agit de profiter du Copper pour repointer le canal DMA Sprite numéro 1 à chaque balayage. Quant à l’instruction SWAP que vous pouvez remarquer dans les premières lignes de la routine, elle permet indirectement de Poker respectivement dans la Copper List les poids forts et faibles du début de la Sprite- List. Et donc par répercussion, de vectoriser le canal DMA Sprite numéro 1 sur la Sprite-liste. En effet, SWAP inverse les mots de poids faible et de poids fort d’un long mot. Par exemple, en admettant que dO contienne initialement $ 12345678. à la suite d’un SWAP dO. DO contient $ 56781234. Il convient de préciser deux petites subtilités : la première correspond à l’utilisation du PC (pointeur de pile), ce qui permet une économie de mémoire, à fortiori une plus grande raDidité d’exécution. Nous reviendrons dans un prochain numéro sur ce mode d’adressage; sachez cependant que pour la routine ci-présente, nous aurions pu tout aussi bien se passer du PC. La deuxième subtilité concerne les lignes sur lesquelles nous animerons les étoiles; celles-ci passeront uniquement sur les lignes paires. Pourquoi ? Pour deux raisons : le canal DMA ne pouvant lire que deux mots par ligne, et nos étoiles ne faisant qu’une ligne de haut, le DMA doit, après chaque étoile, connaître les coordonnées de la suivante. Cependant, ces coordonnées prennent deux mots, il en résulte donc que le DMA nécessite une liane sur deux pour lire les coordonnées et ne peut afficher les étoiles qu’une ligne sur deux. Cette raison est suffisante pour ne pas s’encombrer d’étoiles à chaque ligne. De plus, le bit de poids le plus faible de la position horizontale du Sprite se trouvant dans le second mot, contrairement aux autres bits qui se trouvent dans le premier, il serait bien laborieux d’incrémenter ce bit. Notez pourtant que si vous souhaitez absolument des étoiles à chaque ligne, vous devez alors utiliser au moins deux canaux DMA (un pour les lignes paires et l’autre pour les lignes impaires). La raison de “retour à la case départ” de chaque étoile s’explique par le fait que lorsque le compteur de chacune d’elle dépasse l’abscisse 512, ce compteur étant sur 9 bits, la valeur suivante est 0. Il apparaît évident que nous aurons un temps pendant lequel chaque étoile n’apparaîtra pas à l’écran, c’est-à-dire sur les abscisses allant de la limite gauche de l’écran à l’abscisse 512.
Avant de passer à la suite, précisons l’utilisation de l’instruction LSL. Son rôle est simple, elle décale vers la gauche le contenu d’un octet si elle est suivie de .B. d’un mot pour .W. ou enfin d’un mot long pour .L. Ce décalage se fait du nombre de bits spécifié à la suite de l’instuction. Par exemple, LSL.W 2.X décale le contenu de X de deux bits vers la gauche. Comme vous avez certainement pu le remarquer, de par le système binaire, un décalage vers la gauche d’un bit correspond à une multiplication par 2. Par conséquent, l’objet de l’instruction au sein du programme est de multiplier par 2 puissance 2, soit 4, la valeur de la vitesse, ce qui donne un nombre permettant d’accéder aux données des couleurs.
Un dernier petit détail concernant le dépassement de la ligne 255 : effectivement, sur les huit bits de la position verticale du premier mot de contrôle, nous ne pouvons pas excéder la ligne 255. Heureusement, le second bit du deuxième mot de contrôle nous sert de neuvième bit; il en émane que nous pouvons animer les Sprites sur 512 lignes. Cependant, le bas de l’écran s’arrêtant à la 296ème ligne, li nous suffit de faire un test astreignant les étoiles à ne pas dépasser celle-ci.
Sur ce, je vous quitte et vous donne rendez-vous dans le prochaine numéro avec du changement : nous allons explorer le fin fond du hardware de la machine ou de l’unité de disquette au moyen d’un Virus-Killer ultra-performant. Qui plus est, nous passerons la Tube-lntro, mais cette fois sans aucun commentaire, dans son intégralité.
Little Zeus
Routine
d'animation d'étoiles
de Little Zeus
Routine
faisant figure
de complément à la Tube-lntro
Possibilité d'utiliser cette
rout i ne
en dehors de la Tube-lntro
Création de la Sprite-list
îtars:
move.1
spri te.dO
move.w
d0,sprite0+6
swap
dO
move.w
d0,sprite0+2
clr. 1
d2
lea
xpos(pc),a0 ; table des coordonnées X
lea
speed(pc)fa2 ; table des vitesses
lea
sprite(pc),a1 ; début de la liste
move.1
$ 20,dO ; on commence à la ligne 32
starloop:
clr. 1
d1
lea
spcolors-4(pc),a3 ; couleurs
move.b
d0,(a1)+ ; position verticale
move.b
(a0)+,(a1)+ ; position horizontale
addq.w
1,d0 ; ce sprite s'arrête une ligne
move.b
d0,(a1)+ ; plus bas
move.b
d2,(a1)+ ; les coor X sont tjs paires
move.b
(a2)+,d1 ; vitesse -> couleur
Isl .w
2,d1 ; fois 4 (2 exposant 2)
add. 1
d1,a3 ; adresse des datas couleur
move.1
(a3),(a1)+ ; couleur dans la liste
addq.w
1,d0 ; passe à la prochaine étoile
cmp.w
$ 00fe,d0 ; jusqu'à la ligne 254
ble.s
starloop
moveq
6,d2
cmp.w
$ 0128,d0 ; on recommence jusqu'à
bne.s
starloop ; la ligne 296
rts
; on anime tout
stars_move:
move.w
131,dO ; on déplace 132 étoiles
lea
speeed(pc),a2 ; table des vitesses
lea
sprite+1(pc),a1 ; table x dans liste
move_loop:
move.b
(a1),d1 ; valeur X dans D1
move.b
(a2)+,d2 ; vitesse dans D2
add.b
d2,d1 ; somme de D1 et D2
move.b
d1,(a1) ; déplacement vers la droite
add.w
8,a1 ; on passe à la prochaine x
dbf
d0,move_loop ; retour à Move_loop
rts
; table des couleurs
spcolors:
de. 1
$ 80000000,$ 00008000,$ 00008000
de. 1
$ 80008000,$ 80008000
; table des vitesses
speeed:
dc. b
2,4,1,3,5.3,2,1,3,2,5
dc. b
1,4,3,4,3,4,1,3,2,5,4,3,2,5
dc. b
2. 3,1,5,4,1,4,2,3,1.4,3.2
Vous trouverez peut-être que ce mois-ci, votre ration d’aides est plus petite que la dernière fois... Rassurez-vous, je vous réserve pour le mois prochain un programme qui vous sera bien utile. Ne voulant pas perturber votre esprit, je n’anticiperai pas plus sur cette merveille routine. Pour l’instant contentez-vous donc de ces deux autres astuces.__
dc. b
$ c0,$ 5b,$ 1a,$ 98,$ 81,$ d3
dc. b
$ 22,$ 48,$ 91,$ c5,$ ff,$ 12
dc. b
$ 45,$ 95,$ a1,$ 39,$ e0,$ 84
dc. b
$ 05,$ b4,$ a f,$ 76,$ 72,$ 19
dc. b
$ 49,$ 58,$ c0,$ d2,$ e2,$ 92
dc. b
$ 19,$ f5,$ 06,$ 35,$ a8,$ d3
dc. b
$ 89,$ 7e,$ 29,$ 90,$ a4,$ 12
dc. b
$ b9,$ c0,$ e3,$ 88,$ 41,$ 2e
dc. b
$ 59,$ 12,$ f0,$ c3,$ 6e,$ 91
dc. b
$ 2c,$ 55,$ 79,$ 1c,$ 01,$ 96
dc. b
$ a5,$ c1,$ d9,$ e7,$ 14,$ 86
dc. b
$ 10,$ 99,$ d3,$ 69,$ a3,$ c8
dc. b
$ 93,$ 12,$ f5,$ 28,$ c2,$ 39
dc. b
$ 92,$ a0,$ 38,$ bb,$ e1,$ e3
; liste de
données sprite
sprite:
blk.l
265
dc. b
5,1,3,2,4,5,1,2.4,5,3,1
dc. b
4,3,5,1,2,1,4,4,5,3,2,4
dc. b
1,5,2,4,2,5,3,5,3,4,3,1,4
dc. b
4,5,3.2,4,1,3,4,1,3,2,5
dc. b
4,1,3,4,2,3,1,4,3,4,1,2,5
dc. b
3,5,1.4,3.5,2,4,2.5.1,4
dc. b
2,3,4,1,3,5,2.4,3,2,1,5,3
dc. b
4,3,5,1.2.4,1
; table
des coordonnées x
xpos:
dc. b
$ 1e,$ 4f,$ ab,$ dd,$ 1b,$ bb
dc. b
$ 6a,$ f3,$ 88,$ ab,$ f3,$ 73
dc. b
$ 27,$ 8a,$ 0e,$ 22,$ bc,$ 3b
dc. b
$ 20,$ 0e,$ 91,$ 14,$ 59,$ f0
dc. b
$ d5,$ 79,$ b0,$ 32,$ d3,$ 55
dc. b
$ b1,$ 95,$ 89,$ 5 b,$ c3,$ 99
dc. b
$ 01,$ 30,$ d4,$ c3,$ b9,$ a1
dc. b
$ 7e,$ 91,$ 09,$ 4e,$ 70,$ a0
LES RESCUES
MILENIUM 2.2
Voici comme promis tous les conseils nécessaires pour s’assurer rapidement une belle victoire dans ce jeu d’aventures spatiales. Plus besoin d’attendre deux cents ans et de sonder l’univers pour trouver les matériaux qui vous seront nécessaires à la construction des vaisseaux, munissez- vous simplement d’un utilitaire équivalent au MIR- ROR HACK PACK. Je vous donne le moyen de devenir un alchimiste des temps futurs : grâce à mes bonnes idées, il vous sera dorénavant possible de transformer une misérable sonde (probe) en un gigantesque vaisseau de guerre. De bien belles économies en perspectives, n’est-il pas ? Et bien sur le tout sans avoir eu besoin de faire des recherches scientifiques (option “project” du logiciel) au préalable. Soyez bien attentif si vous ne voulez pas créer des monstres ou planter tout simplement le programme.
Commencez tout d’abord une partie ou reprenez votre dernière sauvegarde : fabriquez un probe (en lui donnant un nom sympa) et sauvez le tout sur disquette, en position numéro 1. Chargez maintenant l’éditeur de secteurs et lisez les blocs 45 et 46. Après avoir bien visionné le tout, placez-vous juste au début du nom de l’engin. L’octet qui précède la première lettre correspond au type de vaisseau. Vous devez trouver normalement un 01 indiquant que c’est un Probe, sinon recommencez tout, par précaution. Voici les différentes modifications possibles pour cet octet :
01 : probe
02 : grazer 03, 04 : ???
05 : carrack
06 : transporteur de fighter
07 : ???
08 : Juggernaut
Nous prendrons pour point de repère le 0 qui suit le nom. On trouve alors :
sur un octet le nombre de personnes à bord;
sur un mot la destination de vaisseau (ne pas modifier);
sur un mot la capacité de stockage maximum du ship;
sur un mot le nombre de tonnes encore disponibles;
un octet le portrait du vaisseau (1 = probe, 2 = grazer, etc., jusqu’à 5. Attention, certains vaisseaux ont des portraits identiques et d’autres n en ont pas, comme la base spatiale).
Pour avoir beaucoup de fighters, d anti-virus et de MKI 10 : à partir de la position 22, répétez à la suite 16 fois le mot $ 2672, puis 11 fois I octet $ ff, et enfin une fois l’octet $ 7f.
ET VOILA, C’EST TOUT POUR CE JEU!
Je rappelle à ceux qui n’auraient rien compris qu’un mot correspond à deux octets et qu’un long mot a deux mots, soit quatre octets. Par exemple, si vous souhaitez que la capacité de stockage (stockée sur un mot) soit de 8 tonnes, le 8 se retrouve à droite : 0008 (attention ce nombre est héxadécimal).
P. S. : Si vous en avez marre des jeux d’aventure, dites-nous pour quels jeux d’action vous aimeriez avoir des trucs, en envoyant vos demandes à l’adresse habituelle :
Commodore Revue Little Zeus 1 bis, rue de Paradis 75010 Paris
* *********************************
* F.O.F.T. cheat par LIITLE ZEUS *
* *********************************
F. O.F.T.
Beaucoup de personnes n’ont pas la patience de faire assez de missions pour avoir l’argent qui permettrait d’accéder à des armes supérieures, ce qui est vraiment bien dommage car cela est capital si l’on veut survivre et découvrir toutes les planètes. Pour ces gens-là, j’ai mijoté un listing leur donnant plus de crédits qu’il n’en faudrait pour finir le jeu cent fois. Mais ce n’est pas tout, il vous faut aussi ajouter un petit message personnel de votre cru dans l’ordinateur de bord (d une très grande utilité), ainsi que fortifier les armes les plus utilisées. C’est- à-dire le laser et le plasma. “Fortifier” veut dire stopper la décrémentation des compteurs (ils restent toujours à cent).
Nous devons, pour le listing soit opérationnel, le faire appeler à partir du jeu. Cette opération se réalise ainsi : cherchez à l’aide d’un éditeur de secteurs la séquence suivante sur la disquette : 23FC 000 080E 000 0020 puis remplacez le début par celle-ci : 4EF9 0000 00D0.
N’oubliez pas de faire recalculer le checksum en sauvant le secteur, sinon il deviendra illisible. Assemblez le listing et faites un reset après avoir inséré le jeu dans le drive (n’éteignez pas votre Amiga!!!). Rassurez-vous, le programme ne sera pas effaçé de la mémoire, car il commence à l’adresse $ d0 (il n’y a que quelques octets disponibles mais ceux-ci sont protégés du système d’exploitation). Vous devrez ensuite répéter cette opération avant chaque partie, sinon le jeu se plantera lamentablement (à moins que vous ne remettiez le 23FC 0000 etc. à sa place).
Voilà donc quelques explication sur le fonctionnement du petit programme qui a été écrit sur l’assembleur K-SEKA (réservez 20 K cela suffit largement) :
Au moment où le listing est appelé (c’est-à-dire juste après à la fin du chargement du jeu), il installe le détournement (routine “next”) et trafique les compteurs des armes (annule les décrémentations). La routine next affiche notre message après nous avoir ajusté un joli magot qu’on aimerait bien avoir en réalité. D’une simplicité enfantine, n’est-ce pas ? Vous avez de la chance, car vous n’aurez pas tous les mois un listing aussi court.
En attendant la surprise du mois prochain, qui je l’espère ne vous déplaira pas, je vous laisse découvrir entièrement toutes les richesses de ces deux jeux.
Little Zeus
; bien lire les explications avant toute ; manipulation
0RG $ d0
LOAD $ d0
; installe la déviation en copiant le ; "jsr next" au début du programme move.1 po(pc),$ 30430
move.l po+4(pc),$ 30434
move.I po+8(pc),$ 30438
clr.w $ 2d960
clr.w $ 2daf2
; exécute l'instruction effacée ; par la déviation move.l $ 80e,$ 20
; et retourne au jeu j mp $ 80a
po:
jsr next
nop
nop
; détournement : next:
; prend la derniere coordonnée move.l $ 35b44,(a0)
; affiche le message du jeu jsr $ 35b98
; on remet la somme si le joueur a perdu cmp.l 800000,$ 4e75c
; trop d'argent bcc bye
move.l 9999999999,$ 4e75c
bye:
lea message(pc),a0
; prend la derniere coordonnée move.l $ 35b44,(a0)
; affiche notre message jmp $ 35b98
message: de. I 0
dc. b "Make your choice, "
dc. b "slave of LITTLE ZEUS",0
; vous n'êtes pas obligé de modifier...
end
Très courte, notre initiation de ce mois-ci, puisque toute la place dont je dispose actuellement est occupée par le listing d’un programme qui devrait vous montrer comment créer et gérer un véritable Requester sous Intuition.
Ce programme met en fait en pratique toute la théorie que nous avons vue jusqu’ici : écran, fenêtres, menus et bien sûr requesters. D’une taille conséquente (plus de 550 lignes de code source!), il a été écrit avec l’assembleur Devpac Amiga version 2, mais son adaptation à tout autre assembleur ne devrait poser aucun problème. J’ai évité l’emploi de fichiers “include”, ce qui permettra aux possesseurs du K-Seka d’en profiter également (et du même coup, accélère les temps d’assemblage...). Celà dit, rien ne vous empêche, si vous avez la flemme de taper tout les EQUates préliminaires, d’inclure les fichiers "exec.i”, “exec lib.i”, “intui- tion.i”, “intuition lib.i”, “graphics.i”, “graphies lib.i” et diskfont lib.i”.
Mais trêve de bavardages, on se retrouve le mois prochain pour les explications inhérentes mais néanmoins indispensables.
Max
; Ce programme est une démonstration ; de la manière de construire et de ; gérer un Requester.
; Assemblé tel quel, il n'occupe ; que 1884 octets (pour quelque chose ; comme 550 lignes de code source) !
; Définition des bits de flags pour ; l'écran, la fenêtre et les gadgets
MODE_640
EQU
$ 8000
CUSTOMSCREEN
EQU
$ 0F
GADGETDOUN
EQU
$ 20
GADGETUP
EQU
$ 40
MENUPICK
EQU
$ 100
WINDOWDRAG
EQU
$ 2
BACKDROP
EQU
$ 100
BORDERLESS
EQU
$ 800
ACTIVATE
EQU
$ 1000
RMBTRAP
EQU
$ 10000
ITEMTEXT
EQU
2
COMMSEQ
EQU
4
ITEMENABLED
EQU
$ 10
HIGHCOMP
EQU
$ 40
GADGHCOMP
EQU
0
GADGHNONE
EQU
3
RELVERIFY
EQU
1
BOOLGADGET
EQU
1
PROPGADGET
EQU
3
STRGADGET
EQU
4
AUTOKNOB
EQU
1
FREEHORIZ
EQU
2
; Définition des fonctions des libraries
; Exec Library
ExecBase=4
OpenLibrary
EQU
- 408
CloseLibrary
EQU
- 414
GetMsg
EQU
- 372
ReplyMsg
EQU
- 378
; Intuition Library
OpenScreen
EQU
- 198
CloseScreen
EQU
- 66
OpenW i ndow
EQU
- 204
CloseWindow
EQU
- 72
SetMenuStrip
EQU
- 264
ClearMenuStrip EQU
- 54
AutoRequest
EQU
- 348
DisplayBeep
EQU
- 96
; Graphics Library
OpenFont
EQU
- 72
CloseFont
EQU
- 78
; DiskFont Library
OpenDiskFont
EQU
- 30
; Autres définitions utiles
UserPort
EQU
86 "
MsgClass
EQU
20'
MsgCode
EQU
24
MsgAddress
EQU
28
. A*********************
INITIATION A L’ASSEMBLEUR 68000
; * Début du programme *
. . **********************
Start:
movem.I d1-d7 a0-a6,-(sp)
bsr
Openlnt ; Ouvre Intuition
bne.s
Oklnt ; Tout va bien ?
Move.1
20,dO ; Non : on s'barre
bra
Fin
Oklnt:
bsr
OpenGfx
bne.s
OkGfx
bsr
Closelnt
move.1
30,dO
bra
Fin
OkGfx:
bsr
OpenS
bne.s
OkScr
bsr
CloseGfx
bsr
Closelnt
move.1
40,dO
bra
Fin
OkScr:
lea
WindowDefs.aO
bsr
OpenW
bne.s
OkWin
bsr
CloseS
bsr
CloseGfx
bsr
Closelnt
move.1
50,dO
bra
Fin
OkWin:
move.1
IntBase,a6 ; Coucou le menu
move.1
WinHandle.aO
lea
MenuDefs.al
jsr
SetMenuStrip(aô)
; Saut à la
routine principale
bsr
Main
move.1
IntBase.aô
move. 1
WinHandle.aO
jsr
ClearMenuStrip(aô)
move.1
WinHandle.aO
bsr
CloseW ; Ferme la fenêtre
bsr
CloseS ; Ferme l'écran
bsr
CloseGfx ; Ferme Graphics
bsr
Closelnt ; Et Intuition
clr.l
dO ; R. A. S
Fin:
movem.1
(sp)+,d1-d7 a0-a6
rts ; Et ciao la compagnie !
* ********
Routine principale * (sortie par RTS) *
r
mi
n
£
LU
L
3
3
3
?
R***
Main:
MaînLoop:
; Message pour moi ? Move.l ExecBase,a6
move.l WinHandle.aO
move.1
UserPort(aO),aO
jsr
GetMsg(a6)
move.1
d0,a0
tst. 1
dO
beq.s
MainLoop ; Non
move.1
MsgClass(aO),d0 ; Oui
cmp. 1
MENUPICK,dO ; C'est le menu ?
Bne.s
MainLoop ; Non
MsgCode(aO),dO ; Oui
DoMenu:
move.w
; Ici, on calcule quel item ; de quel menu ou de quel ; sous-menu a été sélectionné.
Move.w dO, d2
Isr.w 8,d2
Isr.w 3,d2 ; N° de sous-menu dans d2
; *** Isr.w 11,d2 est impossible
move.w d0,d1
Isr.w 5,d1
and.w $ 3f,d1 ; N° d'item dans dix
$ 1f,d0 ; N° de menu dans dO
and.w
* *******************
* Réaction au menu *
* *******************
DoMenul: tst.w dO
bne.s DoMenu2
DoMenu1_1: tst.w d1
bne.s DoMenu1_2
rts ; Sortie de "Main" DoMenul_2: cmp.w 1,d1
bne.s Do_Menu1_3
bsr.s DoRequest
Do_Menu1_3:
; *** Rien à faire ici (et pour cause !) DoMenu2:
; *** Ici non plus... bra MainLoop
?**??*******?*****????**
* Gestion du requester *
* ***********************
DoRequest:
lea ReqUindowDefs.aO
bsr OpenW ; Ouvre la fenêtre
bne.s DoRequestLoop ; du Requester
; Mais retourne à "Main"
; en cas d'échec ! Rts
DoRequestLoop: move.l ExecBase,a6
move.1
ReqWinHandle.aO
move.1
UserPort(aO),aO
jsr
GetMsg(a6) ; Message Requester ?
Tst.l

beq
DoRequestLoop ; Non
move.1
d0,a1 ; Ah si, y'en a un !
Move.1
MsgClass(a1),d2
move.1
MsgCode(a1),d3
move.1
MsgAddress(a1),a2
; Il convient
, bien que
; ce ne soit
pas obligatoire.
; de répondre
au message,
; histoire de
dire à Madame
; Intuition qu'on la bien reçu.
; ReplyMsgO
fait ça très bien.
Jsr
ReplyMsg(aô)
move.w
$ 26(a2),d0 ; gg_GadgetID dans dO
sub.w
61,dO ; Etait-ce "OK" ?
Beq.s
DoReqGadl
subq.w
1,d0 ; Ou "Ca flashe !!" ?
Beq.s
DoReqGad2
subq.w
1,d0 ; Ou le String-Gadget ?
Beq.s
DoReqGad3
; Aucun des 3
, donc on boucle
bra
DoRequestLoop
; Traitement
du gadget "OK"
)oReqGad1:
move.1
ReqUinHandle.aO
bsr
CloseU ; Ferme le Requester
rts
; Et retourne à "Main"
; Traitement
du gadget "Ca flashe !!"
DoReqGad2:
move.1
IntBase,a6
move.1
ScrHandle,aO
jsr
DisplayBeep(a6) ; L'écran clignote
bra
DoRequestLoop
; Traitement du String-Gadget :
; On va simplement afficher
; la chaine de caractères entrée
; dans le String-Gadget dans un
; autre Requester, mais de type
; plus simple celui-là, puisqu'il
; s'agit d'un
bête AutoRequester.
DoReqGadî:
move.1
IntBase,a6
move.1
ReqUinHandle.aO
lea
BodyiText,a1
lea
ButtoniText,a2
lea
ButtoniText,a3
move.1
0,d0
move.1
0,d1
move.1
300,d2
move.1
60,d3
jsr
AutoRequest(aô)
bra
DoRequestLoop
; Eventuellement, si d'autres ; gadgets sont à traiter,
; c'est ici que ça se passe___
DoReqGad4:
bra DoRequestLoop
• **?????******¦*?*?*?*?***?********* r
; * Sous routines d'initialisation * . **********************************
Openlnt: move.l ExecBase,a6
lea IntName,a1
jsr 0penLibrary(a6)
move.l dO,IntBase
rts
Closelnt: move.l ExecBase,a6
move.l IntBase,a1
jmp CloseLibrary(a6)
OpenGfx: move.l ExecBase,a6
lea GfxName,a1
jsr 0penLibrary(a6)
move.l dO,GfxBase
rts
CloseGfx: move.l ExecBase,a6
move.l GfxBase,a1
jmp CloseLibrary(a6)
; En plus d'ouvrir l'écran,
; la routine OpenS s'occupe ; de charger en mémoire la fonte ; "emerald 17".
; Pourquoi OpenS ?
; Et pourquoi pas ?
OpenS: move.I lea jsr
ExecBase,a6
DiskFontName,a1
0penLibrary(a6)
dO.DiskFontBase
NoDiskFont
d0,a6
FontDefs.aO OpenD i s k F on t(a6) dO,TextFont
move.I beq.s
move.I lea jsr
move.I
NoDiskFont: move.I lea jsr
IntBase,a6 ScreenDefs.aO OpenScreen(aô) dO,Scr Handle
move.I rts
; CloseS se charge également ; de libérer la mémoire ; occupée par la fonte
; supplémentaire. CloseS:
move.1
IntBase,a6
move.1
ScrHandle,aO
jsr
CloseScreen(a6)
move.1
GfxBase,a6
move.1
TextFont,d0
beq
DontCloseFont
move.1
d0,a1
jsr
CloseFont(a6)
DontCloseFont: move.l ExecBase,a6
move.l DiskFontBase,a1
jmp CloseLibrary(a6)
OpenW:
move.l IntBase,a6
move.l aO,-(sp)
lea 4(a0),a0
move.l ScrHandle,30(a0)
jsr OpenWindow(a6)
move.l (sp)+,aO
move.l dO,(aO)
rts
CloseW: move.l IntBase,a6
jmp CloseWindow(a6)
. ********************
; * Zone des données *
. ********************
IntBase:
dc. l 0
GfxBase:
dc. l 0
DiskFontBase:
dc. l 0
ScrHandle:
dc. l 0
TextFont:
de. 1 0
IntName:
dc. b "intuition.1ibrary",0 even
GfxName:
dc. b "graphies.library",0 even
DiskFontName:
dc. b "diskfont.1ibrary",0 even
; *** Structure NewScreen ScreenDefs:
dc. w
0,0,640,256,2
dc. b
2,1
dc. w
MODE_640,CUSTOMSCREEN
de. 1 ScrT i tre:
0,ScrTi tre,0,0
dc. b
"Commodore Revue",0 even
; *** Structure NewWindow WindowDefs:
WinHandle:
de. 1
0
dc. w
0,0,640,256
dc. b
0,1
de. 1
MENUPICK
de.I BACKDROP|BORDERLESS|ACTIVATE
dc. l 0,0,0,0,0 ; Pas de titre !
Dc.w 50,50,320,256,CUSTOMSCREEN
; *** Structure NewWindow pour le Requester ReqWindowDefs:
ReqWinHandle:
dc. l 0
dc. w 0,11,320,120
dc. b 0,1
dc. l GADGETUP|GADGETDOWN
dc. l WINDOWDRAG|ACTIVATE|RMBTRAP
dc. l ReqGadgetDefs
dc. l 0,ReqWinTitre,0,0 ; Pas de titre !
Dc.w 0,0,0,0,CUSTOMSCREEN
ReqWinT i tre:
dc. b "Et un Requester, un !",0
even
; *** Structures Gadget, IntuiText, Border ; et Image pour le Requester ReqGadgetDefs:
ReqGadgetl:
dc. l ReqGadget2 ; NextGadget
dc. w 25,100,40,9 ; Pos & Taille
dc. w GADGHCOMP ; Flags
dc. w RELVERIFY ; Activation Flags
dc. w BOOLGADGET ; Gadget Type (boolean)
dc. l ReqBorderl ; Gadget Image
dc. l 0 ; Gadget Select
dc. l ReqGadliText ; Gadget Text
dc. l 0 ; Mutual Exclude
dc. l 0 ; Spécial Info
dc. w 60+1 ; Gadget ID
dc. l 0 ; User Data
ReqBorderl:
dc. w 0,0 ; Offset
dc. b 1,1 ; Dpen, Bpen
dc. b 1 ; Write Mode
dc. b 5 ; Nb Coords
dc. l ReqCoordsl ; Coords Border
dc. l 0 ; NextBorder
ReqGadliText:
dc. b 1,1 ; Couleurs
dc. b 0,0 ; Write Mode, even
dc. w 11,1 ; xPos, yPos
dc. l 0 ; Font
dc. l ReqGadlTxt ; Texte
dc. l 0
ReqCoordsl:
dc. w -1,-1,40,-1,40,9,-1.9,-1,0
ReqGadlTxt:
dc. b "OK“,0
even
ReqGadget2:
dc. l ReqGadget3
dc. w 95,100,200,9
dc. w GADGHCOMP,RELVERIFY,BOOLGADGET
de. I ReqBorder2,0,ReqGad2iText,0,0
dc. w 60+2 ; GadgetID
dc. l 0
ReqBorder2:
dc. w
0,0
dc. b
1,1,1,5
de. 1
ReqCoords2,0
ReqGad2iText:
dc. b
1,1,0,0
dc. w
46,1
de. 1
0,ReqGad2Txt,0
ReqCoords2:
dc. w
- 1,-1,200,-1.200,9,-1,9,-1,0
ReqGad2Txt:
dc. b
"Ca Flashe !!",0 even
ReqGadget3:
de. 1
ReqGadget4
dc. w
25,80,270,9
dc. w
GADGHCOMP.RELVERIFY.STRGADGET
de. 1
ReqBorder3,0,ReqGad3 i Text,0
de'. 1
ReqGad3lnfo
dc. w
60+3
de. 1
0
ReqBorder3:
dc. w
0. 0
dc. b
1,1,1,5
de. 1
ReqCoords3,0
ReqGad3iText:
dc. b
1. 1,0,0
dc. w
0,-10
de. 1
0,ReqGad3Txt,0
ReqCoords3:
dc. w
- 1,-1,270,-1,270,9,-1,9,-1,0
ReqGad3Txt:
de .b
"Un peu de place pour écrire :",0 even
ReqGad3lnfo:
dc. l TextBuffer ; Buffer
de. 1
UndoBuffer
dc. w
0 ; Curs pos
dc. w
33 ; Max. cars
dc. w
0 ; 1er car.
Dc.w
0,0,0,0,0
de. 1
0 ; Rastport
de. 1
0 ; Longlnt
de. 1
0 ; KeyMap
TextBuffer:
dcb. 1
9
UndoBuffer:
dcb. 1
9
ReqGadgetA:
de. 1
ReqGadget5
dc. w
25,40,270,20
dc. w
4,0,PROPGADGET
de. 1
Reqlmage4,0,0,0
de. 1
ReqGad4Info
dc. w
60+4
de. 1
0
Reqlmage4:
dc. w
0,0,0,0,1 ; Pos, Taille & Prof
de. 1
ReqImgData4 ; Data image
dc. b
0,0 ; Couleurs
de. 1
0 ; Next Image
ReqImgData4:
de. 1
0,0,0,0 ; Pas de données
ReqGad4Info:
dc. w
AUTOKNOB|FREEHORIZ
dc. w
0
ReqGad4Pos:
de .w
0
dc. w
$ ffff 16,0
dc. w
0,0,0,0,0,0
ReqGadget5:
de. 1
0
dc. w
25,16,270,20
dc. w
GADGHNONE,0,BOOLGADGET
de. 1
ReqBorder5,0,ReqGad5i T ext,0,0
dc. w
60+5
de. 1
0
ReqBorder5:
dc. w
0,0
dc. b
1,0,0,5
de. 1
ReqCoords5,0
ReqGad5iText:
dc. b
1,1,0,0
dc. w
7. 2
de. 1
FontDefs,ReqGad5Txt,0
ReqCoords5:
dc. w
- 1,-1,270,-1,270,20,-1,20,-1,-1
ReqGad5Txt:
dc. b
"VOICI DE L'EMERALD 17",0
even
; *** Structure TextAttr pour la fonte (emerald 17)
FontDefs:
de. 1
FontName
dc. w
17
dc. b
%0010,0 ; Style Gras
FontName:
dc. b
"emerald.font",0 even
; *** Structures IntuiText pour l'AutoRequester
BodyiText:
dc. b
2. 0.0,0
dc. w
10,5
de. 1
0,BodyTxt,BodyiText2
BodyTxt:
dc. b
"Texte du String-Gadget :",0 even
BodyiText2:
dc. b
3,0,0,0
dc. w
10,15
de. 1
0,TextBuffer,0
ButtoniText:
dc. b
3,0,0,0
dc. w
5,3
de. 1
0,ButtonTxt,0
ButtonTxt:
dc. b
"Merci",0 even
; *** Structure Menu
MenuDefs:
?
T I G I C
MIGHÎ
n I z I iu I s
Menul:
de. 1
0
dc. w
8,0,80,10,1
de. 1
MenulTïtre,Menul 1
dc. w
0,0,0,0
MenulTi tre:
dc. b
"Projet",0
even
; *** Structure Menultem
Menu1_1:
de. 1
Menul 2
dc. w
0,0,110,12
dc. w
ITEMTEXT|COMMSEQ1ITEMENABLED|HIGHCOMP
de. 1
0,Menu1_1iText,0
dc. b
"Q", 0
de. 1
0,0
Menu1_1iText :
dc. b
2,0,0,0
dc. w
3,2
de. 1
0,Menu1_lTxt,0
De plus en plus axé programmation (et ce en tous langages), l’Amiga News Tech possède dorénavant son propre courrier technique. Nous ne pourrons de fait et malheureusement n’y traiter que les questions concernant les problèmes de programmation que vous pourrez renconter sur Amiga. Soyez donc gentils d’éviter les questions concernant l’imprimante XYZ qui n’est pas compatible avec le logiciel ABCD ou qui ne possède pas de driver adéquat, nous ne pourrons de toute façon pas faire grand chose pour vous...
Question : Bonjour, pourriez-vous me donner le format d’un fichier IF F ILBM, afin que je puisse intégrer des routines de chargement sauvegarde dans le logiciel graphique que je suis en train d’écrire (en langage C)? D’avance merci.
Jean-Luc Verlay, Evry
Réponse : Mais certainement! Comme vous le savez sans doute, le format IFF a été développé par Electronic Arts à la demande de Commodore Amiga, afin de créer un standard pour la communication des données entre les différents logiciels. Ce format inclut en fait non seulement les dessins bitmap créés à l’aide de programmes comme DeluxePaint, mais aussi les textes, musiques, sons échantillonés, etc.
Les quatre premiers octets d’un fichier IFF contiennent toujours la valeur "FORM” (codée en ASCII, bien sûr). Une forme en IFF sert justement à différencier les blocs de données contenus dans le fichier (et nommés “chunks”). Plusieurs formes peuvent être mises à la suite dans un même fichier.
Menu1_1ïxt:
dc. b
"Qui tter",0
even
Menul_2:
de. 1
0
dc. w
0,12,110,12
dc. w
ITEMTEXT|ITEMENABLED|HIGHC0MP
de. 1
0,Menul 2iText,0
dc. b
o. o
de. 1
0,0
Menu1_2iText:
dc. b
2,0,0,0
dc. w
3,2
de. 1
0,Menu1_2Txt,0
Menu1_2Txt:
dc. b
"Requester___", 0
even
END
On trouve ensuite un mot long (4 octets encore) contenant la longueur de cette forme, exprimée en octets. Dans le cas d’un fichier IFF ne contenant qu’une seule forme, ce mot long sera égal à la taille du fichier moins quatre. Un fichier IFF minimum aura donc une taille de huit octets : 4 pour “FORM” et 4 autres pour la taille (0).
Suit alors un mot long (à nouveau 4 octets) indiquant le type du chunk.Tl s’agit d'un mot de quatre lettre ASCII, qui peut être :
- ILBM : graphique;
- WORD : texte;
- S MUS : musique;
- 8SVX : échantillon sonore 8 bits;
- ANIM : animation;
- etc.
Ce mot long est immédiatement suivi du nom du chunk à venir (4 octets) et de sa longueur (4 autres octets). Il existe à l’heure actuelle beaucoup de noms de chunks possibles, mais voici toujours ceux que l’on peut trouverdans un fichier ILBM (pas forcément dans l'ordre!) :
- BMHD (BitMap HeaDer) : caractéristiques du dessin ;
- CMAP (Color Map) : table des couleurs;
- BODY (Corps) : données des bitplanes du dessin;
- CAMG (Commodore AmiGa) : mode de représentation.
On peut également trouver les chunks NAME et AUTH qui contiennent respectivement les noms de l’œuvre et de son auteur.
Voici maintenant la description du contenu de chacun de ces chunks; n’oubliez pas que le nom d'un chunk est toujours suivi de sa longueur, exprimée sur un mot long, et non prise en compte dans les offsets donnés :
Chunk BMHD
OffsetTaille Signification
+ 0 1 mot Largeur du dessin
+ 2 1 mot Hauteur du dessin
+ 4 1 mot Position X du dessin dans la page
+ 6 1 mot Position Y du dessin dans la page
+ 8 1 octet Nombre de plans de bits + 9 1 octet Masquage
0 = pas de masquage
1 = masquage
2 = transparent
3 = lasso + 10 1 octet Compression
0 = pas de compression
1 = compression “ByteRunl" + 11 1 octet Inutilisé
+ 12 1 mot Numéro de registre de couleur du fond + 14 1 octet Aspect X
+ 15 1 octet Aspect Y
+ 16 1 mot Largeur de la page source
+ 18 1 mot Hauteur de la page source
Chunk CMAP (pour chaque couleur)
Offset
Taille
Signification
+ 0
1 octet
Valeur du rouge
+ 1
1 octet
Valeur du vert
+ 2
1 octet
Valeur du bleu
Chunk CAMG
OffsetTaille Signification
Faites attention à ce qu’un chunk doit toujours être d’une longueur paire dans le fichier. Par exemple, dans un chunk CMAP avec une seule couleur, la longueur utile du chunk, celle exprimée tout de suite après son nom, serait 3, mais sa longueur véritable dans le fichier serait 4.
L’algorythme de compression utilisé porte le nom de “ByteRunl”. Il est basé sur le principe du comptage des octets identiques. Pour le décoder, il faut lire un octet, et comparer sa valeur à 128 :
- s’il est inférieur à 128, il faudra lire autant d’octets dans le BODY et les afficher tels quels à l’écran;
- s’il est supérieur à 128, l’octet suivant dans le BODY sera répété (257 -octet) fois à l’écran;
- enfin, une valeur égale à 128 indique... qu’il ne faut rien faire du tout !
On passe ensuite à l’octet suivant, et ainsi de suite jusqu’à la fin du fichier.
Voilà qui, nous espérons, aura répondu, peut-être même au delà de vos espérances, à votre question. Remercions au passage Max, l’auteur de l’initiation à l’assembleur 68000, pour ces précieux renseignements.
Question : Je voudrais savoir s’il est possible d’intégrer des musiques créées avec SoundTracker dans ces programmes en GfaBasic?
Denis Jarril, Draveil
Réponse : Oui, cela est parfaitement possible, moyennant tout de même un petit peu de travail... et
• beaucoup de mémoire (pas vous, l’ordinateur). Avant toute chose, il faut disposer du listing assembleur de la PlayRoutine, Listing “diffusé” avec SoundTracker. Assurez-vous alors qu’elle est entièrement écrite en code relogeable (si mes souvenirs sont bons, elle l’est). Assemblez-la avec le k- Seka et incluez votre module musical avec la commande RI. Finalement, sauvegardez le tout avec la commande Wl. Vous obtenez sur la disquette un fichier contenant votre musique et la routine assembleur pour la jouer, fichier qu’il ne reste plus qu’à inclure dans votre programme en Gfa grâce à l’instruction INLINE. Par la suite, une simple instruction C: ou CALL suffira à lancer la musique.
+ 0 1 long Mode de représentation selon
OpenScreen( )
Chunk BODY
Offset Taille Signification
+ 0 Taille Données des bitplanes, compressées ou non selon le BMHD. Les bitplanes sont disposés les uns à la suite des autres.
Question : Qu'est-ce donc que ce fameux Arexx dont on entend parler un peu partout depuis quelques temps ? Peut-on en savoir un peu plus sur le sujet?
Philippe de Menibus, le Vésinet
Réponse : Ouille, ouille, ouille... Ça risque d’être très difficile de décrire Arexx en quelques phrases... C’est pourquoi je préfère vous laisser sur votre faim en vous promettant pour bientôt un article complet sur le sujet. En attendant, sachez qu’un conçurent à nous (que je ne nommerai pas, mais bon, il n’y en pas 36) a consacré une page entière de son dernier numéro à ce très intéressant langage.
Question : Voilà, je débute en programmation sur Amiga, en assembleur pour être plus précis, et il y a quelque chose que je ne comprends pas. Ne riez pas, c’est certainement tout bête : pourquoi certains programmeurs "incluent”-ils des fichiers “.i" dans leurs programmes, et d’autres non? Qu’apportent-ils concrètement, ces fichiers? Et comment puis-je, avec mon vieux K-Seka des familles, les utiliser?
Olivier Vaneuken, Ruy
Réponse : c’est en effet tout bête ! Les fichiers dits “include” évitent au programmeur des tonnes de définitions d’ESUates préliminaires; ils contiennent entre autres choses toutes les constantes importantes pour la programmation du système de l'Amiga, ainsi que les offsets de saut des fonctions des bibliothèques. Certains préfèrent les inclure dans leur code source, d’autres préfèrent définir eux-mêmes les constantes dont ils auront besoin. C'est une question de goût, uniquement. Quant à k- Seka, étant donné qu’il ne reconnaît pas la directive “include", seule la seconde solution est valable.
Voilà qui clôt notre courrier de ce mois-ci. Nous tenons tout de même, avant de nous séparer, à rassurer ceux qui ont écrit à Little Zeus concernant sa Tube-lntro : il nous a promis le listing entier (mais sans commentaires) pour le mois prochain.
Ok et Cancel
VIEWPORT
CADEAU-SURPRISE (BIS)
Après moultes aventures ensolleillées, le cadeau-surprise promis le mois dernier arrive quand même. Rappelons qu’il s’agit du listing d’un programme mettant en oeuvre la routine de défilement d’étoiles utilisée dans le jeu ‘‘Eagle’s Rider” de Microids. Avec toutes nos excuses à Microids et
à nos lecteurs._
.*****************.
• * *.
;* EAGLE'S RIDER *;
¦ * *.
;* MICROIDS 89 *;
.* *.
.*****************.
; Version mettant uniquement ; en oeuvre te déplacement ; des étoiles.
ScreenSize,dO ; Demande de la CHIP,d1 ; mémoire pour
AllocMem(a6) ; l'écran physique dO,Ecr_Phys F in3
ScreenSize,dO ; Idem, mais
; pour COMMODORE REVUE
ExecBase
EQU
4
Forbid
EQU
- 132
Permi t
EQU
- 138
AllocMem
EQU
- 198
FreeMem
EQU
- 210
OpenLibrary
EQU
- 408
CloseLibrary
EQU
- 414
Custom
EQU
îdffOOO
BPL1PTH
EQU
$ 0e0
DIWSTRT
EQU
$ 08e
DIWSTOP
EQU
$ 090
DDFSTRT
EQU
$ 092
DDFSTOP
EQU
$ 094
DMACON
EQU
$ 096
C0P1LCH
EQU
$ 080
COPJMP1
EQU
$ 088
COLOROO
EQU
$ 180
JOY1DAT
EQU
$ 00c
BPLCONO
EQU
$ 100
VHPOSR
EQU
$ 006
CIAAPRA
EQU
$ bfe001
CIAAPRB
EQU
$ bfec01
PlaneX
EQU
320
PlaneY
EQU
200
PlaneS i ze
EQU
PlaneX 8*PlaneY
NbPlanes
EQU
5
ScreenSi ze
EQU
PlaneS i ze*NbPlanes
CHIP
EQU
2
CLR_CHIP
EQU
CHIP+$ 10000
Clsi ze
EQU
13*4
StartList
EQU
38
movem.1
d0-d7 a0-a6,-(sp)
Main:
move.1
ExecBase,a6
; a6 = AbsExecBase
lea
Custom,a5
; a5 = Custom Chips
jsr
Inï t_Ecr: move.I move.I jsr
move.I beq
Forbid(aô) ; Interdit le multitâche
move.I
move.1
CLR_CHlP,d1 ; pour l'écran
jsr
AllocMem(a6) ; logique
move.1
dO,Ecr_Log
beq
Fin2
move.1
CLsize,dO ; Et puis encore
move.1
CLR_CHIP,d1 ; un petit peu, mais
jsr
AllocMem(a6) ; cette fois pour
move.1
dO,CLadr ; la Copper-list
beq
Fini
move.w
$ 0080,DMACON(a5) ; Stoppe le Copper
move.1
Cladr,C0PHCH(a5) ; Initial ise
clr.w
COPJMP1(a5) ; de Copper-List
move.w
$ 4081,DIWSTRT(a5) ; PlayField
move.w
$ ECC1,DIWSTOP(a5) ; en 320x200
move.w
$ 0038,DDFSTRT(a5)
move.w
$ OODO,DDFSTOP(a5)
move.w
%0100001000000000,BPLCON0(a5)
move.w
$ 8080,DMACON(a5) ; Copper On
lea
Palette,aO ; Change les couleurs
lea
COLOROO(a5),a1 ; de la palette
moveq
31,d0 ; 32 couleurs
SetPalette:
move.w
(a0)+,(a1)+
dbra
dO,SetPalette
* ***********************.
?
*.
* Boucle principale *;
?
*.
* ***********************.
Départ:
La routine ci-dessous efface l'écran logique.
Elle doit être rapide, d'où cette profusion de
"movem.1" et
le petit nombre d'itération
de la boucle
Cls:
movem.1
d1-d7 a1-a6,-(sp)
lea
VideEcr,a0
movem.1
(a0),d1-d7 a1-a6
moveq
( ScreenSize 1000)-1, dO
move. 1
Ecr_Log,a0
add. 1
ScreenSi ze,a0
ClsLoop:
movem.1
d1-d7 a1-a6,-(aO) ; 52 octets
movem.1
d1-d7 a1-a6,-(a0) ; 104 octets
movem.1
d1-d7 a1-a6,-(aO) ; 156 octets
movem.1
d1-d7 a1-a6,-(aO) ; 208 octets
movem.1
d1-d7 a1-a6,-(a0) ; 260 octets
movem.1
d1-d7 a1-a6,-(aO) ; 312 octets
movem.1
d1-d7 a1-a6,-(a0) ; 364 octets
movem.1
d1-d7 a1-a6,-(aO) ; 416 octets
movem.1
d1-d7 a1-a6,-(a0) ; 468 octets
movem.1
d1-d7 a1-a6,-(a0) ; 520 octets
movem.1
d1-d7 a1-a6,-(a0)
572 octets
movem.1
d1-d7 a1-a6,-(aO)
624 octets
movem.1
d1-d7 a1-a6,-(aO)
676 octets
movem.1
d1-d7 a1-a6,-(aO)
728 octets
movem.1
d1-d7 a1-a6,-(aO)
780 octets
movem.1
d1-d7 a1-a6,-(aO)
832 octets
movem.1
d1-d7 a1-a6,-(a0)
884 octets
movem.1
d1-d7 a1-a6,-(aO)
936 octets
movem.1
d1-d7 a1-a6,-(aO)
988 octets
movem.1
d1-d6,-(a0) ; 1000
octets
dbra
dO,ClsLoop ; * 40
40000 octets
movem.1
(sp)+,d1-d7 a1-a6
bsr
macetoile ; Gestion des étoiles
bsr
Joystick ; Gestion
de l'Eagle
move.w
$ 0080,DMACON(a5)
Copper Off
move.1
Ecr_Phys,dO ; Echange les addresses
move.1
Ecr_Log,Ecr_Phys ;
des écrans
move.1
d0,Ecr_Log
move.1
Cladr,a0 ; Recalcule la nouvelle
move.w
BPHPTH,d1 ; Copper List
moveq
NbPlanes-1,d2
Flip_Ecr:
move.w
d1,(a0)+
addq.w
2,d1
swap
dO
move.w
dO,(a0)+
move.w
d1,(a0)+
addq.w
2,d1
swap
dO
move.w
dO,(a0)+
add. 1
PlaneSi ze,d0
dbra
d2,Flip Ecr
move.1
$ fffffffe,(aO)
move.w
$ 8080,DMACON(a5)
Copper On
Vsync: ; Attend le Vsync
cmp.b
2,VHPOSR(a5)
bne.s
Vsync
btst
7,CIAAPRA ; test
e bouton de feu
bne
Départ ; boucle principale
.***************************************** -
;* FIN DU
PROGRAMME
* ¦ 9
;* RESTORE
LA MEMOIRE ET RETOURNE
AU CLI *;
• *****************************************• t •
move.w
$ 0080,DMACON(a5)
Copper Off
tea
GfxName,a1
clr. 1
dO
jsr
OpenLibrary(a6)
move.1
d0,a0
move.1
StartList(aO),COPlLCH(a5) ; Ancienne
clr.w
COPJMP1(a5) ; Copper-List en place
move.h
$ 8080,DMACON(a5) ; Copper on
move.1
aO, a1
jsr
CloseL ibrary(aé)
Fin:
move.1
Cladr,a1 ; Libère la CHIP-Ram
move. 1
CLsize,dO ; de la Copper-List
jsr
FreeMem(a6)
Fini:
move.1
Ecr_Log,a1 ; Ainsi que celle occupée
move.1
ScreenSize,dO ; par l'écran logique
jsr
FreeMem(a6)
Fin2:
move.1
Ecr_Phys,a1 ; et l'écran physique
move.1
ScreenSi ze,d0
jsr
FreeMem(a6)
Fin3:
jsr
Permit(a6) ; autorise le multitâche
movem.t
(sp)+,dO-d7 aO-a6
rts ; Fin du programme
* **************************.
;* Module d'acquisition du Joystick *;
Joystick:
clr.w
Joy_x
clr.w
J°y_y
move.w
JOYlDAT(a5),dO ; Lecture du joyl
btst
1,d0 ; A droite ?
Beq
Joystickl ; Non
move.w
-1,Joy_x ; oui->étoiles à gauche!
Joystickl
btst
9,d0 ; A gauche ?
Beq
Joystick2
move.w
1,Joy_x ; Oui->étoiles à droite!
Joystick2:
move.w
d0,d1
Isr.w
1 ,d1
eor.w
d0,d1
btst
0,d1 ; En bas ?
Beq
Joystick4
move.w
1,Joy_y ; Oui
Joystick4:
btst
8,d1 ; En haut ?
Beq
Joystick5
move.w
-1,Joy_y ; Oui
Joystick5:
clr.l
d5
trai_clavier:
move.w
Joy_y,d5
add.w
d5,Hautbas
cmpi.w
10,Hautbas
bmi
trai_clavier1
move.w
9,Hautbas
trai_clavier1:
cmpi.w
-10,Hautbas
bgt
trai_clavier2
move.w
-9,Hautbas
trai_clavier2:
move.w
Joy_x,d5
add.w
d5,Droigau
cmpi.w
10,Droigau
bmi
trai_clavier3
move.w
9,Droi gau
trai_clavier3:
cmpi.w
-10,Droigau
bgt
trai_clavier4
move.w
-9,Droigau
trai_clavier4:
rts
* Module de gestion de déplacement des étoiles *
* *??***?*******???*??**??**?*•*******?*??*****¦**?*
macetoile:
; Affichage du 1er plan d'etoile
lea
Etoile,a4 ; Table des coordonnées
move.w
1,Cou ; Couleur des étoiles
bsr
affplan ; Affiche les étoiles
; Affichage du 3eme plan d'etoile
lea
Etoile3,a4 ; Table des coordonnées
move.w
4,Cou ; Couleur des étoiles
bsr
affplan ; Affiche les étoiles
; Calcul des nouvelles coordonnées
; pour le plan 1
lea
Etoile,a4 ; Table des coordonnées
move.w
0f1f,Var1 ; vitesse de déplacement
move.1
Ecrbuf1,Var2
bsr
coor ; calcule les coordonnées
move.1
Var2,Ecrbuf1
move.w
Var1,0f1f
; pour le plan
3
lea
Etoile3,a4 ; Table des coordonnées
move.w
0f3f,Var1 ; vitesse de déplacement
move.1
Ecrbuf3,Var2
bsr
coor ; calcule les coordonnées
move.1
Var2,Ecrbuf3
move.w
Var1,0f3f
rts ; Fin du
module de gestion des étoiles
TRANSACTOR L’ART DU LANGAGE-MACHINE
La suite de ce passionnant article de Johr Toebes, paru chez notre confrère Canadier “Transactor for the Amiga”, dans laquelle l’auteur passe en revue de nouvelles techniques d’optimisation des programmes écrits er langage-machine.
L’OPTIMISATION LOCALE
Contrairement à tout ce que nous avons vl jusqu’ici, l’optimisation locale requiert un peu plus de réflexion quant aux moyens à utiliser. L'exemple le plus simple qui vienne à l’esprit est la multiplication.
Ainsi, pour adresser un élément particulier d’un tableau, il est nécessaire de multiplier son indice par la taille maximale des éléments. En assembleur, un bon programmeur se débrouille toujours pour jongler avec les puissances de deux. Au lieu de :
; décalage de 16 bits à gauche : swap dO
moveq 0,d0
; décalage de 24 bits à gauche : swap dO
moveq 0,d0
IsI.L 8.d0
; décalage de 25 bits à gauche : swap dO
moveq 0,d0
IsI.L 8,d0
add.L dO,dO
; décalage d’1 bit à droite (pas optimisé) :
Isr.L 1 ,d0
; décalage de 16 bits à droite : moveq 0,d0
swap dO
; décalage de 25 bits à droite : moveq 0,d0
swap dO
Isr.L *8,d0
Isr.L 1 ,d0
move.L
Indice,
dO
muls.w
8.d0
il écrira :
move.L
Indice,
dO
IsI.L
3.dO
En ce qui concerne les décalages de bits, plusieurs règles sont à observer, qui sont résumées dans le tableau ci-dessous :
; décalage d’un bit à gauche : add.L dO,dO
; décalage de 2 bits à gauche : IsI.L 2,d0
; décalage de 4 bits à gauche : Idl.L 4,d0
; décalage de 8 bits à gauche : IsI.L 8,d0
; décalage de 9 bits à gauche : IsI.L 8,d0
add.L dO,dO
; décalage de 10 bits à gauche : IsI.L 8,d0
IsI.L 2,d0
Toutes ces séquences sont plus rapides que :
moveq Nb bits, d1
IsI.L d1,d0
De plus, elles évitent l’utilisation d’un second registre. Elles sont particulièrement efficaces pour des décalages entre 9 et 15 bits. Pour des décalages de 16 bits et plus, rappelez-vous de toujours effectuer le SWAP au bon moment, suivant le sens du décalage.
Il est important de noter que tous ces décalages “maison” ne s’occupent absolument pas d’un éventuel bit de signe, mais il est vrai qu’en assembleur, on ne s’en soucie que rarement. Si vous avez vraiment besoin du bit se signe, utilisez l’instruction EXT.L en lieu et place de MOVEQ =0.
Une optimisation particulière concerne l’écriture d’un logiciel assembleur... en assembleur : lorsque l’on génère le code machine d’un registre quelconque, il faut d’abord masquer son numéro avec la constante 7, puis décaler ce résultat de 9 bits vers la gauche. Un bon programmeur aurait écrit quelque chose du style (en considérant que le numéro du registre se trouve dans d’O) :
moveq
7.dl
2 octets
4 cycles
and.L
d1,dO
2 octets
8 cycles
IsI.L
8,dO
2 octets
24 cycles
add.L
dO,dO
2 octets
8 cycles
Total :
8 octets
44 cycles
Mais un
programmeur
(un peu plus) astucieux
aurait certainement écrit
Isl.b
5,dO
2 octets
1 6 cycles
IsI.L
4 4,d0
2 octets
1 6 cycles
Total :
4 octets
32 cycles
(NDLR : les explications manquant dans le texte original, en voici quelques-unes, succinctes certes, mais qui présentent au moins l'avantage d'être là... La première instruction décale tout d’abord l'octet de poids faible du registre dO de 5 bits vers la gauche, ce qui “élimine" au passage les bits supérieurs et donc réalise le AND =7 escompté. La seconde instruction effectue enfin un décalage de 4 bits vers la gauche, complétant ainsi le décalage de 9 bits souhaité).
Ne jamais oublier que certaines instructions affectent les bits du CCR.
Un bon programme en assembleur ne comporte pour ainsi dire aucune instruction TST. Le 68000 est en effet suffisamment bien conçu pour positionner les bits du CCR en fonction des opérations effectuées, tout seul comme un grand. Le seul cas ou le CCR n'est pas affecté est lors de l'initialisation d’un registre d’adresse.
Mais chaque médaille à son revers: si vous modifiez après coup un programme pourtant considéré comme terminé, rien ne dit que vous n'allez pas modifier du même coup le CCR. C'est pourquoi il est parfois plus sûr d'utiliser l'instruction MOVEM. Plus gourmande en mémoire et en temps d'exécution que MOVE, pour sauvegarder des registres, etc.
Je ne vous apprendrais rien en vous disant que tester les bits du CCR permet de réagir à certaines conditions, pour programmer des branchements divers. L’assembleur offre le luxe de pouvoir tester trois conditions en une seule fois :
add.L Vall,dO
bcs.s Débordement ; C,
bit.s Négatif ; S,
beq.s Zéro ; et Z sont positionnés!
C’est une situation que l'on ne retrouve dans aucun langage évolué (exception faite du Fortran). Lorsqu’on écrit de tels branchements, il est important d’avoir bien en tête celui qui aura le plus de chance de se produire. En d'autres termes, il faut être sûr que la condition que l'on va tester est celle QUI A LE MOINS DE CHANCES d'être vérifiée. Ainsi, vous éviterez à chaque fois la perte de temps occasionnée par le saut lui-même :
moveq 1 ,dO and.L dO,d1
bne.s Errorl ; Erreur peu fréquente!
; suite du programme...
Abusez de l’instruction Dbcc
La meilleure instruction du 68000 est encore Dbcc (décrémentation d'un registre de données et branchement conditionnel). Même sur un 68010, toutes les instructions comprises entre Dbcc et l’adresse du branchement sont copiées dans une mémoire- cache interne, ce qui accélère leur traitement.
Il faut toutefois porter une attention toute particulière a l'instruction DBRA :
- le compteur de boucle est sur 16 bits, les 16 autres restant inchangés:
- il serait idéal de n'inclure qu'une seule instruction dans la boucle:
- la boucle est effectuée une fois de plus que spécifiée dans le compteur.
L utilisation de DBRA la plus courante, est sans nul doute la copie de portions de mémoire :
moveq 15,dO ; copier 16 octets
lea source.w,aO
lea dest.w,al
Lab: move.L (aO) + ,(aI) + dbra dO,Lab
Mais les instructions Dbcc sont trop puissantes pour les limiter aux copies de mémoire. Elles sont particulièrement adaptées aux comparaisons, à l'exploration et au remplissage de zones de mémoire :
move.w Long,dO
move.L ;chaine,aO
moveq ascii,dl ; caractère cher
ché
bra.s dbr
Lab: cmp.b(aO) + ,d1 Lbr: dbne.sdO,Lab
L’OPTIMISATION GLOBALE
Nous avons déjà fait un grand pas en avant, en économisant encore quelques octets et quelques cycles par ci par là. Il nous reste encore à optimiser le programme dans son ensemble.
Choisissez vos registres avec beaucoup d’attention
Un bon programme essaie de charger un ou plusieurs registres avec une valeur ou une adresse souvent utilisée, et n’y touche plus par la suite. Cette valeur est ainsi accessible en permanence.
Le meilleur exemple sur l'Amiga est AbsExecBase, qui devrait être en permanence accessible dans le registre a6 quitte à le sauvegarder ou à le réinitialiser lors d’appels à d’autres bibliothèques qu’Exec.
Evitez MOVEM autant que possible.
Il est souvent utile, lors d’appels à un sous- programme, de sauvegarder les registres corrompus pour les récupérer en revenant. Essayez plutôt de faire en sorte que vos routines n’utilisent pas les mêmes registres que le programme principal.
Evitez LINK et UNLK autant que possible.
LINK est souvent utilisée dans les langages compilés, tel le C. On ne la croise par contre que rarement dans un programme en langage machine (NDLR : elle sert à créer un espace mémoire utilisable pour sauver des données trop grandes pour un registre. En pratique, on l’utilise surtout lors de la programmation de routines récursives). Quoiqu’il en soit, il est de loin préférable de créer une sous-routine supplémentaire chargée de sauver les valeurs, voire carrément de les empiler.
Choisissez vos “flags” avec attention.
Si un octet de mémoire vous sert de drapeau à trois états, il est plus efficient de lui affecter comme valeurs possibles 1, 0 et 1, ce qui permet des branchements plus rapides (avec Bcc, sans TST ni CMP avant).
Utiliser les tableaux comme il faut!
Beaucoup d’opérations peuvent être réalisées à l’aide de tableaux. Par exemple, pour une rotation de bloc dans un programme de dessin, il est préférable de calculer auparavant les 360 valeurs du sinus et de le stocker dans un tableau, plutôt que de les calculer par programmation.
En moyenne, seulement 5 % d’un programme monopolisant quelques 95 % de son temps d’exécution. Il y a beaucoup à gagner en s’occupant d’optimiser les 95 % restants...
DERNIER TRUC
Apprenez à utiliser le bit X
Le bit X du OCR est une des choses les plus étranges du 68000. Il n’est influencé que par peu d’instructions, et n’est de fait presque jamais utilisé. Il possède pourtant la très intéressante particularité d'initialiser un registre à 0 ou à 1, d’après sa valeur initiale :
subx.1 dO,dO
Voilà. Nous allons terminer avec un petit test, histoire de voir si vous feriez un bon “optimiseur” : une valeur quelconque est dans dO, et l’on ne connaît pas l’état du Ccr; initialisez dl à 0 si dO est nul, et à 1 dans le cas contraire. Vous pouvez au besoin perdre le contenu de dO. La solution est dans une dernière page de l’Amiga NewTech de ce mois-ci.
John Toebes
Notes sur l'auteur :
John Toebes est analyste système au SAS Insti- tute Inc. de Cary, en Caroline du Nord. Il programme sur Amlga depuis 1985 et est notamment l'auteur de plusieurs versions du compilateur Lattice C. Il s'occupe également du groupe “The Software Dis- tillery", à qui l'on doit plusieurs programmes du domaine public comme Hack, PopCLI, NemWatch ou encore Blink.
1989 John A. Toebes et Transactor for the Amiga 1989 Commodore Revue. Traduction et adaptation française assurées par Stéphane Schreiber.
L’ARTILLERIE LOURDE
Tout ceci ne représente en aucun cas une liste exhaustive et immuable de ce qu’il faut faire pour améliorer ses programmes en assembleur 68000. Avec un peu de pratique, tout ce qui a été dit ici deviendra partie intégrante de vous-même, comme un réflexe de programmation.
Solution au problème de John Toebes : neg.L dO subx.L d1,d1 neg.L d1
es du 68000. Il n’est influencé que par peu d’instructions, et n’est de fait presque jamais utilisé. Il possède pourtant la très intéressante particularité d'initialiser un registre à 0 ou à 1, d’après sa valeur initiale : subx.1 dO,dO
Voilà. Nous allons terminer avec un petit test, histoire de voir si vous feriez un bon “optimiseur” : une valeur quelconque est dans dO, et l’on ne connaît pas l’état du Ccr; initialisez dl à 0 si dO est nul, et à 1 dans le cas contraire. Vous pouvez au besoin perdre le contenu de dO. La solution est dans une dernière page de l’Amiga NewTech de ce mois-ci.
John Toebes
Notes sur l'auteur :
John Toebes est analyste système au SAS Insti- tute Inc. de Cary, en Caroline du Nord. Il programme sur Amlga depuis 1985 et est notamment l'auteur de plusieurs versions du compilateur Lattice C. Il s'occupe également du groupe “The Software Dis- tillery", à qui l'on doit plusieurs programmes du domaine public comme Hack, PopCLI, NemWatch ou encore Blink.
1989 John A. Toebes et Transactor for the Amiga 1989 Commodore Revue. Traduction et adaptation française assurées par Stéphane Schreiber.
L’ARTILLERIE LOURDE
Tout ceci ne représente en aucun cas une liste exhaustive et immuable de ce qu’il faut faire pour améliorer ses programmes en assembleur 68000. Avec un peu de pratique, tout ce qui a été dit ici deviendra partie intégrante de vous-même, comme un réflexe de programmation.
Solution au problème de John Toebes : neg.L dO subx.L d1,d1 neg.L d1

Click image to download PDF

AMIGA NEWS TECH numero 05 (10-1989)

Merci pour votre aide à l'agrandissement d'Amigaland.com !


Thanks for you help to extend Amigaland.com !
frdanlenfideelhuitjanoplptroruessvtr

Connexion

Pub+

66.2% 
8.9% 
2.3% 
2.2% 
1.7% 
1.7% 
1.3% 
1% 
0.7% 
0.6% 

Today: 4
Yesterday: 98
This Week: 649
Last Week: 1108
This Month: 3391
Last Month: 3918
Total: 89523

Information cookies

Cookies are short reports that are sent and stored on the hard drive of the user's computer through your browser when it connects to a web. Cookies can be used to collect and store user data while connected to provide you the requested services and sometimes tend not to keep. Cookies can be themselves or others.

There are several types of cookies:

  • Technical cookies that facilitate user navigation and use of the various options or services offered by the web as identify the session, allow access to certain areas, facilitate orders, purchases, filling out forms, registration, security, facilitating functionalities (videos, social networks, etc..).
  • Customization cookies that allow users to access services according to their preferences (language, browser, configuration, etc..).
  • Analytical cookies which allow anonymous analysis of the behavior of web users and allow to measure user activity and develop navigation profiles in order to improve the websites.

So when you access our website, in compliance with Article 22 of Law 34/2002 of the Information Society Services, in the analytical cookies treatment, we have requested your consent to their use. All of this is to improve our services. We use Google Analytics to collect anonymous statistical information such as the number of visitors to our site. Cookies added by Google Analytics are governed by the privacy policies of Google Analytics. If you want you can disable cookies from Google Analytics.

However, please note that you can enable or disable cookies by following the instructions of your browser.

Visitors

Visite depuis
03-10-2004
Visite depuis
23-02-2014