Sponsors

FacebookTwitterGoogle Bookmarks

FAISONS RESET AVEC LE SOURIRE D’une manière générale, je n'aime guère les programmeurs de méga- démos, d'abord parce que je suis méchant et n’aime personne, ensuite parce que j’ai tellement vu de “sinus-scroll” et autres que je ne suis pas loin de l’indigestion, enfin parce que lesdits programmeurs programment la plupart du temps en utilisant des routines élaborées par d’autres (le piratage va bon train I), et qui plus est comme des cochons, sans le moindre respect pour le formidable système d’exploitation de cet Amiga que j’aime tant. (Il faut bien que j’aime quelque chose quand même !) Vous ne me croyez pas ? Alors laissez-moi vous raconter : Il était une (mauvaise) fois où je me suis laissé aller à booter une démo (tout le monde craque un jour ou l'autre). Que vois-je ? Une démo belle et même superbe, avec une musique bien tapageuse comme il se doit. Bien me dis-je et je clique la souris pour quitter. Et alors là, qu'arriva-t- il ? Un fait ahurissant, désolant, exaspérant, horripilant, terrifiant, décevant, énervant, agaçant, désopilant, crispant, irritant, excrément : la Led-power de mon Amiga à moi se met à clignoter, une espôvantable couleur jaune apparaît sur le moniteur, puis l’ordinateur finit tant bien que mal par faire un reset gouroutisant au lieu de me rendre la main. Comme je suis un très vilain curieux, j’examine de plus près ce trepelu programme et m'aperçoit que l'auteur a semé un tel b dans la machine qu’il ne sait plus comment rendre la main. Bon admettons, mais là où je me roule par terre de rire c'est qu’il m’apparaît que notre auteur n’est même pas capable de programmer un tout bête reset convenablement. Qu’a-t-il fait : un saut en ROM à l’adresse $ FC00D2 comme ça, sans la moindre délicatesse. C’est ce très misérable saut en ROM qui provoque le phénomène décrit plus haut (beurkl). Mais là où ça devient grave, c’est que j’ai vu il y a peu de temps dans certains ouvrages ou revues des routines reset aussi mal programmées : Aaarrrgh ! UN RESET PROPRE Cela suffit. Je vous donne donc le moyen de rebooter l’Amiga à chaud convenablement. Quelques explications sur ce programme : On appelle la routine Supervisor d'exec.library (ne pas confondre avec Superstate). Cette routine met l’Amiga en mode Superviseur (afin de permettre l’emploi des instructions privilégiées du 68000) et saute immédiatement dans un convertisseur de trap pointé par A5 (vous pouvez faire quelques révisions sur ce sujet dans l'article Gurujnterceptor). Dans ce convertisseur de trap, on charge $ 2 dans A0 puis on utilise l’instruction 68000 RESET. De par la connection des pins (prononcer pine) du 68000, cette instruction provoque te recouvrement de la chip- ram via le CIA-A par la ROM, il suffit alors de sauter à l’adresse pointée par A0, qui de ce fait vaut $ FC0002, pour suivre un processus reset normal. Au cours du processus reset le bit 0 (prononcer bite) du CIA-A est inversé pour annuler le recouvrement mémoire. Pour le processus reset, vous pouvez vous reporter à l'article Boot-Allocator dans CR 26. Par ce simple procédé, l’horrible couleur jaune n’apparaît plus, mais ce qui est beaucoup plus important, c’est que grâce à l’emploi de l’instruction RESET, tous les périphériques et autres cartes connectés à l’Amiga seront CORRECTEMENT réinitialisés.

Click image to download PDF

AMIGA NEWS TECH numero 17 (11-1990)

Document sans nom - s S** ol -
* »«>&»
APPLICATION
Faites vos jeux avec Amos
par S. Schreiber, p. 43
INITIATION
e, p. 54
AMAL le langage de
GFABasic
l'animation
Un squelette de
par F. Lionet, p. 52
MACRO-RECORDER
par S. Schreider, p. 56
REQUESTER
par F. Mazué, p. 58
LANGAGE C
C UN CONCOURS
par P. Amiable, p. 54
Inacan bbbb
IMIGHI
1 r
APPLICATION
GURU INTERCEPTOR
Supportastes vous oncques gourou ? Caisgne ! Réduisez à mémoire la contenance qu'aviez. Tapait-il sur vos nerfs, ce gourou plein de mystères ? Cela suffit, jetons-lui un sort, carissant de mon chapeau magique, voici programme pantagruélique : le très renommé GURU INTERCEPTOR.
CIBLONS LE PROBLEME
Vous l’avez compris, il est question aujourd'hui de ne plus se laisser embêter par des méditations du gourou tout à fait intempestives. Mais entendons nous bien car tout comme il y a programmeur et programmeur, il y a gourou et gourou. Je m’explique par un exemple : un amateur veut modifier une librarie et pour cela change arbitrairement une adresse de saut sans prévenir le système. Eh bien si le système d’exploitation, pour une raison qui lui appartient, vérifie le checksum de la libraire ainsi estropiée, il se fera une joie de renvoyer à notre amateur une méditation du gourou de n° 81000003 bien méritée. Il n’est pas question d’intercepter de telles “lamers failures”, un programmeur digne de ce nom n’encourant pas ce type de risques car il sait qu’un système d’exploitation d’ordinateur ça se respecte et pour notre exemple, aurait employé la routine SetFunction. Ceci étant précisé, il faut bien reconnaître qu’il est permis à tout le monde de se tromper en écrivant un programme. Que celui qui n’a jamais transféré un mot long à une adresse impaire me jette le premier octet !
Je vous propose donc aujourd’hui le moyen d’éviter les guru-médita- tions de n° 3 à n° B, erreurs qui peuvent toujours survenir, ne serait-ce qu’à cause d’une simple faute de frappe. Ceci nous évitera d'avoir à rebooter (le derrière) le système et nous permettra grâce à un débogueur d’aller immédiatement désassembler l’endroit litigieux sans perdre de temps. Tout ceci sera bien utile pour la mise au point de programmes intraçables du genre démos ou autres...
PETIT PREAMBULE
Avant de commencer, il faut que je vous précise que tout ce qui va être dit dans cet article concerne les Amiga équipés de microprocesseur 68000. Ceux qui auraient gonflé leur ordinateur à grand renfort de 68020 ou 68030 devront se reporter aux livres adaptés pour faire les corrections nécessaires. Néanmoins le principe général de l’article restera valable.
Pour ceux qui veulent tout connaître du microprocesseur 68000 et appronfondir ce qui est dit dans cet article, je me permets de recommander l'excellent livre “Mise en œuvre du 68000 de C.VIEILLEFOND aux éditions SYBEX”.
PARTICULARITES DU 68000
Le microprocesseur 68000 est un de ceux qui possède le jeu d’instruction le plus complet qui soit. Parmi toutes les instructions existantes certaines sont dites “normales” et d’autres sont dites “privilégiées”. En dehors des sauts d’interruptions communs à tous les microprocesseurs, le 68000 se distingue par une particularité supplémentaire : il dispose de 2 modes de fonctionnement : le mode User ou mode Utilisateur et le mode Superviseur.
Il est également nécessaire de savoir que le 68000 dispose de deux “stack pointers” c’est-à-dire de deux registres de pile. Le premier de ces registres est le registre A7, il est employé lorsque le 68000 tourne en mode User. Le second est le registre A7’ qui est évidemment
H
employé quand le 68000 tourne en mode Superviseur. Maintenant voyons d’un peu plus près les différences entre les instructions.
- Les instructions dites “normales” peuvent être utilisées indépendamment du mode de fonctionnement du microprocesseur, c’est-à-dire aussi bien en mode User qu’en mode Superviseur.
- Les instructions dites “priviligiées” ne peuvent être utilisées qu'en mode Superviseur.
Bien. L’un des secrets de l’informatique est de tout prévoir (ou tout au moins d'essayer !) Avant de concevoir ou de programmer quelque chose. Les concepteurs du 68000 n’ont bien sûr pas manqué de se conformer à cette règle et ont prévu les cas suivants :
- Le 68000 est mal connecté (au niveau hard) et une erreur de bus est engendrée.
- le 68000 n’est pas conçu comme ayant la capacité de transférer un mot ou un long mot à une adresse impaire. Si on le force, il y a erreur d’adresse.
- Le microprocesseur rencontre une instruction qui n’existe pas. Il y a alors erreur dite d'instruction illégale.
- Le microprocesseur rencontre une instruction non implémentée c’est- à-dire dont le code binaire commence par 1111 ou 1010. Ceci est légèrement différent de l’instruction illégale.
- On demande au 68000 d’effectuer une division par zéro. Il y a impossibilité.
- Un programme tournant en mode User veut utiliser une instruction “privilégiée”, il y a erreur de violation de privilège.
A propos voici l'énumération des instructions privilégiées :
STOP
RESET
RTE
MOVE to SR ANDI to SR EORI to SR ORI to SR MOVE USP
Peut être est-il intéressant ici d’apporter quelques explications :
- Les instructions STOP et RESET sont assez hermétiques, prochainement je vous donnerai une application avec RESET.
- RTE sera expliquée en détail plus loin.
- Les quatre instructions suivantes montrent qu’il est interdit en mode User d’accéder au registre SR. Par contre il est permis d'en lire le contenu avec une instruction du type MOVE SR to. Le registre SR, dit registre d'état, est un registre 16 bits qui peut en fait être considéré comme un double registre 8 bits.C'est la partie poids fort qui est intouchable (le gourou me précise : “de la caste des intouchables”, c’est malin I), la partie poids faible, qui contient des flags genre carry, over- flow et autres, peut, elle, être manipulée sans problème. Cette partie poids faible est sous-nommée registre OCR. Donc une instruction de type MOVE to COR peut être employée en mode User.
- Enfin l’instruction MOVE USP est une instruction qui peut être très appréciée par les fins bidouilleurs que vous êtes. Elle permet, lorsque le 68000 est en mode superviseur, et donc lorsqu’il utilise le registre A7' comme pointeur de pile, d’accéder au pointeur de pile qui sera utilisé lors du retour en mode User (l’inverse n'est pas possible). Ceci permet de se construire des routines bien surprenantes pour celui qui voudrait jeter des regards indiscrets dans vos programmes. Je laisse libre cours à votre imagination...
VENONS-EN AU FAIT
Puisqu’il est prévu que le 68000 rencontre des instructions qui n'existent pas ou autres bêtises, Il est donc conçu pour ne pas "coincer” bêtement dans de tels cas. Généralement un 68000 est utilisé en mode User sur un ordinateur, le mode Superviseur étant en principe réservé au système d’exploitation de l’ordinateur. C’est le cas de notre cher ami gars.
Vous avez donc votre programme qui tourne en mode User et tout d’un coup, une erreur est rencontrée. Voici comment réagi le 68000 :
yiHBBB HHHP
3 ..... .g
- Il passe en mode Superviseur.
- Il examine de quel type d’erreur il s'agit.
- Il empile (dans la pile Superviseur), d’abord le contenu du PC, c’est-à- dire l'adresse du programme à laquelle s’est produite l’erreur sur un long mot, puis le contenu du registre SR au moment de l’erreur. Les très fins bidouilleurs auront peut-être besoin de savoir que le registre SR est également conservé dans une mémoire interne au 68000. Je viens de dire plus haut que le 68000 examine de quelle erreur il s'agit : dans le cas d'une erreur d’adresse, le contenu de la pile sera un peu plus compliqué même si le principe reste le même. Je n’entre pas ici dans le détail car ce serait inutile. Vous pouvez toujours vous reporter aux livres spécialisés.
- Enfin le 68000 saute dans un vecteur de routine dite routine de traitement d’exception, li doit exister en effet une routine de traitement pour chaque type d'erreur. Les concepteurs du 68000 appelle ça des exceptions tout simplement parce qu’elles doivent se produire exceptionnellement (si si !).
- Les addresses des routines de traitement doivent figurer en bas de la ram. (voir tableau).
- A la fin de la routine de traitement DOIT figurer l’instruction RTE qui provoque le dépilement inverse à l’empilement précédent (RTE dépile le registre SR), remet le 68000 en mode User et le programme repart à l’instruction trouvée derrière celle qui a provoqué l’erreur.
Voici maintenant un petit tableau :
N° Vecteur
Adresse
Exception
0 -
>
$ 000
>
Reset: initialisation de SSP
I
>
$ 004
>
Reset: initialisation de PC
2
>
$ 008
>
Erreur bus
3 -
>
$ 00C
>
Erreur adresse
4
>
$ 010
>
Instruction illégale
5 -
>
$ 014
>
Division par zéro
6 -
>
$ 018-
>
Instruction CHK
7 -
>
$ 01C-
>
Instruction TRAPV
8 -
>
$ 020-
>
Violation de privilège
9 -
>
$ 024
>
Trace
10
>
$ 028
>
Emulateur 1010
11
>
$ 02C
>
Emulateur 1111
J’en vois déjà qui, à la vue de ce tableau, sentent d'où vient le vent :
Un programme comportait une erreur d’adresse et il y a eu un gourou n° 3 : c'est le vecteur correspondant à l'erreur adresse. Ceux qui ont essayé de diviser par 0 ont eu un gourou n° 5: c'est à nouveau le vecteur correspondant à cette erreur. Mais patience nous allons entrer dans ces détails un peu plus tard.
Auparavant je voudrais apporter encore quelques compléments afin d'être le plus précis possible. J’ai dit plus haut qu’en cas d’erreur, le 68000 “saute” dans le vecteur correspondant. Prenons un exemple : erreur de division par 0:
Le 68000 analyse l'erreur et s’aperçoit qu’elle concerne le vecteur 5. Il charge alors son PC avec le CONTENU de l’adresse correspondante. Dans notre exemple le contenu de l’adresse $ 014. Qu’y a-t-il dans ces addresses ? Patience j’y viens.
Je voudrais d'abord vous expliquer pourquoi figurent dans le tableau les instructions CHK et TRAPV alors que je ne vous en avait pas parlé lors du recensement des erreurs. Ces deux instructions sont en quelque sorte bâtardes car elles ne déclenchent pas systématiquement (contrairement aux autres du tableau) un état d’exception.
- CHK sert à faire un test d’encadrement. Si le résultat est vrai, le programme continue normalement son cours, sinon l’exception de vecteur 6 est déclenchée.
- TRAPV. Si le flag V (overflow) dans le registre d’état est faux le programme se poursuit comme si de rien n’était. Si le flag V est vrai, l’exception de vecteur 7 est déclenchée.
Aussi étonnant que cela puisse paraître, l’utilisation de ces deux instructions dans des programmes “mathématisants” peut parfois considérablement simplifier la vie. Aussi ne faut-il pas les négliger.
Pour en terminer avec le 68000, une dernière précision est nécessaire. J’ai dit plus haut que lors d’une exception le 68000 empilait le PC et donc l’adresse à laquelle s’est produite l’erreur. Ceci n'est exactement vrai que dans le cas suivant : l’instruction litigieuse est codée sur deux octets. C’est le cas de l’instruction ILLEGAL $ 4AFC. Dans le cas d'une erreur d’adresse lors d’un adressage très compliqué la valeur empilée peut être incrémentée de 2 à 12 octets proportionnellement à la longueur du codage machine de l’instruction. Ce phénomène propre au 68000 est appelé par ses concepteurs le phénomène d’anticipation. Voilà, Maintenant que nous avons ces quelques succintes explications (si!) Sur le 68000 nous pouvons nous intéresser à notre cher ordinateur.
L’AMIGA
Si nous exceptons le cas très particulier de Reset, nous voyons d'après le tableau que le 68000 peut avoir besoin du contenu des addresses $ 008 à $ 02 C.
Le contenu de ces addresses ne dépend bien sûr pas du 68000 mais est particulier à chaque ordinateur. Dans le cas de l’Amiga le contenu de ces addresses est lié à exec.library. C’est elle qui charge les bonnes valeurs lors de l'initialisation de la machine. Ces valeurs sont du genre $ FCxxxx donc des sauts en ROM.
Résumons : si le 68000 saute à des vecteurs d'exceptions, ce qui est fait lors de ces sauts de DEPEND PAS du 68000 mais de l’ordinateur. Voyons sommairement comment l’Amiga (en fait exec.library) traite les exceptions.
D'abord, à son tour, exec détermine de quel vecteur d’exception il s’agit et ceci d’une manière très simple. Il lui suffit au début de la routine de traitement que cette routine regarde elle-même à quelle adresse elle tourne pour en déduire le N° du vecteur. Ce N° de vecteur est ensuite empilé lui aussi par exec sur la pile superviseur du 68000. Ce N° de vecteur est au format long mot. On a donc finalement sur la pile un long mot pour le vecteur, un mot pour le registre SR, un long mot pour l’adresse de l’erreur.
Encore une fois, le traitement de l'erreur d’adresse est beaucoup plus compliqué à cause du phénomène d'anticipation et exec elle-même est contrainte d’empiler quantité d’informations supplémentaires pour être en mesure de s’y retrouver par la suite.
Ensuite exec recherche la tâche qui a provoqué l’exception 68000 et examine si cette tâche dispose d'un convertisseur de trap. Comme ce n’est généralement pas le cas exec use de son convertisseur par défaut. Celui-ci nous envoie d’abord le message’Task Held Software Error. Finish ALL disk activity”. Lorsque l’on clique sur Cancel, exec essaie de lancer son propre débogueur appelé ROM-WACK. Celui-ci ne tournera que si il y a un terminal branché sur le port série de l'Amiga. Comme ça n’est généralement pas non plus le cas, exec charge en D6 le N° de vecteur de tout à l’heure, en D7 l’adresse de la tâche qui a planté, et appelle la très subtile routine Alert qui nous donne le très redouté message tout de rouge clignotant “guru méditation 0000000x,xxxxxxxx”. Et comme l’alerte en question est une DEA- DEND_ALERT, l’Amiga fait un Reset et tout est fichu.
DEUX REMEDES
Le bon et le mauvais
Il est possible d’envisager de modifier le contenu des addresses $ 008 à $ 02C afin de détourner le 68000 sur des routines de traitements personnelles. Ceci est évidemment faisable, mais c’est une mauvaise solution car l'aspect-mufti-tâches de l’Amiga ne sera plus respecté puisque le traitement sera le même quelle que soit la tâche qui plante.
Si vous voulez un exemple de cette méthode, vous pouvez désassembler le très connu X-COPY. Ce programme a besoin de tourner en mode Superviseur afin de s’assurer d'être le seul à pouvoir accéder aux drives. Si vous désassemblez ce programme vous verrez au tout début qu’il modifie l'adresse de saut de la violation de privilège sur lui-même, fait un monstrueux MOVE, to SR afin de déclencher l’exception et de
continuer ainsi à s'exécuter en mode Superviseur. Voilà qui est bien bestial et délirant car ça ne trompe personne et il aurait été bien plus simple d’appeler la routine SuperState d’exec.library qui met l’Amiga en mode Superviseur on ne peut plus naturellement. Encore une fois, sur un Amiga, il est possible de tout programmer sans pour autant contrarier le système d’exploitation.
Pour ceux qui voudrait faire tourner un programme en mode Superviseur, veillez bien à ne pas confondre la routine SuperState avec la routine Supervisor de la même exec.library car cette dernière est beaucoup plus chatouilleuse.
Voyons maintenant la bonne solution. Pour cela, il faut se remémorer la structure Task:
struct Task
i
struct Node tc_Node;
UBYTE
tc_Flags;
UBYTE
tc_State;
BYTE
tcJDNestCnt;
BYTE
tc_TNDestCnt;
ULONG
tc_SigAlloc;
ULONG
tc_SigWait;
ULONG
tc_SigRecvd;
ULONG
tc_SigExcept;
UWORD
tcJTrapAlloc;
UWORD
tc_TrapAble;
APTR
tc_ExceptData;
APTR
tc_ExceptCode;
APTR
tc_TrapData;
APTR
tc_TrapCode;
APTR
tc_SPReg;
APTR
tc_SPLower;
APTR
tc_SPUpper;
VOID
(*tc_Switch)0;
VOID
(*tc_Launch)();
struct List
tcJVIemEntry;
APTR
tcJJserData;
};
Il est maintenant possible de faire le point. D’une part j’ai parlé d’exception à propos du 68000 et d’autre part j’ai dit qu’exec examinait si la tâche disposait d’un convertisseur de Trap. Y aurait-il de ma part une incohérence ? Eh bien non car la terminologie Motorola (pour le 68000) n’est pas la même que la terminologie Commodore. Ge que Motorola appelle une exception, Commodore appelle ça un Trap. Il ne faut donc pas se tromper de champ dans la structure Task. On pourrait être tenté d'y introduire un pointeur sur une routine personnelle en tc_ExceptCode mais on aurait tout faux car l’état d’exception d’une tâche est quelque chose qui n’a rien à voir avec le sujet de cet article. En conclusion, il faut bien fournir à la tâche un pointeur sur une routine personnelle dans le champ tc_TrapCode afin d’obtenir un convertisseur de trap spécifique à la tâche. Le pointeur tçJrapData est tout simplement un pointeur dont on peut se servir pour pointer sur certaines données. Son initialisation n'est pas indispensable.
LE PROGRAMME
Maintenant que tout cela est dit, parvenir au but que nous nous sommes fixés est d’une facilité sans nom.
Le programme a été écrit sur Devpac 2. Les utilisateurs de Seka sont punis et devront faire l’adaptation eux-mêmes.
Le programme, avant toute chose, commence par sauvegarder le pointeur de pile (User) et son contenu dès le départ. Tout simplement parce que la pile pointe à ce moment sur la routine de traitement de retour, que le programme soit lancé depuis Devpac ou depuis un CLI ou depuis ailleurs (ne le lancez pas par la fenêtre tout de même I). Le CLI utilise une pile “profonde”, c’est pour cela que le pointeur de pile est sauvegardé en plus du contenu.
Ensuite le programme recherche l’adresse de sa propre tâche afin de pouvoir initialiser le pointeur sur le convertisseur de trap. A toutes fins utiles et pour assurer, on sauvegarde également l’état du hardware au départ et le tour est joué. Il ne reste qu’à sauter au programme qui risque de planter.
LE CONVERTISSEUR TRAP
Qu’y fait-on ? A nouveau que des choses très simples. D’abord on sauvegarde en mémoire le contenu des registres afin de pouvoir savoir ce qu’ils contenaient au moment du plantage. Vous remarquerez que A7 n’est pas sauvegardé. En effet ceci serait une faute car à ce moment nous sommes en mode Superviseur et que le pointeur de pile Superviseur est totalement indépendant du plantage. De plus l’adresse mise sur la pile par le 68000 lors du plantage nous suffit pour connaître l’adresse litigieuse.
On sauvegarde également en mémoire le registre SR. Ça peut être très utile de pouvoir connaître l’état des flags au moment du plantage.
Vous remarquerez également que l’on teste s’il s'agit d’une erreur d’adresse par cmp.l $ 3,(sp) (Je me permets de vous rappeler que c’est exec qui a mis le N° de vecteur sur la pile.C’est bien pratique et voilà une raison de plus pour ne pas modifier les addresses de saut en bas de mémoire.) Auquel cas le traitement est légèrement différent à cause du format de la pile bien que le principe soit le même.
Sont sauvergardés ensuite en mémoire le N° de vecteur et l’adresse du plantage. (Il suffit d’aller les pêcher dans la pile Superviseur.)
Maintenant que nous avons tout le nécéssaire, nous allons quitter le mode Superviseur avec l’instruction RTE. Si nous le faisons tout de suite, le programme reprendra son cours derrière l’erreur précédente mais à nos risques et périls. Nous allons donc, avant de quitter le mode Superviseur par RTE, modifier le contenu de l’adresse de retour de la pile Superviseur afin de se retrouver dans un programme dont nous sommes sûrs en mode User. Ceci est réalisé par move.l exit,2(sp).
EXIT
Comme son nom l’indique, il s’agit maintenant de quitter le programme proprement.
- On ouvre graphics.library et intuition.library.
- On transforme les données numériques des registres précédemment sauvegardées en chaînes de caractères tout en les insérant en même temps dans une structure AlertMsg, ceci grâce à l’utilisation de RawDoFmt (exec.library). Comme je suis méchant, je ne peux pas m’empêcher de me rouler par terre de rire en voyant les efforts de programmations que certains font pour leur sortie de texte ! Je n’ai pratiquement jamais vu cette routine utilisée (correctement cela s’entend) dans des programmes (toujours cette manie de négliger le système d’exploitation ô combien puissant de notre Amiga). Moi je suis un grand paresseux, vous commencez à le savoir, alors j’utilise RawDoFmt qui fait tout le travail pour moi, plutôt que programmer des routines (bug- gées ?) Des quelques kilo-octets.
- Ensuite, à partir de l'adresse de base de la graphics.library, on va chercher l’adresse de l'ancienne copper-list et on la réinitialise (de manière très paresseuse, cela s'entend, mais néanmoins efficace), puis on remet le harware (DMA,Blitter,Raster....) dans l’état où il était avant de lancer le programme. Ainsi si le programme testé est une méga- démo avec une copper-list d’enfer, il est malgré tout possible d’en revenir sans casse.
- On envoie une RECOVERYJ LERT avec l’AlertMsg précédemment constitué de façon à simuler une guru-méditation, avec en plus la possibilité de visualiser le contenu des registres.
- On ramène l’écran du Workbench au premier plan, sait-on jamais...
- On ferme les librairies.
- On restaure la pile initiale et on s’en va, le tour est joué.
ESSAYONS LE PROGRAMME
Celui-ci saute au label main. Si vous assemblez tel quel, sauter au label main, c’est sauter n’importe où, donc c’est un gourou assuré et un excellent (et paresseux) moyen d’essayer le programme.
Vous pouvez aussi essayer :
main
ILLEGAL
pour obtenir un gourou N°4 main
lea $ 1000,a0 add.l $ 1 ,a0 move.l (aO),dO
pour obtenir un gourou N°3
main
move.w $ ffff,sr
pour obtenir un gourou N°8
Et ainsi de suite à votre bon choix messieurs-dames !
Mais le mieux est d’insérer en “main” un source que l’on vient d’écrire, d’assembler le tout et d’essayer immédiatement pour voir si quelque chose ne va pas. Si c’est le cas, comme le -programme vous rend la main, vous pouvez aller immédiatement désassembler le corps du délit avec un débogueur quelconque.
Vous pouvez, pour les experts, linker ce progamme avec un autre.
QUELQUES CONSEILS
Je me permets de vous recommander de ne pas faire de faute de frappe dans ce programme. En effet, s’il y avait une erreur d’adresse pendant le traitement d'exception “erreur d’adresse", tout serait bloqué irrémédiablement dans le 68000 !! Il faudrait alors faire un Reset.
Ce programme ne peut évidemment pas servir en quoi que ce soit sivous programmez une routine d’interruption. En effet il serait impossible de reprendre la main car l'interruption reviendrait tout le temps déclencher l’alerte. Il faut dans ce cas essayer votre routine indépendamment, puis ne la placer sous interruption qu’après être sûr que tout va bien.
Si vous lancez votre programme depuis Devpac, ce dernier considère le programme comme un prolongement de lui-même. Dans ce cas, le convertisseur de trap est donc installé sur la tâche de Devpac. Ainsi tout autre programme lancé plus tard continuera à bénéficier du convertisseur. Amusant non ?
Enfin une dernière remarque. Le Gurujnterceptor est utile pour débo- guer les programmes intraçables mais n’est pas traçable lui-même. Le traceur planterait dès l’installation du convertisseur de trap.
Bon amusement !
F. MAZUE En direct de Katmandou.
* **********************************************************
* *
* Programme: GURU INTERCEPTOR (modestement nommé) *
* Auteur: F MAZUE pour COMMODORE REVUE *
* Fonction: Vous éviter les crises de nerfs *
* Assembleur: Devpac 2 (the only one !) *
* *
* **********************************************************
include "exec exec.i" include "exec execbase.i" include "exec exec_lib.i" include "exec tasks.i" include "intuition intuition.i" include "intuition intuition_lib.i" include "graphics gfxbase.i" include "graphies graphics_lib.i" include "hardware custom.i"
; XREF main ajouter cette ligne pour
;un linkage éventuel
move.l sp,Pointeur_Pile sauvegarde du pointeur de pile
move.l (sp),Pile sauvegarde du contenu de la pile
ylBBIBlB HHHEI
au départ
movera.l d0-d7 a0-a6,-(sp)
sauvegarde des registres
sub.l al,al CALLEXEC FindTask move.l d0,a0 move.l dO,Task
on recherche notre propre tâche ça peut toujours vous servir
move.l trap,TC_TRAPCODE(aO)
atTRAPeur de gourou installé pour la tâche
lea $ dff000,a0
move.w intenar(aO), intena
move.w dmaconr(aO), dmacon
ici on sauvegarde l'état du hard
movem.l (sp)+,d0-d7 a0-a6
récupération des registres et
bra main
saut au programme qui risque d'invoquer un gourou
trap
ne pas toucher aux registres dans le convertisseur Trap
movem.l dO-d7 aO-a6,registre move.w 6(sp),état
pour pouvoir les afficher
ensuite
registre sr
cmp.l t$ 3,(sp) beq Odd Adr move.l (sp)+,Data Guru move.l 2(sp),Data Adr move.l texit,2(sp)
erreur d'adresse ?
si oui
l'adresse de retour dans la pile est sournoisement modifiée.
Rte
retour en mode user
Odd Adr
move.l (sp),Data Guru move.l 14(sp),Data Adr subq.l $ 4,sp move.l exit,2(sp) rte
traitement de faveur pour les erreurs d'adresses
voir plus haut,
c'est la même chose
exit
move.l 0,d0 lea graf name(pc),al CALLEXEC OpenLibrary tst.l dO beq end
move.l dO, GfxBase
numéro de version
move.l 0,d0 lea int name(pc),al CALLEXEC OpenLibrary tst.l dO beq end
move.l dû, IntuitionBase
numéro de version
lea Format0,a0 lea Data Guru,al _ lea PutChProc,a2 lea Sortie0,a3 CALLEXEC RawDoFmt
transforme nombres en chaîne de caractères
lea Formatl,aO lea Datai,al lea PutChProc,a2 lea Sortiel,a3 CALLEXEC RawDoFmt
lea Format2,a0 lea Data2,al lea PutChProc,a2 lea Sortie2,a3 CALLEXEC RawDoFmt
lea Format3,a0 lea Data3,al
lea PutChProc,a2 lea Sortie3,a3 CALLEXEC RawDoFmt
lea Format4,a0 lea Data4,al lea PutChProc,a2 lea Sortie4,a3 CALLEXEC RawDoFmt
* * A tout hasard, on va rétablir la copper-list **
* * ies DMA et les interruptions initiaux
* * ça peut toujours être utile
lea 5df0000,a0
adresse de base custom-chip
move.l GfxBase,al
move.l gb copinit(al),copllc(a0)
; ancienne copper-list clr.w copjmpl(aO) réactivée
move.w intena,d0 or $ 8000,dO move.w d0,intena(a0)
conditions d'interruptions rétablies
move.w dmacon,d0 or $ 8000,dO move.w d0,dmacon(a0)
DMA rétablis
move.l RECOVERY_ALERT,dO lea text_alert(pc),a0 move.l 90,dl CALLINT DisplayAlert
et un faux gourou UN!
CALLINT WbenchToFront
ça peut toujours être utile d'avoir le Wbench disponible
move.l IntuitionBase,al CALLEXEC CloseLibrary
move.l GfxBase,al CALLEXEC CloseLibrary
end
move.l Pointeur_Pile,sp move.l Pile,(sp)
rts
restauration du pointeur de pile remise en état du contenu de la pile
PutChProc move.b dO, (a3) + rts
graf name GRAFNAME even
int name INTNAME even
IntuitionBase “dc.l 0
GfxBase
dc. l 0
text alert
dc. b 0,30,15,"Tu t'es planté quelque part Old Boy !",0,1
dc. b 1,170,15,'Are you a poor LAMER ??',0,1
dc. b 0,190,30
SortieO dcb.b 34,0
dc. b 0,1
dc. b 0,130,40 Sortiel dcb.b 47,0
dc. b 0,1
dc. b 0,130,50 Sortie2 dcb.b 47,0
dc. b 0,1
place pour la chaine fabriquée par RawDoFmt
etc.
Dc.b 0,130,60 Sortie3 dcb.b 47,0
dc. b 0,1
dc. b 0,130,70 Sortie4 dcb.b 43,0
dc. b 0,1
dc. b 0,190,80,"GURU'S name is F MAZUE( Yeaah !)",0,0
* **** ici Sont les formats de sortie de style langage C ***** FormatO
dc. b "guru méditation %081x.%081x",0 even
Formatl
dc. b "D0=%081x D1=%081x D2=%081x D3=%081x",0 even
Format2
dc. b "D4=%081x D5=%081x D6=%081x D7=%081x'',0 even
Format3
dc. b ”A0=%081x Al=%081x A2=%081x A3=%08Ix",0 even
Format4
dc. b "A4=%081x A5=%081x A6=%081x SR=%04x",0 even
Data_Guru
dc. l 0 Data_Adr
dc. l 0
registre
Datai ;D0 à D3
dc. l 0
dc. l 0
dc. l 0
dc. l 0
Data2 ;D4 à D7
dc. l 0
dc. l 0
dc. l 0
dc. l 0
Datai ;A0 à A3
dc. l 0
dc. l 0
dc. l 0
dc. l 0
Data4 ;A4 à A6
dc. l 0
dc. l 0
dc. l 0
état ;SR
dc. w 0
Task ;ne sert à rien dans ce programme mais
;peut être utile pour certain essai
dc. l 0
Pile
dc. l 0
Pointeur_Pile
dc. l 0
_intena
dc. w 0
_dmacon
dc. w 0
main ; insérer ici un programme risquant ;de planter lamentablement
|GinHP PBHP 11161(1
APPLICATION
LES LIBRAIRIES MATHEMATIQUES
move.l dü,_doubbasbase beq fin
Comme convenu, voici la suite de l’article du mois dernier sur les librairies mathématiques.
Adresse tpn ascii convertit en DP dans
lea ascii,c jsr AtoDP
'resul' (pour essais)
lea asc2,a0 ; adresse tpn ascii
movem.l resul,dO-1
jsr DptoA ; convertit en ASCII
CONVERSIONS FLT -> ASCII
Le principe est très peu différent, les opérations étant effectuées en sens inverse. L'exemple suivant convertit un nombre IEEE en une chaîne ASCII, il est à modifier (assez peu) pour convertir un nombre FFP en une chaîne ASCII,
move.l jdoubbasbase,al move.l 4,a6 jsr CloseLibrary(a6) fin: rts
referme mathieeedoubbas.library
* *********************************************************** Ce programme transforme un nombre ASCII en DP ou vice-versa: routines 'AtoDP' et 'DPtoA'
*
(flottant, double précision )
* ***********************************************************
* ***********************************
MATH: routines de BASE
* ***********************************
Fix
EQU
- 30
Fit
EQU
- 36
Cmp
EQU
- 42
Tst
EQU
- 48
Abs
EQU
- 54
Neg
EQU
- 60
Add
EQU
- 66
Sub
EQU
- 72
Mul
EQU
- 78
Div
EQU
- 84
Floor
EQU
- 90
Ceil
EQU
- 96
• * * * *
* ******
* ******************
MATH: routines TRANSCENDENTALES
* *************************************************
Atan
EQU
- 30
Sin
EQU
- 36
Cos
EQU
- 42
Tan
EQU
- 48
Sincos
EQU
- 54
Sinh
EQU
- 60
Cosh
EQU
- 66
Tanh
EQU
- 72
Exp
EQU
- 78
Log
EQU
- 84
Pow
EQU
- 90
Sqrt
EQU
- 96
Tieee
EQU
- 102
Fieee
EQU
- 108
Asin
EQU
- 114
Acos
EQU
- 120
LoglO
EQU
- 126
• ***
* ********
* *****
routines
EXEC:
* ***********************************************
OldOpenLibrary =-408 CloseLibrary =-414
run:
move.l doubname,al moveq 0,d0 move.l 4,a6
jsr OldOpenLibrary(a6) ; ouvre mathieeedoubbas.library
p|
CE: D0 D1 = nombre IEEE.
; AO- pointe sur un tpn ASCII.
; CS: la valeur ascii est dans le tpn ; ASCII + 0 à la fin. Movem.l d0-7 a0-6,-(a7) ; tous registres préservés move.l _doubbasbase,a6 movem.l dO-l,interm move.l aO,adresse clr.l signe jsr tst(a6) ;>0? Bpl r4 ; si oui move.l 1,signe move.l adresse,aO move.b (aO) + move.l aO,adresse r4:
movem.l interm,dO-l
jsr abs(a6) ;valeur absolue pour éviter problèmes de signe
movem.l dO-l,interm
jsr rectif ajoute 0,0000000005 pour approx.
jsr floor(a6) partie entière du nombre en DP
movem.l d0-l,pent
move.l d0,d2
move.l dl,d3
movem.l interm,d0-l
jsr sub(aë) partie décimale du nombre en DP move.l d0,d4 move.l dl,d5
move.l 1000000000,dO -> nombre de chiffres gardés après la virgule jsr fit(a6) move.l d4,d2 move.l d5,d3 jsr mul(a6) jsr floor (a6) movem.l d0-l,pdec movem.l pent,dO-1 jsr itoa traduit partie ent.
Movem.l pdec,dO-1 jsr tst(a6)
beq r5 si partie déc. = 0
move.l adresse,aO
move.b ",",(a0)+ ;+ virgule (ou comme vous préferez)
move.l aO,adresse movem.l pdec,d0-l jsr itoa traduit partie déc.
R5:
move.l adresse,aO
clr.b (a0)+ ;0 comme butée après le nombre ASCII
movem.l (a7)+,dO-7 aO-6 récupéré registres rts
rectif:
move.l 2000000000,dO jsr fit(a6) move.l d0,d2 move.l dl,d3 move.l l,d0 jsr fit(a6)
DptoA:
;si non
dans tpn ascii
;x 1000000000
partie décimale x 1000000000
( -> les 9 prem.chiffres )
jsr div(a6) movem.l interm,d2-3 jsr add(a6) movem.l dO-l,interm rts
«
1BBE3B BEBB
itoa: ; CE: D0 D1 = nombre entier en DP ; CS: convertit en ASCII et placé ; dans le tpn pointé par 'adresse movem.l dO-l,interm move.l 10,dO jsr flt(a6) movem.l d0-l,tpl0 lea tpn,a0 move.l a0,-(a7) itl:
movem.l tpl0,d2-3 movem.l interm,d0-l jsr div(a6) jsr floor(a6) movem.l interm,d4-5 movem.l d0-l,interm movem.l tpl0,d2-3 jsr mul(a6) move.l d0,d2 move.l dl,d3 move.l d4,d0 move.l d5,dl jsr sub(a6) jsr fix(a6) cmp.l 10,dO bcs it3 clr.l dO it3:
; quotient euclidien par 10
; reste euclidien par 10 ;soit un chiffre ; 10?
;si oui
;si non: erreur d'approximation ;en ASCII ; stocké
chiffre = 0
add.l "0",d0 move.l (a7)+,a0 move.b dO,(a0)+ move.l a0,-(a7) movem.l interm,d0-l jsr tst(a6) ;quotient bne itl
0?
Move.l (a7)+,a0 ;fin de la chaîne (à inverser) move.l adresse,al it2:
move.b (aO),(al)+ recopie la chaîne en l'inversant
cmp.l tpn,a0 bne it2
move.l al,adresse rts
AtoDP: ; CE: A0 pointe sur le nombre ASCII ; terminé par un zéro ; CS: RESUL contient la valeur IEEE ; D0 1 aussi... (NDLR: et Félicie?)
Move.l _doubbasbase,a6 move.b (aO),dO clr.l signe ;0 si positif cmp.b "-",d0 bne rl
move.l 1,signe ;1 si négatif add.l l,a0 avancer d'un caract. Rl: -> D7 = nbre de chiffres
bsr atoi -> D0 D1 = val entière FLT, A0 pointe sur movem.l d0-l,pent dernier caract lu + 1 clr.l pdec 0 si absente
clr.l ndec 0 si pas de chiffre
clr.l dO clr.l dl tst.b (a0)+
beq r2 pas de partie déc.
Bsr atoi -> D0 D1 = part déc et D7 = nbre de ch.
Movem.l d0-l,pdec move.l d7,ndec subq.l l,d7 move.l d7,d4 move.l 10,dO jsr fit (a6) movem.l d0-l,interm moveq.l l,d0 jsr fit (a6) bclel:
compteur
;10 en FLT
dans interm
movem.l interm,d2-3 jsr mul(a6)
dbra d4,bclel calcule 10 exp ndec en FLT
move.l d0,d2
move.l dl,d3 movem.l pdec,d0-l
jsr div(a6) divise pdec par 10 exp ndec r2:
move.l d0,d2 move.l dl,d3 movem.l pent,d0-l jsr add(a6) + pdec en FLT
tst.l signe beq r3 positif jsr neg(a6) prend l'opposé
r3:
movem.l d0-l,resul rts
atoi: CE: A0 pointe sur 1er caract . (C'est la même)
CS: D0 D1 = val enti phi>re format IEEE (routine que celle) D7 = nbre caract. (du programme)
A0 = pointe sur dern val + 1 (ASCII -> DP)
clr.l d2 move.b (a0)+,d2 move.l a0,-(a7) sub.l $ 30,d2 ‘ move.l d2,d0
jsr flt(a6) 1er chiffre en DP
movem.l d0-l,interm move.l 10,dO jsr flt(a6) 10 en DP
movem.l d0-l,tpl0 moveq.l l,d7 movem.l interm,d0-l atl:
move.l (a7)+,a0 tst.b (aO) beq fatoi cmp.b ".",(aO) beq fatoi cmp.b "," beq fatoi move.b (a0)+,d6 move.l a0,-(a7) sub.l $ 30,d6 movem.l tpl0,d2-3 jsr mul(a6) nbre courant
",(aO)
10 en DP
movem.l d0-l,interm move.l d6,d0
jsr flt(a6) chiffre courant en DP
movem.l interm,d2-3 jsr add(a6) somme des deux
addq.l l,d7
bra atl chiffre suivant fatoi: rts
ascii: dc.b "-54321.123456",0 ds.b 30 pour chiffres supplém. Even
asc2: ds.b 310 car le nombre peut comporter jusqu'à 308 chiffres
even
tpn: ds.b 310 tpn ASCII intermédiaire
even
signe: dc.l 0
pent: dc.l 0,0 pdec: dc.l 0,0 ndec: dc.l 0,0 resul: dc.l 0,0 interm: dc.l 0,0 tplO: dc.l 0,0
adresse: dc.l 0
,*2 mots longs en double précision ( IEEE )
adresse tpn ascii de DptoA
even
_doubbasbase: dc.l 0
doubname: dc.b "mathieeedoubbas.library",0
La routine “rectif” qui est appelée est une astuce : comme une erreur de calcul est souvent faite sur le dernier chiffre de la partie décimale, on ajoute 0,000 000 000 5 au nombre pour que l’erreur se produise sur un chiffre qui ne compte pas, car on ne garde que les 9 premiers chiffres... On pourrait passer comme paramètre de la routine DptoA le nombre de chiffres à prendre dans la partie décimale, l’instruction move.l 1000000000,dO de “DPtoA” serait remplacée par une boucle du genre:
move paramètre, d6 ; registre inutilisé = nbre de chiffres demandés
subq.l l,d6 ,-nombre de boucles
move.l 10,dO
jsr Fit(aë)
movem.l dO-l,interm
move.l tl,d0
jsr Fit(aë)
boucle: • multiplie 1 par 10 autant de fois
movem.l interm,d2-3 que demandé par le paramètre jsr Mul(aë) dbra dë,boucle
(La routine “rectif” serait alors ajustée en conséquence...)
APPLICATIONS :
Un des avantages de la routine DptoA est qu’elle permet de vérifier en mode trace la validité d’un calcul : il suffit de l’appeler pour traduire le nombre calculé D0 D1 en chaîne ASCII que l’on visualise à l'aide du traceur ( fenêtre 3 de DEVPAC en mode trace = “monam2" ).
Elle pourrait aussi permettre de debugger un programme de calcul vicieux qui méditerait trop souvent si vous voyez ce que je veux dire... Par exemple, et pour répondre à la question d’un GL (Gentil Lecteur) du club “Mais-dis-tu-rame-hé”, supposons que l’on soit pris d’un désir irrépressible de calculer le carré de e = 2,718... (NDLR : base des logs népériens [pour attendre]), on remplacerait la partie “run” du programme précédent par celle-ci :
run:
move.l doubname,al moveq 0,d0 move.l 4,a6
jsr OldOpenLibrary(aë) ouvre mathieeedoubbas.library move.l d0,_doubbasbase beq lin
move.l doubtransname,al moveq 0,d0 move.l 4,aé
jsr OldOpenLibrary(aë) ouvre mathieeedoubtrans.library move.l dO,_dtbase ;(à définir plus loin)
move.l _doubbasbase,aë move.l 2,d0
jsr Flt(aë) exposant 2
move.l _dtbase,aë
jsr Exp(aë) calcule e exp(D0 Dl) et le met dans D0 D1
lea asc2,aû adresse tpn ascii jsr DptoA convertit en ASCII
move.l _dtbase,al
move.l 4,aë
jsr CloseLibrary(aë)
move.l _doubbasbase,al move.l 4,aé
jsr CloseLibrary(aë) referme mathieeedoubbas.library fin: rts
Après lancement, si on regarde (ou si on écrit à l’écran) la chaîne “asc2”, on voit -ô miracle- qu’elle contient la valeur ardemment cherchée soit 7,.... ce qui suscitera en vous une joie ineffable, ô ami GL.
D. GENOT
APPLICATION
FAISONS RESET AVEC LE SOURIRE
D’une manière générale, je n'aime guère les programmeurs de méga- démos, d'abord parce que je suis méchant et n’aime personne, ensuite parce que j’ai tellement vu de “sinus-scroll” et autres que je ne suis pas loin de l’indigestion, enfin parce que lesdits programmeurs programment la plupart du temps en utilisant des routines élaborées par d’autres (le piratage va bon train I), et qui plus est comme des cochons, sans le moindre respect pour le formidable système d’exploitation de cet Amiga que j’aime tant. (Il faut bien que j’aime quelque chose quand même !)
Vous ne me croyez pas ? Alors laissez-moi vous raconter :
Il était une (mauvaise) fois où je me suis laissé aller à booter une démo (tout le monde craque un jour ou l'autre). Que vois-je ? Une démo belle et même superbe, avec une musique bien tapageuse comme il se doit. Bien me dis-je et je clique la souris pour quitter. Et alors là, qu'arriva-t- il ? Un fait ahurissant, désolant, exaspérant, horripilant, terrifiant, décevant, énervant, agaçant, désopilant, crispant, irritant, excrément : la Led-power de mon Amiga à moi se met à clignoter, une espôvantable couleur jaune apparaît sur le moniteur, puis l’ordinateur finit tant bien que mal par faire un reset gouroutisant au lieu de me rendre la main. Comme je suis un très vilain curieux, j’examine de plus près ce trepelu
programme et m'aperçoit que l'auteur a semé un tel b dans la
machine qu’il ne sait plus comment rendre la main.
Bon admettons, mais là où je me roule par terre de rire c'est qu’il m’apparaît que notre auteur n’est même pas capable de programmer un tout bête reset convenablement. Qu’a-t-il fait : un saut en ROM à l’adresse $ FC00D2 comme ça, sans la moindre délicatesse. C’est ce très misérable saut en ROM qui provoque le phénomène décrit plus haut (beurkl). Mais là où ça devient grave, c’est que j’ai vu il y a peu de temps dans certains ouvrages ou revues des routines reset aussi mal programmées : Aaarrrgh !
UN RESET PROPRE
Cela suffit. Je vous donne donc le moyen de rebooter l’Amiga à chaud convenablement. Quelques explications sur ce programme :
On appelle la routine Supervisor d'exec.library (ne pas confondre avec Superstate). Cette routine met l’Amiga en mode Superviseur (afin de permettre l’emploi des instructions privilégiées du 68000) et saute immédiatement dans un convertisseur de trap pointé par A5 (vous pouvez faire quelques révisions sur ce sujet dans l'article Gurujnterceptor). Dans ce convertisseur de trap, on charge $ 2 dans A0 puis on utilise l’instruction 68000 RESET. De par la connection des pins (prononcer pine) du 68000, cette instruction provoque te recouvrement de la chip- ram via le CIA-A par la ROM, il suffit alors de sauter à l’adresse pointée par A0, qui de ce fait vaut $ FC0002, pour suivre un processus reset normal. Au cours du processus reset le bit 0 (prononcer bite) du CIA-A est inversé pour annuler le recouvrement mémoire. Pour le processus reset, vous pouvez vous reporter à l'article Boot-Allocator dans CR 26. Par ce simple procédé, l’horrible couleur jaune n’apparaît plus, mais ce qui est beaucoup plus important, c’est que grâce à l’emploi de l’instruction RESET, tous les périphériques et autres cartes connectés à l’Amiga seront CORRECTEMENT réinitialisés.
PARESSE MAXIMUM
Avez vous remarqué que pour faire un reset par le clavier, il faut appuyer en même temps sur trois touches du clavier tellement éloignées les unes des autres qu’il est nécessaire d’utiliser les deux mains ?
Voilà pourquoi, j’ai ajouté dans le listing l’instruction include ”misc easystart.i” qui permet au programme d'être lancé depuis le Workbench en cliquant une icône.
Il vous est maintenant possible de faire reset d’une seule main ! Bien
début
entendu ce que vous faites de votre autre main pendant ce temps ne me regarde pas.
Movem.l dO-d7 aO-a6,-(sp)
PAL
lea graf name(pc),al clr.l dO
CALLEXEC OpenLibrary
Comme autre application au reset, je vous propose, même si l’idée
clr.l dO
move.w gb_DisplayFlags(aO),d0 ;a0 contient lui aussi gfxbase
n’est vraiment pas nouvelle, un petit programme qui teste si l’Amiga a
and.w PAL,dO
bien booté en PAL. Si oui, le programme rend la main sans autre forme
beq reset
de procès. Sinon c’est que l’Amiga a booté en NTSC et dans ce cas on
move.l aO,al
fait reset. Vous pouvez placer ce programme en début de votre startup-
CALLEXEC CloseLibrary
séquence, mais il est encore possible de faire mieux : ce programme
movem.l (sp)+,d0-d7 a0-a6
est entièrement écrit en code relatif au PC et peut donc être installé
rts
dans un boot-block. Ainsi, si l’Amiga qui vient de booter est par NTSC saboté, il pourra rebotter au débotté, voilà qui devrait vous botter en
reset
beauté. Et tout ceci avec une perte de temps minimum.
Lea.1 Clean Reset(pc),a5
Si vous ne savez pas installer un programme dans un boot-block,
CALLEXEC Supervisor
sachez qu’un excellent utilitaire conçu à cet effet est paru dans le CR
20. Courez l’acheter, il n’y en aura pas pour tout le monde,
Clean Reset
Il n'est point vrai que je n’aime personne et pour preuve avant que de
lea.l 2,a0
vous quitter bonnes gens, gueux, vilains, affamés, croque-lardons, clo-
RESET
chepins, porte-rogatons, gaigne-deniers, lichecasses, goinfres,
jmp (aO)
coquillards, golfarins, gloutons, quémandeurs, gourmands, mais non
pas vous jeunes pucelles, mais vous surtout nobles dames et gentes damoiselles, entendez la devise humaniste, généreuse, charitable, bien
graf name GRAFNAME
veillante, prodigue et débonnaire du bon et pantagruélique auteur de cet article :
F. MAZUE
avec ses copains partage son pain !
* ****************************************************************
* *
* ****************************************************************
* Programme: CLEAN RESET *
* Auteur: F MAZUE pour COMMODORE REVUE le 20 08 90 *
* Fonction: Générer un Reset proprement *
* *
* Assembleur: Devpac 2 (the only one !) *
* Programme: PAL *
* *
* Auteur: F MAZUE pour COMMODORE REVUE le 20 08 90 *
* ****************************************************************
* Fonction: Générer un Reset si l'Amiga a booté en NTSC *
* Particularité: Peut être installé dans un boot-block *
include "exec exec.i" ; Eh Max, je mets les
* Assembleur: Devpac 2 (the only one !) *
include "exec execbase.i" ;includes même pour
* *
include "exec exec lib.i" ;si peu. Na!
* ****************************************************************
include ”misc easystart.i"
include "exec exec.i"
lea.1 Clean Reset(pc),a5
include "exec execbase.i"
CALLEXEC Supervisor
include "exec exec lib.i" include "graphies graphies lib.i"
Clean Reset
include "graphics gfxbase.i"
lea.l 2,a0
PAL equ $ 4 ;cf gfxbase.h
RESET jmp (aO)
AMIGA500
FROMO
AMIGA500
+ souris + peritel
INCROYABLE
AMIGA500
+peritel
AMIGA500
+extension 512K
+ écran 1084
+horloge
FROMO
3890
A IIGA5 ) )
LECTEUR3"1 2
avec compatibilité
EXTEFSSE
PC
790
nousconsulter
A500+péritel+ext512K+horloge 3890
A500+péritel+lect ext 3" 1 2 .3890
A500+ 1084S+ext512K+horloge .5990
A500+1084S+ext512K+lect 3" 1 2 ..6590
AMIGA500
- técran 1084 +Deluxe Paint III +Star LC-10 Coukurs
8290
LC10 ....
.....1890
LclOcoul.....
.....2490
LC24-10......
.....2990
SWIFT24
.....3790
AMIGA2Û00
+ecran 1084 +carte XT +disqueGVP46Mo
15990
AMIGA2000
- fécran 1084 +carteAT
+Star LC-10 couleur
AMIGA2000
+écran 1084 +carteXT +Star LC-10
11990
PHASE
Carie extension!
2 Mo extensible à 8 2950
15990
GALKRI1TLESQIIARE
93, Avenue tin Gl Leclerc 75014PARIS
45 45 75 (X)
M"Alésia- l()hà I9hLundi-Samedi
mÈÈMÊÊK
ëHH
disquedur20MopourA500 ...
......3990
.510
Nordic Power ..
..850
REPRISE POSSIBLE DE VOTRE ANCIEN MICRO CREDIT-DÉTAXE VENTE PAR CORRESPONDANCE -PRIX T.T.C.
i r
APPLICATION
FAITES VOS JEUX AVEC AMOS
FAITES VOS JEUX EN AMOS
Ce mois-ci, un superbe PacMan fait maison
Programme par Septh - graphismes par Huit
Economise un peu de mémoire et planque la souris
Close Editor : Hide : Rem
Après avoir abordé la théorie essentielle de la programmation d'un jeu, nous allons passer à la pratique en construisant pour commencer un clône de Pac-Man, baptisé d’un doux nom aux consonnances érotiques : Pac-Rev.
AUJOURD’HUI : PAC-REV
Le principe du jeu est simple et connu de tous : un gentil personnage - le PacRev - doit manger toutes les pastilles d’un labyrinthe. Il est poursuivi par deux méchants qui essaient de le manger lui aussi, d’où la cocasserie de la situation et l’intérêt du jeu. Notre gentil PacRev est aidé dans sa quête par quelques super-pastilles qui lui permettent de dévorer à son tour les monstres, durant un temps toutefois limité.
Avant que de se lancer tête baissée dans la programmation du jeu, il va vous falloir exercer vos talents de graphiste pour dessiner les sprites et icônes nécessaires. Ce ne sera pas bien long, il n’en faut qu’une vingtaine et tous ont la même taille, soit 16 pixels sur 16. Reportez-vous pour plus de détails aux petits schémas que notre vénéré rédacteur en chef vous a concoctés.
J’ai essayé dans ce jeu d’obéir à la fois aux régies de l’optimisation et à celles de la structuration d'un programme. Toutefois, pour des raisons de mise en page dans le journal, les bouts de routines se répétant ont été “compressés”, c’est-à-dire présentés de manière moins structurée. Il n’en reste pas moins que vous vous retrouvez avec quelques 400 lignes de programme à saisir... Bonne chance ! Avis aux fainéants de tous poils (surtout dans la main) : vous pourrez bientôt vous procurer ce jeu, ainsi que les suivants réalisés dans cette rubrique), sur les disquettes ANT que nous sommes en train de préparer. Cela vous évitera à la fois les crampes au petit doigt et les fautes de frappe, et vous donnera qui plus est la possibilité d’admirer le talent graphique de l’ami Huitric. Fin de l'auto-publicité, retour aux choses sérieuses.
Load Iff "RAD:PacRev PacRev.IFF",0 : Rem
Charge 1' image de fond Charge les sprites Et les icônes
Load "RAD:PacRev PacRev_Spr.ABK" ; Rem
Load "RAD:PacRev PacRev Icn.ABK" : No Icon Mask
Rem
Dim TABLEAU(16,15) i Rem ' Variables pour les trois Bobs
Dim TAB_X(3) , TAB_Y (3) ,SCR_X(3) ,SCR_Y (3),BDIR(3), VITESSE (3)
Dim VAR1 (3) ,VAR2 (3) ,VAR3 (3)
' Constantes PACREV=1 : ST=2 : MAC=3
' Variables
VIES=3 : SCORE=0 : NB_PASTILLES=0
SUPER=False
BOUFFE=False
' Chaînes d'animations AMA1 pour le PacRev
HAUT_ANIMS="Anim 0, (4,6) (1,6)" : BAS_ANIM$ ="Anim 0, (5,6) (1,6)" GAUCHE_ANIM$ ="Anim 0, (3,6)(1,6)" : DROITE_ANIM$ ="Anim 0,(2,6)(1,6)"
' Chaines d'animation pour le flashage
FLACH1$ ="(000, 5)(200,5)(400,5)(600,5)(400,5)(200,5)”
FLACH2$ ="(000,3)(200,3)(400,3)(600,3)(400,3)(200,3)"
FLACH3$ ="(000,1)(200,1)(400,1)(600,1)(400,1)(200,1)"
FLACH=0
' Déclarations globales pour que toutes les procédures accèdent aux variables
Global TABLEAU(),SCR_X(),SCR_Y(),TAB_X(), TAB_Y()
Global BDIR(),VITESSE(),VAR1(),VAR2(),VAR3()
Global PACREV, ST, MAC, SUPER, NB_PASTILLES, BOUFFE Global HAUT_ANIM$ , BAS_ANIM$ , GAUCHE_ANIM$ , DROITE_ANIM$
Global FLACH1S,FLACH25,FLACH3$ ,FLACH
Ce tableau contiendra... le tableau
DESSINE_TABLEAU : Double Buffer : Rem ' Boucle pour chaque vie Repeat
Flash Off : BOUFFE=False : SUPER=False
Restore INIT_VARS : Rem For 1=1 To 3
Read TAB_X (I), TAB_Y (I), SCR_X (I), SCR__Y (I ), BDIR( I), VITESSE ( I) VAR1(I)=0 : VAR2(I)=0 : VAR3(I)=0 Next I INIT_VARS :
Data 8,9,120,136,4,4,7,8,104,120,2,4,8,8,120,120,2,4
' Affiche les trois sprites
Bob PACREV, SCR_X (PACREV), SCR_Y (PACREV), 3
Bob ST,SCR_X(ST),SCR_Y(ST),6 : Bob MAC,SCR_X(MAC),SCR_Y(MAC),7 Clear Key : Repeat : Until Len(Inkey$ ) or Fire(l) : Rem Channel 1 To Bob PACREV : Amal 1, GAUCHE_ANIM$ : Amal On 1 : Rem
' Boucle principale
Repeat
' Affiche le PacRev, le ST, le Mac et le score
Bob PACREV, SCR X (PACREV), SCR_Y (PACREV), t-
Bob ST, SCR_X (ST), SCR_Y (ST), 6 : Bob MAC, SCR_X (MAC), SCR Y (MAC), 7
Dessine le tableau (hé oui)
Initialise les variables
Attends une touche C’est parti
SCR Y(ST)=120
' Déplace les trois Bobs
DEPLACE_PACREV : DEPLACE_MONSTRE [ST] : DEPLACE_MONSTRE [MAC]
DE L’UTILITE DES VARIABLES
Toujours dans le but de ne pas monopoliser toute la place au sein de Commodore Revue, les tests nécessaires au déplacement de chaque personnage
- et qui seront détaillés plus loin - sont effectués par les mêmes procédures, qu’il s’agisse du Pac-Rev ou des monstres. Ceci nous oblige donc à avoir une zone de données identique pour chacun d’entre eux, à savoir des tableaux dimensionnés en début de listing, dont la signification est la suivante :
- TAB_X() et TAB_Y0 contiennent les coordonnées- tableau des personnages. En effet, il est nécessaire
' Vérifie les collisions des bobs If Bob Col(PACREV,ST To MAC)
If SUPER : Add SCORE,10000
If Col(ST) : TAB_X(ST)=7 : TABJY(ST)=8 : SCR_X(ST)=104 BDIR(ST)=1 : VITESSE(ST)=4 Else TAB_X(MAC)=8 : TAB_Y(MAC)=8 : SCR_X (MAC) =120 : SCR_Y (MAC) =120 BDIR(MAC)=1 : VITESSE(MAC)=4 End If
Else BOUFFE=True : End If End If
DSC3D BHHP
de savoir à chaque instant où il se trouve pour pouvoir décider de son déplacement et, dans le cas du Pac-Rev, s’il a mangé une pastille ou non,
- SCR_X() et SCR_Y0 contiennent les coordonnées- écran des bobs. Ces variables n’étaient pas réellement nécessaires, mais il est plus rapide de les stocker ainsi plutôt que de les calculer à chaque fois d'après des fomules compliquées. Et n’oubliez pas que la rapidité est primordiale, surtout dans ce genre de jeux ;
- BDIR() indique la direction dans laquelle se déplace actuellement le bob. Les valeurs possibles sont 1 = haut, 2 = bas, 4 = gauche et 8 = droite ;
- VITESSEO : donne la vitesse, en pixels, de déplacement. Les valeurs possibles sont 1 = escar-gro- tesque, 2 = lent, 4 = moyen, 8 = rapide et 16 = injouable (seuls les diviseurs de 16 sont autorisés, puisque, rappelons-le, une case du jeu mesure 16 pixels sur 16) ;
- enfin VAR1 (), VAR2() et VAR3() sont des variables de calcul utilisées uniquement par les monstres, pour décider du chemin qu’il doivent suivre lorsqu’ils pourchassent le Pac-Rev (voir plus bas).
LE DESSIN DU TABLEAU
C'est la procédure “DESSINE_TABLEAU” qui se charge de devinez quoi ? De dessiner le tableau à l’écran, oui. Afin de permettre un maximum de ver- salité, le tableau du jeu est codé sous forme de datas, donc librement modifiable par vous-même (voir au label ”TABLEAU1:”). Notez au passage que comme on pense à tout et surtout à vous, la disquette citée plus haut contiendra également un éditeur de tableaux approprié. Mais dans l’immédiat, il vous sera possible de délirer comme bon vous semble lorsque vous saurez que d’une part, le tableau fait obligatoirement 14 cases de large sur 15 de haut, ceci pour des raisons de “mise en écran" et que d’autre part, chaque chiffre de data correspond à une case du tableau. Il s’agit d’un numéro d’icône à afficher, agrémenté d’une indication quant à la présence éventuelle d’une pastille sur la case concernée. Le bit 7 du numéro indique une pastille "normale” et le bit 8, une super-pastille. Pour simplifier :
- numéro de $ 1 à $ A = case sans pastille ;
- numéro de $ 41 à $ 4A = case avec une pastille “normale” ;
- numéro de $ 81 à $ 8A = case avec une super-pastille ;
(c'est de l’hexadécimal. Le “A” correspond donc à
10) . On déduit de tout ça que le nombre de pastilles est entièrement variable et ne dépend que de votre volonté. Il est stocké dans la variable ”NB_PAS- TILLES”, qui est initialisée dans la procédure..
On calcule les coordonnées écran de l’icône à afficher - et par extension, de tous les objets graphiques, bobs compris - par les formules suivantes :
x_écran = 8 + (16*(x_tableau) -1) y_écran = 8 + (16*(y_tableau) -1 )
Else If FLACH=99 : Flash 0,FLACH1$ : Rem
Flash lent
Else If FLACH=49 : Flash 0,FLACH2$ : Rem
Flash moyen
Else If FLACH=24 : Flash 0,FLACH3$ : Rem
Flash rapide
End If
End If
End If
End If
End If
Until NB PASTILLES=0 or BOUFFE
If BOUFFE : Dec VIES : Amal Off : Bob Off ST : Bob Off MAC : Wait 50 : End If
Until NB_PASTILLES=0 or VIES=0
Show : Default : Edit
Procédure DEPLACE_PACREV
' Déplacement du PacRev
MOVE IT[PACREV] : OK=Param
If OK
Z-TABLEAU (TAB Y (PACREV), TAB X (PACREV) )
If Z>$ 3F
TABLEAU(TAB Y(PACREV),TAB X(PACREV))=Z and $ 3F : Add
SCORE,10
If Btst(7,Z) : Add SCORE,5 : SUPER=True : FLACH=100
: End If
Paste Icon SCR X(PACREV),SCR_Y(PACREV),Z and $ 3F
Dec NB PASTILLES
End If
If Jup(l) or Key State($ 4C) : Rem
Joystick en haut ou flèche haut
BDIR(PACREV)=1 : Amal 1,HAUT ANIM$ : Amal On 1
Else If Jdown(l) or Key State($ 4D) Rem
Joystick en bas ou flèche bas
BDIR(PACREV)=2 : Amal 1,BAS ANIM$ : Amal On 1
Else If Jleft(l) or Key State($ 4F) : Rem
Gauche
BDIR(PACREV)=4 : Amal 1,GAUCHE ANIM$ : Amal On 1
Else If Jright(1) or Key State($ 4E) : Rem
Droite
BDIR(PACREV)=8 : Amal l,DROITE_ANIM$ : Amal On 1
End If
i End If
End If
End If
i End If
: End Proc
Procédure DEPLACE MONSTRE[M]
' Déplace les vilains
MOVE_IT[M] : OK=Param
If OK : Rem
Il est temps de décider où on va
TEST_DIR[M] : SENS=Param
' Premier cas (la maison)
If TAB X(M)>6 and TAB X(M) 10 and TAB_Y(M)>6 and TAB_Y(M) 9
If SENS and 1 : BDIR(M)=1
Else If BDIR(M) and 4 : BDIR(M)=4
Else BDIR(M)=8 : End If
End If : Pop Proc
End If
V=TAB Y(M)-TAB Y(PACREV) : V2=Abs(V) : Rem
Détermine la direction verticale
H=TAB X(M)-TAB X(PACREV) : H2=Abs(H) : Rem Détermine la direction horizontale
If SUPER : V=-V : H=-H : End If
If M=ST : V=-V : H=-H : End If
' Deuxième cas (on poursuit le PacRev)
If VAR1 (M) =0
If H2>=V2 : Rem Diminue toujours la plus grande distance
If H>0 : Rem
Si on doit aller à gauche
If SENS and 4 : Rem
Et qu'on le peut
BDIR(M)=4 : Pop Proc : Rem
Alors on y va
Else Rem
Sinon
VAR1 (M) =4 : Rem
On se souvient où on doit aller,
VAR2 (M) =8 : Rem
d'où on vient,
VAR3 (M) =0 : Rem et on remarque qu'on n'a pas encore change d axe
End If
Else If H 0 : Rem
Idem pour la droite
If SENS and 8 : BDIR(M)=8 : Pop Proc
Else VAR1(M)=8 : VAR2(M)=4 : VAR3(M)=0 : End If
End If
End If
Else If V>0 : Rem
Idem pour le haut
If SENS and 1 : BDIR(M)=1 : Pop Proc
Else VAR1(M)=1 : VAR2(M)=2 : VAR3(M)=0 : End If
Else If V 0 : Rem
Et pour le bas
If SENS and 2 : BDIR(M)=2 : Pop Proc
Else VAR1(M)=2 : VAR2(M)=1 : VAR3(M)=0 : End If
End If
End If
End If
End If
' Troisième cas (bloqué par un mur, on cherche une autre direction)
On VAR3(M)+1 Goto ETAPE1,ETAPE2,ETAPE3
Ces formules découlent du fait que les coordon- nées-tableau sont comprises entre 1 et 14 (1 et 15 pour la hauteur) et non 0 et 13 (d’où la soustraction de 1), que chaque icône fait 16 pixels sur 16 (d’où la multiplication par 16) et que tout le tableau est "décalé" de 8 pixels par rapport aux bords de l’écran, ceci pour des raisons d’esthétique (d’où l'addition de 8). Reportez-vous au deuxième croquis, tout deviendra plus clair.
LET THE GAME BEGIN
On en arrive à la gestion du jeu proprement dit. Après avoir réinitialisé les variables citées plus haut pour être sûr que tout démarre dans les bonnes conditions, on attend l’appui sur une touche ou sur le bouton de feu du joystick, puis c’est parti, on entre dans la “boucle principale” (cf. Listing).
Comme vous pouvez le constater, cette boucle est très courte ; elle accomplit néanmoins tout le travail nécessaire : affichage des trois bobs à leurs coordonnées respectives, détection des collisions éventuelles (AMOS a tout ce qu’il faut pour ça), déplacement des trois personnages et test si le Pac-Rev a mangé une super-pastille, auquel cas le flag “SUPER” est mis, indiquant qu’en cas de rencontre avec un monstre, c’est ce dernier qui meurt et non le joueur. Le plus gros du travail est cependant réalisé par quatre procédures judicieusement nommées DEPLACE.PACREV, DEPLACE_MONSTRE, TEST_ DIR et MOVEJT, procédures que nous allons détailler sans plus tarder.
DEPLACEPACREV
DEPLACE_PACREV se charge, on s’en serait douté, du déplacement de notre gentil héros. Elle teste pour cela le joystick et le clavier, et actualise éventuellement la variable BDIR() après s’être assurée que la direction demandée était permise (cf. Procédure TEST_DIR).
MOVEJT
La procédure MOVEJT quant à elle, déplace à l’écran le bob dont le numéro lui est passé en paramètre, tout simplement en additionnant sa vitesse VITESSE)) à ses coordonnées-écran SCR_X() et SCR_Y(). Elle vérifie également si le bob en question a ou non "changé” de case à l’intérieur du tableau. Ce test s'effectue de manière fort simple : si la nouvelle coordonnée écran (après addition, donc) est strictement divisible par 16, c'est que le passage d’une case à l’autre est terminé, on peut donc tester si le bob change de direction ou non. Dans la pratique, cela se traduit par “tant que l’on est pas complètement sur une case du tableau, on ne peut pas changer de direction”. Ceci évite qu'un bob ne se trouve à cheval sur deux cas, ou pire, sur un mur.
On en arrive maintenant à TEST_DIR, qui se charge de vérifier si la direction demandée est possible ou non. Pour ce faire, il faut savoir sur quelle case le bob se trouve et quelles sont celles qui l’entourent. Prenons un exemple tout bête (suivez avec le premier croquis sous les yeux) : le Pac-Rev se trouve sur une case numéro 2. Cette case l'empêche d’aller
Igiheih nnmm
I'm II
ETAPE1: Rem
On essaye d'abord de changer d'axe
If VAR1(M)=1 : Rem
Si va en en haut
If H>0 : Rem
on se rapproche sur l'axe horizontal
Si on peut aller à gauche et qu'on n'en vient pas
If(SENS and 4) and(VAR2(M) and 4)=0
BDIR(M)=4 : Rem
Alors on y va
VAR2 (M) =VAR2 (M) or 8 : Rem
on se souvient qu'on vient de droite
VAR3(M) =1 : Rem et on marque qu'on a changé 1 fois d'axe
Pop Proc
Else If(SENS and 8) and(VAR2(M) and 8)=0
BDIR(M)=8 : VAR2(M)=VAR2(M) or 4 : VAR3(M)=1
: Pop Proc
Else If SENS and 2
BDIR(M)=2 : VAR2(M)=VAR2(M) or 1 : Pop Proc
Else BDIR(M)=1 : Pop Proc : End If
End If
End If
Else If(SENS and 8) and(VAR2(M) and 8)=0
BDIR(M)=8 : VAR2 (M) =VAR2 (M) or 4 : VAP.3 (M)-1
Pop Proc
Else If(SENS and 4) and(VAR2(M) and 4)=0
BDIR(M)=4 : VAR2(M)=VAR2(M) or 8 : VAR3(M)=1
: Pop Proc
Else If SENS and 2
BDIR(M)=2 : VAR2(M)=VAR2(M) or 1 : Pop Proc
Else BDIR(M)=1 : Pop Proc : End If
End If
End If
End If
End If
If VAR1(M)=2 : Rem
Ça marche pareil, mais pour le bas
If H>0
If(SENS and 4) and(VAR2(M) and 4)=0
BDIR(M)=4 : VAR2(M)=VAR2(M) or 8 : VAR3(M)=1
Pop Proc
Else If(SENS and 8) and(VAR2(M) and 8)=0
BDIR(M)=8 : VAR2(M)=VAR2(M) or 4 : VAR3(M)=1
: Pop Proc
Else If SENS and 2
BDIR(M)=2 : VAR2(M)=VAR2(M) or 1 : Pop Proc
Else BDIR(M)=1 : Pop Proc : End If
End If
End If
Else If(SENS and 8) and(VAR2(M) and 8)=0
BDIR(M)=8 : VAR2(M)=VAR2(M) or 4 : VAR3(M)=1
Pop Proc
Else If(SENS and 4) and(VAR2(M) and 4)=0
BDIR(M)=4 : VAR2(M)=VAR2(M) or 8 : VAR3(M)=1
: Pop Proc
Else If SENS and 2
BDIR(M)=2 : VAR2(M)=VAR2(M) or 1 : Pop Proc
Else BDIR(M)=1 : Pop Proc : End If
End If
End If
End If
End If
If VAR1(M)=4 : Rem
Idem aussi pour la gauche
If V>0
If(SENS and 1) and(VAR2(M) and 1)=0
BDIR(M)=1 : VAR2(M)=VAR2(M) or 2 : VAR3(M)=1 :
Pop Proc
Else If(SENS and 2) and(VAR2(M) and 2)=0
BDIR(M)=2 : VAR2(M)=VAR2(M) or 1 : VAR3(M)=1
: Pop Proc
Else If SENS and 8
BDIR(M)=8 : VAR2(M)=VAR2(M) or 4 : Pop Proc
Else BDIR(M)=4 : Pop Proc : End If
End If
End If
Else If (SENS and 2) and(VAR2(M) and 2)=0
BDIR(M)=2 : VAR2(M)=VAR2(M) or 1 : VAR3(M)=1 :
Pop Proc
Else If (SENS and 1) and(VAR2(M) and 1)=0
BDIR(M)=1 : VAR2(M)=VAR2(M) or 2 : VAR3(M)=1
: Pop Proc
Else If SENS and 8
BDIR(M)=8 : VAR2(M)=VAR2(M) or 4 : Pop Proc
Else BDIR(M)=4 : Pop Proc : End If
End If
End If
End If
End If
If VAR1(M)=8 : Rem
Ditto pour la droite
If V>0
If(SENS and 1) and(VAR2(M) and 1)=0
BDIR(M)=1 : VAR2(M)=VAR2(M) or 2 : VAR3(M)=1 :
Pop Proc
Else If(SENS and 2) and(VAR2(M) and 2)=0
BDIR(M)=2 : VAR2(M)=VAR2(M) or 1 : VAR3(M)=1
Pop Proc
Else If SENS and 4
BDIR(M)=4 : VAR2(M)=VAR2(M) or 8 : Pop Proc
Else BDIR(M)=8 : Pop Proc : End If
End If
End If
Else If(SENS and 2) and(VAR2(M) and 2)=0
BDIR(M)=2 : VAR2(M)=VAR2(M) or 1 : VAR3(M)=1 :
Pop Proc
Else If(SENS and 1) and(VAR2(M) and 1)=0
fèm®
vers le haut. Si le joueur désire aller à gauche, il faut que la case à gauche de celle sur laquelle il se trouve ne comporte pas de mur à droite, donc qu’elle porte un numéro différent de 3, 5, 6, 7, 8 et 9. De même, s’il désire aller en bas, il ne faut pas que la case de dessous comporte de mur en haut, donc qu’elle porte un numéro différent de 2, 4, 6, 7, 8, 9 et 10. Compris ?
SI JE T’ATTRAPE, JE TE MORDS
J'avais gardé le plus difficile pour la fin : la procédure DEPLACE, MONSTRE. Il s’agit ici de pourchasser le Pac-Rev tout en évitant de rester coincé dans un cul-de-sac. Si le premier but est facile à atteindre, le second l’est beaucoup moins (j'en sais quelque chose). En fait, trois cas sont à dissocier :
- en début de jeu ou après s’être fait manger, le monstre sort de sa “maison’’. C’est le cas le plus simple, il ne prend que 6 lignes de programme (suivez sur le listing, quoi I) ;
- en cours de jeu, la direction à prendre est indiquée par deux variables (H et V pour ne pas les nommer) qui sont respectivement le résultat des soustractions des coordonnées X et Y des monstres de celles du Pac-Rev. Ainsi, si H est négatif, le monstre se trouve à gauche du Pac-Rev, il doit donc aller vers la droite pour le rattraper.
Une fois cette direction théorique déterminée, deux possibilités sont à envisager : soit il est possible d’y aller, auquel cas on y va gaiement, soit le chemin est bloqué, et on rentre dans le troisième cas possible ;
- arrivé ici, il faut d’abord se souvenir de l’endroit où on désirait se rendre. C’est le rôle de la variable VAR10. Qui mémorise la direction visée.
Ensuite, et pour éviter que le monstre ne reste bloqué quelque part, il faut se souvenir quel chemin il a déjà emprunté.
Plus concrètement: s’il allait vers la gauche, il faut éviter qu’il ne retourne vers la droite, sinon il rentrerait dans une boucle sans fin, puisque revenu au second cas, la variable H lui dirait de retourner illico vers la gauche en direction du Pac-Rev. La variable VAR2Q se charge de cette mémorisation.
Enfin, on considère que le monstre peut reprendre sa course vers le Pac-Rev lorsqu'il a changé deux fois d’axe. Ainsi, s’il était bloqué à gauche (donc sur l’axe horizontal), on attend qu’il soit d’abord monté ou descendu (donc sur l'axe vertical) puis reparti à gauche (à nouveau sur l’axe horizontal) pour revenir dans le second cas, celui du déplacement “libre”. C’est la variable VAR30 qui se charge de comptabiliser le nombre de changements d'axe.
Une dernière remarque en passant : lorsque le Pac- Rev a mangé une super-pastille, les monstres n’essaient plus de le rattraper mais au contraire le fuient. Cet effet est obtenu en testant le flag "SUPER” (positionné plus haut, remember) : s’il est mis, les valeurs de H et de V sont inversées (changées de signe). Ainsi, tout se passe exactement de la même manière, mais à l’envers.
??G3D ??
Imigrsüüüü m
BDIR(M)=1 : VAR2 (M) =VAR2 (M) or 2 : VAR3(M)=1 :
Pop Proc
Else If SENS and 4
3DIR(M)=4 : VAR2(M)=VAR2(M) or 8 : Pop Proc
Else BDIR(M)=8 : Pop Proc : End If
End If
End If
End If
End If
ETAPE2: Rem 2ème étape -> on essaye à nouveau de changer d’axe
If SENS and VAR1 (M) : Rem on a trouvé un chemin dans la bonne direction
BDIR(M)=VAR1 (M) : VAR1(M)=0 : VAR2(M)=0 : VAR3IM)
=0 : Pop Proc
End If
If VAR1(M)=1 or VAR1(M)=2 : Rem
si on est sur l’axe vertical
If H>0
If(SENS and 4) : Rem
Ça va à gauche ?
If(VAR2(M) and 4)=0
BDIR(M)=4 : VAR2(M)=VAR2(M) or 8 : VAR3(M)=2 :
Pop Proc : End If
Else If(SENS and 8)
If(VAR2(M) and 81=0 : Rem
Et à droite ?
BDIR(M)=8 : VAR2(M)=VAR2(M) or 4 : VAR3(M)=2
Pop Proc : End If
End If
End If
Else If(SENS and 8)
If(VAR2(M) and 81=0
BDIR(M)=8 : VAR2(M)=VAR2(M) or 4 : VAR3(M)=2 :
Pop Proc : End If
Else If(SENS and 4)
If(VAR2(M) and 4)=0
BDIR (M) =4 : VAR2 (M) =VAR2 (M) or 8 : VAR3(M)=2
Pop Proc : End If
End If
End If
End If
End If
If VAR1 (M) =4 or VAR1(M)=8 : Rem
Si on est sur l’axe horizontal
If V>0 : Rem
Tout marche pareil ! !
If(SENS and 1) and(VAR2(M) and 1)=0
BDIR(M) =1 : VAR2 (M) =VAR2 (M) or 2 : VAR3(M)=2 :
Pop Froc
Else If(SENS and 2) and(VAR2(M) and 2)=0
BDIR(M)=2 : VAR2(M)=VAR2(M) or 1 : VAR3(M)=2 :
Pop Proc : End If
End If
Else If(SENS and 2) and(VAR2(M) and 2)=0
BDIR(M)=2 : VAR2(M)=VAR2(M) or 1 : VAR3(M)=2 :
Pop Proc
Else If(SENS and 1) and(VAR2(M) and 11=0
BDIR(M)=1 : VAR2(M)=VAR2(M) or 2 : VAR3(M)=2 :
Pcp Proc : End If
End If
End If
End If
ETAPE3: Rem
Troisième étape -> On est bon !
BDIR(M)=VAR1(M) : VAR1(M)=0 : VAR2 (M) =0 : VAR3 (M)
=0
End If
End Proc
Procédure MOVE IT(QUI]
' Cette procédure actualise les coordonnées de chaque sprite
TEST DIR[QUI) : SENS=Param
If BDIR(QUI)=1 and(SENS and 1)
Add SCR Y(QUI),-VITESSE(QUI)
Else If BDIR(QUI)=2 and(SENS and 2)
Add SCR Y(QUI),VITESSE(QUI)
Else If BDIR (QUI) =4 arid(SEN5 and 4)
Add SCR X(QUI),-VITESSE(QUI)
Else If BDIR(QUI)=8 and(SENS and 8)
Add SCR X(QUI) , VITESSE(QUI)
End II
End If
End II
End If
' Là, on teste si on a change de case dans le tableau
TEST_X=(SCR_X(QUI)-8) and 15 : TEST_Y=(SCR_Y(QUI)-
8) and 15
' Si oui....
If TEST Y=0
If BDIR(QUI)=1 and(SENS and 1)
If TAB Y(QUI)>1 : Dec TAB Y(QUI)
Else. TAB Y(QUI)=15 : SCR Y(QUI)=8+(16*(TAB Y(QUI)
- 1)) : End If
Else If BDIR(QUI)=2 andISENS and 2)
If TAB Y(QUI) 15 : Inc TAB Y(QUI)
Else TAB_Y(QUI)=1 : SCR_Y(QUI)=8+(16*(TAB_Y(QUI)
- 1)) : End If
End If
End If
End If
If TEST X=0
If BDIR(QUI)=4 and(SENS and 4)
If TAB X(QUI)>1 : Dec TAB X(QUI)
CONCLUSION
Ihheih hhhh
Imighi
Voilà, c'est tout pour notre Pac-Rev du mois. Il y a évidemment bon nombre d’améliorations à y apporter, par exemple plus de monstres, des super-pastilles “dédiées” à un monstre particulier (le Pac-Rev ne pourrait manger que celui-là), des tableaux supplémentaires, etc. Tout cela est laissé à votre entière perspicacité.
Stéphane “Septh (7)” Schreiber et Yves “Huit (8)” Huitric. PassWord 7887.
A = tableau
El e n ? Tu n ?
ŒJ ? S ? ? ? EU
Else TAB_X(QÜI)=14 : SCR_X(QUI)=8+ 16*(TAB_X QÜI)-1)) : End If Else If BDIR(QUI)=8 and(SENS and 8)
If TAB_X(QUI) 14 : Inc TAB_X(QUI)
Else TAB_X(QUI)=1 : SCR_X(QUI)=8+(16*(TAB_X(QUI)-1)) : End If End If End If End If
End Proc[TEST_X=0 and TEST_Y=0]
Procédure TEST_DIR[OU]
' Vérifie les 4 directions possibles ' Commence par tester les pièces alentour
A1=TABLEAU (TAB_Y (OU) +0,TAB_X (OU) +0) and $ 3F : Rem
Pièce courante Pièce supérieure Pièce inférieure Pièce de gauche Pièce de droite
A2=ÎABLEAU (TAB_Y (00) -1,TAB_X (00)+0) and ?3F : Rem
A3=TABLEAU(TAB_Y(OU)+1,TABJÎ(OU)+0) and $ 3F : Rem
A4=TABLEAU(TAB_Y(OU)+0, TAB_X(OU)-1) and $ 3F : Rem
A5=TABLEAÜ(TAB_Y(OU)+0,TAB_X(OU)+1Î and 53F : Rem ¦
' Alors, on peut y aller ?
S=0
If(Al >2 and Al >6 and Al >9 and A2 >4 and A2 >7 and A2 >8) Then Add S,1
If(Al >4 and Al >7 and Al >8 and A3 >2 and A3 >6 and A3 >9 and A3 >10) Then Add S, 2
If(Al >3 and Al >6 and Al >7 and A4 >5 and A4 >8 and A4 >9) Then Add S,4
IffAloS and Al >8 and Al >9 and A5 >3 and A5 >6 and A5 >7) Then Add S, 8
End Proc[S]
Procédure DESSINE_TABLEAÜ Restore TABLEAU1 For 1=1 To 15 : For J=1 To 14 Read A : TABLEAU(I,J)=A : Paste Icon 8+(16*(J-l)),8+(16*(1-1)),A and 53F If A and 540 Then Paste Bob 8+(16*(J-l)),8+(16*(1-1)),8 : Inc NB_PASTILLES If A and 580 Then Paste Bob 8+(16*(J-l)), 8+(16*(1-1)),9 : Inc NB_PASIILLES Next J : Next I
TABLEAU1:
Data 546,$ 42,542,542,542,541,542,542,$ 41,542,542,542,542,$ 49 Data 543,586,543,542,542,542,542,541,542,542,549,545,589,545 Data 543,543,$ 43,$ 46,542,542,$ 42,542,$ 42,542,$ 42,545,$ 45,$ 45 Data 543,$ 43,$ 43,$ 42,$ 42,$ 42, $ 42,$ 42,542,$ 42, $ 41, $ 42,545,$ 45 Data $ 43,543,$ 47,$ 46,$ 42,542,$ 49,545,$ 42,549,$ 41,$ 49,545,545 Data 541,$ 43,$ 41,$ 41,$ 46,$ 42,541,541,$ 41,$ 42,$ 44,548,$ 45,541 Data $ 43,$ 43,$ 45,$ 41,549,541,56,$ A,$ 9,541,$ 43,541,541,545 Data $ 43,543,$ 42,$ 42,549,541,57,$ 4,58,541,$ 47,549,$ 45,549 Data $ 43,$ 43,$ 42,$ 42,$ 41,541,$ 41,$ 41,$ 41,$ 44,544,$ 44,548,545 Data $ 43,542,$ 42,$ 42,$ 49,541,$ 46,$ 49,541,$ 43,$ 41,$ 41,541,$ 45 Data 541,546,$ 48,$ 45,$ 41, $ 41,$ 45,541,$ 44,$ 43, $ 46, $ 42,541,$ 43 Data 543,$ 44,544,$ 48,$ 45,$ 41,545,541,$ 43,541,$ 47,$ 44,$ 44,$ 49 Data $ 43,$ 44,$ 44,$ 41,545,$ 41,$ 45,541,546,541,$ 43,$ 41,$ 41,$ 45 Data $ 43,$ 87,$ 44,$ 48,$ 49,$ 41,$ 45,541,$ 41,$ 42,$ 46,$ 49,589,545 Data $ 47,$ 44,$ 44,$ 44,548,$ 41,$ 47,$ 44,543,$ 44,$ 44,$ 44,$ 44,548 End Proc
ATTENTION
¦ ¦ ¦
L'AMIGA NEWS-TECH PREND BIENTÔT SON ENVOL NE LE RATEZ PAS.
EN EFFET L'ANT N° 20 DE FÉVRIER 91
COMPORTERA 36 PAGES ET NON PLUS 20
DE PLUS, VOUS POURREZ VOUS PROCURER LES SOURCES ET EXÉCUTABLES DES PROGRAMMES SUR DISQUETTES, MAIS CE N'EST PAS TOUT...
GAGNEZ AUSSI UNE CARTE ACCÉLÉRATRICE
VOIR PAGE 27
BBE3B HBBB
INITIATION
AMAL LE LANGAGE DE L’ANIMATION
Le plus simple des jeux d’arcade est déjà constitué d’un grand nombre d’objets animés en même temps sur l’écran. Déplacer au 1 50° de seconde 20 personnages à la fois est une tâche ardue pour un basic, même compilé. AMOS se devait d’être un outil pour la création simple de jeux rapides. Il fallait donc trouver quelque chose ! AMAL est le résultat de longues soirées de cogitations et nuits de programmation. C'est certainement l’un des points fort d'AMOS. Aujourd’hui commence une série d’articles dans lesquels j'espère vous en faire découvrir la puissance.
AmAL c’est quoi ?
- L’abréviation de Amos Animation Langage,
- un véritable langage, comportant plus de 35 instructions, d’une syntaxe proche du basic,
- précompilé, volontairement simplifié pour en accélérer l'exécution et atteindre ainsi une vitesse proche du langage machine (et une compilation ultra-rapide !)
- exécuté en interruptions, indépendamment du programme principal : celui-ci se contente de regarder la position des personnages, et de gérer les collisions,
- un multi-compilateurs : l’on peut exécuter en même temps pas moins de 64 programmes AMAL. En comptant le programme AMOS lui-même, 65 programmes tournent dans votre AMIGA !
- un moyen de simplifier énormément la programmation d’animations complexes et répétitives,
- L'extension des instructions d'animations du STOS.
Enfin en lisant ce qui précède, vous comprenez certainement que je suis assez content du résultat. Qu’un programmeur me jette la première pierre !
PRINCIPES GENERAUX
Les exemples qui vont suivre doivent être tapés en mode direct. Vous devez charger une banque de sprites de la disquette DATA :
Load “AMOS_DATA:Sprites Octopus.Abk” Return>
Maintenant tapez la ligne suivante pour changer la palette de couleurs : Get Sprite Palette Return>
LE PREMIER PROGRAMME AMAL
Les programmes sont transmis au compilateur AMAL sous la forme de chaînes de caractères, par l’instruction :
AMAL Canal,"Chaîne”
* Canal est le numéro du canal d’animation. Nous en reparlerons plus loin.
* “Chaîne” est le programme d'animation lui-même.
Tapez l’exemple suivant (en mode direct, en ayant chargé la banque de sprite avant)
- Respectez SCRUPULEUSEMENT les majuscules et minuscules !
Sprite 1,160,100,1 Return>
Une pieuvre apparaît sur votre moniteur. C’est elle que nous allons faire bouger.
Amal 1,”Move 100,50,200” Return>
Rien ne se produit en apparence, mais votre chaîne vient d’être compilée et stockée en mémoire. Pour lancer le mouvement tapez :
Amal On Return>
La pieuvre glisse lentement en. Bas à droite. Notez que vous pouvez taper du texte au clavier, ou exécuter des instructions : la pieuvre continue à se mouvoir.
LA CHAINE AMAL
Le programme AMAL de l'exemple précédent était réduit à une seule instruction :
“Move 100,50,200”
H
Voici les principaux points à connaître :
- Le compilateur AMAL ne reconnaît que les MAJUSCULES, les CHIFFRES et les OPERATEURS dans la chaîne.
- Tous les autres caractères sont ignorés (minuscules, espaces, ponctuation, codes de contrôle...)
- Une instruction AMAL n'est constituée que de UNE ou DEUX lettres majuscules. L'instruction utilisée dans l’exemple était ”M”.
Notre petit programme peut s’écrire comme nous l'avons fait, mais aussi :
“M100,50,200" ou bien :
“Move le beau sprite sur le bel écran, 100 en x,50 en Y,200"
D’une manière générale, pour de longues chaînes, il vaut mieux éviter les extrêmes ! N’utiliser que les majuscules rendra le programme extrêmement difficile à comprendre plus tard.
UN PEU PLUS COMPLIQUE...
Nous allons améliorer un peu le mouvement de notre pieuvre. Tapez en mode direct :
Amal 1,”Anim 0,(1,2)(2,2)(3,2)(4,2); Move -100,-50,400” Return> Amal On Return>
La pieuvre retourne à sa position initiale en agitant les bras ! Le programme AMAL produit outre la coordonnée X et Y, le numéro de l’image à afficher. C'est en faisant varier ce numéro que l’on obtient l’animation des bras.
En avant-goût du mois prochain, voici la fonction de l’Instruction Move que nous utilisons beaucoup dans nos exemples.
M(ove) DX,DY,NombreDePas Move initialise un mouvement entre la position actuelle du canal (X et Y) et la position finale (X+DX.Y+DY). En fait, AMAL trace une droite entre les deux points. NombreDePas spécifie la vitesse du mouvement.
M 100,100,100 ... le sprite dessinera une ligne diagonale, 1 pixel
chaque 1 50° de seconde, en 2 secondes M 100,100,50 ... le sprite fera le même chemin en 1 seconde
M 100,100,1 ... le mouvement sera instantané.
DX et DY peuvent être nuls (pas de mouvement) ou négatifs (mouvements à gauche ou vers le haut).
LE CANAL D’ANIMATION
Nous appellerons dorénavant chaque programme AMAL un “canal d’animation”.
Le canal d’animation produit trois choses :
- Une coordonnée en X
- Une coordonnée en Y
- Un numéro d’image
AMOS permet d’exploiter au maximum les trois chiffres de chaque canal. Vous pouvez en effet choisir leur destination avec l’instruction CHANNEL.
2. 4.1. CHANNEL canal TO SPRITE num
C’est le mode que nous avons utilisé sans le savoir dans l’exemple. Les chiffres servent à déterminer la position d’un sprite hardware.
- canal est le numéro du canal d’animation (le même numéro que celui de l’instruction AMAL)
- num est le numéro du sprite qui sera animé.
Lorsque AMOS apparaît, il effectue automatiquement l'équivalent du programme suivant :
For N=0 To 63 Channel N To Sprite N Next
Chaque canal animera le sprite de même numéro. L’exemple a utilisé le sprite 1 et le canal 1. Les lignes suivantes ne donneront aucun résultat : Amal 2,"Move 100,100,100” Return>
Amal On Return>
Le canal numéro 2 est inltialisé. Les coordonnées sont produites, vers le sprite 2... qui n’existe pas ! Rien ne bougera à l’écran.
2. 4.2. CHANNEL canal TO BOB num
Certainement le plus intéressant. Cette instruction dirige la sortie du canal vers le bob de numéro num. Comme précédemment, il faut que le bob soit affiché pour voir un résultat.
W nnmm hbhp
Tapez les lignes suivantes (vous devez toujours voir la première pieuvre bouger sur votre écran I)
Bob 1,50,150,1 Return>
Tout d’abord on affiche un BOB. Notez le flash d’une des couleurs dû au curseur.
Flash Off Return>
...et ça ne flashe plus.
Channel 2 To Bob 1 Return>
Redirige la sortie du deuxième canal vers notre bob. Pour l’exemple nous n’avons pas pris des numéros identiques entre le canal et le bob, mais dans vos programmes, je vous conseille FORTEMENT de le faire. Amal 2,”L: Move 100,0,100; Move -100,0,100; Jump L” Return> Amal On Reîurn>
Démarre un nouveau programme dont nous verrons les instructions dans un prochain article. Vous avez maintenant DEUX canaux qui fonctionnent en même temps, un pour chaque pieuvre.
2. 4.3. CHANNEL canal TO SCREEN DISPLAY num
De plus en plus amusant. Les coordonnées du canal vont servir à calculer la position de l’écran numéro num (comme l’instruction SCREEN DISPLAY). Tapez les lignes suivantes :
Channel 3 To Screen Display 0 Return>
Amal 3,”L: Move 0,25,5; Move 0,-25,5; Jump L” Return>
Amal On Return>
Et voilà' notre troisième canal en fonction. Impressionnant non ? Notez que le BOB suit l'écran, et que le SPRITE reste indépendant. Un sprite hardware “survole” le terrain de jeu. Cette faculté peut être extrêmement utile dans certains jeux (par exemple le vaisseau du joueur dans un “Defender”).
2. 4.4. CHANNEL canal TO SCREEN OFFSET um
Idéal pour faire des scrollings. Les coordonnées produites par le canal d’animation ont le même effet que l’instruction SCREEN OFFSET.
Les lignes suivantes vont rendre l’affichage encore plus insupportable : Channel 4 To Screen Offset 0 Return>
Amal 4,”L: Move 320,0,20; Move -320,0,20; Jump L” Return> Amal On Return>
Excusez-moi, je vais chercher un cachet d’aspirine pour observer le résultat ! Nous en sommes à 4 canaux simultanés.
2. 4.5. CHANNEL canal TO RAINBOW num
AMOS peut facilement produire des dégradés de couleurs avec le cop- per, On peut les animer avec un canal d’animation.
Dans ce cas ;
- La coordonnée en X est affectée à la BASE du “rainbow”
- La coordonnée en Y est la ligne d’écran où commencera l’effet.
- Le numéro d’image change la FIAUTEUR de l’arc en ciel.
Et hop, ajoutons encore un canal à notre exemple :
Set RainbowO.0,64,"(1,1,15)(1,-1,15)",””,”” Return>
Rainbow 0,56,1,255 Return>
Et apparaissent les couleurs !
Channel 5 To Rainbow 0 Return>
Amal 5,”L: For R0=0 To 63; Let X=R0; Next R0; Jump L” Return> Amal On
Et les couleurs défilent. Remarquez au passage que l’on peut faire des boucles For Next en AMAL. Nous les détaillerons plus tard.
Nous avons terminé l’exploration des instructions CHANNEL. Il ne reste plus qu'une chose à voir avant de terminer, une variante de l’instruction AMAL qui ouvre de nouvelles perspectives :
2. 4.5. AMAL canal,"Chaîne” TO adresse
En spécifiant une adresse mémoire après la chaîne de caractères, l’on indique à AMAL un endroit où stocker les coordonnées.
Cette adresse doit être PAIRE, et dans un espace mémoire réservé à cet effet. Le mieux est de réserver une petite banque de mémoire : Réserve As Work 10,16, puis Amal canal,"Chaîne” To Start(10)
ATTENTION : n’utilisez pas une chaîne de caractère comme espace de travail : les addresses les chaînes sont souvent déplacées en mémoire : l’adresse fournie à l’instruction AMAL peut être changée au moment même où le canal d’animation stocke les coordonnées. Le crash total de la machine serait alors fort probable !
Vous pouvez ensuite récupérer les coordonnées du canal l’animation avec DEEK. Dans notre exemple :
Start(10): Flags: Bit 0 indique que X est modifié
Bit 1 “ “ Y “
Bit 2 “ “ l’image est modifiée
Start(10)+2: X
Start(10)+4: Y
Start(10)+6: Image
Je pense que vous avez assez admiré les exemples que nous avons tapés jusqu’à maintenant. Appuyez sur ESC pour revenir sous l'éditeur et entrez le programme suivant :
' Définition du programme AMAL. Remarquez-le ' titre, entièrement en caractères ignorés par ' le compilateur AMAL.
' On peut facilement donner un semblant de structuration ' au listing en utilisant A$ =A$ +"...
A$ =A$ +" "
A$ =A$ +" t demo amal to adresse "
a$ =a$ +" mtmummmmmr
A$ =A$ +"Loop: Move 39,0,50;"
A$ =A$ +" Move 0,24,50;"
A$ =A$ +" Move 39,0,50;"
A$ =A$ +" Move 0,-24,50;"
A$ =A$ +" Jump Loop"
' Réservation d'une petite banque de mémoire
Réserve As Work 10,16
' Initialisation des variables
AD_X=Start(10)+2 AD_Y=Start(10)+4 Doke AD_X,0 Doke AD_Y,0
' Préparation de l'écran
Curs Off Scroll Off
* Démarrage du programme
Amal 0,A$ To Start(lO)
Amal On
' Boucle d'affichage: une étoile aux positions X et Y!
Repeat
X=Deek(AD_X) : Y=Deek(AD_Y)
Locate X,Y : Print Wait Vbl
Locate X,Y : Print "
Until Inkey$ >""
A
' Arrêt du canal Amal Off
Quelques remarques :
- Le programme précédent est bien entendu complètement nul. Le résultat est totalement désastreux (c’est un émulateur ZX81 pour ceux qui ont. Connu!), mais c’est un excellent exemple de récupération des coordonnées produites par un canal d’animation.
- Il faut ABSOLUMENT arrêter le canal à la fin du programme: les banques de mémoire sont effacées AVANT les canaux d’animation : avec un peu de malchance, les coordonnées seront stockées en mémoire ENTRE l’effacement de la banque et l’arrêt du canal, d’où crash possible. Cela vient justement de m’arriver, Hum,,.
Voilà c’est tout pour-aujourd’hui. Le mois prochain nous verrons en détail les principales instructions d’AMAL. Vous pouvez en attendant explorer les exemples se trouvant sur la disquette Langage de l'AMOS et concernant AMAL: dossier Manual ChapterJ 4 ...
D'ici là, bon AMOS et bon AMAL!
François LIONET
Chers lecteurs et lectrices, bonjour. Ce mois-ci je vous propose de réaliser un pré-processeur d’objets pour le programme d'animation en filalre “Anim" que nous avons étudié ensemble il y a deux mois. Ce pré-processeur va nous décharger de la fastidieuse opération de création d’objets puisqu’il va générer les fichiers de points et de lignes à partir de quelques données de base. Pour étayer mon propos je vous propose un exemple de programme qui va générer un tore.
|nHcaa bhhb
C UN CONCOURS
Avant d'étudier cet exemple de pré-processeur, je vais effectuer un bref rappel sur la structure des fichiers de points et de lignes qui composent notre objet.
Le fichier de points (point.dat) contient la liste des coordonnées X,Y,Z de chaque point 3-D de l’objet. Sa structure est la suivante :
1re Ligne N> (nombre de points)
2e Ligne X1 > Y1 > Z1 > (coordonnées du 1er point)
3e Ligne X2> Y2> Z2> (coordonnées du 2e point)
N+1re Ligne Xn> Yn> Zn> (coordonnées du ne point)
Le fichier de lignes (ligne.dat) contient quant à lui les numéros des points origines et extrémités de chaque segment composant l’objet. Sa structure est la suivante :
1re Ligne M> (nombre de lignes)
2e Ligne Origine1> Extrèmité1 :> (1er segment)
3e Ligne Origine2> Extrémité2> (2e segment)
M+1re Ligne OrigineM> ExtrémitéM> (Même segment)
Ce petit rappel effectué, nous allons passer aux choses sérieuses. L’idée de départ consiste à générer un objet complexe à partir d'un nombre restreint de données à l'origine. L’exemple que nous allons étudier est celui d’un tore. Un tore est défini mathématiquement par 3 nombres, R1 représente le petit rayon du tore, R2 représente le grand rayon (ou rayon central) du tore et n le nombre de points également répartis sur le cercle central et sur le petit cercle (Fig 1).
La première étape de la programmation va consister à générer le fichier de points. Il nous faut calculer pour commencer le nombre de points de l'objet. C’est très simple puisque n représente à la fois le nombre de points répartis sur le petit cercle et le grand cercle, Le nombre de points total de l’objet est dont n*n.
Nous allons maintenant calculer les coordonneés X, Y, Z de chaque point de l'objet. Le grand cercle du tore a pour équation paramétrique:
X2 = R2*cos(alpha)
Y2 = R2*sin(alpha)
Z2 = 0
Ces coordonnées X2,Y2,Z2 représentent également les coordonnées des centres des petits cercles de notre tore. Dans le cas où alpha vaut zéro les équations d’un point appartenant au petit cercle sont :
x = R1*cos(beta)+R2
y = 0
z = R1*sin(beta)
Lorsque alpha varie décrivant notre tore on calcule facilement les coordonnées d’un point quelconque de ce tore en multipliant les coordonnées (x,y,z) ramenées en alpha = 0 par une matrice de rotation d’axe z et d’angle alpha. Ce qui nous donne les équations suivantes pour les coordonnées d’un point (X’.Y’.Z’) d’un point du tore.
X’ = x*cos(alpha)
Y’ = x'sin(alpha)
Z' = z
Nous avons là tous les éléments nécessaires à la génération du fichier de points. Ce problème étant réglé, nous allons nous pencher sur la manière dont nous allons relier ces points par des segments et ainsi créer notre objet.' Il s'agit de la création du fichier ligne.dat.
Pour chaque segment de notre tore il faut déterminer les numéros des points origines et extrémités le caractérisant. Le maillage du tore s’effectue en deux étapes. Chaque petit cercle du tore est défini par n points, ces points sont connectés entre eux par n segments représentés par des couples de points. Par exemple pour le premier petit cercle ces couples sont (j,j+1) j variant de 0 à n-2, le couple (n-1,0) clôturant le cercle. Pour un cercle quelconque i les couples sont (i*n+j,i*n+j+1), j variant toujours de 0 à n-2. Le segment de clôture est dans ce cas (i*n+n-1,i*n). L’algorithme de création des segments associés aux petits cercles se détermine à partir des constatations ci-dessus.
Pour( i variant de 0 à n-2 par incrément de 1) pour ( j variant de 0 à n-2 par incrément de 1) origine = i*n+j
extrémité = i*n+j+1 écrire(origine, extrémité) finpour origine = i*n+j extrémité = i*n écrire(origine,extrémité) finpour
Nous avons donc tous les segments associés au petits cercles, il s’agit donc d’en faire de même pour les segments liés aux grands cercles. Pour le premier grand cercle un segment est défini par un couple (i‘n,i*n+n) i variant de 0 à n-2. Le segment de clôture du cercle associé est (n*(n-1),0). Pour un grand cercle quelconque ce couple devient (i*n+j,i*n+j+n) avec en clôture (n*(n-1)+j,j). L’algorithme de calcul de ces différents couples est donc :
pour ( j variant de 0 à n-1 par incrément de 1) pour ( i variant de 0 à n-2 par incrément de 1) origine = i*n+j
extrémité = i*n+j+n écrire(origine,extrémité) finpour
origine = n*(n-1)+j extrémité = j écrire(origine,extrémité) finpour
Dernier point à déterminer le nombre de segments liés à un objet. Nous avons n*n segments liés aux petits cercles et autant pour le grand cercle. Le nombre de segments total est donc 2*n*n.
A partir de toutes ces explications il est très facile de réaliser un petit programme en C qui génère ce tore. Les fichiers tpoint.dat et tigne.dat pouvant être ensuite relus par le programme ANIM afin d'être visualisés à l'écran. Une petite remarque toutefois ; n'oubliez pas de redimension- ner les tableaux de points et de lignes du programme ANIM en fonction des objets que vous allez manipuler,
Ce petit programme m'a donné une idée. Afin que tous les lecteurs puissent participer à cette série d’articles, je vous propose un petit concours ayant pour objet la réalisation d’un pré-processeur d’objet original. Pour participer à ce concours il vous faudra envoyer à l’adresse ci-dessous un programme en C générant un objet de votre choix à partir de quelques paramètres (le tore réalisé dans cet article en est un exemple ). Pour participer à ce concours vous devez respecter les impératifs suivants :
1 - La taille maximum du programme est fixée à 5 Kilo-octets
2 - Vous devez me faire parvenir sur disquette non seulement le source du programme mais aussi un exécutable afin que je puisse le tester facilement.
3 - Vous indiquerez également sur l'étiquette de la disquette vos nom et adresse (lisiblement) pour éviter tous risques de pertes de vos coordonnées ainsi que le type de compilateur C utilisé et le numéro de version associé (ex. : Lattice V 5.04 ou Aztec V 5.0c).
4 - Cette disquette devra parvenir à la rédaction de Commodore Revue avant le 31 décembre 1990 cachet de la poste faisant foi, à l’adresse suivante :
COMMODORE REVUE PASCAL AMIABLE CONCOURS 3D EN C 1 bis, rue de Paradis, 75010 Paris
Le (ou les) valnqueur(s) de ce concours verront (et c’est la moindre des choses) leur programme publié dans Commodore Revue et se verront octroyer un an d'abonnement gratuit à Commodore Revue. De mon côté je vais essayé de voir ce que je peux faire, je vous en dirai plus le mois prochain. En attendant je vous souhaite bonne chance et faites bien travailler vos chers compilateurs.
HDV Gluten... (cf. Gotlib) est difficilement paramétrable...
delta = 2.0*PI n; * CALCUL DU PAS DE ROTATION *
fprintf(fp,"%d n",n*n); * NOMBRE DE POINTS DE L'OBJET *
* CALCUL DES COORDONNEES DES DIFFERENTS POINTS *
for(i=0;i n;i++)
1
alpha = i*delta; for(j = 0;j n;j++)
(
beta = j*delta; x = R2+Rl*cos(beta); fprintf(fp,"%f if if n",cos(alpha)*x,sin(alpha)*x,Rl*sin(beta)); )
1
fclose(fp);
* OUVERTURE DU FICHIER DE LIGNES *
if(!(fp = fopen("tligne.dat","w"))) exit();
fprintf(fp,"%d n",n*n*2); * NOMBRE DE LIGNES DE L'OBJET *
* CALCUL DE LA PREMIERE SERIE DE LIGNES (PETITS CERCLES) *
for(i=0;i n;i++)
(
for(j = 0;j n-l;j++)
fprintf(fp,"%d %d n",i*n+j,i*n+j+l); fprintf(fp,"%d %d n",i*n+j,i*n);
)
* CALCUL DE LA DEUXIEME SERIE DE LIGNES (GRANDS CERCLES) *
for(j=0;j n;j++) f
for(i = 0;i n-l;i++)
fprintf(fp,"%d %d n",i*n+j,i*n+j+n); fprintf(fp,"%d %d n",n*(n-1) +j, j) ;
}
fclose(fp);
* *
* *
* Préprocesseur générant des objets filaires pour ANIM * * *
* Cet exemple génère un Tore *
* *
* P. AMIABLE *
* *
* *
include stdio.h> finclude math.h>
main()
i
FILE *fp, ‘fopen ();
float R2,RI,alpha,beta,delta,x;
int n,i,j;
* SAISIE DES DONNEES n,R2,Rl PERMETTANT LA DESCRIPTION DU TORE *
printf("Nombre de rotation sur le tore : "); scanf("%d",Sn) ;
printf("Valeur du rayon du grand cercle : "); scanf("% f",SR2);
printf("Valeur du rayon du petit cercle : ") ; scanf("%f",SRI);
DBE3B OBBB
APPLICATION
UN SQUELETTE DE MACRO-RECORDER
C'est chose courante sur Mac, sur PC et même sur ST, mais encore bien rare sur ¦Amiga. Les “Macro-Recorders” sont ces petits programmes qui permettent d’enregistrer les mouvements de la souris et les frappes au clavier pour les rejouer ensuite à l’infini.
Il est vrai que sur une machine multi-tâches, qui plus est équipée d’Arexx, le macro-recorder perd quasiment toute son utilité. Mais imaginez quand même votre pointeur de souris se balladant tout seul sur l'écran, allant comme par magie double-cliquer sur une icône de disque puis sur celle de votre programme préféré, pour ensuite sélectionner dans ses menus et requesters les fonctions et options que vous aimez. Tout est alors prêt comme vous l’aimez, vous n’avez plus qu’à commencer à travailler...
C’est donc pour étudier ce phénomène d'un peu plus près (NDLR : et aussi pour combler une défection d’Etienne Mouratila et de son ? @! De moniteur de disquettes...) que nous allons voir maintenant comment cela est possible.
INPUT.DEVICE
Tout se joue depuis un device bien particulier, nommé fort à propos “input.device". C’est lui qui se charge de collecter les différents événements en provenance des périphériques d'entrée connectés à l’Amiga. Il collecte les informations dont il a besoin depuis le keyboard.device (pour le clavier), le gameport.device (pour la souris et les joysticks) et le timer.device (pour la durée de répétition des touches) et les dissémine dans le système, en particulier vers la console.device et Intuition. Ce sont d'ailleurs ces deux derniers points qui nous intéressent plus particulièrement, puisque notre tâche (sans jeu de mots !) Consistera à envoyer nos propres informations à l’input.device, qui les redistribuera au console.device et à Intuition. En d’autres termes, il nous suffira de lui dire un truc du genre “hé, coco, signale à qui tu veux - mais surtout à Intuition - que la souris a bougé de tant de pixels et qu’on a appuyé sur le bouton droit" pour que notre brave input.device s’exécute, sans chercher à savoir si cela est vrai ou non. La conséquence sera bien évidemment celle attendue : le pointeur de la souris se déplacera “tout seul” à l’écran, et la barre de menu sera activée.
COMMENT CA MARCHE ?
Concrètement, il faut savoir que l’input.device est un device Amiga tout- à-fait standard. Il s’ouvre donc à l'aide de la fonction OpenDevice, en ayant au préalable pris soin de créer un message-port qui nous servira à communiquer avec lui (je précise dès maintenant que le but de cet article n’est pas de faire un cours complet sur les devices et leur utilisation ; reportez-vous pour cela à la littérature adéquate, et plus particulièrement à l’Amiga ROM Kernal Manual, Libraires & Devices. Pour les curieux, signalons que l'input.device est automatiquement ouvert par le console.device au moment de la ré-initialisation du système. Enfin, comme tout device, l’input.device fonctionne au moyen de commandes qui lui sont fournies dans le champ io_Command de sa structure lOStdReq associée :
Commandes de l’input.device
Nom
Valeur
Signification
IND.ADDHANDLER
9
Ajoute un handler personnel'à la liste des handlers
IND_REMHANDLER
10
Enlève un handler de la liste des handlers
INDJVRITEVENT
11
Envoie un flux d’événement à tous les "demandeurs”
1ND_SETTHRESH
12
Règle le temps avant qu’une touche ne se répète
IND_SETPERIOD
13
Règle la vitesse de répétition des touches
IND SETMPORT
14
Définit le port de la souris (1 ou 2)
IND.SETMTYPE
15
Définit le type de périphérique
le port souris.
Connecté sur
IND.SETMTRIG .
16
Définit les conditions que doit remplir la souris avant qu’un événement souris ne soit signalé
(je vous rassure, une seule de ces commandes nous sera utile, il s’agit de IND_WRITEEVENT). Pour ceux qui veulent en savoir plus, un “hand- ler” est une routine appelée chaque fois qu’une liste d'événements va être passée aux “demandeurs” et qui peut modifier le contenu de ces événements (par exemple, pour inverser l'effet des boutons gauche et droit), il peut avoir plusieurs handlers définis, c'est pourquoi ils sont appelés par ordre de priorité. Intution a une priorité de 50, le console.device de 0. Ce n’est toutefois pas ce qui nous intéresse ici.
La commande IND_WRITEVENT utilise également une structure InputEvent, dont plusieurs champs vont nous être utiles :
Structure InputEvent
Signification
Offset
4 (byte) 6 (word)
Nom
ie_Class
ie_Code
nature de l’événement (clavier, souris, etc.) touche du clavier ou bouton de la souris concerné
Indique les touches spéciales actives au moment de l'événement (Alt gauche et droit, Ctrl, etc.)
ie_Qualifier 8 (word)
Déplacement horizontal de la souris Déplacement vertical de la souris
10 (word) 12 (word)
ie_X
ie_Y
Pour résumer la manœuvre :
- création d'une message-port avec port%=CreatePort(0,0) ;
- création d'une structure InputEvent (longueur : &H16 octets) avec event%=AllocMem(&H16,&H 1 ) ;
- création d’une structure lOStdReq avec io%=CreateExtlO(Port, &H30) ;
- on relit les deux ensembles par LONG io%+&H28)=event% ;
- ouverture de l'input.device avec OpenDevice(V:device_name$ , 0,io%,0) ;
- remplissage des structures InputEvent et lOStdReq avec les valeurs appropriées (voir ci-dessous) ;
- envoi de l’événement factice avec DolO(io%) ;
- fermeture “en sens inverse” de tout ce qui a été ouvert ou alloué.
Avant que de vous laisser cogiter sur le programme, voyons de plus près quels événements on peut ainsi créer. Ils se divisent en deux catégories : les événements clavier et les événements souris. C’est la valeur du champ ie_Class qui décide de tout ça :
I MicroPunch >
$
Evénements clavier et souris
CONCEPTION FABRICATION
DISTRIBUTION ASSISTANCE
ie_Class Valeur Effet
UES AhlaAtca
IEC_NULL IEC RAWKEY
IEC_RAWMOUSE
IEC_GADGETDOWN
IEC_GADGETUP
IEC_CLOSEWINDOW
IEC_SIZEWINDOW
IEC_DISKREMOVED
IEC DISKINSERTED
COUS VWCH
éçof
seulement.
0 Aucun !
1 Evénement clavier ; ie_Code contient le code SCAN de la touche (bit 7=0 -> touche appuyée, relâchée sinon)
2 Evénement souris ; ie_Code contient le bouton concerné (&H68=bouton gauche, &H69=bouton droit). Si en plus ie_Qualifier contient la
valeur &H8000, alors ie_X contient le déplacement en X et ie_Y le déplacement en Y
7 Gadget appuyé
8 Gadget relâché
11 Fenêtre fermée
12 Fenêtre changée de taille
15 Disque enlevé d’un lecteur
16 Disque Introduit dans un lecteur
Ce sont là les plus importants dans le cadre d’un macro-recorder. Notez au passage que ces événements ne se contentent pas seulement de porter les mêmes noms que certains flags IDCMP, ils remplissent également les champs ie_Code et ie_Qualifier de la même manière que ces derniers (reportez-vous à la littérature sur Intuition pour en savoir plus).
LE PROGRAMME DU MOIS
Ce programme est volontairement assez court. L'honnêté m’oblige à préciser que c’est la “traduction” parfaite en GfA-Basic du programme d’exemple page 699 du “RKM Libraries & Devices”. Vous remarquerez que le GfA possède toutes les fonctions nécessaires en standard (CreatePortO, CreateExtlO(), DeletePort(), etc.) sauf DeleteExtlO(). Pourquoi ? Cela restera un mystère pour tout le monde. Du coup, on se la tape à la main, ça rajoute 10 lignes de programme, mais tant pis. Regardez bien comment le fonctionnement général, cela vous donnera peut-être des idées...
Stéphane Schreiber
AKR 79,J
Input.Device.Demo
input_device$ =”input,device”+CHR$ (0)
port%=CreatePort(0,0) ! Création du message-port IF port%
ev%=AllocMem(&H16,&H1) ! Création de la structure InputEvent IF ev%
io%=CreateExtlO(port%,&H30) ! Création de la structure lOStdReq IF io%
IF NOT OpenDevice(V:input_device$ ,0,io%,0) I Ouverture du device
FOR 11 &=0 TO 3 FOR I2&=0 TO 7 FOR I3&=0 TO 19
LONG(ev%)=0 ! Pas d’autre événement après nous
DIGITALISEUR SONORE "DIGICOMPACT” 320F
Qualité exceptionnelle. Restitution du son remarquable. Petite merveille d’intégration. Essayez le ! Vous l’adopterez sûrement Logiciels inclus.
EXTENSION MEMOIRE 512K (sans horloge) 450F
Etend l’Amiga 500 à 1 Méga. Montage facile et sans soudures.
EXTENSION MEMOIRE 2 MEGAS (avec horloge) 2190F
Etend l’Amiga 500 à 2,5 Megan. Montage facile et sans soudures.
CARTE COMPATIBLE PC AT 286 - 8 MHZ 2490E
Pour A500 et A2000. Enfin, un vrai compatible AT dans votre Amiga.
Se monte directement sur le support du 68000. Installation sans soudures.
VARIATEUR DE VITESSE 2 fonctions 250F
Permet de régler la vitesse d'exécution de 0 à 100% afin de gagner aux jeux les plus difficiles. Arrêt total pour photo d’écran, pause café ou téléphone.
Facilite la programmation en mode pas à pas. Fonctionne aussi sur Amiga 1000.
MODULE ANTIVIRUS (PROTECTION + DETECTION) 250F
Indispensable pour détecter tout Boot ou Linlt Virus inconnu. Protège vos disquettes de toute écriture illicite. Visualisation par 2 voyants rouge et orange.
COMMUTATEUR JOYSTICK SOURIS àieds 250F
Evite de débrancher la souris à chaque fois que l’on utilise le deuxième joystick.
Deux leds indiquent la position choisie.
CARTE CHANGE KICKSTART (sans rom) 250F
Plus de problèmes de compatibilité. Tous vos logiciels ou démos fonctionnent Montage facile et sans soudures.
Tou8 nos produits sont livrés avec une notice d’explications ou de montage en français.
11 sont garantis un an, pièces et main d’oeuvre. Cette offre est valable pour le mois en cours. Un Service Technique compétent répondra à vos questions tous les mercredis de 18h à 21h. Durant PAMIGA EXPO de COLOGNE (7 au 14 11) veuillez appeler au: 88 60 58 63. Pour commander: utilisez le bon ci-dessous ou un papier libre et renvoyez à:
MICROPUNCH Barbat 33480 - LISTRAC MEDOC
Tel: 56 58 14 00
BON DE COMMANDE
NOM, Prénom: Adresse:
Veuillez m’envoyer le COLIS PUNCH oui |non|
Veuillez m’envoyer:
Port et emballage en sus 30F
Pour un envoi en contre-remboursement, rajouter 20F . Ci-joint mon règlement de :......
BYTE ev%+4}=2 ! Ie_Class = IECLASS_RAWMOUSE
ip BBEIB BBBB
W0RD ev%+6}=&HFF ! Ie_Code = IECODE_NOBUTTON WORD ev%+8}=&H8000 ! Ie_Qualifier = IEQUALIFIER_RELA- TIVEMOUSE
WORD ev%+10}=0 ! Ie_X
WORD ev%+12}=0 ! Ie_Y
SELECT I2& ! Modifie ie_X et ie_Y en fonction
CASE 0 ! De ia valeur de la boucle 12
WORD ev%+10}=1 CONT CASE 1
WORD ev%+12)=1 CASE 2
WORD ev%+12}=1 CONT CASE 3
WORD ev%+10}=-1 CASE 4
WORD ev%+10}=-1 CONT CASE 5
WORD ev%+12}=-1 CASE 6
WORD ev%+12}=-1 CONT CASE 7
WORD ev%+10)=1
ENDSELECT
LONG io%+&H28}=ev% ! Io_Data = event WORD io%+&H1C)=&HB ! Io_Command = INDJVRITEEVENT BYTE io%+&H1E}=0 ! Io.Flags =0
LONG io%+&H24}=&H16 ! Io_Lenght = sizeof(struct
InputEvent)
~DolO(io%)
NEXT I3&
NEXT I2&
NEXT 11 &
~CloseDevice(io%) ! Ferme le device ENDIF
~@delete_ext_io(io%) ! Supprime la structure lOStdReq ENDIF
~FreeMem(ev%,&H16) ! Supprime la structure InputEvent ENDIF
~DeletePort(port%) ! Supprime le message-port ENDIF EDIT
' Fonction DeleteExtlO() faite maison. En effet,
1 pour une raison inconnue, le GfA ne la ' reconnaît pas...
FUNCTION delete_ext_io(io%)
IF io%
BYTE io%+8}=&HFF LONG io%+14}=-1 LONG io%+&H18}=-1
- FreeMem(io%,WORD io%+&H 12})
ENDIF
RETURN TRUE ENDFUNC
62, rue Gabriel Péri - 93200 Saint-Denis Tel: 42.43.22.78 - Fax: 42.43.92.70 Métro Saint-Denis Basilique Du lundi au samedi de 9h à 19h Ouvert dimanche matin de 9h à 12h30
PROMO DU MOIS
Lecteurs externes complets 3"l 2
690,00 frs
Dans la limite des stocks disponibles
UNITES CENTRALES
rachète votre A500 our l'achat d'un A2000 aux meilleures conditions...
Amiga 500
Amiga 500 écran 1084S Amiga 2000 T C
miçjc 00 écraiG084S r* •
A3000 en Démo... et
disponible
OCCASIONS
¦ici tous!
W
I
DIVERS
Moniteur multisyncro.
4490,00
Carte FlickerFlixer
NC
Extension 512Ko
NC
Extension 2Mo interne
NC
Carte 68020
NC
Carte AT
NC
Star LC 10 Star LC 10 couleur Star LC 24-10
noms SONT IniTil VOS MAINS."
Reprise aux meilleures conditions de votre Atari pour tout achat d'un AMIGA
Disquettes
49F.....
IMPRIMANTES
SOPtft
PROIAO
SUPER
lBHCÜB BBBD
REQUESTER
Attaquons courageusement par une lettre « KOLOSSALE », qu’il m’a fallu pour raison d’encombrement, amputer copieusement.
Question : Possédant un Amiga 500 (et lisant COMMODORE REVUE) depuis quelques mois, j’ai décidé dernièrement, à la faveur d’une amélioration de ma situation financière, de me mettre à la programmation en assembleur et en langage compilé sur Amiga. Je me suis donc procuré Draco, langage du domaine public dont le coût est infiniment moins cher que le prix scandaleux d’un langage C du commerce, et je vais bientôt le compléter par un assembleur (probablement Devpac 2), et je me trouve actuellement confronté au problème du choix des livres... Je vous demanderai donc de bien vouloir me conseiller, notamment sur un livre pour apprendre l’assembleur, sachant que j’ai un peu pratiqué l’assembleur Z80, et que j’ai donc besoin d’un ouvrage très complet, plus que d’un ouvrage d’initiation. De plus je voudrai des précisions sur les Amiga Rom Kernel Manual, c’est-à-dire les différents tomes, ce dont ils parlent et leurs prix approximatifs : habitant en province, je ne pourrai les consulter qu’en me rendant à Paris, et n’ayant ni l’occasion, ni le temps, je ne peux m’en rendre compte par moi-même. En fait, je m’étais même (sic!) Rabattu sur la Bible de l’Amiga, ne pensant jamais arriver à les trouver, avant d’avoir lu dans votre numéro de Juillet-Août qu’ils sont disponibles chez MAD.
Etant aussi intéressé par la digitalisation de sons et la musique sur Amiga, je vous demanderai si vous connaissez un moyen de se procurer la dernière version de SoundTracker (c’est-à-dire au moins la 2.4, puisque vous l’avez décrite dans un article ; je n’en possède malheureusement qu’une vieille version incomplète) [...] (NDLR : je coupe ici une quantité des questions qui sont du ressort d’un vendeur compétent, pas de TANT i’m sorry !).
A propos de musique, ce serait sympa de me dire comment déconnecter, par exemple en assembleur, le filtre passe-bas, dans la mesure où les auteurs de la Bible de l’Amiga ne semblent pas savoir que c’est possible, ni d’ailleurs qu’il est lié à la diode POWER...
Savez-vous où je pourrai me procurer Arexx et les commandes ARP (je suppose que ça doit se trouver sur les disquettes du domaine public, encore faut-il savoir lesquelles !!!) [...]
Je dois vous féliciter pour vos tests, très complets et surtout pour les articles de l’ANT sur les applications du blit- ter (NDLR : merci, merci !), qui ont le mérite de combler un grave manque : la plupart des livres techniques du commerce ne traitent (NDLR : ou ne maltraitent !) Que de l’utilisation théorique du hardware ou des langages, et il est donc très pratique de trouver dans votre revue des exemples. (Bien que je n’ai pas encore d’assembleur sur Amiga, je connais l'importance des exemples et je garde toutes vos revues en prévision...) Excusez-moi si je ne retourne pas votre sondage, mais je ne sais pas si j’aurai le temps de le photocopier, et je ne veux pas mutiler mon journal...
Laurent Dudouet (???) (NDLR : avis à tous, n’oubliez donc pas si souvent de nous donner votre adresse, vous qui souhaitez si ardemment des réponses...)
Réponse : Je vais d’abord répondre à une question qui n’est finalement pas posée, mais je pense que certaines précisions peuvent être utiles. Il s’agit des langages compilés. On peut certes considérer comme élevé le prix d’un compilateur C du commerce car sortir 2.500 F (pour un Lattice C 5.04 [the best]) n’est pas à la portée de toutes les bourses. Mais si l’on considère que le Lattice C 5.04 comprend un excellent éditeur de textes multi-fenêtres qui permet la compilation depuis l’éditeur, que le compilateur ne comporte pas de bugs (en tout cas je n’en ai pas vu) et est capable de produire un code objet très optimisé, que l’on dispose d’un débogueur avec des options remarquables, enfin que l’environnement de développement comporte me multitude de programmes utilitaires, dont un macro assembleur, une version revue et corrigée de Blink et qu’une documentation très complète (deux classeurs) est fournie et enfin qu’un suivi client sérieux est assuré par Lattice, il devient possible de dire qu’à ce prix-là c’est donné.
En ce qui concerne Draco (Fred Fish 76, 77, 201), il faut rendre hommage à son développeur qui a conçu un excellent langage et un très bon compilateur. Celui-ci dispose d’ailleurs d’une librairie mathématique très intéressante qui permet de faire des calculs sur les nombres complexes.
Mais considérez quand même que LE langage des systèmes multi-tâches est le langage C (le système d’exploitation d’UNIX est écrit en C, c’est quand même une référence). Considérez également que Draco a d'abord été conçu pour des ordinateurs utilisant le système d’exploitation CP M et qu’il n’a été que beaucoup plus tard adapté sur Amiga. Considérez enfin que Draco n’obéit à aucun standard contrairement au C. Ceci dit il existe des compilateurs C dans le domaine public. Je n’ai aucune idée de leur valeur car je ne les ai pas essayés. Renseignez- vous auprès de HERMES Diffusion, 123, rue Desandrouins, 3 cour Lannoy 59220 Denain.
Si vous achetez un assembleur, n’hésitez-pas : choisissez Devpac2. C’est incontestablement le meilleur macroassembleur existant à ce jour.
Pour débuter en assembleur je vous conseille deux livres :
- “Le livre du langage machine” de Micro-Application. Ce livre a le gros avantage de présenter de petits programmes dans l’environnement Amiga.
- pour un livre complet sur le 68000, je vous recommande “Mise En Œuvre du 68000” aux éditions SYBEX.
Les Amiga Rom Kernel Manual. Il existe trois volumes.
- “Libraries and Devices” (300 F) qui traite de toutes les librairies et de tous les devices de l’Amiga avec d’excellents et nombreux (et sans erreurs mais écrits sur Lattice C 5.04) programmes d’exemples. Malheureusement la dos.library, librairie hybride s’il en est, n’est pas traitée . Pour obtenir des renseignements complets sur cette dernière, il faut s’adresser à COMMODORE FRANCE afin d’obtenir les docs développeurs. Attention, c’est très cher.
- “Includes et Autodocs” (300 F) donne les conditions d’entrées et de sorties de toutes les routines systèmes dont COMMODORE considère qu’il est permis au programmeur d’y accéder.
Je vous illustre ceci par un exemple : passer en mode superviseur.
Dans “Includes et Autodocs”, la routine SuperState d’exec.library est complètement décrite. Par contre la très délicate routine Supervisor de la même exec.library est considérée comme réservée au système d’exploitation et est de ce fait totalement passée sous silence. Mais ceci n’enlève rien à la valeur de ces livres qui sont de véritables MINES D’OR sans équivalent.
“Includes et Autodocs” donnent également tous les fichiers includes, aussi bien pour le langage C que pour l’assembleur, décrit les formats IFF, et les linkers librairies (de bug.lib, amiga.lib...) etc.
- “Hardware Réference Manual” (260F) décrit le hardware de l’Amiga. Aussi bien le brochage des composants que leurs programmations, avec ici aussi de nombreux programmes d’exemples.
Je connais beaucoup (certes pas tous) de magasins informatiques sur Paris. MAD est le SEUL chez qui j’ai vu les Amiga Rom Kernel Manual. Il faut ici rendre hommage à ce vendeur très compétent et qui a la délicate préoccupation de fournir à ses clients une bonne documentation. Sachez que MAD doit se démener comme un diable dans un bénitier pour faire venir (au compte-gouttes) ces livres directement des USA. De cela, il faut déduire que ces livres ne sont pas en permanence disponibles chez MAD. Un coup de téléphone avant de s’y rendre s’impose.
A propos de SoundTracker : la seule version commercialisée est la première (développée par les Allemands Karsten et Obarski). Toutes les autres sont des contrefaçons excepté bien sûr Oktalyzer (le “soundtracker 8 voix’’) qui n’est pour l’instant commercialisé qu’en Allemagne. On ne peut se procurer soundtracker 2.4 que “sous le manteau’’. Toutes les versions entre l’original et la version 2.4 sont buggées : elles plantent lamentablement sur un clavier français. Par contre la version 2.4 plante à l’utilisation de la Preset List. Il existe une version nommée “Noise SoundTracker”, ultérieure à la version 2.4 qui ne plante pas sur la Preset List. A se procurer sous le manteau également.
Soyons sympa. En fait le filtre passe bas n’est pas relié à la led power. De par le brochage du CIA-A, c’est le bit 1 dudit CIA-A qui bascule à la fois l’état de la led power et l’état du filtre passe bas. Cela peut être réalisé en assembleur de la façon suivante :
bchg l,$ bfe001
Arexx est la version Amiga du langage Rexx. Vous pouvez vous procurer l’original également chez MAD pour le prix de 379 F. Ce prix est ridicule si l’on considère le potentiel de Arexx. Il existe effectivement un langage Rexx pour Amiga dans le domaine public. De même les commandes ARP et la ARP library sont du domaine public. Renseignez-vous à l’adresse donnée plus haut.
?aacsa
Question : Je vous écris pour voir si votre réputation est à la hauteur de mes pensées.
Voici donc les quelques problèmes dont je suis la victime.
- Tout d’abord il faut vous dire que je possède un AMIGA 2000B muni d’une carte AT286 (un peu lente).
Il se trouve que j’ai un mal fou à trouver un lecteur 5”l 4 pour AT (formatage 1,2 Mo). Pour les programmes qui tournent sur PC, un lecteur c’est un peu court n’est-ce pas ? (NDLR : certes mais finalement que voulez-vous savoir ?)
- D’autre part j’aimerai savoir si vous pourriez m’indiquer un modèle de disque dur pour y mettre mes fichiers PC ainsi que ceux d’AMIGA ; ou au minimum ceux de PC.
- Une dernière chose : il me semble que vous avez fait une petite erreur dans le n°90 de COMMODORE REVUE, dans la rubrique périphériques (pages bleues), entre les extensions mémoire A2058-2 et A2058-8 (NDLR : ????)
Martial ? (???)
Réponse : Une disque dur n’est finalement ni plus ni moins qu’une grosse disquette à accès rapide. On y met ce que l’on veut à condition de le formater et de le partitionner convenablement. Un disque dur est toujours vendu avec des utilitaires destinés à cet effet. Ce que vous souhaiter est faisable avec n’importe quel disque dur.
Je ne pense pas que nous ayons fait une erreur car tout bien considéré, le n° 90 n’est pas encore près de paraître...
QQQQQ
Question : Ça he fait pas longtemps que je vous lis car ça ne fait pas longtemps que je vous connais. Nez en moins (NDLR : copieur !) Je trouve votre revue super, notamment TANT. Comme j’ai raté une bonne partie de l’initiation à l’assembleur, je me permets de poser quelques questions.
Qu’est-ce qu’une fenêtre RAW ? J’ai essayé d’en appeler une par NEWSHELL RAW:0 0 640 200, mais je n’arrive pas à entrer de données.
Ensuite, qu’est-ce qu’une copper-list ? Je voudrais également savoir s’il est possible d’ouvrir un écran de la même manière qu’une fenêtre avec la fonction Open de la dos.library, et si oui, comment préciser la résolution et la profondeur ? Dans un autre domaine, j’ai reçu (NDLR : comment ça reçu ?) Récemment un petit- fils de soundtracker qui permet de faire de la musique 8 voix. Comment est-ce possible puisque l’Amiga n’en a que quatre ?
Frédéric DELACROIX (Querenaing)
Réponse : CON: est un device permettant de gérer les entrées sorties utilisées par les fenêtre CLI
NEWCON: est un device plus performant utilisé par les fenêtresShell
RAW: quant à lui est un device rudimentaire (raw veut dire cru en anglais) qui offre au programmeur la possibilité de gérer les entrées sorties comme bon lui semble avec un programme de son cru (si j’ose dire). Ouvrir “de l’extérieur’’ une fenêtre RAW: comme vous l’avez fait n’a aucun intérêt : puisque les I O ne sont pas gérées, vous ne pouvez même y écrire EndCli pour la fermer...
Le copper est un processeur graphique qui fonctionne indépendamment du 68000. La liste d’instruction qu’il exécute s’appelle le copper-list. Cette éxécution est synchronisée avec le balayage écran.
Ouvrir un écran avec la dos.library n’est pas possible. C’est du ressort d’intuition.library, à moins que vous ne vouliez construire votre écran vous-même entièrement auquel cas il faut utiliser la graphies, library.
Vous parlez sans doute d’Oktalyzer ? Ce logiciel n’est commercialisé pour l’instant qu’en Allemagne. Il n’y a effectivement que 4 voix sur l’Amiga. Mais il est possible en additionnant deux à deux les courbes sonores avant de les jouer d’obtenir “l’effet 8 voix’’ d’Oktalyzer.
Profondeur ? Dans un autre domaine, j’ai reçu (NDLR : comment ça reçu ?) Récemment un petit- fils de soundtracker qui permet de faire de la musique 8 voix. Comment est-ce possible puisque l’Amiga n’en a que quatre ? Frédéric DELACROIX (Querenaing)
Réponse : CON: est un device permettant de gérer les entrées sorties utilisées par les fenêtre CLI
NEWCON: est un device plus performant utilisé par les fenêtresShell
RAW: quant à lui est un device rudimentaire (raw veut dire cru en anglais) qui offre au programmeur la possibilité de gérer les entrées sorties comme bon lui semble avec un programme de son cru (si j’ose dire). Ouvrir “de l’extérieur’’ une fenêtre RAW: comme vous l’avez fait n’a aucun intérêt : puisque les I O ne sont pas gérées, vous ne pouvez même y écrire EndCli pour la fermer...
Le copper est un processeur graphique qui fonctionne indépendamment du 68000. La liste d’instruction qu’il exécute s’appelle le copper-list. Cette éxécution est synchronisée avec le balayage écran.
Ouvrir un écran avec la dos.library n’est pas possible. C’est du ressort d’intuition.library, à moins que vous ne vouliez construire votre écran vous-même entièrement auquel cas il faut utiliser la graphies, library.
Vous parlez sans doute d’Oktalyzer ? Ce logiciel n’est commercialisé pour l’instant qu’en Allemagne. Il n’y a effectivement que 4 voix sur l’Amiga. Mais il est possible en additionnant deux à deux les courbes sonores avant de les jouer d’obtenir “l’effet 8 voix’’ d’Oktalyzer.

Click image to download PDF

AMIGA NEWS TECH numero 17 (11-1990)

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


Thanks for you help to extend Amigaland.com !
frdanlenfideelhuitjanoplptroruessvtr

Connexion

Pub+

31.7% 
18.5% 
5.9% 
5.3% 
4.9% 
3.9% 
2.8% 
2.1% 
1.6% 
1.2% 

Today: 15
Yesterday: 117
This Week: 132
Last Week: 762
This Month: 2688
Last Month: 2931
Total: 63756

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