Sponsors

FacebookTwitterGoogle Bookmarks

Nous admettons que CoolCapture a été précédemment vectorisé sur INIT (voir mois dernier). Rappelons que CoolCapture est un vecteur de l'Amiga correspondant au reset. C'est-à-dire que la case mémoire d'adresse Coolcapture contient l'adresse de base de la routine à appeler lorsque les touches Control Amiga Amiga sont pressées. Cependant, après chaque reset, Coolcapture est correctement réinitialisé par le système. Il nous faut donc à nouveau le vectoriser sur INIT. D'où un certain cercle vicieux. De la même manière, si le Virus Killer a été appelé par un autobootage, CoolCapture doit être vectorisé afin de prévoir un futur reset. Ensuite, il s'agit d'anticiper, en vue d'une possible introduction de disquette infectée dans le drive sans qu'il n'y ait eu de reset. Nous n'allons pas revenir lourdement sur la méthode consistant à détourner Dolo. Rappelons simplement qu'à chaque nouvelle disquette introduite dans l'un des drives, la routine Dolo est appelée par le système d'exploitation et que, par un subtile subterfuge, nous avons réussi à détourner Dolo sur le Virus-Killer. Il est intéressant de remarquer qui si bon nous semble, le Virus-Killer peut être inhibé : il suffit de presser le bouton de la souris à la suite de sa manifestation graphique. D'une manière plus explicite, le Virus est signalé par un effet de couleurs; le fait de presser le bouton rendra notre routine inopérante. Nous reviendrons d'une manière plus détaillée sur ce problème le mois prochain. Enfin, il suffit d'une petite routine dont nous étudierons le principe la prochaine fois, pour que la disquette dans le drive se charge automatiquement. Seulement, vous dites-vous, si la disquette est infectée, le Virus-Killer laisse le virus se reproduire sans même intervenir. En fait, et heureusement, il n'en est rien. Comme Dolo est détournée sur notre routine LTZ alors si la disquette contient un quelconque virus, il sera immédiatement détecté. Précisons l'utilité des deux variables AUT et TIME. Le fait d'avoir mis AUT à 1 signigie que la routine a déjà été appelée. Rapplez-vous que l'Amiga peut fonctionner en multitâches et que par conséquent, si deux disquettes infectées sont insérées en même temps, Dolo est détournée deux fois.

Click image to download PDF

AMIGA NEWS TECH numero 07 (12-1989)

Document sans nom ÆWS-TECH
A
M
I
G
A
N°7
Le Virus-Killer Deuxième partie
Little Zeus
nffify * dTïm
Gfa et Intuition .. Une nouvelle série,
Denis Ohriot
L’assembleur 68000
* Bien démarrer...
Max
Trucs et astuces AmigaDOS

Phantasia
LE
LISTING
COMPLET
EDITO
Michel Descoins nous a quitté, laissant! En suspend son initiation à l’Amiga- Basic. En attendant de lui trouver un remplaçant, nous vous proposons une nouvelle série qui vous expliquera tout sur l’interfaçage GfA-Basic Intuition.
Sinon vous trouverez comme promis le listing complet de la désormais célèbre Tube-lntro de Little Zeus'(accompagné de quelques explications succintes), listing également accessible en téléchargement sur le 36-15 COMREV.
Stéphane Schreiber
INTUITION ET GFA
Le Gfa-Basic possède une liste impressionnante d'instructions permettant une utilisation aisée des possibilités d'intuition (la partie du système d'exploitation chargée de gérer écrans, fenêtres, requesters, menus et gadgets). Seule l'utilisation des gadgets n'est pas directement permise par ce langage.
- APTR : adresse mémoire de l'Amiga (c'est ce qu'on appelle un "pointeur" en C et en Pascal);
- LONG : variable de type "entier" stockée sur 4 octets ;
- SHORT : variable de type "entier" stockée sur 2 octets;
- USHORT : variable de type "entier non signé" stockée sur 2 octets.
Voilà pour les définitions préliminaires. Et maintenant, au travail !
Pourtant, tous les programmes du commerce utilisent abondamment ce moyen simple et pratique de communiquer avec l'ordinateur. Il serait de fait très intéressant de posséder des routines qui permettraient d'utiliser facilement les gadgets sous Gfa-basic (NDLR : ça tombe très bien, c'est justement le but de cette série d'articles que de vous les fournir).
WHAT IS A GADGET?
Pour donner une définition simple du gadget, nous pouvons dire qu'il s'agit d'une zone d'écran particulière pouvant être actionnée par la souris et envoyant dans ce cas un message au programme, par l'intermédiaire d'intuition.
Comme presque tous les éléments du système d'exploitation de l'Amiga, un gadget se définit dans une structure directement issue du langage C :
struct Gadget C
struct
Gadget 1NextGadget *
Gadget suivant *
SHORT
LeftEdge,TopEdge
*
Coin haut-gauche *
SHORT
Width,Height
*
Hauteur et largeur *
USHORT
Flags
*
Voir plus loin *
USHORT
Activation
*
Voir plus loin *
USHORT
GadgetType
*
Type du gadget *
APTR
GadgetRender
*
Image non active *
APTR
SelectRender
*
Image active *
struct
IntuiText *GadgetText * Texte du gadget *
LONG
MutualExclude
r
Exclusion mutuelle *
APTR
Spécial Info
r
Structure spéciale *
USHORT
GadgetId
r
Numéro du gadget *
APTR
UserData *
Réservé au programmeur *
Quelques explications pour ceux qui ne sont pas familiarisés avec le langage C :
- STRUCT : zone de mémoire organisée qui permet, par référence a son seul nom, de manipuler un ensemble de variables de types très différents;
THE PROCEDURE
Nous trouvons ci-après le listing de la procédure qui nous servira à construire aisément une structure Gadget en Gfa-Basic. Après avoir tapé cette procédure dans l'éditeur du Gfa, sauvez-la sous forme de bloc, ce qui vous permettra par la suite de l'incorporer facilement dans vos programmes, sans avoir besoin de la retaper à chaque fois.
PROCEDURE gadget(x&, y&, largeur&, hauteur&, flag&, acti&, type&, image%, imageselect%, gadgetid&, specialinfo%, VAR gadget%)
gadget%=MALLOC(44 &H4)
IF gadget%=0 PRINT "Plus de mémoire !"
END END IF
Gadget suivant x
y
largeur
hauteur
Flags
Activation GadgetType GadgetRender SelectRender IntuiText MutualExclude Spécial Info GadgetId UserData
LONG gadget%+0}=0 INT gadget%+4}=x&
INTCgadget%+6>=y&
I NT gadget%+8>=largeur&
I NT Cgadget%+10>=hauteur&
I NT gadget%+12}=flag&
CARD(gadget%+14}=acti &
CARDCgadget%+16>=type&
LONGCgadget%+18>= i mage%
LONGCgadget%+22}= i mageselec LONG gadget%+26}=0 LONGCgadget%+30}=0 L0NG gadget%+34)=spec i ali nf CARD gadget%+38)=gadget i d&
LONGCgadget%+40}=0 fenetre%=WINDOW(1) pos%=-1
pos%=AddGadget(fenet re% gadget%, pos%)
• Longueur de la structure Gadget : 44 octets RETURN
les commentaires correspondent aux membres de la
j structure C.
La première ligne de la procédure réserve la mémoire nécessaire à la définition de la structure. La fonction Gfa MALLOCO alloue une zone de mémoire de la longueur et du type spécifiés (voir le manuel du Gfa, page
46) . Ici, nous demandons 44 octets de mémoire FAST (&H4 réserve la mémoire en dehors de la mémoire CHIF->: à noter pour les Amiga avec moins d'un rnéga de mémoire, qu'il est nécessaire d'indiquer &H 1 (NDLR ; ou mieux, &H5 qui demande en priorité de la mémoire FAST et au cas où il n'y en a pas suffisamment, de la mémoire CHIP)).
Nous récupérons l'adresse du début de cette zone dans la variable godget%. Si celle-ci vaut zéro, c'est qu'il n'y a pas assez de mémoire disponible dans l'Amigal Sinor, grâce aux fonctions de manipulation de la mémoire qu'offre le Gfa, nous remplissons la structure avec les valeurs passées en arguments à la ! Procédure.
Pour finir, la fonction AddGadgetO de la bibliothèque Intuition ajoute le gadget dans la liste des gadgets de la fenêtre voulue (celle-ci est indiquée par son adresse
récupérée dans la ligne précédente).
Rien de tel qu'un bon exemple pour bien comprendre. Pour commencer, nous allons définir un gadget du type le plus simple : un gadget booléen (c'est-à-dire ne pouvant avoir que deux états, ON ou OFF). L'instruction Gfa se présente ainsi :
gadget (100, 100, 50, 50, 0, 2, 1, 0, 0, 1, 0, gadget 1 %)
- les quatre premières valeurs ( 1 OO. 1 OO, 50 et bO) représentent les coordonnées du coin supérieur gauche ainsi que la largeur et la hauteur de la zone de
sélection du gadget;
- les trois valeurs suivantes (O, 2 et 1 ) définissent les caractéristiques du gadget (voir plus bas);
- les deux zéros suivants sont en fait des pointeurs de type NULL, car ce type de gadget ne se sert pas des informations qu'ils représentent;
- le 1 représente le numéro d'identification du gad- I get (utilisé par Intuition uniquement pour communiquer quel gadget a été sélectionné). Vous pouvez en fait lui donner la valeur que vous voulez;
- gadget 1% est la variable dans laquelle nous récupérons l'adresse de la structure Gadget ainsi définie. Les trois valeurs définissant les caractéristiques du gadget méritent quelques explications. En les prenant
dans l'ordre :
Flags détermine la façon de rendre compte à l'écran de la sélection du gadget :
0 : inversion vidéo de la zone de sélection;
1 : tracé d'un rectangle autour de la zone de sélec
tion,
2 : affichage d'une image de sélection;
3 : pas d'action à l'écran.
(nota : ce flag peut prendre d'autres valeurs que nous verrons plus tard)
- Activation définit la méthode de sélection autorisée pour ce gadget :
1 : la souris doit encore pointer la zone de sélection quand le bouton est relâché;
2 : Intuition prévient immédiatement, sans attendre que le bouton soit relâché;
4 : indique que ce gadget, une fois sélectionné, termine le requester auquel il est rattaché;
8 : Intuition communiquera tous les déplacements de la souris tant que le gadget sera sélectionné;
2 56 : le gadget sera alternativement activé puis désactivé.
(nota : on peut combiner plusieurs caractéristiques par un OR entre les valeurs, par exemple : 8 OR 256).
- Type définit le type du gadget :
SLEEP LOOP UNTIL MOÜSEK=2
i
1 Fin du programme CLOSEW 1 CLOSES 1 END
i
PROCEDURE mess
IF MENU(1)=32 THEN PRINT "Un gadget vient d'être cliqué"
PRINT "Numéro du gadget : ";CARD MENU(4)+38} ENDIF
RETURN
i
1 Insérer ici la procédure Gadget
THE END
Voilà, c'est tout pour aujourd'hui. La prochaine fois, nous verrons comment définir une image au format Intuition, ce qui nous permettra d'ajouter l'image à notre gadget. En attendant, amusez-vous bien...
Denis Obriot
APPLICATION
Nous avions laissé en suspend le fonctionnement global du Virus-Killer. Rappelons ses caractéristiques : nous avons à faire à un Virus-Killer virus, c'est-à-dire que dès que celui-ci détecte un quelconque élément gênant, il s'empresse de proposer à l'utilisateur sa suppression. Si ce dernier l'accepte, le Virus-Killer nettoie l'intrus de la mémoire et s'auto-reproduit sur le boot-block de la disquette infectée. Par conséquent, à chaque boot sur cette disquette, notre Virus- Killer s'actionnera et guêtera. Cependant, il reste un problème, à savoir la mise en marche de notre routine après un Reset.
Ainsi, nous comptons trois entrées différentes à notre programme : par auto-boot, par reset ou par introduction d'une disquette contaminée alors que le programme principal se déroule.
L'AUTO-BOOTAGE
Nous admettons que notre Virus Killer est déjà implanté sur le bootblock de la disquette. Les deux premiers blocs contiennent les données suivantes : tout d'abord le mot "DOS" (en majuscules), puis le checksum des deux premiers blocs, suivi du numéro du bloc contenant le directory et enfin d'un programme de boot (ici, notre Virus-Killer). Attention, les
deux premiers blocs font exception à la règle; habituellement, chaque bloc comprend son propre checksum plus un grand nombre de données concernant le ou les fichiers qu'il contient... Le checksum d'un cylindre correspond à un calcul sur l'ensemble de ses octets. La tête de lecture lit donc tranquillement ces neuf premiers octets. En arrivant à notre Virus-Killer, elle l'exécute.
Cependant, deux grandes difficultés apparaissent ; premièrement, le programme ne doit jamais être physiquement altéré, le checksum en deviendrait erronné et la disquette se retrouverait dans l'incapacité de démarrer. Seconde difficulté, les addresses du programme. Effectivement, si vous laissez libre choix à la machine d'implanter le programma où bon lui semble dans la mémoire, vos instructions "jmp" n'auront plus aucune signification. Il est clair que si la routine a été assemblée en $ 7fOOO, elle ne pourra jamais être exécutée en $ 300000. Cela serait par contre possible s'il n'y avait ni jmp ni jsr. C'est d'ailleurs ce dont nous allons nous servir pour remédier à cette seconde difficulté : il suffit tout simplement de mettre en avant du programme une mini-routine recopiant le Virus-Killer à partir de son adresse normale d'exécution. Cette routine se nomme MASTER dans le listing.
En ce qui concerne la première difficulté, il s'agit d'envisager toutes les possibilités de modification du programme initial. En d'autres mots, nous devons recenser tous les paramètres susceptibles d'être modifiés. Apparaissent tout d'abord les variables de tests telles AUT, TIME, etc. Ensuite les messages qui peuvent être modifiés en fonction de la source du Virus : en l'occurence, le message relatif au Drive d'où provient le Virus. La suite de la sous-routine de chargement est commune à celle du reset.
LE RESET
Nous admettons que CoolCapture a été précédemment vectorisé sur INIT (voir mois dernier). Rappelons que CoolCapture est un vecteur de l'Amiga correspondant au reset. C'est-à-dire que la case mémoire d'adresse Coolcapture contient l'adresse de base de la routine à appeler lorsque les touches Control Amiga Amiga sont pressées. Cependant, après chaque reset, Coolcapture est correctement réinitialisé par le système. Il nous faut donc à nouveau le vectoriser sur INIT. D'où un certain cercle vicieux. De la même manière, si le Virus Killer a été appelé par un autobootage, CoolCapture doit être vectorisé afin de prévoir un futur reset.
Ensuite, il s'agit d'anticiper, en vue d'une possible introduction de disquette infectée dans le drive sans qu'il n'y ait eu de reset. Nous n'allons pas revenir lourdement sur la méthode consistant à détourner Dolo. Rappelons simplement qu'à chaque nouvelle disquette introduite dans l'un des drives, la routine Dolo est appelée par le système d'exploitation et que, par un subtile subterfuge, nous avons réussi à détourner Dolo sur le Virus-Killer.
Il est intéressant de remarquer qui si bon nous semble, le Virus-Killer peut être inhibé : il suffit de presser le bouton de la souris à la suite de sa manifestation graphique. D'une manière plus explicite, le Virus est signalé par un effet de couleurs; le fait de presser le bouton rendra notre routine inopérante. Nous reviendrons d'une manière plus détaillée sur ce problème le mois prochain.
Enfin, il suffit d'une petite routine dont nous étudierons le principe la prochaine fois, pour que la disquette dans le drive se charge automatiquement. Seulement, vous dites-vous, si la disquette est infectée, le Virus-Killer laisse le virus se reproduire sans même intervenir. En fait, et heureusement, il n'en est rien. Comme Dolo est détournée sur notre routine LTZ alors si la disquette contient un quelconque virus, il sera immédiatement détecté.
Précisons l'utilité des deux variables AUT et TIME. Le fait d'avoir mis AUT à 1 signigie que la routine a déjà été appelée. Rapplez-vous que l'Amiga peut fonctionner en multitâches et que par conséquent, si deux disquettes infectées sont insérées en même temps, Dolo est détournée deux fois. Or, les registres du 68000 ne peuvent contenir deux valeurs différentes en même temps et il y a bug. Cependant, afin d'éviter cet inconvénient fatal, on réduit la puissance du programme, c'est-à-dire que celui-ci ne peut être appelé qu'une seule fois en même temps. Pour ce faire, on utilise AUT, qu'on met à 1 lorsque le Virus Killer est appelé, et à 0 sinon. Il émerge donc de ceci que dans le cas de deux disquettes infectées insérées simultanément, seule une sera purgée. Néanmoins la probabilité d'une telle situation est quasiment nulle.
TIME est mis à 1 lorsque l'on vient de faire un reset ou lorsqu'il y a eu un auto-boot. De cette manière, pour la valeur de TIME égale à 1, le Virus Killer revectorisera Coolcapture sur LTZ et remettra TIME à 0.
DISQUETTE INFECTEE
En fait, le paragraphe pourrait tout aussi bien porter le titre de "introduction d'une disquette sans qu'il y ait bootage". Comme vous pourrez progressivement le remarquer, la routine marche par élimination, et ceci se révélera encore plus vrai dans ce qui va suivre.
Effectivement, s'il y a chargement d'une disquette contenant le Virus-Killer, la routine concernant reset est appelée; de même, cette dernière appelle indirectement LTZ en détournant Dolo. Il en découle que, dans tous les cas possibles, le programme passe par la routine LTZ.
Celle-ci procède par élimination. Après une suite de tests, elle sera en mesure de donner le diagnostic de la disquette. Dans un premier temps, il faut s'assurer que LTZ n'est pas en train d'être doublement appelée via Dolo. Rappelons aussi que Dolo sert aux transferts de données entre tous les les périphériques et la mémoire. Par conséquent, rien ne nous permet d'affirmer qu'à un instant donné, Dolo assure un transfert de données entre le drive et la mémoire ; cela pourrait tout aussi bien être l'imprimante, le modem, etc.
Il se trouve que Dolo requiert un et un seul argument : l'adresse de base de la table des paramètres nécessaires à son bon fonctionnement. L'adresse de base de cette table figure dans A 1, ce qui nous permettra de l'explorer pour vérifier que c'est bien une opération sur disquette qui est en cours.
Nous ne verrons cependant pas l'ensemble des données contenues dans la table, mais uniquement celles dont nous nous servirons :
- en A1 + 36 se trouve le nombre d'octets à transférer. Si ce transfert concerne un Virus, il ne peut qu'être inférieur au nombre d'octets des deux premiers blocs de la disquette. A fortiori, ce nombre est inférieur à 1 02 5. Si tel est le cas, les tests peuvent se poursuivre;
- en A 1 T 44 figure numéro de la piste concerné. S'il ne s'agit pas de la piste 0, on laisse tomber;
- A1 +29etA1 + 2 7 indiquent respectivement s'il y a lecture d'un secteur et si oui, sur quel drive;
- en 40 + A 1 se trouve l'adresse à partir de laquelle les données en provenance du drive vont être logées en mémoire. On sauvegarde cette valeur en WAIC, car elle nous permettra de connaître la zone comportant le virus. Il sera ainsi facile de l'éliminer de la mémoire.
- en A 1 + 31 enfin, est placé un numéro d'erreur éventuelle survenue lors de la lecture ou de l'écriture sur la disquette.
Etant bien entendu que si un quelconque virus est détecté, le programme enchaînera sur le processus de reproduction du Virus-Killer, il apparaît évident que Dolo sera directement appelée par notre programme afin d'écrire sur la disquette. Du coup, le message d'erreur peut facilement différer de celui précédemment rencontré. Imaginez la situation : un programme appelle Dolo et du coup passe par le Virus-Killer (je rappelle aux abrutis qui dorment au fond que Dolo est détournée sur notre Virus-Killer), qui lui-même appelle pour ses besoins internes la véritable routine Dolo.
Celle-ci place un numéro d'erreur en A1 +31. Seulement voilà, le programme principal n'a rien à faire de notre message d'erreur, il doit retrouver le sien.
C'est pourquoi ce message d'erreur est provisoirement stocké en NERROR afin d'être repoké avant le retour au programme principal. Remarquons que la valeur d'erreur n'est stockée qu'après le lancement de la véritable Dolo.
THAT'S ALL FOLKS
Nous achèverons le Virus-Killer le mois prochain, en expliquant son installation sur le boot-block. Nous en profiterons pour étudier précisément le fonctionnement du reset et ses possibilités d'utilisation. Nous approfondirons aussi certaines des notions étudiées dans ces pages, en particulier l'auto-boot.
Little Zeus Brothers S.A.R.L.
_________...... EL. ....
Openlib=-408
open=-30
deb=$ 7f800
org
deb
load
deb
begin:
dc. b
"DOS",0
checksum:
de. 1
0
de. 1
$ 370
i
; Copie le programme en 3
master:
movem.1
a0-a1 dÜ,-(Y7)
move.w
$ ff,dQ
move.1
deb,aO
lea
begin(pc),a1
bis
move.1
(A1)+ (a0)+
dbra
d0,bl
jsr
init
movem.1
(a7)+,aû-a1 d0
lea
dosl+2(pe) ,a1
jsr
- 96(a6)
tst. 1
dO
beq
mer
move.1
d0 a0
move.1
22(a0),a0
moveq
$ 00,dO
rts
mer:
move.w
$ ff,d0
rts
i
Erratum concernant le numéro 17 de Commodore Revue : trois lignes de la routine sont inutiles. Veuillez supprimer
move. 1 dO,rom1 +2(pc) move. 1 d0,rom2 + 2(pc) jsr -456(a6)
Avec toutes mes excuses....
LE VIRUS-KILLER DE LITTLE ZEUS : DEUXIEME PARTIE
; Virus Killer de Lit le Zeus ; Deuxième partie
i
; Partie à installer AVANT ; la routine du mois dernier
i
ExecBase=4 AllocAbs=-204 DisplayAlert=-90
; Routine appelée après chaque reset init :
; Détournement de CoolCapture peseta:
jsr inïtcc
move.l $ 4,a6 ; Détournement de Doîo move.l ltz -454(a6)
; Indique par une effet de couleurs ; présence du Vi rus -ici lier move.w $ f000,d0 nop:
move.w d0,$ dff180
dbra dO,nop
move.w 1,time clr.w aut
btst 6,Sbfe001 ; souris ?
Bne mas
; Remet l'ancienne Dolo move.l $ fc06dc,-454(A6)
; Efface CoolCapture clr.l 46(a6) jsr mam
mas: rts error:
clr.w aut
rts
t I G I C
n g Ku I s
TRUCS ET ASTUCES AMIGADOS
Qui n'a pas rêvé d'un disque virtuel à l'épreuve du reset? Eh bien il existe, avec le KickStart 1.3, un périphérique nommé RAD : qui permet de démarrer (booter) comme une vraie disquette. Qui a dit que l'Amiga n'était pas magique?
RAD : s'emploie comme DFO :, RAM DHO etc. Sa taille, comme nous le verrons plus loin, est fonction du goût de l'utilisateur, mais surtout de la mémoire disponible.
Le plus intéressant serait bien sûr, pour les possesseurs du KickStart 1.3, de mettre le Workbench sur RAD : Pour les autres, RAD : reste tout de même utile pour stocker certains fichiers du Workbench.
La question est donc : comment, Maestro, mettre le Workbench en RAD : et démarrer à partir de lui?
Tout d'abord il faut savoir que RAD : doit être "mounté", grâce à la commande MOUNT RAD après avoir adapté sa taille à ses besoins en modifiant le paramètre HighCyl dans la MountList (en effet, la taille de RAD : n'est pas extensible, contrairement à ce qui se passe avec RAM :). Les conventions suivantes sont à utiliser :
Valeur de
Taille de
HighCyl
RAD :
90
1 Mo
45
51 2 Ko
(les matheux auront remarqué qu'il s'agit d'une suite géométrique de raison 1 2)
Il convient, après l'avoir "mounté", de formater RAD : de manière tout-à-fait standard, avec la commande FORMAT DRIVE RAD : NAME CeQueVous- Voulez.
Pour désamorcer RAD :, on utilise la commande 1 .3 RemRAD, mais attention, elle réduit RAD : à sa plus simple expression et le rend inaccessible, sans pour autant l'éliminer; il faudra pour cela attendre le prochain CTRL Amiga Amiga.
Imaginons maintenant une Startup-Sequence copiant le Workbench en RAD :. Il faut évidemment faire un choix des fichiers indispensables, pour ne pas dépasser la capacité d'accueil du disque virtuel.
On pourrait avoir par exemple dans le fichier Startup lui-même (ou dans un autre fichier pour éviter de surcharger le listing) :
MOUNT RAD:
; Répertoire C
IF EXITS RAD:C ASSIGN C: RAD:C ELSE MAKEDIR RAD:C COPY C: RAD: C
; Ici il serait plus judicieux ; de ne copier qu'une partie de C:
ENDIF
; Répertoire Devs IF EXITS RAD:Devs ASSIGN Devs: RAD:Devs ELSE
MAKEDIR RAD:Devs
COPY Devs:System-configurât ion RAD:Devs COPY Devs:Parallel.device|Printer.device RAD:Devs COPY Devs:Printers Imprimante RAD:Devs ; A la place d'"Imprimante",
; indiquer l'imprimante utilisée ENDIF
; Répertoire l IF EXITS RAD:l ASSIGN l: RAD:l ELSE MAKEDIR RAD:l COPY l: RAD: l ENDIF
; Répertoire Libs ;
IF EXITS RAD:libs ASSIGN Libs: RAD:L i bs ELSE
MAKEDIR RAD:Libs COPY Libs: RAD:L i bs ENDIF
; Le Shell
IF NOT EXITS RAD:Shell COPY : Shell RAD:
ENDIF
Pour vous simplifier les choses, sauvez ce fichier sous le nom RADConfig, et rendez-le exécutable avec la commande PROTECT RADConfig +S, ce qui vous évitera d'avoir à utiliser la commande EXECUTE à chaque fois. Après son exécution, les parties essentielles du Workbench sont dans RAD :.
Il peut paraître surprenant d'y avoir inclu le printer.device et le driver correspondant, mais il est toujours assez désagréable de devoir insérer la disquette Workbench à chaque impression.
Il faut aussi observer qu'il est indispensable d'avoir le répertoire L : en RAD :, car il contient des fichiers obligatoires pour le démarrage du système (sous 1.3).
J'allais oublier de dire qu'il n'est pas vraiment utile de copier en RAD :Cdes commandes déjà résidentes (sauf si vous possédez 32 Mo de Ram, dans ce cas, pas de soucis d'économie...).
Phantasia
Et Joyeux Noël !!
Ça y est, les temps d'intuition sont révolus. Ôn a vu tout (ou presque) ce qu'il était possible de voir concernant l'interface graphique de l'Amiga, sans pour autant être arrivés au bout de nos peines.
Surtout que, comble du paradoxe, tous les programmes que nous avons pu étudier ensemble jusqu'ici, refusaient absolument de se lancer à partir du Work- bench, sous peine de plantage. En d'autres termes, il est impossible de leur associer une icône sur laquelle il suffirait de double-cliquer pour les exécuter. Un comble que, vous vous en doutez certainement, nous allons tout de suite réparer.
UN PEU DE THEORIE
Voyons pour commencer le cas le plus simple, l'appel à partir du Shell.
Vous savez sans doute, pour avoir déjà utilisé des commandes telles que DIR ou RENAME, qu'il est possible de transmettre des paramètres à un programme. Par exemple, lorsque vous écrivez :
DIR DFO :
DIR est le nom de la commande (programme), et la chaîne "DFO est le paramètre dont se servira DIR pour déterminer de quel disque ou dossier elle devra fournir la liste.
Dans un tel cas, le programme appelé possède un moyen très simple de récupérer ses paramètres : AmigaDOS lui transmet dans AO l'adresse de l'emplacement en mémoire où se trouve le texte (dans notre exemple : DFO :) et dans DO, la longueur (en nombre de caractères -I- 1 ) de ce texte (ici, ce serait 5). Pourquoi la valeur contenue dans DO est- elle supérieure d'une unité à la longueur réelle du texte ? Tout simplement parce qu'AmigaDOS considère le code ASCII 1 0 (Line Feed) correspondant à l'appui sur la touche Return comme faisant partie intégrante de la liste des paramètres.
Le seul inconvénient de cette méthode au demeurant fort pratique, est qu'elle ne permet la transmission que de chaînes ASCII. Si votre programme a besoin d'un nombre comme paramètre (par exemple, une adresse), il faudra lui inclure une routine transformant la chaîne ASCII en nombre binaire.
Voici, pour les plus fainéants, telle routine:
Startup:
move.b 0,-1(a0,d0.w) ; Remplace Line Feed par 0
moveq
0,d0 ;
Efface dO
move.1
d0 d1 ;
et d1
GetDeci:
move.b
(a0)+,d1 ; Lit un caractère ASCII
beq.s
Gotlt ;
C'est le 0 -> on a fini
sub.b
101,d1
; Sinon, le changer en nombre
mu lu
10,dO
; Multiplie dO par 10
add. 1
d1,dO ;
et lui ajoute d1
bra.s
GetDeci
; Boucle jusqu'au 0 final
Gotlt: ;
On a le
nombre dans dO.L
Attention toutefois, cette routine ne teste en aucune manière la validité du paramètre; que vous entriez TONTON MAX, =D446xw ou 1 5.63.40, le résultat sera tout de même évalué, avec les bugs pouvant en découler.
INITIATION A L'ASSEMBLEUR 68000
Avouez que c'est hyper-simple. Pour illustrer tout celà, je vous propose une nouvelle petite commande Shell qui attend un paramètre - en l'occurence, un nombre décimal quelconque - qu'elle convertira d'abord en hexadécimal puis en binaire. Les programmeurs apprécieront.
; C0NV - Pax Max
i
; Affiche un nombre décimal ; en hexa et en binaire
; Usage : C0NV x
; Avec x = nombre décimal quelconque
; Exec Library ExecBase EQU 4 OpenLib EQU -408 CloseLib EQU -414
; Dos Library Output EQU -60 Write EQU -48
Startup:
move.b 0,-1(a0,d0.w) ; Remplace Line Feed par 0
subq
1 ,d0
bne.s
OkPar ; Y a-t-il un paramètre ?
Moveq
20,dO ; Non -> on èort avec le code
rts
; d'erreur 20
OkPar:
moveq
0,d0 ; Efface dO
move.1
d0,d1 ; et d1
GetDeci:
move.b
(a0)+,d1 ; Lit un caractère ASCII
beq.s
Gotlt ; C'est le 0 -> on a fini
sub.b
'0'fd1 ; Sinon, le changer en nombre
move.l d0,d2 ; Multiplie dO par 10.
Isl.l 3,d0 ; On n'utilise pas MUL 10,DO
Isl.l 1,d2 ; car cette instruction ne
add.l d2,d0 ; permet pas de récupérer des
; nombres sur 32 bits add.l d1,d0 ; Et lui ajoute d1
bra.s GetDeci ; Boucle jusqu'au 0 final
Gotlt:
move.l d0,d7 ; Sauve le nombre dans d7
move.l ExecBase,a6 ; Ouvre la dos.library
lea DosName(pc),a1
jsr OpenLib(a6)
move.l d0 d6 ; DosBase dans d6
bne.s OkDos ; Erreur ?
Moveq 30,dO ; Oui -> on sort avec le code
rts ; d'erreur 30
OkDos:
move.l d6,a6 ; DosBase dans a6
jsr 0utput(a6) ; Handle de la fenêtre Shell
move.l d0,d5 ; dans d5
HexOut:
lea Hexïext(pc),aO ; Conversion en hexa dans le
move.l d7,d0 ; buffer HexText
moveq 7,d1 ; 8 caractères à sortir
HexLoop:
rol.l 4,d0 ; Isole le quartet supérieur move.w d0,d2
andi.w $ f,d2
addi.w '0',d2 ; Le convertit en chiffre 0-9
cmpi.w '9',d2
bis.s HexOk
addq.w 7,d2 ; Ou en lettre A-F au besoin HexOk:
move.b d2,(a0)+ ; Et l'écrit dans le buffer
dbra d1,HexLoop ; Boucle jusqu'au dernier
B i nOut:
lea BinText(pc),aO ; Conversion en binaire dans
move.l d7,d0 ; le buffer BinText moveq 31,d1 ; 32 caractères à sortir moveq 0,d3 ; Ruse pour gagner du temps BinLoop:
moveq '0',d2 ; Par défaut, écrit un 0 roxl.l 1,d0 ; mais au besoin, addx.w d3,d2 ; le remplace par un 1
move.b d2,(a0)+ ; Et l'écrit dans le buffer
dbra d1,BinLoop ; Boucle jusqu'au dernier
Print:
move.l d5,d1 ; Sort le texte dans la move.l Texte,d2 ; fenêtre Shell moveq TexteLen,d3 jsr Write(a6)
CloseDos:
move.l ExecBase,a6 ; Ferme la dos.library
move.l d6,a1
jsr CloseLib(a6)
moveq 0,d0 ; Et retourne au Shell avec
rts ; le code d'erreur 0
DosName: dc.b "dos.Iibrary",0
even
; Comme d'une part on travaille ; à l'octet dans les buffers ; HexText et BinText et comme ; d'autre part, la fonction Write ; de la dos.library attend ; l'adresse du texte à écrire dans un ; registre de données, on se ; moque bien de savoir si les labels ; Texte, HexText et BinText se trouvent à des addresses paires xj non. Enfin quelque chose ; de sympathique dans le BCPL !
Texte: dc.b "Hexadécimal : S"
HexText: dc.b "00000000",$ 0a
dc. b "Binaire : %"
BinText: de.b "00000000000000000000000000000000"
dc. b $ 0a
TexteLen: EQU *-Text ; Longueur du texte à écrire even
END
TOUS LES MATINS, MON ICONE ET MOI... CLIC, CLIC!
Reste maintenant à voir comment se présente la situation lorsque le programme est lancé depuis le Workbench. Là encore, il peut recevoir des paramètres, mais pas de la même manière. Il existe deux moyens distincts pour passer des paramètres à un programme par l'intermédiaire du Workbench :
- dans le cas où le paramètre est le nom d'un fichier, il faut d'abord cliquer une fois sur son icône, puis ensuite double cliquer sur celle du programme, tout en maintenant la touche Shift appuyée;
- si les paramètres concernent des options de configuration, il faut les entrer dans la partie ToolTypes de la fenêtre Info (l'exemple le plus conu étant la taille, position et nom de la fenêtre CLI ou Shell - voir votre manuel de l'Amiga pour en savoir plus là-dessus).
Il faut là encore distinguer les deux cas. Dans le premier, le programme concerné reçoit ses paramètres par l'intermédiaire de messages.
La procédure minimale à suivre consiste à :
- attendre le message au moyen de la fonction Wait- PortO d'Exec;
- aller le chercher avec GetMsgO;
- exécuter le programme proprement dit;
- prévenir le Workbench, au moyen de ReplyMsgO, qu'on n'a plus besoin de son message.
ExecBase EQU 4
FindTask EQU -294
WaitPort EQU -384
GetMsg
EQU
- 372
ReplyMsg
EQU
- 378
pr_MsgPort EQU
$ 5c
WBStart:
move.1
ExecBase a6
suba.1
a1 ,a1
; Où suis-je ?
Jsr
FindTask(a6)
move.1
d0,a4
lea
pr_MsgPort(a4),aO ; MessagePort dans aO
jsr
WaitPort(a6)
; Attend le message
lea
pr_MsgPort(a4),aO
jsr
GetMsg(a6)
; Puis va le chercher
move.1
dO,WBMsg
; et le sauve
GetToolTypes:
; Voir plus bas
; Ici se trouve le programme ; principal
Main:
; Répond au message WB ; retour au WorkBench
move.l WBMsg,a1 jsr ReplyMsg(a6)
rts
WBMsg: dc.l
Dans le deuxième cas, c'est-à-dire celui où les paramètres sont transmis par l'intermédiaire du gadget ToolTypes de la fenêtre Info, il faut utiliser certaines fonctions de l'icon.library, car n'oublions pas que ces ToolTypes sont stockés dans le fichier de l'icone elle- même. La procédure à suivre est donc légèrement plus complexe, surtout qu'il faut de toute manière procéder à la recherche du message Workbench. La routine qui suit devra donc être insérée au label "GetToolTypes" du listing précédent.
Sm_ArgLis EÛU $ 24
wa__Name EQU $ 04
do_ToolTypes EQU $ 36
GetDiskObject EQU -78
GetToolTypes: lea jsr tst. I beq
IconName(pc),a1
0penLibrary(a6)
dO
Main
Ouvre l'icon.library
Saut si er eur
move.l d0,a6 ; IconBase dans a6
move.l WBMsg,a0 ; WBMessage dans aO move.l sm_ArgLis(aO),aO ; Liste des arguments move.l wa__Name(aO),aO ; Pointeur sur le nom du prg jsr GetDisk0bject(a6) ; Lire les informations
move.l d0fa0 ; Pointeur sur les ToolTypes
move.l do_ToolTypes(a0),a0 ; dans aO
Arrivé à ce stade-là, le plus gros est fait, a 1 contient un pointeur sur ce qu'on appelle le ToolTypesArray, qui est en fait un pointeur sur une liste de pointeurs sur les textes des ToolTypes et se terminant par un pointeur NULL (0). Pour lire les ToolTypes un à un, il faut donc utiliser une routine du genre (ne pas l'insérer à la suite du listing ci-dessus!) :
ToolLoop:
move.l (a0)+,a1 ; Pointeur sur le ToolType
cmpa.l 0,a1 ; NULL ?
Beq Tool End ; Oui -> sort de la boucle
___; Non, on fait ce qu'on veut
bra ToolLoop ; Et on boucle
ToolEnd: ... ; Suite du programme
Vous imaginez aisément la galère pour tester un à un tous les ToolTypes que le programme attend? C'est pourquoi l'icon.library met deux fonctions à notre dis position pour nous simplifier la tâche (ah, quand même!), ce sont FindToolType (offset -96) et Match ToolType (offset -102). Voici comment elles fonctionnent.
FindToolTypeO attend dans AO un pointeur le ToolTypesArray évoqué plus haut, et dans A1 un pointeur sur un texte ASCII terminé par O décrivant le ToolType à rechercher. Imaginons pour les besoins d'un exemple que nous attendions un ToolType du style WINDOW = ON OFF (qui signifie que le ToolType "WINDOW" peut prendre les valeurs "ON ou OFF"). On écrit alors (en assumant que AO pointe déjà sur le ToolTypesArray et que A6 contienne déjà IconBase) :
lea tt_WIND0W(pc),a1
jsr FindToolType(a6)
tst.l dO
beq PasT rouve
tt_WIND0W: dc.b "WINDOW",0
En retour, si un ToolType du nom de WINDOW est trouvé, DO contiendra un pointeur sur le texte se trou vant après le signe égal (ici, soit "ON", soit "OFF") et O dans le cas contraire. Il revient alors au programme de vérifier la conformité des arguments précisés.
MatchToolTypeO peut justement y aider. Elle attend comme argument le pointeur renvoyé par FindToolTypeO transféré dans AO, et dans A1 un pointeur sur le texte à comparer (n'oubliez jamais que les ToolTypes sont toujours exprimés en ASCII, même s'ils représentent des nombres). Pour continuer notre exemple du ToolType WINDOW :
move.l dO,aO ; dO = FindToolTypeO
lea WIND0W_0N(pc),a1 ; Texte à comparer
jsr MatchToolType(aô) ; a6 = IconBase
tst.l dO
bne 0k_0N
lea WIND0W_0FF(pc),a1
jsr MatchToolType(a6)
tst.l dO
bne 0k_0FF
; etc.
WINDOW_ÜN: dc.b "ON",0,0
WINDOW_OFF: dc.b "OFF»,0
Vous pouvez maintenant terminer la routine Get- ToolTypes à votre guise, en utilisant FindToolTypeO et MatchToolTypeO suivant vos besoins. N'oubliez pas simplement de refermer l'icon.library avant le label Main, à moins que vous n'en ayez besoin ailleurs dans votre programme.
Tiens, pour la forme, je vais vous donner le contenu complet de la structure DiskObject dont l'adresse est renvoyée par la fonction GetDiskObjectO.
Structure
DiskObject
Offset
Nom standard
Signification
$ oo
do -Magic
Validation du fichier
$ 02
do Version
Numéro de version
$ 04
do Gadget
Structure Gadget de
l'icône
$ 30
do Type
Type d'objet (Tool, etc.)
$ 32
do DefaultTool
Idem fenêtre Info
$ 36
do T oolT ypes
Pointeur sur les ToolTypes
$ 3A
do CurrentX
Position X de l'icône
$ 3E
do CurrentY
Position Y de l'icône
$ 42
do DrawerData
Pointeur sur la fenêtre
$ 46
do Tool Windo w
Fenêtre pour les Tools
$ 4A
do StackSise
Taille de la pile
D'OU VIENS JE?
Je sais, c'est assez inhabituel de finir par le commencement, mais il faut encore que notre programme soit capable de déterminer s'il a été appelé à partir du Shell ou du Workbench. Heureusement, c'est hyper*
J simple.
Voici donc une routine Startup complète, qui détermine si le programme a été appelé depuis le Shell ou le Workbench, exécute le programme principal, puis retourne à l'appelant.
Vous pouvez soit l'inclure à votre source principal par la directive Include "startup.s", soit l'assembler en fichier objet dans la perspective d'un linkage ultérieur.
Cette routine possède tout de même deux limitations, qui fort heureusement ne sont pas trop contraignantes. Primo, votre programme doit commencer par le label Main (à moins que vous ne changiez ce nom dans la routine de Startup), et secondo, il doit se ter miner par l'instruction RTS, en étant sûr d'avoir remis la pile dans l'état où il l'a trouvée en entrant.
Le passage concernant l'icon.library et les fonctions GetDiskObjetO, FindToolTypeO et MatchToolTypeO n'est pas inclus, c'est à vous de vous en occuper si vous en avez réellement besoin.
Insistons encore sur un dernier point : si vous désirez que votre programme puisse être indifféremment appelé du Shell ou du Workbench, il faut que vous prévoyiez les deux éventualités lorsque vous récupérerez les paramètres; n'oubliez pas que dans le cas du Shell, aO pointe la liste des paramètres et dO contient
la longueur de la ligne de commande plus 1, alors que dans le cas du Workbench, aO pointe le premier para I mètre, et dO contient le nombre total de paramètres.
On se retrouve le mois prochain pour une nouvelle t série portant sur la gestion des fichiers en assembleur, et par là-même, sur TamigaDos en général
; Routine de startup complète ; à inclure avant votre programme ; qui doit débuter par le label Main
; Exec Library
ExecBase
EQU
4
FindTask
EQU
- 294
WaitPort
EQU
- 384
GetMsg
EQU
- 372
ReplyMsg
EQU
- 378
; Autres
pr_CLI
EQU
Sac
pr_MsgPort EQU
S5c
sm__NumArgs EQU
Sic
sm_ArgList EQU
S24
Startup:
movem.l d0 a0,-(sp) ; Sauver aO et
; dO en cas d'appel depuis le Shell
move.1
ExecBase,a6 ; Où suis-je ?
Sub. 1
a1, a 1
jsr
FindTask(a6)
move.1
dO, aO
tst. 1
pr_CLI(aO) ; D'où viens je ?
Beq.s
FromWB
FromShell
:
movem.1
(sp)+,dO aO
bra
Main ; Saut au programme
FromWB;
lea
pr_MsgPort(a4),aO
jsr
WaitPort(a6) ; Attend le message du WB
lea
pr_MsgPort(a4),aO
jsr
GetMsg(a6) ; Puis va le chercher
move.1
dO,WBMsg ; Et sauve le
move.1
dO, aO
move.1
sm__NumArgs(aO),dO ; Nombre de paramètres
move.1
sm_ArgList(aO),a0 ; Et leur adresse
bsr
Main ; Appelle le prog principal
move.1
dO,-(sp) ; Sauve le code de retour
move.1
ExecBase,a6
move.1
WBMsg,a1
jsr
ReplyMsg(aô) ; Répond au message du WB
move.1
(sp)+,dO ; Reprend le code
rts
; Et retour à l'envoyeur !
WBMsg: dc.l 0
Il était temps, la Tube-lntro est enfin achevée... Nous allons pour votre plus grand plaisir vous en présenter le listing dans son intégralité.
LA TUBEINTRO
fiez un offset de $ 800, tapez "e" et répondez par $ 40000 aux deux questions suivantes. Enfin, sauvez sous le nom qui vous plaît;
Il est conseillé d'ajouter la ReplayRoutine de SoundTracker pour obtenir un fond musical (facultatif).
Little Zeus Brothers Incorporation, Ltd
IVIais dans l'immédiat, vous pourrez constater que, pour des raisons d'optimisation, certaines lignes du programme ont été modifiées. De même, afin de ne pas monopoliser trop de place dans Commodore Revue, les commentaires ont été supprimés. Ceux qui auraient absolument besoin de ces commentaires sont priés de se reporter aux anciens numéros de Commodore Revue, le cas échéant disponibles auprès de la rédaction.
Voici quand même quelques indications quant à la mise en œuvre de la Tube-lntro :
En ce qui concerne le logo ondulant, n'oubliez pas de modifier les valeurs des couleurs dans la Cop- perList. Pour celà, désassemblez votre image IFF non tronquée et rassemblez les octets par 3 à partir de l'octet $ 3C. Par exemple, si vous lisez 04 08 09 04 02 01 mettez dans la CopperList, à l'endroit indiqué : DC.W $ 182, $ 489, $ 184, $ 421 etc. Répétez l'opération quatre fois pour la police de caractères et huit fois pour le logo (un couple de mots correspond à une couleur);
Si vous vous êtes débarrassé des $ 98 premiers octets de l'image IFF (elle doit être non compactée; pour celà, utilisez IFF Converter, présent sur DPAINT
3) , n'oubliez pas de supprimer les ''+$ 98" sur les pointeurs des images IFF (il y a une indication dans le listing);
Les caractères de la fonte mesurent 3 2 pixels de hauteur sur 40 de large en 4 couleurs et sont disposés ainsi sur l'image IFF :
ABCDEFGH IJKLMNOP QRSTUVWX etc.
(il y a huit caractères par ligne, vu que 40 x 8 égale 320 pixels). Si l'ordre des caractères est changé dans l'image IFF, n'oubliez pas de modifier la chaîne de caractères "let" dans le listing (vous trouverez un
repère);
L'intro doit être compactée pour devenir exécutable. La démarche à suivre avec le compacteur Byte Killer est simple : réservez 1 00 Ko, entrez le nom sous lequel l'intro a été sauvée à partir du Seka, spéci
* *****************************
* TUBE INTRO DE LITTLE ZEUS *
; Assembler (sous K-Seka): a cr> cr> ; puis :
; ri r> fonte r> cara r> r>
; ri r> logo r> pi et r> r>
; sauvegarder le tout :
; wi r> nom r>
; start r>
; end r>
; puis compacter avec ByteKiller org $ 40000
load $ 40000
; -- graphies.Iibrary -- scrollraster=-396 setapen=-342 initbitmap=-390 initrastport=-198 ; -- exec.library -- openlibrary=-408 closelibrary=-414 forbid=-132 permit=-138
execbase=$ 04
Start:
movem.1
dO-d7 aO-aô,-(a7)
move.1
execbase,a6
lea
gfxname,a1
jsr
openlibrary(a6)
move.1
dO,gfxbase
jsr
forbid(a6)
move.1
gfxbase,a6
move.1
bi tmap,aO
moveq
$ 02,dO
move.1
368,d1
move.1
200,d2
jsr
initbitmap(a6)
bsr
pf1
lea
rastport,a1
jsr
initrastport(a6)
move.l bitmap,r_bitmap
dc. w $ 18e,$ 930,$ 1aO,$ 111
move.l $ 70000,aO
dc. w $ 1a2,$ 333,$ 1a4,$ 555
move.w $ 35e8,d0
dc. w $ 1a6,$ 777,$ 0100,$ 320
clr:
eff :
clr.l (a0)+
blk.b 109*24
dbra dO,clr
dc. w $ 9809,$ fffe,$ 100,$ 1200
dc. w $ e2,$ 6bd0
jsr stars
ml 1 :
jsr setco
dc. w $ 9d09,$ fffe,$ 100,$ 4600
jsr courbe
dc. w $ 182,0
jsr ppicture
ml2:
jsr ini toc
dc. w $ 9e09,$ fffe
move.l gfxbasefaO
dc. w $ e2,$ 1226+46
add.w $ 32,30
dc. w $ ea,$ 5a06+46
move.l (aO),oldcopper
dc. w $ e6,$ 3616+46
move.l newcopper,(aO)
dc. w $ ee,$ 7df6+46 ; Les lignes suivantes
wait:
correspondent à
cmp.b 242,$ dff006
; la palette des caractères
bne wa i t
dc. w $ 182,$ 004,$ 184,$ fff
bsr rout
dc. w $ 186,$ 444,$ 192,$ 456
bsr effets
dc. w $ 194,$ 789,$ 196,$ 234
bsr effets2
coco:
bsr star_move
blk.b 32*12
btst 6,$ bfeOÛ1
ml3:
bne.s wa i t
dc. w $ Be09,$ fffe
dc. w $ 100,$ 1200
move.l gfxbase,a1
dc. w $ 182,0
add.w $ 32,a1
dc. w $ 100,$ 0200
move.l oldcopper,(a1) move l execbase,a6
‘ae.w $ ffff,$ Tffe
move.l gfxbase,a1
gfxbase: dc.l 0
jsr closelibrary(a6)
bitmap: blk.w 4,0
move.l gfxbase,aO
planel: dc.l 0,0,0
move.l execbase,a6
rastport: dc.l 0
jsr permft(a6)
r_bitmap: blk.l 26,0
movem. 1 (a7)+,d0-d7 a0-a6
gfxname: dc.b “graphies.
Clr.l dO
1ibrary“,0
rts
even
newcopper:
mg 1=46*102
dc. w $ 01OC,$ 0200
mg2=46*133
dc. w $ 9c,$ 8010
b1=$ 70000
dc. w $ 180,0,$ 190,0
b2=$ 723f0
dc. w $ 008e,$ 2c81,$ 0090,$ 2ec1
b3=$ 747e0
dc. w $ 0092,$ 0038,$ 0094,$ 00d0
b4=$ 76bd0
dc. w $ 0108,$ 0006,$ 010a,$ 0006
b5=$ 78fc0
I dc.w $ 0102,$ 0000,$ 0104,$ 0000
b6=$ 7b3b0
dc. w $ 00e0,$ 0007,$ 00e2,$ 0000
haut1=b1+mg1+2
dc. w $ 00e4,$ 0007,$ 00e6,$ 23f0
haut2=b3+mg1+2
dc. w $ 00e8,$ 0007,$ 00ea,$ 47e0
haut21=b2+mg1
dc. w $ 00ec,$ 0007,$ 00ee,$ 6bd0
haut22=b4+mg1
dc. w $ 00f0,$ 0007,$ 00f2,$ 8f cÔ
bas1=b1+mg2+2
i dc.w $ 00f4,$ 0007,$ 00f6,$ b3bC'
bas2=b3+mg2+2
spriteO:
bas21=b2+mg2
de.1 $ 01200000,$ 01220000 de.1 $ 01240000,$ 01260000
bas22=b4+mg2
de.1 $ 01280000,$ 012a0000
piedata: dc.l cara+$ 98
de.1 $ 012c0000,$ 012e0000
pdata: dc.l pict+$ 98
| de.1 $ 01300000,$ 01320000
; Enlevez les “+$ 98" si
I dc.l $ 01340000,$ 01360000
vos images sont
dc. l $ 01380000,$ 013a0000 ! Dc.l $ 013cÛ000,$ 013e00Û0
; t ronquées
; les 6 prochaines lignes'
ccol :
correspondent
move.l ccolor,d0
; a la palette du logo
move.l drc,d1
dc. w $ 182,$ 528,$ 184,$ fdb
add.l d1,d0
dc. w $ 186,$ fb7,$ 188,$ f93
add.l d1,d0
dc. w $ 18a,$ d7û,$ 18c,$ b50
move.l dO,ccolor
move.w
culig,d4
move.1
bas22+46,a4
lea
coco,a1
bra
sui te
move.1
31,d3
bdrc2:
move.1
ccolor,d1
move.1
bas1+46,a3
cmp. 1
chcolf,d1
move.1
bas2+46,a4
bne
bcb2
move.1
bas21,aO
move.1
chcol,ccolor
move.1
bas22,a1
bra
bcb3
sui te:.
Bcb2:
moveq
8,d3
cmp. 1
chcol-2,d1
cop:
bne
bcb3
move.1
(aO),(a3)+
move.1
chcolf-2,ccolor
move.1
(a1),(a4>+
bcb3:
add.w
4,a0
move.1
ccolor,a0
add.w
4, a1
boucle:
d4,(a1)
dbra
d3,cop
move.w
move.w
(a0),(a3) .1
add.w
8, a1
move.w
(a1),(a4)
move.w
$ 182, ( a 1 )+
rts
move.w
(a0)+,(a1)+

add. 1
$ 100,d4
courbe:
cmp. 1
chcolf,a0
move.w
culig,d0
bne
boucle2
lea
coco,a0
lea
chcol,a0
lea
colist,a1
boucle2:
moveq
31,dl
dbra
d3,boucle
bb3:
exi ty2:
move.w
dO,(a0)+
rts
move.w
move.w
$ fffe,(a0)+ $ 102,(a0)+
scrup:
clr.b
(a0)+
tst.b
wt
move.b
(a1),(aO)+
bne
bri
add.w
$ 100,dO
tst. 1
dre
add.w
1 ,a1
beq
bri
add.w
4,a0
bsr
trans
dbra
d1,bb3
bsr
anum2
rts
bri :
bsr
pf1
setco:
move.1
drc,d1
moveq
31,d3
bsr
scrold
lea
colist,aO
rts
setl:
scrold:
move.b
(a0),d0
clr.l
dO
move.b
13,d1 S
clr.l
d2
move.b
d0,d2
move.1
101,d3
asl .b
4,d2
move.1
320,d4
sub.b
d0,d1
move.1
134,d5
add.b
d1,d2
lea
rastport,a1
move.b
d2,(a0)+
jsr
scrollraster(a6)
dbra
d3,setl ?
Rts
rts
trans:
pf1:
cmp. 1
1,drc
move.1
b1,planel
bne
adrc2
move.1
b3,plane1+4
move.1
haut1,a0
move.1
b5,plane1+8
move.1
haut2,a1
rts
move.1
haut21-46,a3
pf2:
move.1
haut22-46,a4
move.1
b2,planel
bra
suite
move.1
b4,plane1+4
adrc2:
move.1
b6,plane1+8
move.1
haut1-46,a3
rts
move.1
haut2-46,a4
move.1
haut21,a0
culia:
move.1
haut22,a1
dc. w $ 9e09
bra
sui te
colist:
anum2:
dc. b 12
,10,8,6,5,4,3,3
cmp. 1
1,drc2
dc. b 2,
2,1,1,0,0,0,0
bne
bdrc2
dc. b 0,
0,0,0,1,1,2,2,3
move.1
bas1,a0
dc. b 3,
4,5,6,8,10,12
move.1
bas2,a1
drc2:
dc. l 1
move.1
bas21+46,a3
dre:
dc. l -1
num:
de. 1 0
lea
rastport,a1
move.1
101,dO
• ......scrotling horizontal
add.l
1 ,d0
rout:
moveq
46,d1
move.1
gfxbase,a6
moveq
40,d2
move.w
mt1,d0
nxtcar:
cmp.u
$ 9b09,d0
move.1
char,a0
bne.s
prd
move.b
(a0),d3
move.w
$ 100,inc
cmp.b
$ ff,d3
bra.s
pol
beq
stt
prd:
cmp.b
$ fe,d3
cmp.w
$ cb09,d0
beq
stt2
bne.s
prd2
cmp.b
$ fd,d3
move.w
-$ 100,inc
beq
stt3
pol :
cmp.b
$ fc,d3
tst .b
roi _
beq
stc
beq
prd2
cmp.b
$ fb,d3
move.1
drc,dO
beq
stc2
move.1
drc2,drc
cmp.b
$ fa,d3
move.1
d0,drc2
beq
sreb
prd2 :
cmp.b
$ f9,d3
move.w
i ne,dO
beq
upreb
add.w
d0,ml3
cmp.b
$ f8,d3
add.w
d0,ml1
beq
dwreb
add.w
d0,ml2 _
cmp.b
$ f7,d3
add.w
d0,culig
beq
rolst
cmp.b
$ f6,d3
bsr
ccol
beq
rolup
] bsr
scrup
cmp.b
$ f5,d3
bsr
pf1
beq
roldw
cmp.b
$ 20,d3
move. 1
gfxbase,a6
bcc. 1
l in
j lea
rastport,a1
tst.b
d3
j move.l
scspeed2,d0
beq
stopse
clr.l
d1
clr.w
d4
| moveq
16,d2
chscc:
move.l
101,d3
move.u
d3,d4
i .nove. 1
360,d4
moveq
40, d5
move.l
134,d5
divu
d4,d5
jsr
scrollraster(a6)
move.1
d4,scspeed2
bsr
pf2
move.b
d5,sespeed
| lea
rastport,a1
add.l
1,char
move.1
drc2,d1
bra
rout
move.l
scspeed2,d0
rolst:
tst .b
wt
clr.b
roi
beq
nowt
bra
stt
j clr.l
dO
rolup:
’] nowt :
move.w
-$ 100,inc
clr.l
d2
move.b
1,roi
move. 1
101,d3
bra
stt2
move. 1
320,d4
roldw:
5 move. 1
134,d5
rnove. W
$ 100,inc
jsr
scrollraster(a6)
move.b
1,roi
move.1
scspeed2,d0
bra
stt3
tst. 1
scspeed2
stc:
bne.s
ssp>eed
move.b
1 ,wt
sub. 1
1 ,scount
bra
rep
une
fiscroll
stc2:
inove. 1
4,scspeed2
move.b
0,wt
move.b
10,scspeed
bra
rep
bra
nxtcar
stopse:
d sspeed:
add.w
, 1,a0
cmp. 1
40,scspeed2
clr.l
beq.s
ni l
move.b
(a0),d0
sub.b
$ 01,rows
mulu
2,d0
bne
fiscroll
move.1
d0,scount
move.b
sespeed,rows
clr. 1
scspeed2
ni l :
add. 1
2,char
inove. 1
gfxbase,a6
bra
rout
.
stt:
clr.l
dre
cb2:
clr. 1
drc2
move.b (a0),(a1)+
rep:
move.b 40(a0),(a2)+
add.l
1 ,char
add.w 1,a0
bra. 1
nxtcar
dbra d2,cL2
sreb:
add.w 76,aO
clr.w
inc
add.w 41,a1
bra.s
rep
add.w 41,a2
upreb:
dbra d3,caraboucle
move.w
-$ 100,inc
espace:
bra.s
rep
rts
dwreb:
move.w
$ 100,inc
destl: dc.l Û
bra.s
rep
dest2: dc.l 0
stt2:
rows: dc.b 1
move.1
1,drc
sespeed: dc.b 10 S
move.1
-1,drc2
char: dc.l message
bra.s
rep
scount: dc.l 0
stt3:
scspeed2: dc.l 4
move.1
*1,drc
move.1
1,drc2
message:
bra. S
rep
dc. b $ f7,*ï SALUT ! "
i eux : add. 1
dc. b ,$ f8,$ fe,Ü,64,$ fa,$ ff
$ 01,char
dc. b “COMMODORE REVUE “
bra.L
nxtcar
dc. b $ f5,Û,48,$ f7," ET “
lin:
dc. b $ ff4$ f8,M LE PUISSANT "
bsr.s
textl
dc. b "LlTTLE",$ fe,0,16,$ ff
add. 1
$ 01,char
dc. b $ fc," 2EUS »
cmp. 1
finmessage.
Dc.b $ f5,$ fb,$ fol,0,128+64
char
dc. b $ ff,$ fa,$ fc,“ "
bne.s
fiscroll
dc. b $ fb,$ fcl,0,48,$ f7
move.1
message,char
dc. b “ PRESENTENT LA TUBE “
fiscroll
dc. b » INTRO J',$ f8,$ fe,0,64
rts
dc. b $ fa,$ ff,cl AMUSEZ VOUS ”
textl:
dc. b “ BIEN “,$ f7
mulu
dû,d1
dc. b $ fd," HELP ! M
add. 1
40,d1
dc. b $ 15,0,120,“ ”,$ ff
cmp.b
$ 20,d3
dc. b " A BIENTOT » H “
beq
espace
dc. b $ fa
lea
let,a5
dc. b Sfe, «IL EST TRES DÏFFI”
clr.l
d6
dc. b “LE DE LIRE CETTE PARTI”
testl:
dc. b “E DU TEXTE “
cmp.b
(a5,d6),d3
dc. b “CET EFFET PEUT ETRE
beq
sort
dc. b “DIFFERENT EN MODIFIANT"
add. 1
1 ,d6
dc. b “LES AUTRES PARAMÉTRES “
bra
testl
dc. b 4," “
sort:
FINMESSAGE:
move.b
d6,d3
; 1,2,4,5,8,20 : vitesses
clr.w
d4
; $ ff : pas de rotation
move.b
d3,d4
; Sfe : rotation vers le haut
divu
8,d4
; $ fd : rotation vers le bas
move.w
d4,d5
; $ fc : stop scrotling arriéré
swap
d4
; $ fb : reactive scrolling arriéré
mulu
2560, c5
; $ fa : stop rebonds
mulu
5,d4
; Sf9 : rebonds départ vers le haut
add. 1
d4,d5
; $ f8 : rebonds départ vers le bas
add. 1
picdata,d5
; $ f6 : fait rouler le scrolling sur
move.1
d5,a0
; l'ecrar», départ vers le haut
move.1
d1 ,d0
; $ f5 : fait rouler le scrolling sur
add. 1
b1,d0
; l'écran, départ vers le bas
move.1
d0,dest1
; $ f7 : arrête $ F5 ou $ F6
move.1
d1,dest2
add. 1
b3,dest2
; Les lignes suivantes correspondent
move.1
dest1,a1
; à la disposition des caractères
move.1
dest2,a2
; dans votre font
move.1
31,d3
let: dc.b “ABCDEFGHÏJKLMNOPQRST'5
4 caraboucle:
dc. b "UVWXYZ.7!90r;12345678"
move.1
4,d2
even
jccolor: dc.l chcol
A
fa
i i
A
dc. w 0
dc. w $ f06 :hcol:
dc. w $ f00,$ f00,$ f00,$ f00,$ 000
dc. w $ dOO,$ dOO,$ dOO,$ dOO,$ 000
dc. w $ b00,$ b00,$ b00,$ b00,$ 000
dc. w $ 900,$ 900,$ 900,$ 900,$ 000
dc. w $ 700,$ 700,$ 700,$ 700,$ 000
dc. w $ 500,$ 500,$ 500,$ 500,$ 000
dc. w $ 400,$ 400,$ 400,$ 400
dc. w $ 000,$ 500,$ 500,$ 500,$ 500
dc. w $ 000,$ 700,$ 700,$ 700,$ 700
dc. w $ 000,$ 900,$ 900,$ 900,$ 900
dc. w $ 000,$ b00,$ bOO,$ bOO,$ bOO
dc. w $ 000,$ dOO,$ dOO,$ dOO,$ dOO
dc. w $ 000,$ f00,$ f00,$ f00,$ f00 :hcolf :
wt: dc.b 0
roi : dc.b 0
oldcopper: dc.l 0
ne:
stars: move.I move.w swap move.w clr.l clr. I lea lea lea
move.b tarloop: clr. I lea
move.b
sprite,dû d0,spri te0+6 dO
d0,sprite0+2
dO
d2
xpos(pc),a0 speeed(pc),a2 sprite(pc),a1 $ 20,dO
d1
colors-4(pc),a3
d0,(a1)+
move.b (a0)+,(a1)+ addq.w 1,dÛ move.b d0,(a1)+ move.b d2,(a1)+ move.b (a2)«-,d1 Isl.w 2,d1 add.t d1,a3 move.I (a3),(a1)+ addq.w 1,d0 cmp.w $ 00fe,d0 ble.S starloop moveq 6, d2 cmp.w $ 0128,dO bne.S starloop rts starjnove: move.w 131,dO
lea speeed(pc),a2
lea sprite+1(pc),a1
move_loop: move.b (a1),d1 move.b (a2)+,d2 d2,d1 d1,(a1)
add.b
move.b
add.l
dbf
rts
8,a1
d0,move_loop
colors:
dc. l $ 80000000,$ 00008000 de.I $ 00008000,$ 80008000
dc. l $ 80008000
speeed:
dc. b 2,4,1,3,5,3,2,1,3,2,5,1
dc. b 4,3,4,3,4,1,3,2,5,4,3,2
dc. b 5,2,3,1,5,4,1,4,2,3,1,4
dc. b 3,2,5,1,3,2,4,5,1,2,4,5
dc. b 3,1,4,3,5,1,2,1,4,4,5,3
dc. b 2,4,1,5,2,4,2,5,3,5,3,4
dc. b 3,1,4,4,5,3,2,4,1,3,4,1
dc. b 3,2,5,4,1,3,4,2,3,1,4,3
dc. b 4,1,2,5,3,5,1,4,3,5,2,4
dc. b 2,5,1,4,2,3,4,1,3,5,2,4
dc. b 3,2,1,5,3,4,3,5,1,2,4,1
xpos:
dc. b $ 1e,$ 4f,$ ab,$ dd,$ 1b,$ bb
dc. b $ 6a,$ f3,$ 88,$ ab,$ f3,$ 73
dc. b $ 27,$ 8a,$ 0e,$ 22,$ bc,$ 3b
dc. b $ 20,$ 0e,$ 91,$ 14,$ 59,$ f0
dc. b $ d5,$ 79,$ b0,$ 32,$ d3,$ 55
dc. b $ b1,$ 95,$ 89,$ 5b,$ c3,$ 99
dc. b $ 01,$ 30,$ d4,$ c3,$ b9,$ a1
dc. b $ 7e,$ 91,$ 09,$ 4e,$ 70,$ a0
dc. b $ c0,$ 5b,$ 1a,$ 98,$ 81,$ d3
dc. b $ 22,$ 48,$ 91,$ c5,$ ff,$ 12
dc. b $ 45,$ 95,$ a1,$ 39,$ e0,$ 84
dc. b $ 05,$ b4,$ af,$ 76,$ 72,$ 19
dc. b $ 49,$ 58,$ 00,$ d2,$ e2,$ 92
dc. b $ 19,$ f5,$ 06,$ 35,$ a8,$ d3
dc. b $ 89,$ 7e,$ 29,$ 90,$ a4,$ 12
dc. b $ b9,$ c0,$ e3,$ 88,$ 41,$ 2e
dc. b $ 59,$ 12,$ f0,$ c3,$ 6e,$ 91
dc. b $ 2c,$ 55,$ 79,$ 1c,$ 01,$ 96
dc. b $ a5,$ c1,$ d9,$ e7,$ 14,$ 86
dc. b $ 10,$ 99,$ d3,$ 69,$ a3,$ c8
dc. b $ 93,$ 12,$ f5,$ 28,$ c2,$ 39
dc. b $ 92,$ a0,$ 38,$ bb,$ e1,$ e3 spri te: blk.l 265
id=0
l inmem=$ 6f000 max=108
poslist:
dc. l efflist-4 efflist:
dc. l eff1,eff2,eff3, eff4,eff5
dc. l eff4,eff5,eff4, ef f5,eff7
dc. l eff6,eff8
efflistf
:
tnt2:
dc. w 0
tnt3:
dc. w 0
tnt4:
dc. w 0
tnt5:
dc. w 53 -
point:
dc. l linmenH-318
compt:
dc. w 0
effets2:
move.1
eff+14,a1
move.1
1inmem,a0
clr.w
d2
clr.b
d5
dest:
jmp
ef fO
rts
effO:
add.w
1, tnt3
cmp.w
1,compt
rts
beq
oko
ef f5:
move.w
1,compt
cmp.w
26,tnt4
rts
beq
exit
Jr oko:
move.w
tnt4,d3
clr.w
compt
jsr
empl ine
sub. 1
6,point
move.w
tnt3,d3
move.1
point,a0
jsr
twol ines-----
cmp.w
0,tnt5
move.w
tnt2,d3
beq
exit
jsr
one l i ne
' move.w
tnt5,d3
move.w
tnt3,d3
move.b
- 1
1 ,d5
jsr
twolines
jsr
oneli ne
move.w
100,d3
move.w
tnt2,d3
jsr
empline
clr.b
d5
add.w
1,tnt4
jsr
oneline
add.w
2,tnt2
move.w
120,d3
sub.w
1,tnt3
jsr
empline
rts
sub.w
1,tnt5
eff6:
add.w
1,tnt2
cmp.w
2,tnt4
rts
beq
exit
ef f 1 :
move.w
tnt4,d3
cmp.w
52,tnt3
jsr
empline
beq
exi t
move.w
tnt3,d3
move.w
tnt3,d3
jsr
twolines
jsr
twolines
move.w
tnt2,d3
move.w
tnt2,d3
jsr
oneline
jsr
oneline
sub.w
1,tnt2
move.w
100,d3
add.w
1,tnt3
jsr
empl ine
sub.w
1,tnt4
sub.w
1,tnt2
rts
add.w
1,tnt3
ef f8:
rts
cmp.w
53,tnt2
ef f2:
beq
exit
cmp.w
53,tnt4
move.w
2,d3
beq
exi t
jsr
empl ine
move.w
tnt4,d3 S
move.w
tnt3,d3
jsr
empline
jsr
twolines
move.w
tnt3,d3
move.w
tnt2,d3
jsr
twolines
move.w
100,d3
jsr
oneli ne
jsr
oneline
move.w
100,d3
sub.w
1,tnt3 '
jsr
empline
add.w
1,tnt4
add.w
1ftnt2
rts
sub.w
1,tnt3
ef f3:
rts
cmp.w
27,tnt4
ef f7:
53,tnt2
beq
exi t2
move.w
move.w
tnt4,d3
clr.w
tnt3
jsr
empl ine *
cmp.w
53,tnt4
move.w
53,d3 X
beq
exit2
jsr
move.w
tnt4,d3
oneline s
move.w
100,d3
jsr
empl ine
jsr
empline
move.w
53,d3
sub.w
1,tnt4 **
jsr
oneline
rts
add.w
1,tnt4
eff4:
rts
cmp.w
5,tnt4
exi t2:
tnt3
beq
ex i t
clr.w
move.w
tnt4,d3
move.w
53,tnt2
jsr
empl ine
exit:
move.w
tnt3,d3
add. 1
4,poslist
jsr
twolines
cmp. 1 bne
efflistf,poslist
move.w
tnt2,d3
non
jsr
oneline
move.1
efflist,poslist
move.w
tnt3,d3
move.w
53,tnt2
jsr
twolines
clr.w
tnt3
sub.w
1,tnt4
clr.w
tnt4
sub.w
2,tnt2
non:
rainbow:
dc. w $ f00,
dc. w $ f40,
dc. w $ f90,
dc. w $ feO,
dc. w $ cfO,
dc. w $ 8f0,
dc. w $ 3f0,
dc. w Sof1
dc. w $ 0f6,
dc. w $ 0fb
dc. w $ 0ff,
dc. w $ 0bf,
dc. w $ 06f,
dc. w $ 01f,
dc. w $ 00c,
dc. w $ 008,
dc. w $ 003,
dc. w $ 200,
dc. w $ 600,
dc. w $ a00, rainbowf:
$ f30
$ f70,$ f80
$ fc0,$ fd0
$ df0
$ 9f0
$ 5f0,$ 4f0
$ 0f0
$ 0f4,$ 0f5
$ 0f9,$ 0fa
$ 0fe
$ 0cf
$ 08f,$ 07f $ 03f,$ 02f $ 00d $ 009
$ 005,$ 004 $ 000,$ 100 $ 500 $ 900
$ d00,$ e00
$ f10,$ f20, $ f50,$ f60, $ fa0,$ fb0, $ ff0,$ ef0, $ bf0,$ af0, $ 7fO,$ 6fO, $ 2f0,*$ 1f0, $ 0f2,$ 0f3, $ 0f7,$ 0f8, $ 0fc,$ 0fd, $ 0ef,$ 0df, $ 0af,$ 09f, $ 05 f,$ 04f, $ 00f,$ 00e, $ 00b,$ 00a, $ 007,$ 006, $ 002,$ 001, $ 300,$ 400, $ 700,$ 800, $ b00,$ c00,
sinus :
de.
W
$ 77,$ 66
,$ 66,$ 55
,$ 55
$ 44-
de
w
$ 44,$ 33
,$ 33,$ 22
,$ 22
$ 11
de
w
$ 11,$ 11
,$ 00,$ 00
,$ 00
$ 00
de
w
$ 00,$ 11
,$ 11,$ 11
,$ 22
$ 22
de
w
$ 33,$ 33
$ 44,$ 44
,$ 55
$ 55
de
w
$ 66,$ 66
,$ 77,$ 88
,$ 88
$ 99
de
w
$ 99,$ AA
$ AA,$ BB
, $ BB
$ CC
de
w
$ CC,$ DD
,$ DD,$ DD
,$ EE
$ EE
de
w
$ EE,$ EE
,$ EE,$ DD
,$ DD
$ 0D
de
w
$ CC,$ CC
,$ BB,$ BB
,$ AA
$ AA
de
w
$ 99,$ 99
,$ 88,$ 88
sinusf
anbl
de. 1
108
cnbl
de. 1
108
mocu
de. 1
s i nus
meu:
de. 1
rainbow
cara
blk.
B 13000,
0
pi et
!
Blk.
B 19200,
0
end:
move.1
poslist,a0
clr.w
a1)
move.w
$ e2,(a0)+
move.1
(a0),dest+2
add.l
4,a1
move.w
(a2),(a0)+
rts
clr.w
(a1 )
move.w
$ e6,(a0)+
onel i ne :
add. 1
4,a1
move.w
2(a2),(a0)+
cmp.w
-1,d3
clr.w
(a1 )
move.w
$ eA,(a0)+
beq
prts
add. 1
16,a1
move.w
4(a2),(a0)+
foroot:
add.l
1 ,d2
add. 1
6,a2
move.w
(a0),(a1)
cmp. 1
max,d2
add.w
$ 100,dO
add.l
4,a1
bcc
prts
dbra
d3,boc
move.w
2(a0),(a1)
dbra
d3,empline
i
add. 1
4,a1
rts
effets:
move.w
4(a0),(a1)
lea
eff+10,a1
add. 1
16,a1
ppicture:
move.1
anbl,d3
cmp.b
0,d5
move.1
pict,a3
move.1
mcu,d1
bne
jumpi t
move.1
1inmem,a0
cmp. 1
rainbowf,d1
add. 1
6,a0
move.1
b6,d0
bne.L
br2
jumpî t:
move.1
d0,a1
move.1
rainbow,mcu
add. 1
1 ,d2
move.1
60*3*40,d2
br2:
cmp. 1
max,d2
move.1
mcu,a0
bcc
prts
move.1
d2,d3
bocle:
dbra
d3,foroot
j j r 3 :
move Al
(a0)+,(a1)
prts:
move.w
(a3),(a1)+
add. 1
24,a1
rts
add.w
2,a3
cmp. 1
rainbowf,a0
twolines:
dbra
d3,jjr3
bne
bocle2
cmp. 1
-1,d3
move.1
60*3,d3
lea
rainbow,aO
beq
prts
j j r:
bocle2:
foroot2:
move.w
dO,(a0)+
dbra
d3, boc l e
move.w
(aO),(al)
add.l
40,dO
add. 1
2,mcu
add. 1
4,a1
dbra
d3,jjr
move.1
cnbl,d3
move.w
2(a0),(a1)
move.1
50*3,d3
lea
eff+6,ar
add. 1
4,a1
j jr2:
move.1
mocu,d1
move.w
4(a0),(a1)
move.w
$ 6bd0,(a0)+
cmp. 1
sinusf,d1
add. 1
16,a1
dbra
d3, j j r 2
bne
epl
move.w
(a0),(a1)
rts
move.1
s i nus,mocu
add. 1
4,a1
ini toc:
epl :
move.w
2(a0),(e1)
move.1
108,d3
move.1
mocu,a0
add. 1
4,a1
move.w
$ 2b09,d0
rap:
move.w
4(a0),(a1)
move.1
1inmem,a2
move.w
(a0)+,(a1)
add. 1
16,a1
lea
eff,a0
add. 1
24,a1
add. 1
6,a0
boc:
cmp. 1
sinusf,a0
add. 1
2,d2
move.w
dO,(a0)+
bne
epl2
cmp. 1
bcc
dbra
max,d2
move.w
$ fffe,(a0)+
lea
sinus,a0
prts
d3,foroot2
move.w
$ 102,(a0)+
epl2:
add. 1
2,a0
dbra
cB, rap
rts
move.w
$ 182,(a0)+
add. 1
2,mocu
empline:
add. 1
2,a0
rts
BON COURAGE!
1
Second gadget
gadget(300,100,50,50,1,2,1,0,0,2,0,gadget2%)
BOX 300,100,350,150 ! Trace un cadre autour
i
1 Traitement des événements Intuition
i
ON MESSAGE GOSUB mess
i
1 Attente d'un événement et bouton droit pour finir DO
amily:Arial, sans-serif;">move.w $ 102,(a0)+
epl2:
add. 1
2,a0
dbra
cB, rap
rts
move.w
$ 182,(a0)+
add. 1
2,mocu
empline:
add. 1
2,a0
rts
BON COURAGE!
1
Second gadget
gadget(300,100,50,50,1,2,1,0,0,2,0,gadget2%)
BOX 300,100,350,150 ! Trace un cadre autour
i
1 Traitement des événements Intuition
i
ON MESSAGE GOSUB mess
i
1 Attente d'un événement et bouton droit pour finir DO

Click image to download PDF

AMIGA NEWS TECH numero 07 (12-1989)

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


Thanks for you help to extend Amigaland.com !
frdanlenfideelhuitjanoplptroruessvtr

Connexion

Pub+

52.7% 
11.6% 
4.6% 
3.7% 
3.1% 
2.2% 
2.2% 
1.5% 
0.9% 
0.9% 

Today: 65
Yesterday: 104
This Week: 258
Last Week: 665
This Month: 2700
Last Month: 2920
Total: 72310

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