Sponsors

FacebookTwitterGoogle Bookmarks

L’ASSEMBLEUR L'assembleur Genlm2 suit entièrement les définitions énoncées par Motorola pour le 68000 ainsi que pour les 68010 et 68020. Et accepte, comme beaucoup de ses confrères, quelques petites améliorations, comme par exemple la possibilité d'utiliser l'instruction MOVE au lieu de MOVEA ou encore DBRA au lieu de DBE. Genlm2 permet l'assemblage du texte source soit en fichier objet prêt à être linké. Soit directement en programme exécutable. Il est malheureusement impossible de créer un fichier binaire pur, pour inclusion, par exemple, au sein d'un programme Basic (il faut pour ce faire passer par le déboggueur). Genlm2 peut être rendu résident et étre'appelé depuis le CLI ou GenAm2. Dans ce dernier cas, c'est l'éditeur qui se charge de lui transmettre toutes les options nécessaires, ce qui réduit son appel à l'appui sur une simple touche. L'assemblage peut se faire soit en mémoire pour permettre un déboggage immédiat, soit sur disque, soit enfin ne pas avoir lieu du tout, histoire de vérifier la syntaxe du programme, le tout suivant deux modes appelés Fast et Slow, le second utilisant moins de mémoire (utile pour les Amiga avec seulement 512 Ko de RAM). Outre les directives maintenant classiques sur Amiga (inclusion d'un autre fichier avec INCLUDE. Assemblage conditionnel avec IFC et consoeurs), on en trouve quelques unes qui facilitent grandement la tâche du programmeur : ce sont INCBIN (inclusion d'un fichier binaire, par exemple une image-écran, au sein du programme) ou encore 'SECTION (qui permet d'imposer le type de mémoire. Chip. Fast ou Public). Autre point fort de l'assembleur, la possibilité d'inclure des labels "locaux", c'est-à-dire valables uniquement entre deux labels "globaux". L’avantage est évident : on pourra trouver plusieurs fois dans le source une étiquette ".BOUCLE" sans que celà ne provoque de message d'erreur. Les macros sont également pleinement supportées et sont même récursives (une macro peut s'appeler elle-même !). Ce qui offre des possibilités très intéressantes (voir l'exemple de factorielle dans le manuel de Devpac II. Page 66). Autre excellent bon point pour Genlm2. Il optimise sur simple demande le code produit. Celà va du forçage des branchements courts (BRA.S au lieu de BRA) quand celà est possible au remplacement de certaines instructions par leur forme "QUICK". En passant par l'adressage court et la suppression des déplacements nuls dans les modes d'adressage du type indirect avec déplacement: d(An) et indirect avec indexation et déplacement : d(An,Ri). Enfin, tout fichier binaire produit, qu'il soit objet ou exécutable, peut intégrer des informations de déboggage que MonAm2. Ou tout autre déboggueur au format AmigaDOS. Pourra par la suite exploiter. LE DEBOGGUEUR Il s'agit sans doute du plus surprenant et du plus puissant des trois programmes composant ie Devpac. S'intégrant parfaitement dans l'univers multitâche de l’Amiga.

Click image to download PDF

AMIGA NEWS TECH numero 20 (03-1991)

Document sans nom AMI G A
I NEW 3-TE Ci-
Edito
2
Stéphane Schreiber
News
3
Langages : AMOS
4
François Lionnet
ToolBox : Devpac II vs K-Seka
8
Denis Obriot
ExecBase : les bibliothèques publiques
10
Max
Démo : les Rasters Verticaux
12
Franck Charlet
Interview : Franck Ostrowski (auteur du GfaBasic)
15
Stéphane Schreiber
Concours Listing : les fontes vectorielles
16
Morgan Chanet
Utilitaire : deux utilitaires sinon rien !
18
Frédéric Mazué
Sondage : nos lecteurs sont sondés !
23
SOFTRES ANT
SUB.way : l’Amiga et ses écrans
24
HDR GluntenStim...
Requester : le cours rieur délecté
27
Frédéric Marné
SUB.way II : le Consol.device
28
Max
Mode d’emploi de l’Ant
32
HUITRIC
Page écran de ComRoïd, premier tableau du logiciel développé sous Amos dans l’Ant ancienne formule.
Cette initiation continue dans les colonnes A'AMIGA Revue (voir rubrique programmation).
Ce numéro 20 de l’Amiga News-Tech a été tiré à 3000 exemplaires (2417 abonnés enregistrés le 10.02.91). Ce magazine est une publication Commodore Revue Sari. Téléphone de la rédaction : (1) 42 469 290
N
EDIT OH!
Voilà, ça y est, vous le tenez entre vos mains : l’Amiga News Tech nouvelle formule, le petit frère d Amiga Revue devenu grand, a enfin pris son envol solitaire.
Depuis le temps que Ton désirait faire de ce "journal dans le journal" un magazine à part entière... Rendez-vous compte, IANT devient le seul journal en langue française entièrement dédié à ici programmation sur Amiga. Jusqu'à présent, de tels magazines américains ou anglais existaient, mais difficiles à se procurer de par chez nous. Je pense notamment au Transactor, qui avait donné son nom à Tune de nos rubriques.
OURS
Tiens. Je savais bien qu'il y en aurait an moins un pour venir s'abiiiKr les yeux à lire les petits caractères. Alun. S'il. SU s'appelle l'Ouns ei sa puis île niais, ilu journal et îles détails qu'on est obligés de diainer. Nous, c'est Amiga New» Teell (ANTl. Une publication de Commodore Revue S. A. R. !.. l adresse, c'est le 5. Nie de la Fidélité. 7SIII0 Paris, le directeur île la publication s'appelle Jean-Yves Primas et on peut le joindre au (Il 42.-17. 12. I > tou- les jouis entre 12 11 (Kl et 12 11 (12. La cliuniinnic Christine Rohcri est sa sectélaitre de direction, yen a vraiment qui s'embêtent plis, la lédaclion. Mniiitciiniil. Lii seul nuniéni : 11142,4A. 92.9(1. Yi es Huilrie est le rédacteur en chef, courageusement assisté de Stéphane Sclireiber tédaetcur en chef adjoint.
Stépliane Schreiber. Qui sen également de secrétaire de rcda.ri.si Plusieur. Tixis furieux ont exéiaborc à ce numéro : Pascal Amiable- Franck Charli-t. François Lionel. Max. Frédéric Mazué. Antoine Mussard. Denis Obtînt et Stéphane Schreiber (encore lui r. La maquette est signée Yves Huitric. Pour abonner vos copains. Passe donc un coup de
fil à Claude au 11 > 43.78. iVL 21.
Voilà, c'cst tout. >*a d'aulne pages plu», intéressantes à lire.
Dcp*f'éc de Commodore Bum- nevx Machines et qu*Arnica New'-Tech cm une publication totalement indépendante de b xviété Comnxviwe France.
Ce numén> 3» d'Amila News Tech a été réalise sur un Arnica 3**» «7 Mo de mémoire. 68030. Ftickori-lxen avec les logiciels IX’Iuve Paint III. Excdlcnce! 2.0 et Ptolessional Page 10. Quelques nuits Manches et beaucoup de patience. Du coup, le 2 et le 0 sont nos chiffres potto-honheur. Bixxis à t«xis les empilons du monde.
Au sommaire de ce numéro 20 (déjà) : rien que du bon. Les rubriques habituelles, bien sûr : c'est ainsi que vous retrouverez le pantagruélique Frédéric Mazué et ses utilitaires fous-fous-fous, le germanique Doktor Von GlutenStimmellmDorf alias Mister Graphics, l'ex-militaire Max, spécialiste ès assembleur et retardataire de première, François "Amos " Lionet et tous les autres.
Mais également d’autres rubriques, nouvelles, qui profitent des 16 pages supplémentaires qui nous ont été généreusement offèites : avec d'abord le concours listing permanent (voirpage 16), l'invité du mois, le Forum, ou encore le Coin-coin des DemoMakers (page
12) . Les abonnés à la disquette y trouveront les sources et exécutables de tous les programmes publiés dans le journal, ainsi que quelques surprises supplémentaires (démos, domaine public...). Par exemple, la disquette de mars (ANTN°21) contiendra le compilateur C de Mat Dillon complet !
L ANT nouvelle formule, c’est également un saveur Minitel accessible par le 3615 code ANT dès le 16 mars, sur lequel vous pourrez retrouver tous nos collaborateurs, télécharger, échanger des idées, dialoguer avec des programmeurs célèbres...
L'ambition de ce nouvel ANT est de devenir la référence dans le domaine de la programmation sur Amiga. Malgré des débuts difficiles (saviez-vous qu'une cane Passerelle AT plantait irrémédiablement dans un Amiga 2000 équipé de plus de 5 Mo de RAM ? Nous l'avons appris à nos dépends) et quelques défauts de jeunesse ("nobody's peifect"...).
Et puisque le meilleur moyen de vous satisfaire est encore de savoir avec exactitude ce que vous attendez de TANT, allez faire un tour du côté de la page 27 où un superbe sondage vous attend. Trois réponses seront tirées au son. Pour faire gagner à leurs auteurs des heures de connection en 3614 sur le futur saveur ANT.
Stéphane Schreiber
NB : Nous annoncions dans notre dentier numéro d'Amiga Revue, le Guide le l'Amiga 91 en cadeau d'abonnement... Celui-ci étant encore en cours de fabrication, vous ne le recevrez que le mois prochain, avec le numéro 21 de TANT.
NEWS
COMPILATEUR GFA- BASIC
3. 5
Depuis le temps qu'on l’attendait, celui-là... Micro-Application vient tout juste de le sortir en France, il ne devrait pas tarder à débarquer chez vos marchands de frites favoris. L'interpréteur 3.5 se fait lui toujours attendre, puis la dernière version officielle est la 3.41.
Micro-Application, 58. Rue du Faubourg Poissonnière. 75010 Paris.
LA NOUVELLE BIBLE
La Bible de l'Amiga nouvelle édition de luxe est également disponible, mais pas depuis suffisamment longtemps pour pouvoir vous en parler plus longuement dans ce numéro de TANT. En tout cas. On m'a assuré chez Micro-Application qu'elle avait été ré-écrite pour éliminer tous les bugs de la précédente édition (voilà qui devrait faire taire
NE RATEZ PAS LES DISQUETTES DE FICHIERS "ARP" DU CAHIER PRATIQUE D’AMIGA REVUE
Frédéric Mazué). Des chapitres supplémentaires sur le système ont également été ajoutés. On vous en dira plus le mois prochain.
ADAPTEZ- VOUS !
Plus qu'un nouvel assembleur pour Amiga. Adapt est un ensemble de d'utilitaires pour les programmeurs en langage-machine, incluant un macro-assembleur 68040 (!). Un linker simple passe (les deux possédant un port Arexx). Un analyseur de modules et un profiler, le tout pour moins de 50 dollars. Car en effet, il s'agit d'un produit américain, que nous allons nous dépêcher de tester pour vous.
Lake Forest Logic. Inc.. 28101 Ballard Rd. Unit E. Lake Forest. II. 60045. USA.
LE RETOUR DU PROJET D
Ben Fuller, le bidouilleur fou docteur ès-pistes et secteurs, frappe encore en annonçant la version 2.0 de son fameux Projetc D. Pour ceux qui ne connaîtraient pas cet utilitaire, il se présente d’un programme maître chargeant plusieurs modules utilitaires baptisés "Tools". La version 2.0 comprend le BackupTool, un copieur soft de grande qualité, FomniTool. Capable de lire et écrire des disquettes au format MS-DOS ou TOS. L’EditorTool. Un éditeur de secteurs, ainsi que le CatalogTool. Un éditeur et optimiseur de répertoires. La version 2.0 est entièrement compatible avec le Workbench 2.0 des Amiga 3000.
Fuller Computer Systems, Inc. Tel :
(19) -1-800-874-3475.
L’EXPO
La troisième édition d'AmigaWorld Expo (ex-AmiEXPO) se tiendra du 15 au 17 mars prochains à l'hôtel New York Hilton, à New York. Donc. En plus du salon lui-même, plusieurs conférences de programmeurs sont prévues sur les thèmes les plus variés, comme par exemple la vidéo, le multimédia, la musique ou le Workbench
2. 0. Si vous avez les moyens et le temps d'y faire un tour, contactez AmigaWord Expo au
(19) -1-800-322-6442 ou écrivez leur à l'adresse suivante : AmigaWorld Expo. 465 Columbus Avenue. Ste. 285. Valhalla. NY 10595.
FAUX JUMEAUX
Le magazine américain AmigaWorld lance à peu près en même temps que nous l'ANT. L'AmigaWorld Tech Journal, un magazine en langue anglaise, dédié aux professionnels de la programmation. La parution est bimestrielle et l'abonnement magazine+disquette coûte
99. 95 dollars pour l'Europe. The AmigaWorld Tech Journal. P. O. Box 802. 80
|H| AMT : AMOS Technique
Nouveau journal, nouvelle rubrique g AMOS, plus technique et plus axée I sur le fonctionnement de B
l’interpréteur et ses astuces. Nous allons voir aujourd’hui le principe de I programmation d’une extension au I basic.... 1
MOS esi un langage extensible : on peut facilement ajouter de nouvelles instructions aux 600 déjà présentes. Il suffit de respecter quelques règles simples dans la construction du programme.
Pour assembler une extension, vous devez récupérer le fichier "EQL'.S" se trouvant sur la disquette "Extras". Dans le dossier "Extensions". Ce fichier contient la définition de toutes les variables système de F AMOS. Vous devez l'inclure dans votre programme.
Bien que ce ne soit pas indispensable, je vous conseille d'écrire du code relogeable, pour deux raisons :
- vous n'aurez pas à modifier les routines pour le compilateur AMOS qui. Lui. N'acceptera QUE du relatif pc :
- vous ressentirez l'immense satisfaction de produire un tel code!
CHARGEMENT DE L’EXTENSION
Au démarrage. AMOS explore la liste des extensions contenue dans le fichier AMOSl_2.Env. et charge tous les fichiers cités à l'aide de la fonction AmigaDOS LoadSeg(). Une extension est donc un programme normal, pouvant contenir plusieurs hunks. Immédiatement après le chargement, AMOS effectue un JSR à la première adresse du premier hunk. Une extension doit débuter impérativement par la routine d'initialisation à froid (ou "Cold Start").
AMOS transmet plusieurs paramètres à l'extension :
- A0 pointe sur la table d'adresse des routines AMOS :
- AI contient l'adresse de base de l'intuition.library :
- A2 contient l'adresse de base de la graphics.library :
- A3 contient l'adresse de base de la diskfont.library ;
- DO contient l'adresse du rastport de l'écran courant ;
- A5 pointe sur la zone de datas du Basic :
- A6 pointe sur la liste des tables d'instructions de toutes les extensions : De son côté, l'extension doit impérativement retourner plusieurs addresses
- dans A0. La table des instructions de l'extension :
- dans Ai. Le message de bienvenue :
- dans A2. L’adresse de la routine "Warm Start" :
- dans A3, l'adresse de la routine "Quit" :
- dans DO. 0 si tout va bien, -1 si une erreur quelconque est survenue (provoque le retour au CLI) :
- dans Dl. Le numéro de l'extension dans la liste :
- dans D2.0 en temps normal, ou l'adresse de la routine "Bank Check";
L’extension peut réserver de la mémoire, charger des fichiers, procéder à des affichages, faire du bruit, etc... Veillez cependant à ne pas trop ralentir le chargement de F AMOS. L’extension rend la main à 1 AMOS par un simple RTS.
INITIALISATION A CHAUD (WARM START)
Cette routine est appelée au cours de l’initialisation de l'écran, lors d'un RUN ou d'un DEFAULT. L'extension peut ici remettre a zéro toutes ses variables internes (si nécessaire).
ROUTINE DE FIN (QUIT)
Cette routine est appelée lors d'un retour au système. Elle doit faire un ménage complet, et ne laisser en mémoire aucune trace du passage de l'extension.
LA TABLE DES INSTRUCTIONS
Dans cette table sont codées toutes les nouvelles instructions et fonctions qu'ajoute l'extension. Cette table contient aussi les pointeurs sur les routines de traitement.
La table doit débuter par :
dc. vv 1.1
dc. b S80.-I
Suivent ensuite les instructions et fonctions. En premier, un pointeur relatif sur la routine de traitement, par rapport au début de la table (généralement baptisée Tk) :
Si c'est une instruction :
dc. w Routine-Tk.l
Si c’est une fonction :
dc. w I.Routine-Tk
Suit le nom de l'instruction en lettres minuscules, la dernière lettre étant signalée par l’addition de 128 (bit 7 à 1) :
dc. b "no"."m"+S80
Un point d’exclamation au DEBUT du nom sert de MARQUEUR sur ce nom. Un nom VIDE (S80 seul) indique a FAMOS de rechercher le marqueur précédent. Voir plus loin pour comprendre l'utilisation de ce
système.
Il faut maintenant donner a l’AMOS toutes les indications nécessaires pour le test de la syntaxe :
Le type de l’instruction :
- Instruction : "I"
par François LION ET
- Fonction retournant:
- un entier ''0"
- un réel "1"
- une chaîne "2"
La liste de paramètres, terminée par -1 :
- Aucun : -1 seul
- Un paramètre
- entier : "0"
- réel : “1"
- chaîne : "2"
- Un séparateur, seuls sont autorisés :
- la virgule, codée par
- TO. Codé par "t"
Quelques exemples vont rendre tout cela plus clair.
: Instruction ESSAI A.B
dc. w AdEssai-Tk.l
dc. b "essa"."i''+S80,"I0,0”.-1
: Instruction ANT AS.A TO B
dc. w AdANT-Tk.l
dc. b "an"."t"+S80."I2.0t0".-l
; Fonction entière =AMIGA(A,B.C.D). A. B. C et D sont entiers
dc. w l,AdAMIGA-Tk
dc. b "amig"."a"+S80."00.0.0.0".-1
: Fonction réelle =LIONO(A). A est un réel
dc. w l.AdMAX
dc. b “lion"."o"+S80," 11".-1
Certaines instructions ou fonctions peuvent accepter différents nombres de paramètres, par exemple SCREEN COPY. Il faut alors donner chaque syntaxe à la suite l'une de l'autre, en terminant la liste des paramètres par
- 2. La dernière liste se terminera par -1. Pour éviter de taper à chaque fois le nom de l'instruction, on peut utiliser les marqueurs vus plus haut. Voici la définition de SCREEN COPY dans AMOS :
: SCREEN COPY A TO B
dc. w Scop2-Tk,Synt-Tk
dc. b "Iscreen cop","y”+S80."I0t0",-2
: SCREEN COPY A.XI.Y1.X2.Y2 TO B.X3.X4
dc. w Scop8-Tk.Synt-Tk
dc. b S80."IO.O.O,O.OtO.O,0".-2
: SCREEN COPY A.XI.Y1.X2.Y2 TO B.X3.X4.M
dc. w Scop9-Tk.Synt-Tk
dc. b S80.”I0.0.0.0.0t0,0.0.0".-1 Notez bien que vous devez avoir une entrée de routine pour CHAQUE
jeu de paramètres.
TRAITEMENT D’UNE INSTRUCTION
Lors de l'interprétation, AMOS appelle votre routine. Les paramètres sont poussés dans la pile (A3), en ordre inverse. Votre routine doit dépiler TOUS les paramètres demandés, (sous peine de plantage I).
Vous ne devez pas modifier les registres A4, A5 et A6. A5 pointe sur la zone de données du basic. L'extension a donc un accès direct à tout l'AMOS (voir à ce sujet le fichier EQU.S).
TRAITEMENT D’UNE FONCTION
Le déroulement est pratiquement identique à celui d'une instruction. La valeur retournée doit être poussée en -(a3).
LA TABLE D’ADRESSES
Lors du démarrage de l'extension. AMOS fournit une donnée importante en A0 : la table d'adresses du Basic. Cette table contient des sauts à d'importantes routines d'AMOS.
Pour y accéder, il suffit de faire :
Move.l Table(pc),a()
Jsr Fonction(aO)
Voici une rapide vue d'ensemble des fonctions les plus intéressantes.
- Table + S04 : routine de traitement des erreurs normales. Cette routine provoque une erreur. Vous devez lui transmettre en D0 le numéro de l'erreur souhaitée. Tous les numéros se trouvent dans le "Handv Index" de l'AMOS. Cette fonction ne revient jamais, inutile de faire un JSR.
* Paramètres d'entrée :
- D0.1 = numéro de l'erreur
* Exemple d’appel, pour provoquer un "Illégal Function Call" :
Move.l Table(pc).a0
Moveq 23 .dû Jmp (aO)
Les valeurs contenues dans les registres A4-A5-A6 DOIVENT être identiques à celle fournies lors de l'appel de l'instruction.
La pile A3 est restaurée par le système lors d'un appel d'erreur : vous pouvez donc tester les erreurs lors du dépiletneni des paramètres (très utile lorsqu’il y en a beaucoup!) Sans avoir à vous en pré-occuper.
- Table + S08 : routine de traitement des erreurs spécifiques. Cette routine vous permet d'avoir vos propres messages d'erreurs.
* Paramètres d'entrée:
- D0.1 = numéro de l'erreur dans la nouvelle liste :
- Dl.l = numéro de Teneur à partir duquel ON ERROR fonctionnera. Vous pouvez ainsi avoir des erreurs non détournables par le Basic (par exemple, en cas de crash imminent!). Dans l'exemple, toutes les erreurs de l'extension sont détournables.
- A0.1 = adresse de début des messages. Chaque message se termine par un octet à zéro. Exemple de liste :
ErrList:
dc. b "Attention clavier trop chaud!".0
dc. b "Moniteur sur le point d’imploser".0
dc. b "Coca-Cola détecté entre les touches”.!)
: etc...
* Exemple d'appel :
Moveq “Errcur.dO Moveq 0.dl
Lea ErrLisH pci.aO Move.l Table!po.al Jmp 8( a I )
- Table + SOC : trouve l'adresse d'une banque. Petite routine utile si vous désirez récupérer des données dans une banque de mémoire.
* Paramètres d'appel :
- D3.I = numéro de la banque :
* Paramètres de sortie :
- AO.l = adresse de la banque si réservée :
- DO.I = longueur de la banque :
La routine provoquera une erreur "Bank not reserved" si elle ne peut trouver la banque demandée.
- Table + SI!) : routine de "tests”. AMOS appelle cette routine avant tous les branchements et boucles. C'est elle qui provoque le rafraîchissement des bobs, sprites et écrans, qui teste le CONTROL-C. Appelle les menus etc... Vous devez appeller cette routine régulièrement si votre extension garde la main pendant plus de l 50ième de seconde. Elle ne modifie aucun registre à part DO et A!) Et ne nécessite aucun paramètre d'appel.
- Table + S14: Wait. Alicnd un certain nombre de balayages écran tout en appelant la routine de tests.
* Paramètres d'appel:
- D3.I = nombre de balayages à attendre :
- Table +SI8 : adresse d‘un écran. Trouve les addresses d'une structure écran AMOS. Cette structure contient toute la définition interne de l’écran : position, addresses des bitmaps etc...
* Paramètres d'appel :
- Dl.l = numéro de l'écran ou bien fonction spéciale (=LOGIC(m. =PHYSIC(n» représentant l'écran logique ou physique.
* Paramétrés de sortie:
- AO.l = adresse de la structure écran :
- DO.I = adresse dans cette structure des addresses des bitmaps. Si un simple numéro d'écran ou la fonction =LOGIC est envoyé à la routine. DO pointe les bitmaps LOGIQUES. Si vous demandez =PHYSIC. Vous pointerez l'écran PHYSIQUE.
* Exemple d'appel :
Move.l (a.'i+.dl Move.l Table!pci.aO Jsr SI8(aO)
Move.vv NbPlan(aO).dl* Défini dans le fichier EQU.S Subq.vv I .d I
Move.l dO.al * Adresse des addresses Loop:
Move.l (al)+.a2
Move.l -l.(a2)* Pour s'amuser ! Dbra d 1 .Loop
- Table + SIC: adresse ou banque mémoire? Un certain nombre de fonctions A.VIOS vous permettent de représenter l'adresse de début d'une banque mémoire par le simple numéro de cette banque.
Exemple : Bload "Essai.Bin".10 et Bload "Essai.Bin“.Start( 10) sont deux instructions équivalentes.
.vxtinx vFvvs.ri rii 151 V *»n MARS IQQI
La routine numéro SIC fait celte opération pour vous. Elle dépile automatiquement le paramètre de la pile (a3).
* Paramètre d'entrée :
- (A3).l paramètre P à vérifier :
* Paramètre de sortie:
- D3.I adresse de la banque si P i6. Ou même valeur si P>I6 :
- Table + S20 : effacement de banque mémoire.
* Paramètre d'entrée :
- D3.I numéro de la banque à effacer. Vous pouvez ainsi créer dans une extention un instruction effaçant toutes les banques d'une seul coup (bien pratique ça. Pourquoi que je ne l'ai pas mis dans le Basic dès le départ, hein?). Cette routine ne provoque pas de message d'erreur si la banque n'est pas réservée.
- Table + S24 : demander un espace de chaîne. Cette routine n'est accessible qu'à partir de la version 1.23 (disponible maintenant !). Son but est de réserv er un espace dans la zone des v ariables pour retourner une chaîne de caractères. Elle gère automatiquement la “garbage collection" (ou ramassage des miettes).
* Paramètre d'entrée:
- D3.I taille de la chaîne demandée :
* Paramètres de sortie:
- AO.l et A1.1 adresse de stockage autorisée.
* Exemple d'appel: un routine inversant majuscules et minuscules :
* ****** -MAJMINS(AS)
Maj.Min
move.l (a3)+.a2 * Adresse de la chaine
moveq 0.d3
move.vv (a2)+.d3 * Taille
move.l Table!pci.aO
jsr S24(a0) * Demande la taille
move.vv d3.(al )+ * Taille de la réponse beq.s Mm4 subq.vv l.d3 M m I move.b ( a2 )+.d0
Si chaine vide
cmp.b "A".dO bcs.s Mm3 cmp.b "Z".d() bhi.s Mm2 add.b S20.d0 bra.s Mm3 Mm2 cmp.b "a".dO bcs.s Mm3 cmp.b "z".dO bhi.s Mm3 sub.b S20.d0 Mm3 move.b dO.lal l-r dbra d3.Mm I
Majuscule -> Minuscule
Minusucule -> Majuscule
Mm4 move.l a0.d3 moveq 2.d2 rts
1 Retourne le résultat
Voilà, on s'arrête là pour ce mois-ci. Mais on ne se quittera pas comme ça. Puisque je vous livre le listing d'une extension AMOS qui ajoute l'instruction ODD LOKE et la fonction ODD LEEK. Ca n'est pas grand chose, mais ça vous montrera comment il faut faire.
MCI
* Exemple simple d'extension au basic AMOS
* Assemble avec GENAM2
* Ajoute une; instruCLion: Ode Loke adresse,donnée : un LOKE
* qui marche pour des addresses impaires
* et une fonction: =Odd Lcek «Adresse)
INCLUSION DES VARIABLES SYSTEME Ir.clude "Equ.s"
• NUMERO DE L'EXTENSION DANS LA LISTE ExLNumb equ 1C
ROUTINE APPELLES LORS OU CHARGEMENT COLD START) move.1 2 0,dC
lea rk«pc),aO
move.l dû,Tabie-TklaG)
1 ea We 1 corne i p t : , a l
3ea Warmfpc>,a2
i ea End(pet,a 3
moveq ' =0,d2
moveq - Ex t Num.b - 1, d 1
moveq -C,dC
rts
scREEN RESET (rien i C1I ! Warm rts
QuiT (idem)
End rts
* INSTRUCTION “OddLoke A,B‘
Odd_Loke
move. 1 (a3 ) , dû
move.l (a3)+,dl
move.1 d i, a C
btst »C,dl
bne.s Lokl
move.l dC,;a0)
rt s
Lokl moveq - 3,d i Lok2 rcl.l “8,dC move.b dO,(aO)+ dora dl,l.ck2
FONCTION "Ode LeekiAî-
Odd_Leek move.l Ia3 >-,d0 move.l dC, aO btst C,dC bne.s Likl move.l a0),d3
Likl moveq =3,dî
Lik2 roi. 158, d3
move.b «a0;+,d3 dbra dl,Lik2
LISTE DES INSTRUCTIONS ET FONCTIONS Tk: dc.v; 1,0
dc. b S 80,-1
dc. w Odd_I,oke-Tk, 1
dc. b "ode iok¦,"e"-S80,"10,0",-!
OC . V: ! , Odd_I.eek-Tk
dc. b "ode lee","k"+S80,"00",-l
de. 0
ADRESSE DE LA TABLE DU BASIC Table de.1 0
TITRE DE L'EXTENSION Kelcorne dc.b 27,“Y",48*35,"Lisez l'ANTi!î",C
rie. 1 G
NE MANQUEZ PAS LE DEMARRAGE DU 36.15 ANT LE 16 MARS 1991 A PARTIR DE 20hOO
LE MOIS PROCHAIN DANS L’ANT
L’AGENDA DE PRESENCE (jours et heures) DE NOS JOURNALISTES SUR LE 3615 ANT
L’INVITE DU MOIS : FRED FISH
UTILITAIRE : RAJOUTEZ DES MENUS DEROULANTS A VOTRE SHELL
TOOLBOX: POWER-WINDOWS
DEMOS : UNE ROUTINE DE VECTOR-BALLS
DES NOUVELLES DU DEVKIT
ET BIEN PLUS ENCORE...
|0| Devpac 2 : le Kit des Cats
La version 2 de Devpac, L entièrement ré-écrite pour 0 Vamiga, permet la H
programmation en assembleur ¦ avec autant de facilité qu ’un |j langage interprété genre Basic. I
Le kit fourni par HISOFT comprend l'éditeur de textes sources, l'assembleur, le déboggueur et un linker du domaine public, Blink version 7.2, le tout dans un environnement intégré permettant l'écriture, la compilation et l’exécution sans passer par le CLI.
GenAm2. L'éditeur, est loin d'être aussi performant que d'autres du domaine public, comme A; ou même MicroEmacs : pas de macros re-définissables, édition d'un seul fichier en même temps... Il est cependant amplement suffisant pour des programmes assembleur et extrêmement rapide, aussi bien dans la gestion du texte que dans les recherches remplacements. Il est de plus paramétrable, de sorte que le programmeur peut choisir la taille du source qu'il va assembler (jusqu'à 3 Mo !). La création ou non de fichiers backups (,BAK). L'auto-indentation des lignes (très pratique) ou encore le passage à la ligne automatique (c'est une question de goût).
Quasiment toutes les fonctions disponibles sont accessibles soit par les menus déroulants, soit par le clavier, qu’il s'agisse du déplacement du curseur (avec une émulation des touches de Wordstar s'il vous plaît !). Du chercher-remplacer ou encore de la sauvegarde chargement du source. A noter que pour ces deux dernières fonctions. GenAm2 utilise le sélecteur de l'arp.library, à condition bien sûr que celle-ci se trouve dans le répertoire LIBS: du WorkBench (elle est de toute manière fournie sur les disquettes d'origine de Devpac). Dans le cas contraire, un bête requester demandant le nom du fichier est utilisé. La souris quant à elle ne sert qu'à positionner directement le curseur, bien que i'on apprenne rapidement à s'en passer.
Le plus indiscutable de GenAm2 est de permettre l'appel de l'assembleur et du déboggueur sans quitter l'éditeur : le cycle de développement usuel édition assemblâge dé- boggage en est grandement accéléré! On retrouve là la philosophie qui a fait le succès de Borland dans le monde PC. Philosophie d'ailleurs reprise de-ci de-là et notamment par Lanice avec la version 5 de son compilateur C.
L’ASSEMBLEUR
L'assembleur Genlm2 suit entièrement les définitions énoncées par Motorola pour le 68000 ainsi que pour les 68010 et 68020. Et accepte, comme beaucoup de ses confrères, quelques petites améliorations, comme par exemple la possibilité d'utiliser l'instruction MOVE au lieu de MOVEA ou encore DBRA au lieu de DBE.
Genlm2 permet l'assemblage du texte source soit en fichier objet prêt à être linké. Soit directement en programme exécutable. Il est malheureusement impossible de créer un fichier binaire pur, pour inclusion, par exemple, au sein d'un programme Basic (il faut pour ce faire passer par le déboggueur). Genlm2 peut être rendu résident et étre'appelé depuis le CLI ou GenAm2. Dans ce dernier cas, c'est l'éditeur qui se charge de lui transmettre toutes les options nécessaires, ce qui réduit son appel à l'appui sur une simple touche.
L'assemblage peut se faire soit en mémoire pour permettre un déboggage immédiat, soit sur disque, soit enfin ne pas avoir lieu du tout, histoire de vérifier la syntaxe du programme, le tout suivant deux modes appelés Fast et Slow, le second utilisant moins de mémoire (utile pour les Amiga avec seulement 512 Ko de RAM).
Outre les directives maintenant classiques sur Amiga (inclusion d'un autre fichier avec INCLUDE. Assemblage conditionnel avec IFC et consoeurs), on en trouve quelques unes qui facilitent grandement la tâche du programmeur : ce sont INCBIN (inclusion d'un fichier binaire, par exemple une image-écran, au sein du programme) ou encore 'SECTION (qui permet d'imposer le type de mémoire. Chip. Fast ou Public).
Autre point fort de l'assembleur, la possibilité d'inclure des labels "locaux", c'est-à-dire valables uniquement entre deux labels "globaux". L’avantage est évident : on pourra trouver plusieurs fois dans le source une étiquette ".BOUCLE" sans que celà ne provoque de message d'erreur. Les macros sont également pleinement supportées et sont même récursives (une macro peut s'appeler elle-même !). Ce qui offre des possibilités très intéressantes (voir l'exemple de factorielle dans le manuel de Devpac II. Page 66).
Autre excellent bon point pour Genlm2. Il optimise sur simple demande le code produit. Celà va du forçage des branchements courts (BRA.S au lieu de BRA) quand celà est possible au remplacement de certaines instructions par leur forme "QUICK". En passant par l'adressage court et la suppression des déplacements nuls dans les modes d'adressage du type indirect avec déplacement: d(An) et indirect avec indexation et déplacement : d(An,Ri).
Enfin, tout fichier binaire produit, qu'il soit objet ou exécutable, peut intégrer des informations de déboggage que MonAm2. Ou tout autre déboggueur au format AmigaDOS. Pourra par la suite exploiter.
LE DEBOGGUEUR
Il s'agit sans doute du plus surprenant et du plus puissant des trois programmes composant ie Devpac. S'intégrant parfaitement dans l'univers multitâche de l’Amiga. Il permet de traquer impitoyablement les bogues et les gurus sans disturber les autres lâches actives. Autrement dit. Même MonAm2 chargé, si une autre tâche vient à "planter", le ~Guru se manifestera tout de même.
MonAm2 est un déboggueur symbolique, c'est-à-dire capable de reprendre et d'utiliser les labels définis dans le fichier source, si ceux-ci existent. Dans le cas contraire, les addresses hexadécimales sont utilisées. L'utilisation de MonAm2 n'est possible qu'au clavier. Même s'il ouvre son propre écran (au sens Intuition du terme), aucun menu déroulant n'est disponible. Ce qui pourrait paraître à priori gênant se révèle rapidement fort agréable, d'autant plus que toutes les commandes ont été choisie de manière "parlante" (T pour Trace, L pour Load. Etc.).
L'écran est découpé en trois fenêtres : registres, désassemblage et dump mémoire. La première affiche donc le contenu de tous les registres du 68000 (en hexadécimal) ainsi que. Pour les registres d'adresses, les 4 premiers octets de l’adresse qu'ils pointent. Il est évidemment possible de modifier leur valeur à tout moment.
La fenêtre de désassemblage est par défaut pointée sur le PC. L'instruction en cours étant repérée par un signe supérieur (>). Mais il est bien entendu possible de la faire pointer sur n'importe quelle partie de la mémoire, voire même de la scinder en deux pour comparer deux routines. Comme on l’a déjà dit. Les informations de déboggage sont utilisées si elles existent et, plus fort encore, les appels aux libraries du système sont affichés en clair (JSR _LVOOpenScreen(a6) au lieu de JSR
- SC6(a6)). Enfin, le désassemblage peut-être obtenu sur imprimante ou sur disque en vue d'un ré-assemblage ultérieur par Genlm2.
La fenêtre de dump mémoire est également scindable en deux, afin de comparer deux zones de mémoires. Il est bien entendu possible d'éditer la zone pointée pour en modifier le contenu. Autre aspect intéressant, la fenêtre peut être "liée" à un registre donné, afin d'afficher en permanence la zone de mémoire qu'il pointe. Les opérations de remplissage, recherche et remplacement intelligent (c'est-à-dire pouvant couvrir deux zones se chevauchant) sont évidemment supportées.
Le contrôle du déroulement du programme en cours de dégoggage est assez précis. MonAm2 connaît cinq types de points d'arrêt (breakpoint). à savoir : simple (effacé après avoir été atteint), permanent, compté (arrêt du programme après un certain nombre de passages), conditionnel (arrêt du programme si une condition est remplie) ou... involontaire ("plantage" du 68000 après une erreur d'adressage, une instruction illégale, un TRAP. Etc.). Dans ce dernier cas. Il est possible de reprendre l'exécution du programme comme si rien ne s'était passé, simplement en changeant la valeur du PC. Enfin, la trace (déroulement pas à pas du programme) offre quatre possibilités : exécution de l'instruction pointée par le PC en traçant ou non les sous-programmes (BSR et JSR). Exécution du corps d'une boucle (DBcc) jusqu’à sa fin. Ou enfin incrémentation du PC sans exécuter l'instruction en cours.
Par Denis OBRiOT | | O |
K-SEKA : c’est ka.. jSilDl
Une commande particulière permet d’inclure
Enfin, il est possible de quitter MonAm2 en interrompant le programme tracé (mais attention à la mémoire réservée qui n'est pas libérée, aux écrans, fenêtres et fichiers non fermés, etc.) ou bien en le laissant continuer sa tâche comme s'il avait été lancé depuis le CLI.
PAS MAL, NON ?
Le pack de développement d'HiSofl offre tout ce qu'il faut pour réaliser depuis les petits projets jusqu'aux programmes de haut-niveau. Il est certes avant tout ciblé "système" - les programmeurs de démos et de jeux ont peut-être été un peu oubliés - mais reste pour l'instant le meilleur outil de développement en assembleur qui soit sur V Amiga. L'intégration du cycle édition-assemblage-déboggage est un plus indéniable qui permet un gain de temps considérable. A noter qu'une version "Pro" de Devpac existe - au moins en Angleterre - qui permet notamment le déboggage depuis une autre machine (Amiga ou Atari ST).
Denis Obriot et Stéphane Schreiber
Frédéric Mazué et Max n ’ont jamais caché leur antipathie vis-à-vis de l'assembleur de Kuma Computers, qui a pourtant toujours réussi à gagner les faveurs des démomakers, quelque soit la machine concernée.
C'est vrai qu'il a un look préhistorique, le K-Seka. Il fonctionne par "commandes", c'est-à-dire qu'une fois chargé, il attend patiemment les ordres du programmeur, qui peuvent être d'éditer le texte source, l'assembler, désassembler ou dumper une partie de la mémoire. On se croirait sous un Debug amélioré sous MS-DOS.
L'éditeur est sans doute le plus mauvais qu'il m'ait été donné d'utiliser sur un ordinateur. On y accède par la touche Esc et ne mérite même pas que l'on s'y attarde : aucune fonction n'est directement accessible (chargement. Sauvegarde. Chercher, remplacer...), il faut tout d'abord retourner au mode "commandes". Les capacité multitâches de l’Amiga permettent heureusement de palier à ce défaut, en utilisant un autre éditeur. K-Seka ne servant alors plus que d'assembleur.
ARGHHH, ORG
Le macro-assembleur ne présente aucune particularité ou fonctionalité particulière : il se contente d’assembler le plus fidèlement possible le texte source, ce qui est quand même la moindre des choses ! Il peut produire un code binaire selon deux formats : code objet pour linkage ultérieur ou code image pur. C'est-à-dire sans aucune information de relogement. Ce mode est idéal pour créer de petites routines relogeables à intégrer, par exemple, au sein de programmes Basic, et c'est d'ailleurs celui qui manque à Devpac. L'inconvénient est qu'il oblige à donner une adresse de chargement du programme (sauf dans le cas de programmes écrits en mode relatif au PC) à l’aide de la directive ORG. Une telle pratique est bien entendu à proscrire totalement dans un environnement multitâche, ou un programme peut être chargé par le DOS à n’importe quelle adresse libre et susceptible de l'accueillir. Celà convient par contre parfaitement aux démos qui ont besoin de se loger en CHIP-RAM pour fonctionner correctement... Celà dit. La directive SECTION" de Devpac propose une solution élégante à ce problème, et c'est celle que nous avons adoptée dans TANT [regardez la rubrique "démos" pour vous en convaincre).
Un fichier binaire dans le code produit, très utile pour charger des écrans, musiques ou autres données externes dans le programme. Il suffit pour celà de réserver à l'assemblage suffisamment de place (avec la directive "blk". L'équivalent du "deb" prôné par Motorola). Par contre. La directive INCLUDE. Très utile pour programmer des applications "amiga-lriendly". N'a pas été implémentée.
Enfin, il est à noter que notre pourfendeur de bugs devant l'éternel. Frédéric Mazué. Assure que le K-Seka en grouille, acceptant par exemple des instructions ne faisan! Pas partie du jeu du 68000. Et refusant au contraire d'en assembler de parfaitement valides !
MINI-MONITEUR
Le K-Seka possède également un
moniteur-débogueur intégré, qui. S'il est loin d'être aussi puissant que d’autres existant sur Tamiga. Permet d'explorer la mémoire, de tracer le programme instruction par
instruction en visualisant le contenu des registres, de positionner des points d'arrêt, etc. Il n'est malheureusement pas
symbolique, c'est-à-dire qu'il n’affiche pas les labels utilisés dans le code source, mais des addresses hexa-décimales (sur 32 bits, bien sur. Ce qui rend la lecture assez difficile). Dans l'ensemble, ce débogueur est le seul point intéressant du K-Seka.
K-SEKA VS THEOTHERS
K-Seka souffre à l'évidence d'un défaut incorrigible : il date. Sa conception même découle de principes mis au point voilà des années, conception aujourd'hui désuettes. Il donne l'impression assez désagréable de piloter un PC ou un Atari ST (une version du K-Seka existe sur chacune de ces machines) car ne tirant absolument pas partie des capacités propres à l'Amiga (fenêtres, etc.). De plus. Timpossiblité de créer des programmes directement exécutables sans passer auparavant par un compacteur quelconque, le rend plutôt inaccessible au débutant en assembleur sur Amiga. Il est en tout cas hors de question de l'utiliser pour concevoir un projet de large envergure (même le Métacomco est plus efficace), mais pour de petites routines, pourquoi pas ?
M
les bibliothèques publi
Devinette : quel est le moyen à la fois le plus simple, le plus efficace et le plus sûr d’accéder à toute la puissance du système d’exploitation de l’Amiga ?
101
Tous ceux qui ont répondu "les bibliothèques" ont le droit de lire la suite de cet article.
Bien sûr, on peut s’en passer, des bibliothèques. Il existe même certains cas où c’est obligatoire, notamment lorsque l’on se fiche du multitâche comme de l’an 40, et que tout ce que l’on souhaite, c’est faire de zoulis effets avec le Copper et ou afficher des zénormes bobs avec le Blitter. Messieurs les Demo- et GameMakers, vous m’aurez compris.
Mais dès que l'on se penche un peu plus avant sur la cohabitation de plusieurs tâches au même instant dans la même machine (subtil résumé du terme "multitâche"), les choses deviennent un peu plus hardues, voire franchement impossibles. Heureusement. L'Amiga met à notre disposition plusieurs séries de fonctions regroupées par thèmes dans ce que l'on appelle, justement, les bibliothèques ("libraries" en anglais).
CE QU’IL FAUT SAVOIR
Qu'est-ce qu'une bibliothèque, concrètement ? Il ne s'agit ni plus ni moins que d'un ensemble de fonctions, auxquelles on accède via une adresse de base. Pour clarifier les choses, l'adresse de base représente l'adresse d'une table de pointeurs sur les fonctions de la bibliothèque. Ces pointeurs sont relatifs à l'adresse de base et négatifs, car en fait l'adresse de base pointe sur la fin de la table. Pour accéder à une fonction particulière, il faut en connaître son numéro d'offset (c'est-à-dire sa position dans la table) ainsi bien sûr que l'adresse de base de la bibliothèque. L’appel ne peut se faire qu'à partir de l'assembleur, via l'instruction JSR. La règle veut que ce soit le registre A6 qui contienne l'adresse de base de la librarie (règle d'ailleurs obligatoire et immuable, étant donné que la majorité des fonctions accède à des données propres à la bibliothèque qui les contient, en utilisant A6 comme index). Un exemple typique d'appel d'une fonction serait :
movea.l Adresse_de_base,a6 jsr Offset_de_la_fonction(a6)
Pour qu'un programme puisse accéder aux fonctions d'une bibliothèque donnée, il doit d'abord lui en demander la permission. En jargon de programmeurs, on appelle ça "ouvrir la bibliothèque". Et comment fait-on pour ouvrir une bibliothèque ? On appelle une fonction d'une bibliothèque, tout simplement et paradoxalement en même temps.
Tout celà mérite une explication. Il existe en fait une et une seule bilbiothèque à laquelle on peut accéder sans rien demander à personne : il s'agit d'exec.library ; c'est elle qui se charge de la gestion du multitâche au sein de l'Amiga (partage du temps du microprocesseur, allocations de mémoire, communication entre tâches, etc.). L'adresse de base d'exec.library est la seule adresse "fixe" du système d'exploitation, garantie par Commo- dore-Amiga de le rester jusqu'à la saint Glin-Glin. On la trouve à l'adresse 4 :
ExecBaseEQU 4
movea.l ExecBase.aô jsr Fonction_Exec(a6)
Y’A QUELQU’UN ?
Les conventions mises au point par les gens de chez Commodore-Amiga indiquent que le passage de paramètres aux fonctions des bibliothèques se fait par l'intermédiaire des registres du microprocesseur. C’est en effet la méthode la plus rapide, mais également la plus gourmande en mémoire, puisqu'elle oblige à sauvegarder les registres utilisés par les fonctions. Heureusement, ces mêmes conventions limitent les dégâts, en garantissant que seuls les registres aO, al, dO et dl risquent d’être modifiés par les fonctions. Tous les autres sont préservés. Enfin, un usage "intelligent" des registres est fait, puisque toutes les addresses sont transmises par l’intermédiaire des registres d’adresse aO à a5 (a6 étant occupé par l’adresse de base de la bibliothèque) et toutes les autres données, par l'intermédiaire des registres... de données, oui. Une exception à cette règle : la dos.library, qui n’utilise que les registres de données. Enfin, dernière règle, quand une fonction doit retourner une valeur, c’est le registre dO qui la contient.
UN EXEMPLE !
Pour illustrer celà, nous allons utiliser l’exec.library pour ouvrir l'intuition.library (celle qui contient toutes les fonctions de gestion des fenêtres, menus déroulants et autres requesters). Le code présenté ici est écrit en assembleur avec Devpac II. Et en C avec le compilateur Lattice. Jugez-vous même de la différence entre les deux langages.
;; Flash.s
; Cet exemple ouvre la bibliothèque "intuition.library" et ; appelle la fonction DisplayBeepO qui fait flasher l’écran
INCLUDE"exec exec_lib."
INCLUDE"intuition intuition_lib.i”
main leaIntName(pc),al : Nom de la librairie à ouvrir moveq 0.d0 ; N° de la version demandée CALLEXEC OpenLibrary : Appel de la fonction move.l dO,_IntuitionBase ; Sauve l'adresse de base beq Nolnt ; sauf en cas d’erreur
move.l d0,a6 ; Adresse de base dans a6 suba.l a0,a0 ; Paramètre pour DisplayBeep CALLINT DisplayBeep : Appel de la fonction
move.l aô.al ; Paramètre pour CloseLibrary CALLEXEC CloseLibrary : Appel de la fonction
Nolnt moveq 0.d0 : Retour au CLI rts
Partant de là. On peut ouvrir toutes les autres libraries que l'on souhaite. _IntuitionBase:
AMIGA NEWS-TECH ETÎ1 NUMERO 20 MARS 1991
ques par MAX
IntName dc.b "intuition.library".0 even
Le même en C. maintenant.
*
Flash.c
Cet exemple ouvre la bibliothèque "intuition.library" et appelle la fonction DisplavBeepO qui fait flasher l'écran
Sinclude exec types.h>
include exec libraries.h> Sinclude intuition intuitionbase.h>
move.l (_SysBase).w.a6
jsr_LVOI(a6i
ENDM
_SysBase EQU 4
Sachant que dans le fichier "exec execjib.i". on trouve l'EQUate que voici :
_LVOOpenLibrary EQU -552
on en déduit que le programme assemblé ressemblera à quelque chose comme :
Start: lealntName(pc).al moveq SO.dO move.i 4. v.a6 jsr-552(a6)
move.l IntuitionBase.dO
VOID maintvoid)
(
struct IntuitionBase *IntuitionBase:
Intuition Base = (struct IntuitionBase *) OpenLibraryC'intuition.library". OL): if (IntuitionBase 1= NULL)
) DisplayBeep(NULL);
CloseLibrary((struct Library *)IntuitionBase):
1
I
(note : les trois lettres "LVO" signifient Library Vector Offset", soit en français dans le texte. Offset de Vecteur de Bibliothèque).
DERNIER POINT IMPORTANT
Et même très important : lorsque l'on ouvre une bibliothèque dans le but d'utiliser ses fonctions, il convient de la refermer avant de terminer le programme et de retourner au CLI ou au Workbench. Pour vous en
Reste encore un point à éclaircir : où trouve-t-on les numéros d'offsets des fonctions et comment sait-on quels paramètres elles attendent et. Pour les programmeurs en assembleur, dans quels registres les passer ? Il existe heureusement de la documentation spécialisée, notamment les fameux Rom Kernal Manuals. Dont Frédéric Mazué vous dit du bien chaque fois qu'il le peut. Il s'agit en effet de la documentation officielle de Commodore-Amiga sur les routines du système d'exploitation. Mais l'on peut également en trouver une liste (sans aucune explication, hélas) dans la Bible de l'Amiga. Dont Frédéric Mazué vous dit du mal chaque fois qu'il le peut.
Addresses
Les addresses de base des bibliothèques portent des noms particuliers, qui sont utilisés par le linker dans le cas du langage C, et par les macros dans le cas de l’assembleur. Voici un mémento des principales bibliothèques avec le nom symbolique de leur adresse de base.
SPECIAL ASSEMBLEUR
Alors que le langage C fournit un appel direct aux fonctions des bibliothèques (les références étant résolues lors du ‘linkage). Les programmeurs en langage-machine doivent en définir les offsets dans chacun de leurs programmes. Commodore - et Hisoft dans le cas de Devpac II - vient .fort heureusement à leur rescousse, en incluant dans leur assembleur un pool de fichiers baptisés "fichiers include". Qu'il suffit d'inclure dans le source pour pouvoir les utiliser. Ces fichiers contiennent la liste des offsets de toutes les bibliothèques ainsi que des macros facilitant leur utilisation. Pour reprendre l'exemple précédent, la macro CALLEXEC est définie comme suit :
Bibliothèque exec.library
intuition.library graphies.library dos.library layers. Library icon.library
CALLEXEC MACRO
Nom en Assembleur _SysBase ou ExecBase - _IntuitionBase • _GfxBase. _DOSBase. _LayersBase. IconBase.
Nom en C SysBase
ou AbsExecBase IntuitionBase GfxBase DOS Base LayersBase IconBase.
E
iconvaincre, examinons de plus près le fonctionnement de la fonction OpenLibraryt ).
Il dans un premier temps, elle recherche dans la Ram si la bibliothèque demandée n'a pas été déjà ouverte par une autre tâche (c'est souvent le cas. Puisque le Workbench et AmigaDOS utilisent eux-mêmes plusieurs bibliothèques). Si c'est le cas. Elle passe directement au point 5 :
2) dans le cas contraire, elle recherche si la bibliothèque demandée est située en Rom et si oui. Elle saute au point 5 :
3) sinon, c'est que la bibliothèque se trouve sur disque (généralement dans le tiroir LIBS: de la disquette Workbench), auquel cas elle la charge en mémoire et passe au point 5:
4) si on arrive là. C'est que la bibliothèque demandée n'existe pas. Et OpenLibrary retourne une valeur indiquant l'erreur (en l'occurence. Il s'agit de la valeur NULL) :
5) une fois la biliothèque trouvée (ou chargée depuis le disque). OpenLibrary saute à une routine interne à la bibliothèque, qui s'occupe d'inilialiser différents paramètres qui lui sont propres. Celà peut fort naturellement inclure des réservations de mémoire. De plus, une même bibliothèque pouvant être utilsée par plusieurs tâches "en même temps", un compteur interne est incrémenté, qui comptabilise le nombre de "clients" de la bibliothèque :
6) enfin, l'adresse de base de la bibliothèque nouvellement ouverte et initialisée est renvoyée au programme appelant dans le registre dO.
Lorsqu'on ferme une bibliothèque via CloseLibraryQ. Ce sont les opérations inverses qui sont effectuées :
1) saut à une routine interne à la bibliothèque, qui libère la mémoire allouée lors de l'ouverture et décrémente le nombre de "clients" :
2) si le nombre de "clients" est égal à zéro, la bibliothèque est tout bonnement effacée de la Ram. Il faudra la recopier depuis la Rom ou la recharger depuis le disque lors d'un prochain appel à OpenLibraryO.
On voit donc qu'oublier de fermer une bibliothèque conduit immanquablement à des "pertes de mémoire", qui peuvent tôt ou tard s'avérer critiques pour le système.
A noter que si vous avez chargé le Workbench en incluant la commande "LoadWB -debug" dans votre Startup-Sequence. Le menu "invisible" supplémentaire propose l’option "flushlibs". Qui permet de remédier à une "oubli” de fermeture.
THE END
Utiliser les bibliothèques présente deux avantages : dans un premier temps, on s'évite toutes les galères propres au multitâche que d'autres ont déjà résolues pour nous. Et dans un deuxième temps, on est sûr de rester compatible avec toutes les versions futures et à venir du système d'exploitation... à condition toutefois de respecter les règles imposées par Commodore-Amiga et de ne pas taper "n'importe comment n'importe où". Mais celà est une autre histoire...
WE NEED YOU : TANT est sans cesse à la recherche de nouveaux talents pour compléter son équipe pourtant déjà nombreuse et compétente, notamment pour la rubrique ExecBase. Si vous êtes spécialiste dans un domaine particulier (infographie, vidéo, démos. Multitâche ou que sais-je encore ?). N'hésitez surtout pas à nous contacter pour de fructueuses relations, et plus si affinités. Ecr. Au jnl. Qui trsm.
La solution est extrêmement simple et ne présente avec le Copper qu'un seul trait commun : son nom de "rasters". En effet, pour créer cet effet impressionnant, il ne faut pas utiliser le Copper mais le Blitter. Je ne m'attarde pas à vous présenter le Blitter et ses attributs, ceci a déjà été fait dans cette revue (cf. Commodore Revue 21 à 24). Passons donc tout de suite à l'explication : il suffit d'afficher tout d'abord 1 bob de 3 pixels de hauteur sur 16 de largeur et de l'animer de droite à gauche. L'astuce est de recopier ce bob quelques lignes plus bas. Tout en modifiant ses coordonnées pour créer un effet de vague, le Copper se chargeant ensuite de recopier la dernière ligne des bobs sur ce qui reste de l'ecranTen modifiant les valeurs modulo des bitplanes.
Le programme d'exemple qui suit anime 80 barres de ce type. Si vous désirez redessiner le bob qui nous sert de modèle, vous devrez prendre en considération les contraintes suivantes quant à sa taille :
- 16 pixels de largeur ( 1 mot) :
- 3 lignes de hauteur :
- 3 bitplanes (8 couleurs).
Notez bien que cette routine peut être très nettement optimisée, de façon à prendre encore moins de temps pendant le VBL (80 lignes de raster).
WIDTH EQU 120 ;3 PLANS DE 40 OCTETS
HEIGHT EQU 256
RASSIZE EQU WIDTH*HEIGHT
MOVE.L 1,1
MACRO
LEA 1, AO
LEA 2,Al
MOVE.W AO,-(SP)
CLR.W (AO) +
MOVE.W (SP)+,D0
MOVE.W DO,SDFF180 CMP.L Al, AO
BLO.S VIDÈÇ
; -- DEBUT DU PROGRAMME
0, DO
4. W.A6
- 552 (A6 ) ; OPENLIBRARY DO, Al
38 (Al), OLDCOP
- 414(A6) ;CLOSELIBRARY
SDFF000, AO
2 (AO), OLDDMA
SIC ( AO ), OLDINT
PRG ,-SAUT AU PRG PRINCIPAL
SDFF000, AO OLDDMA ( PC ), DO 15,DO
DO,$ 96(AO) ; REMET DMACON
OLDINT (PC), DO 15,DO
DO, $ 9A(A0) ;
OLDCOP(PC),$ 80(AO).
Les Rasters Verticaux
Créer des barres verticales d’un pixel de précision avec le Copper... Impossible ! Me direz-vous, et vous aurez raison. Pourtant de nombreuses démos possèdent cet effet (comme la Mégademo de Dragons).
BNE.S
MOVE.L
MOVE.L
ADD.W
MOVE.L
MOVE.L
MOVE.W
WAITBLT3:
BTST
BNE.S
MOVE.L
MOVE.L
ADD.W
MOVE.L
MOVE.L
MOVE.W
WAITBLT4:
BTST
BNE.S
MOVE.W
LIGNES
CLR.W
MOVE.L
MOVE.L
MOVE.L
ADD.L
MOVE.L
MOVE.W
ADD.W
AND.W
DBF
MOVE.W
ADD.W
AND.W
COMPARAISONS
AND.W
VIDE $ DFF09A (INTENA) ON NE SAIT JAMAIS!) STOPPE LE DRIVE
; EFFACE D'ABORD L'ECRAN
;MAINTENANT ON PEUT AFFICHER NOS BARRES .•ATTEND LE CLICK GAUCHE
,-ATTEND LE BLITTER
BNE.S MOVE.L MOVE.L
MOVE.W RTS
ROUTINE DES RASTERS VERTICAUX
Ëlfll
Avertissent
MOVE.B H$ FF,$ BFD100
; INITIALISATION DE LA COPPERLIST *
MOVE.L HCOPPERLISTl, $ 80(A6)
MOVE.W DO,$ 88(A6)
MOVE.W $ 1C(A6),D0 AND.W H$ F000,D0
ADD.W DO, DO
D0,$ 9A(A6) ;SUPRIME LES INTERUPTIONS
BSR.S EFFACE
BSR.S BARRES
BTST 6,5BFE001
BNE.S RASTERBEAM
RTS
EPFACE L'ECRAN DES BARRES *
14,$ DFF002 EFFACE
HPLAN, $ 54 (A6) ; POINTE SUR L'ECRAN
$ 1000000, $ 40 (A6) ; ET VIDE LE!
(1*64)+60,$ 58(A6) ; DIMENSION
OLDDMA: DC.W 0
OLDINT: DC.W 0
OLDCOP: DC.L 0
GFXNÀME: DC.B "graphies.library"
EVEN
;INITIALISATIONS GENERALES *
PRG: LEA $ DFFOOO,A6
VIDEPIC PLAN,PLAN+RASSIZE
INITPIC PLAN,CBPI
INITPIC PLAN+40.CBP2
INITPIC PLAN+80,CBP3
MOVE.W $ 7FFF,$ 9A(A6)
MOVEQ HO,DO ;VIDE DO INIT: MOVE.B H$ 87,$ BFD100
NOP NOP
MOVE -ï
; BOUCLE DU
RASTERBEAM:
' CMP.B
0,6(A6);BOUCLE A LA LIGNE 262
14,2(A6)
WAITBLT2
HSOURCEBOB+120,$ 50(A6)
SOURCEMAS K,$ 4C(A6)
40,A2 A2,$ 48(A6)
A2,$ 54(A6)
3*64 ) +2, $ 58 (A6) ,-DIMENSION DU PLAN 2
14,2(A6)
WAITBLT3
HSOURCEBOB+240,$ 50(A6)
«SOURCEMASK,$ 4C(A6)
40,A2 A2,$ 48(A6)
A2,$ 54(A6)
(3*64)+2,$ 58(A6) .-DIMENSION DU PLAN 3
14,2(A6)
WAITBLT4 $ 9F0,$ 40(A6)
$ 42(A6) .PLUS BAS -1,$ 44(A6)
$ 40004,$ 64(A6)
A3, $ 50(A6)
120,A3 A3,$ 54(A6)
(3*64)+18,$ 58(A6)
(A4),D0 ;COPIE LA BARRE+L'ECART
$ 7PE,D0 D7,BOUCLE 2(A4),D0 ;ANIME!
D0,4(A4)
$ 7FE,4(A4) ;CES 5 LIGNES EVITENT
$ 7PE,2(A4) ;SUR LA TABLE
; COPIE LA BARRE
PLAN+2,A3 BLOCKRASTER,A4 TABLE,A5 4(A4),D0 79,D7 ;80 BA
BARRES: LEA
LEA
MOVE.W
LSR.W
MOVE.L
ADD.W
AND.W
(A5,D0.W) ,D6
;AJOUTE D0 (VITESSE)
D6,D5
3,D6 ;= DIVU 8,D6 MAIS EN ? RAPIDE
A3, A2 D6.A2 $ F,D5 84, D5 D5,D6
$ FE2,D6 ,-MINTSRN A $ FE2 D6
MOVE.W D5,D6
14,2 (A6) ,-ATTEND LE BLITTER
WAITBLT1
D6,$ 40(A6)
$ FFFF, $ 44 (A6) ,-MASQUE LA MOITIE DU BOB $ 46(A6)
36,$ 64(A6)
,-MODULOS SOURCES ET DEST
36,$ 62(A6)
36,$ 60(A6)
36,$ 66 A6)
îrSOCRCEBOB, $ 50 ( A6 )
MOVE
MOVE
MOVE
MOVE
MOVE
HSOURCEMASK,$ 4C(A6)
A2,$ 48(A6)
A2,$ 54(A6)
(3*64) +2, $ 58 (A6) ; DIMENSION DU PLAN 1
Nous nous sommes toujours attachés, dans TANT, a vous présenter une programmation "propre", c'est-à-dire respectueuse de la machine et de son système d'exploitation, et par voie de fait, compatible avec tous les modèles de l'Amiga. Quelle qu'en soit la configuration (extensions drives supplémentaires..). Aviez-vous remarqué par exemple, que la directive "ORCï" était absente de tous nos listings assembleur, car bannie de notre vocabulaire ?
Les démos échappent la plupart du temps à ces règles, parfois pour des questions d'optimisation des routines souvent par fainéantise, ignorance ou nostalgie des 8 bits des "coders". Nous essaierons cependant tant que faire se peut, de "limiter les dégâts" en proposant des programmes les plus concis possible, et en insistent sur le fait que l'algorythme mis en oeuvre reste finalement plus important que la routine elle-même.
Par Franck CHARLET liloi
AND.W $ 7FE,(A4) ; (ET C'EST PLUS RAPIDE!)
RTS
SECTION DES VARIABLES *
LES 2 PREMIERES VALEURS DONNENT L'ECART ENTRE LES BARRES
ET LA VITESSE DE DEPLACEMENT *
VOUS POUVEZ EVIDEMMENT LES CHANGER A VOLONTE! ! ! *
ESSAYEZ PAR EXEMPLE 1010 POUR L'ECART
BLOCKRASTER:
DC. W 2020 ;ECART ENTRE LES BARRES
DC. W 10 ; VITESSE
DC. W 10
; TABLE DU DEPLACEMENT SUR X (BON COURAGE!)
TABLE: DC.W $ 0080,$ 0080,$ 0081,$ 0082,$ 0083,$ 0083,$ 0084,$ 0085
DC. W $ 0086,$ 0087,$ 0087,$ 0088,$ 0089,$ 008A,$ 008A,$ 008B
DC. W $ 008C,$ 008D,$ 008E, $ 008E,$ 008F, $ 0090,$ 0091, $ 0091
DC. W $ 0092,$ 0093,$ 0094,$ 0095,$ 0095,$ 0096,$ 0097,$ 0098
DC. W $ 0098,$ 0099,$ 009A,$ 009B,$ 009B,$ 009C,$ 009D,$ 009E
DC. W $ 009E,$ 009F,$ 00A0,$ 00A1,$ 00A2,$ 00A2,$ 00A3,$ O0A4
DC. W $ 00A5,$ 00A5,$ 00A6,$ 00A7,$ 00A7,$ 00A8,$ 00A9,$ 00AA
DC. W $ 00AA,$ 00A3,$ 00AC,$ 00AD,$ 00AD,$ 00AE,$ 00AF, $ 00B0
DC. W $ 00B0,$ 00B1,$ 0032,$ 0032,$ 00B3,$ 0034,$ 00B5,$ 00B5
DC. W $ 00B6,$ 00B7,$ 00B7,$ 00B8,$ 00B9,$ 00BA,$ 00BA,$ 00BB
DC. W $ 00BC,$ 00BC,$ 00BD,$ 00BE,$ 00BE,$ 00BF,$ 00C0, $ 00C0
DC. W $ 00C1,$ 00C2,S00C2,$ 00C3,$ 00C4,$ 00C4,$ 00C5,$ 00C6
DC. W $ 00C6,$ 00C7,$ 00C8,$ 00C8,$ 00C9,$ 00Ca,$ 00CA,$ 00CB
DC. W $ 00CB,$ 00CC,$ 00CD,$ 00CD,$ 00CE,$ 00CF,$ 00CF,$ 00D0
DC. W $ 00D0,$ 00D1,$ 00D2,$ 00D2,$ 00D3,$ 00D3,$ 00D4,$ 00D5
DC. W $ 00D5,$ 00D6,$ 00D6,$ 00D7,$ 00D7,$ 00D8,$ 00D9, $ 00D9
DC. W $ 00DA,$ 00DA,$ 00DB,$ 00DB,$ 00DC,$ 00DC,S00DD,$ 00DD
DC. W $ 00DE,$ 00DE,$ 00DF,$ 00E0,$ 00E0,$ 00E1,$ 00E1,$ 00E2
DC. W $ 00E2,$ 00E3,$ 00E3,$ 00E4,$ 00E4,$ 00E4, $ 00E5, $ 00E5
DC. W $ 00E6,$ 00E6,$ 00E7,$ 00E7,$ 00E8,$ 00E8,$ 00E9,$ 00E9
DC. W $ 00SA,$ 00EA,$ 00EA,$ 00EB,$ 00EB,$ 00EC,$ 00EC,$ Q0EC
DC. W $ 00ED,$ 00ED,$ 0OEE,$ 00EE,$ 00EE, $ 00EF, $ 00EF, $ 00F0
DC. W $ O0F0,$ OOFO,$ 00F1,$ 00F1,$ 00F1,$ 00F2,$ 00F2,$ 00F2
DC. W $ 00F3,$ 00F3,$ 00F3,$ 00F4,$ 00F4,$ 00F4,$ 00F5,S00F5
DC. W $ 00F5,$ 00F6,$ 00F6,$ 00F6,$ 00F6,$ 00F7,$ 00F7,$ 00F7
DC. W $ 00F8,$ 00F8,$ 00F8,$ 00F8,$ 00F9,$ 00F9,$ 00F9,$ 00F9
DC. W $ 00FA,$ 00FA,$ 00FA,$ 00FA,$ 00FA,$ 00FB,$ 00FB,$ 00FB
DC. W $ 00FB,$ 00FB,$ 00FC,$ 00FC,$ 00FC,$ 00FC,$ 00FC,$ 00FC
DC. W $ 00FD,$ 00FD,$ 00FD,$ 00FD,$ 00FD,$ 00FD,$ 00FD, $ 00FE
DC. W $ 00FE,$ 00FE,$ 00FE,$ 00FE,$ 00FE,$ 00FE,$ 00FE,$ 00FE
DC. W $ 00FE,$ 00FE,$ 00FF,$ 00FF,$ 00FF,$ 00FF,$ 00FF,$ 00FF
DC. W $ 00FF,$ 00FF,$ 00FF,$ 00FF,$ 00FF,$ 00FF,$ O0FF, $ 00FF
DC. W $ 00FF,S00FF,$ 00FF,$ 00FF,$ 00FF,$ 00FF,$ 00FF,$ 00FF
DC. W $ 00FF,$ 00FF,$ 00FF,$ 00FF,$ 00FF,$ 00FF,$ 00FF,$ 00FE
DC. W $ 00FE,$ 00FE,$ 00FE,$ 00FE,$ 001E,$ 00FE,$ 00FË, $ 00FE DC-W $ 00FE,$ 00FE,$ 00FD,$ 00FD,$ 00FD,$ 00FD,$ 00FD,$ 00FD
DC. W $ 00FD,$ 00FC,$ 00FC,$ 00FC,$ 00FC,$ 00FC,$ 00FC, $ 00FB
DC. W $ 00FB,$ 00FB,$ 00FB,$ 00FB,$ 00FA,$ 00FA,$ 00FA,$ 00FA
DC. W $ 00FA,$ 00F9,$ 00F9,$ 00F9,$ 00F9,$ 00F8, $ 00F8, $ 00F8
DC. W $ 00F8,$ 00F7,$ 00F7,$ 00F7,$ 00F6,$ 00F6, $ 00F6, $ 00F6
DC. W $ 00F5,$ 00F5,$ 00?5,$ 00F4,$ 00F4,$ 00F4,$ 00F3,$ 00F3
DC. W $ 00F3,$ 00F2,$ 00F2,$ OOF2,$ 00F1,$ 00F1,$ 00F1,$ 00F0
DC. W S00F0 $ 00F0 $ 00SF,$ OOFF,0OOFE.$ 00EE,$ 00EE.$ 00ED
DC. W $ 00ED,$ 0QEC,$ 00SC,$ 00EC,$ 00EB,$ 00E3,$ 00EA,$ 00EA
DC. W $ 00EA,$ 00E9,$ 00S9,$ 00E8,$ 00E8,$ 00E7,$ 00E7,$ 00E6
DC. W $ 00E6,$ 00E5,$ 00E5,$ 00E4,$ 00E4,$ 00E4,$ 00E3,$ 00E3
DC. W $ 00E2,$ 00E2,$ 0031,$ 00E1,$ 00E0,$ 00E0,$ 00DF,$ 00DE
DC. W $ 00DE,$ 00DD,$ 00DD,$ 00DC,$ 00DC,$ 00DB, $ 00DB,$ 00DA
DC. W $ 00DA,$ 00D9,$ 00Q9,$ 00D8,$ 00D7,$ 00D7,$ 00D6,$ 00D6
DC. W $ 00D5,$ 00D5,$ 0034,$ 00D3,$ 00D3,$ 00D2,$ 00D2, $ 00D1
DC. W $ 00D0,$ OODO,$ 00CF,$ 00CF,$ 00CE,$ 00CD,$ 00CD,$ 00CD
DC. W $ 00CB,$ 00CB,$ 00CA,$ 00CA,$ 00C9,S00C8,$ 00C8,$ 00C7
DC. W $ 00C6,$ 00C6,$ 00C5,$ 00C4,$ 00C4,$ 00C3,$ 00C2,$ 00C2
DC. W $ 00C1,$ 00C0,$ 00C0,$ 00BF,$ 00BE,$ 00BE,$ 00BD,$ 00BC
DC. W $ 00BC,$ 0033,$ 003A,$ 00BA,$ 00B9,$ 00B8,$ 00B7,$ 00B7
DC. W $ 00B6,$ 00B5,$ 00B5,$ 00B4,$ 00B3,$ 0032,$ 00B2,$ 00B1
DC. W $ 00B0,$ 0030,$ 00AF,$ 00AE,$ 00AD,$ 00AD,$ 00AC,$ 00A3
DC. W $ 00AA,$ 00AA,$ 00A9,$ 00A8,$ 00A7,$ 00A7,$ 00A6,$ 00A5
DC. W $ 00A5,$ 00A4,$ 00A3,$ 00A2,$ 00A2,$ 00A1,$ 00A0, $ 009F
DC. W $ 009E,$ 009E,$ 009D,$ 009C,$ 009B,$ 009B,$ 009A,$ 0099
DC. W $ 0098,$ 0098,$ 0097,$ 0096,$ 0095,$ 0095,$ 0094,$ 0093
DC. W $ 0092,$ 0091,$ 0091,$ 0090,$ 008F,$ 008E,$ 008E,$ 008D
DC. W $ 008C,$ 0083,$ 008A,$ 008A,$ 0089,$ 0088,$ 0087, $ 0087
DC. W $ 0086,$ 0085,$ 0084,$ 0083,$ 0083,$ 0082,$ 0081,$ 0080
DC. W $ 007F,$ 007F,$ 007E,$ 007D,$ 007C,$ 007C,$ 007B,$ 007A
DC. W $ 0079,$ 0078,$ 0078,$ 0077,$ 0076,$ 0075,$ 0075,$ 0074
DC. W $ 0073,$ 0072,$ 0071,$ 0071,$ 0070,$ 006F,$ 006E, $ 006E
DC. W $ 006D,$ 006C,$ 0063,$ 006A,$ 006A,$ 0069,$ 0068,$ 0067
DC. W $ 0067,$ 0066,$ 0065,$ 0064,$ 0064,$ 0063,$ 0062,$ 0061
DC. W $ 0061,$ 0060,$ 005F,$ 005E,$ 005D,$ 005D,$ 005C,$ 005B
DC. W $ 005A,$ 005A,$ 0059,$ 0058,$ 0058, $ 0057, $ 0056, $ 0055
DC. W $ 0055,$ 0054,$ 0053,$ 0052,$ 0052,$ 0051,$ 0050,$ 004F
DC. W $ 004F,$ 004E,$ 004D,$ 004D,$ 004C,$ 004B,$ 004A,$ 004A
DC. W $ 0049,$ 0048,$ 0048,$ 0047,$ 0046,$ 0045,$ 0045, $ 0044
DC. W $ 0043,$ 0043,$ 0042,$ 0041,$ 0041,$ 0040,$ 003F,$ 003F
DC. W $ 003E,$ 003D,$ 003D,$ 003C,$ 003B,$ 003B,$ 003A,$ 0039
DC. W $ 0039,$ 0038,$ 0037,$ 0037,$ 0036,$ 0035,$ 0035,$ 0034
DC. W $ 0034,$ 0033,$ 0032,$ 0032,$ 0031,$ 0030,$ 0030,$ 002F
DC. W $ 002F,S002E,$ 002D,$ 002D,$ 002C,$ 002C,$ 002B, $ 002A
DC. W $ 002A,$ 0029,$ 0029,$ 0028,$ 0028,$ 0027,$ 0026,$ 0026
DC. W $ 0025,$ 0025,$ 0024,$ 0024,$ 0023,$ 0023,$ 0022,$ 0022
DC. W $ 0021,$ 0021,$ 0020,$ 001F,$ 001F,$ 001E,$ 001E,$ 001D DC-W $ 001D,$ 001C,$ 001C,$ 0013,$ 001B,$ 001B,$ 001A,$ 001A
DC. W $ 0019,$ 0019,$ 0018,$ 0018,$ 0017,$ 0017,$ 0016,$ 0016
DC. W$ 0015,$ 0015,$ 0015,$ 0014,$ 0014,$ 0013, $ 0013, $ 0013
DC. W$ 0012,$ 0012,$ 0011,$ 0011,$ 0011,$ 0010, $ 0010, $ 000F DC .W $ 000F,$ OOOF,$ 000E,$ 000E,$ 000E,$ 000D,$ 000D,$ 000D
DC. W $ 000C,$ 000C,$ 000C,$ 0008,$ 000B,$ 000B,$ 000A,$ 000A
DC. W$ 000A,$ 0009,$ 0009,$ 0009,$ 0009,$ 0008, $ 0008,$ 0008
DC. W$ 0007,$ 0007,$ 0007,$ 0007,$ 0006,$ 0006,$ 0006,$ 0006
DC. W$ 0005,$ 0005,$ 0005,$ 0005,$ 0005,$ 0004, $ 0004, $ 0004
DC. W$ 0004,$ 0004,$ 0003,$ 0003,$ 0003,$ 0003, $ 0003, $ 0003
DC. W $ 0002,$ 0002,$ 0002,$ 0002,$ 0002,$ 0002,$ 0002,$ 0001
DC. W$ 0001,$ 0001,$ 0001,$ 0001,$ 0001,$ 0001, $ 0001, $ 0001
DC. W $ 0001,$ 0001,$ 0000,$ 0000,$ 0000,$ 0000,$ 0000,$ 0000
DC. W $ 0000,$ 0000,$ 0000,$ 0000,$ 0000,$ 0000,$ 0000,$ 0000
DC. W $ 0000,$ 0000,$ 0000,$ 0000,$ 0000,$ 0000, $ 0000, $ 0000
DC. W $ 0000,$ 0000,$ 0000,$ 0000,$ 0000,$ 0000, $ 0000, $ 0001
DC. W $ 0001,$ 0001,$ 0001,$ 0001,$ 0001,$ 0001,$ 0001,$ 0001
DC. W $ 0001,$ 0001,$ 0002,$ 0002,$ 0002,$ 0002, $ 0002, $ 0002
DC. W$ 0002,$ 0003,$ 0003,$ 0003,$ 0003,$ 0003, $ 0003,$ 0004
DC. W $ 0004,$ 0004,$ 0004,$ 0004,$ 0005,$ 0005,$ 0005,$ 0005
DC. W $ 0005,$ 0006,$ 0006,$ 0006,$ 0006,$ 0007,$ 0007,$ 0007
DC. W$ 0007,$ 0008,$ 0008,$ 0008,$ 0009,$ 0009, $ 0009, $ 0009 DC .W $ 000A,$ 000A,$ 000A,$ 000B,$ 000B,$ OOOB,$ 000C,$ 000C DC .W $ 000C,$ 000D,$ 000D,$ 000D,$ 000E,$ 000E, $ OOOE,$ 000F
DC. W$ 000F,$ 000F,$ 0010,$ 0010,$ 0011,$ 0011, $ 0011,$ 0012
DC. W $ 0012,$ 0013,$ 0013,$ 0013,$ 0014,$ 0014, $ 0015, $ 0015
DC. W $ 0015,$ 0016,$ 0016,$ 0017,$ 0017,$ 0018,$ 0018,$ 0019
DC. W $ 0019,$ 001A,S001A,$ 001B,$ 001B,$ 001B,$ 001C,$ 001C
DC. W$ 001D,$ 001D,$ 001E,$ 001E,$ 001F,$ 001F, $ 0020, $ 0021
DC. W $ 0021,$ 0022,$ 0022,$ 0023,$ 0023,$ 0024,$ 0024,$ 0025
DC. W $ 0025,$ 0026,$ 0026,$ 0027,$ 0028,$ 0028,$ 0029,$ 0029 DC .W S002A,$ 002A,$ 002B,$ 002C,$ 002C,$ 002D,$ 002D,$ 002E
DC. W $ 002F,$ 002F,$ 0030,$ 0030,$ 0031,$ 0032,$ 0032,$ 0033
DC. W$ 0034,$ 0034,$ 0035,$ 0035,$ 0036,$ 0037, $ 0037, $ 0038
DC. W $ 0039,$ 0039,$ 003A,$ 003B,$ 003B,$ 003C,$ 003D,$ 003D
DC. W$ 003E,$ 003F,$ 003F,$ 0040,$ 0041,$ 0041,$ 0042,$ 0043 DC .W $ 0043,$ 0044,$ 0045,$ 0045,$ 0046,$ 0047,$ 0048,$ 0048 DC .W $ 0049,$ 004A,$ 004A,$ 004B,$ 004C,$ 004D,$ 004D,$ 004E
DC. W$ 004F,$ 004F,$ 0050,$ 0051,$ 0052,$ 0052,$ 0053,$ 0054
DC. W $ 0055,$ 0055,$ 0056,$ 0057,$ 0058,$ 0058,$ 0059,$ 005A DC .W $ 005A,S005B,$ 005C,$ 005D,$ 005D,$ 005E,$ 005F,$ 0060
DC. W $ 0061,$ 0061,$ 0062,$ 0063,$ 0064,$ 0064,$ 0065,$ 0066
DC. W$ 0067,$ 0067,$ 0068,$ 0069,$ 006A,$ 006A,$ 006B,$ 006C
DC. W $ 006D,$ 006E,$ 006E,$ 006F,$ 0070,$ 0071,$ 0071,$ 0072
DC. W $ 0073,$ 0074,$ 0075,$ 0075,$ 0076,$ 0077,$ 0078,$ 0078
DC. W $ 0079,$ 007A,$ 007B,$ 007C,$ 007C,$ 007D,$ 007E,$ 007F ,--- DONNES EN CHIP RAM OBLIGATOIREMENT SECTIONCHIP,DATA_C ;MERCI DEVPAC!
COPPERLIST1:
DC. W $ 008E,$ 2C81,$ 0090,$ 18C1
DC. W $ 0092,$ 0038,$ 0094,$ 00D0 CBP1: DC.W$ 00E0,$ 0000,$ 00E2,$ 0000 CBP2: DC.W$ 00E4,$ 0000,$ 00E6,$ 0000 CBP3: DC.W$ 00E8,$ 0000,$ 00EA, $ 0000
;DIMENSION DE L'ECRAN
.•POINTEUR DES PLANS
DC. W$ 0100,$ 3200 ;3 PLANS+MODE COULEURS
DC. W $ 0102,$ 0000,$ 0104,$ 0000 DC .W $ 0108,$ 0050,$ 010A,$ 0050
DC. W $ 0120,$ 0000,$ 0122,$ 0000
DC. W $ 0124,$ 0000,$ 0126,$ 0000
DC. W $ 0128,$ 0000,$ 012A,$ 0000
DC. W $ 012C,$ 0000,$ 012E, $ 0000
DC. W $ 0130,$ 0000,$ 0132, $ 0000
DC. W $ 0134,$ 0000,$ 0136,$ 0000
DC. W $ 0138,$ 0000,$ 013A,$ 0000
DC. W $ 013C,$ 0000,$ 013E,$ 0000
DC. W $ 0182,$ 0FFF,$ 0184,$ 0DDF
DC. W$ 0186,$ 0BBF,$ 0188, $ 099F DC .W $ 018A,$ 077F,$ 018C,$ 055F
DC. W $ 018E,$ 033F,$ 0180,$ 0000
DC. WS7C09, -2
;+80 AU MODULOS
;PAS DE SPRITES
.•COULEURS DES BARRES
; LA LIGNE SUIVANTE PERMET DE RECOPIER LES BARRES SUR TOUT
L'ECRAN:
; EN METTANT LES MODULOS A -40, LES BITPLANES POINTENT TOUJOURS ; SUR LA MEME LIGNE!
DC. W $ 0108,$ FFD8,$ 010A,$ FFD8
DC. L-2 ; LE COPPER A TERMINE SON BOULOT!
; -- DESSIN DU BOB SOURCEBOB:
DC. W$ A995 ; 1ER MOT=DONNEE S DU BOB DCB.v; 59,$ 0000 ;PUIS 59 MOTS (118 OCTETS)
DC. W $ CE7 3 ;IDEM 2EME LIGNE DU BOB DCB.W 59,$ 0000
DC. W$ F00F ;ET 3EME LIGNE DU BOB DCB.W 59,$ 0000 ; -- MASQUE DU BOB SOURCEMASK:
DC. W $ FFFF DCB.W 59,$ 0000
; DONNES NON INITIALISEES EN CHIP
SECTIONCHIP,BSS_C
PLAN: DS.BRASSIZE ; RESERVATION MEMOIRE POUR L'ECRAN
END
C’est donc par un froid glacial que je débarquai au Parc des Expositions de la Porte de Versailles à Paris, où se tenait ledit
|H| Franck Ostrowski
Pour fêter la sortie de la version PC du GfA-Basic, Micro-Application avait invité son auteur en personne à venir passer quelques heures sur leur stand, au Forum PC. L’occasion pour nous d’aller recontrer ce jeune et sympathique allemand, véritable petit génie de l’informatique
salon. Et déjà, permettez-moi un petit apparté pour vous dire
que Commodore France y avait un stand ma foi plutôt grand et bien placé, juste devant l'entrée. Le PC Forum étant avant tout un salon professionnel (l’entrée est tout de même à 200 balles !). On pouvait y admirer surtout des PC (belle mentalité !) Et... un Amiga 3000. Fin de l’aparté.
Me voici arrivé devant le stand de Micro-Application, où un pot de bienvenue est offert à divers journalistes qui traînaient dans le coin. Hop, je me précipite sur un verre de whisky et demande à ce que l’on me présente le génie de service... Au lieu de ça. J’ai droit à un bonhomme assez bizarre mais tout-à-fait charmant et sympathique, à l'accent germanique assez prononcé : il s'agit de l’une des têtes pensantes de GfA SystemTechnik GmbH, qui accompagne son programmeur-vedette et lui sert de traducteur. Lequel programmeur-vedette est tranquillement assis derrière un PC, à tapoter comme un malade sur son clavier tout neuf -
mais qui ne va pas le rester longtemps s'il continue comme ça.
L’interview peut commencer.
Moi : Bonjour, Franck.
Lui : Bonjour.
Moi : Commençons par les questions bêtes mais obligatoires... Comment en es-tu arrivé à devenir programmeur chez GfA ?
Lui : Après avoir eu mon Bac, j'ai voulu m'inscrire à l'université pour étudier l’informatique. Malheureusement, je n'avais pas les moyens de vivre et de payer mes études en même temps. Alors je vendais des listings pour Atari 800 XL à des journaux pour gagner un peu d'argent. Un jour, j’ai publié dans Happy Computing un programme nommé Turbo-Basic, qui accélérait le Basic de cet ordinateur et y ajoutait quelques fondons. En lisant le journal, le directeur de GfA SystemTechnik a eu l’idée de m’appeler et m’a proposé de développer un Basic spécifique pour le nouvel Atari de l’époque, le 520 ST. qui disposait d'un très mauvais interpréteur. J’ai tout simplement accepté cette proposition.
Moi : Et le GfA-Basic était né. Et il a connu le succès que l'on sait.
Lui : Oui. Les versions ST ont été vendues à plus de 600.000 examplaires à travers le monde.
Moi : Pas mal ! Et la version Amiga ?
Lui : Bof... Seulement 35.000 examplaires. Le problème sur l'Amiga, c’est qu’il y a beaucoup de piratage. On a estimé à GfA SystemTechnik que pour un GfA-Basic Amiga vendu. 6 personnes au moins le copiaient...
Moi : C'est à cause de ça que les efforts n'ont pas été poursuivis ?
Lui : Non. Pas du tout ! Mais on a eu tellement de problèmes pendant le développement de la version Amiga, et puis j'ai du travailler sur la version PC, tout en pensant au compilateur... C’est très difficile de tenir à ce rythme, mais c’est aussi très excitant !
Moi : Des problèmes ? Quel genre de problème ? C’est en rapport avec le système d'exploitation ?
Lui : Oui et non. Notre grosse erreur a été de confier le travail de l'adaptation à un autre programmeur, afin que je puisse me consacrer à d'autres choses. Il a travaillé pendant presque un an dessus, au bout desquels son truc ne marchait toujours pas ! Il a donc fallu que je reprenne tout à zéro ! Quant à l'AmigaDOS. C’est vrai que c'esi un système difficile à aborder quant on est habitué aux 8 bits ou même au ST. Le multitâche impose tellement de contraintes... Mais je dois reconnaître que celà m’a donné quelques bases solides pour la version PC sous Windows qui est également multitâche, et pour une future version UNIX System V, déjà en préparation.
Moi : Je suppose que tout a été écrit entièrement écrit en langage-machine. Tu ne travailles qu'avec ce langage ?
Lui : Tu supposes bien, oui. Mais je programme également en C. voire même en Basic quand il s'agit de faire de petits programmes de test pour les algorythmes. Je gagne beaucoup de temps comme ça.
Moi 7 Micro-Application vient de sortir le compilateur 3.5. mais la l'interpréteur 3.5, lui. N'est pas encore là... Celà signifie-t-il que GfA SystemTechnik a décidé d’arrêter sa production sur Amiga ?
Lui : Non, nous continuerons à sortir de nouvelles version, notamment pour enlever quelques bugs qui traînent encore. Nous pensons également sortir des extensions spécifiques, comme une "DataBase ToolBox” ou un "TextEditor ToolBox". Mais ça, ça n'est encore qu'à l'état de projet. Comme je le l’ai déjà dit, le piratage sur Amiga freine beaucoup d’éditeurs de logiciels. Et c'est bien dommage, car c'est vraiment une machine qui mériterait de se développer encore plus.
Moi : A qui le dis-tu ! Encore deux petites choses : quels utilitaires de programmation utilises-tu, et que reproches-tu le plus à l'Amiga ?
Lui : J'utilises des assembleurs internes à GfA SystemTechnik. Dont certains tournent sur PC. Quant à l'Amiga. Le plus gros reproche que je puisse lui faire en tant que programmeur, c’est le Guru : pourquoi faut-il donc qu'il plante toute la machine ? Sur ST par exemple, on a des bombes qui d’affichent à l'écran, mais le blocage de l'ordinateur est rare. Sous Windows, quand une tâche plante, elle est tout simplement désactivée. Sur Amiga, deux fois sur trois, la machine se bloque pour un rien, et si on a pas pris la précaution de sauvegarder, tout est perdu ! Ca m’est déjà arrivé des dizaines de fois !
Moi : Heu... Tu sais que des utilitaires comme GOMF permettent de remédier à ce (léger) défaut ?
Lui : Maintenant, oui, mais à l'époque, je ne le savais pas ! Quand je me suis mis sur l’Amiga, je ne le connaissais absolument pas. Et j’ai du faire avec ce que j'avais sous la main, c'est-à-dire les Rom Kernal Manuals en tout et pour tout !
Moi : Ok. Pour terminer, un petit mot sur ce que tu souhaiterais faire ou voir venir dans le futur ?
Lui (après mure réflexion) : Ce que j’aimerais, c’est que la maladie du multitâche contamine tous les constructeurs d’ordinateurs. Je pense que c'est la voie naturelle que va suivre l’informatique dans l'avenir. En tout cas, c'est quelque chose dont on ne peut plus se passer une fois qu'on y a goûté.
La conversation continua quelques minutes, puis je pris congé de monsieur Ostrowski, qui replongea illico dans le programme qu'il avait abandonné pour moi quelques instants plus tôt. Ln-cor-ri-gi-ble !
Propos recueillis par Stéphane Schreiber
La différence entre une police "Bitmap" et une police vectorielle, tient essentiellement en ce que la police vectorielle est affichée par des calculs mathématiques, et non grâce à des matrices de points. Cependant, le calcul revient à transformer une police vectorielle en une matrice affichable, donc pour les petites tailles, il n’y aura pas de différence entre les deux types de polices. Niais l'avantage de la police vectorielle est qu'elle peut générer elle-même toutes ses tailles, sans limite théorique (seulement l'affichage), contrairement à la police Bitmap qui doit posséder chaque taille de corps de caractère, sous peine de représenter le caractère avec un effet d'escalier assez désagréable, en procédant à une multiplication des points de la matrice.
101
fontes vectorielles
U Amiga souffre d’un grave défaut au niveau des fontes de caractères : il ne connaît pas les polices vectorielles. Certains programmes, comme ProPage, implémentent donc les leurs, qui suivent leur propre format. En _voici un exemple.
LA THEORIE
Pour représenter la police vectorielle, j'ai renoncé aux coordonnées dites rectangulaires, où un point a pour coordonnées les valeurs x et y par rapport à l'origine, au profit des coordonnées dites polaires, où un point est défini par un rayon et un angle par rapport à l'origine. L'avantage des coordonnées polaires est essentiel lorsque l'on désire procéder à une rotation du caractère, car il suffit d'ajouter l'angle de rotation désiré à l'angle du point et le tour est joué !
Cependant, les instructions graphiques du GfA ne connaissant que les coordonnées rectangulaires (x.y). il faudra procéder à une conversion :
Conversion Polaire à Rectangulaire :
x = r * COS(alpha) y• = r * SIN(alpha)
Conversion Rectangulaire à Polaire :
r = SQR( x~2 + y~2) alpha = ATN(y x)
Dans mes routines, j'utilise les fonctions SINQO et COSQO qui travaillent dix fois plus vite que SIN(} et COS(). Même si la précision est moins bonne, elle est amplement suffisante.
LA PRATIQUE
Avant de pouvoir afficher une police, il faut en posséder les données. A cette fin. Chaque caractère de la police est formé par un certain nombre de vecteurs, théoriquement illimité, mais moires il y en aura, plus rapide sera l'affichage.
Par soucis de simplification, vous définirez vos caractères à l'aide de coordonnées rectangulaires, puis les données seront converties par le programme 2 en coordonnées polaires, sous la forme de DATA, que vous insérerez ensuite dans le programme 1.
Donc en premier lieu, écrivez vos définitions de caractères dans un fichier appelé "VectorFont.data" (utilisez n'importe quel éditeur de textes) sous la forme caractère, x 1. Y 1. X2, y2,.... xn, yn. -1.-1
Par exemple : A. 1.0. 1.7...., -1,-1
- l.-l indique la fin de la définition du caractère.
Chaque caractère est défini à l'aide de segments de droite, il faut donc deux couples de coordonnées pour chaque segment (xl.yl) et (x2,y2). L'origine des points sc trouve en haut à gauche de la matrice.
Enfin, vous devez prévoir la taille de la matrice de la définition d’un caractère dans les variables font_base% (largeur, en principe 8) et font_hcight% (hauteur, en principe 8).
Ces données sont converties en coordonnées polaires pour ne pas avoir à le faire pendant l'exécution du programme, ce qui gagne du temps. Les DATA sont lues et chaque segment est stocké dans un tableau nommé Font_data (). Un autre
OURS-COUCOU-CONCOU R S -C O U
Envie de participer à notre concours listing ? Rien de plus simple, il suffit de nous envoyer vos créations quelgu en soit le domaine (jeu, utilitaire, demo ou intro...) et quelque soit le langage utilisé (AmigaBasic, ufaBasic, C, Assembleur, AMOS). Le règlement est tout aussi simple et se plie aux contraintes de la mise en page du journal : le total article + listing ne doit pas dépasser deux pages, soit en moyenne 3000 caractères de texte (soit 50 lignes de 60 caractères) pour 200 lignes de programme (à raison de 75 caractères maximum par ligne). Ces proportions correspondent à 1 colonne de texte pour 3 colonnes de programme.
Qui dit concours dit cadeau : le gagnant se verra décerner non seulement nos plus sincères félicitations, mais également le DevKit ANT, composé de : - rassembleur Devpac Amiga version 2 - le compilateur C Lattice version 5 - la documentation officielle Commodore "Amiga Rom Kemal Manual" (3 volumes). Le choix du vainqueur sera effectué par la rédaction de l’Amiga News Tech, selon plusieurs critères parmi lesquels l’intérêt du programme bien sûr, mais aussi la qualité de la programmation. Tout le monde n’étant pas graphiste ou musicien, ces deux points ne joueront qu un infime rôle dans la décision finale. L’article quant à lui ne jouera absolument aucun rôle.
Envoyez vos chefs d’oeuvres : article, source ET exécutable ainsi que tous les fichiers annexes nécessaires à la compilation (images, sons...), accompagnés d'une
petite lettre vous décrivant, vous et votre configuration Amiga, à :
Amiga News Tech, 5, rue de la Fidélité 75010 Paris, France. Le cachet de La Poste ne fera foi de rien du tout.
Tableau nommé Font%() servant de table d'index pour retrouver les segments des caractères. D est à 2 dimensions : le premier indice varie de 0 à 255, équivaut au code ASCII. Le second peut prendre les valeurs 1 et 2 : 1 indique l’indice de départ pour Font_data (), 2 indique le nombre de segments pour le caractère demandé. De fait, rien n’oblige à construire une police entière ; on peut se contenter de définir les caractères dont on a réelleent besoin (d’ailleurs, à titre d’exemple, je vous donne la définition des chiffres 0 à 9 seulement). Les routines qui suivent sont relativement simples et suffisamment comentées. Vous pourrez même les améliorer, en permettant par exemple d’utiliser plusieurs polices en même temps... 0
Programme 1 : gestion des fontes vectorielles.
(?init_vec font
OPENS 1,0,0,640,512,2,32772 ! Ecran Hires Lace TITLES 1,"Test de Pontes Vectorielles"
OPENW 1,0,0,640,512,262144,256+2048+4096 r=l
FOR i%=0 TO 360 STEP 5 CLS VSYNC
edraw_line("023",320,220,r,r,i%) r=r+0.2 NEXT i%
PROCEDURE init_vecfont ! Initialisions pour la fonte vectorielle
font_base%=8 ! Largeur d'un caractère
font_height 8 ! Hauteur d'un caractère
DIM font%(255,2),font_data(400,4)
I I
' |_Code ASCII I Nombre de segments pour toutes les
lettres
' (à augmenter si nécessaire)
' font%( ,1) = Indice de départ pour Font_data ()
' font%(...,2) = Nombre de segments constituant la lettre
' font_data (___,1) = Angle
' font_data (___,2) = Rayon Début du segment
font_data ( ,3) = Angle ' font_data (...,4) = Rayon Fin du segment
RESTORE segment8
cpt_data%=l ! Compteur pour l'indice de Font_data () a$ =""
DO
READ a$
EXIT IF a$ ="Fin" font%(ASC(a$ ),1)=cpt_data% cpt_n_data%= 0 DO
READ ang,ray
EXIT IF ang=-l AND ray=-l font_data(cpt_data%,1)=ang font_data(cpt_data%,2)=ray READ ang,ray
font_data(cpt_data%,3)=ang font_data(cpt_data%,4)=ray INC cpt_data%
INC cpt_n_data%
LOOP
1. 4.0.4.8.4.0.2.2,-1,-1
2,2,2,2, 0,2,0,6, 0,6, 0,6, 3, 6,3,2, 8,2, 8,7,8,-1,-1
3. 1.0.7, 0,7,0,7,8,7,8,1,8,7,4,3,4,-1,-1 . 4,5,8,5,0,5,0,1,5,1,5,7,5,-1,-1
"I'_1 5,7,0,3, 0,3,0,1,3,1,3,7,3,7,3,7,8,7,8,1,8,-1,-1
6. 7.0.1.0.1.0.1.8.1.8.7.8.7.8.7.4.7.4.1.4,-1,-1
7. 1.0.7.0.7.0.1.8,-1,-1
8. 1.0.7, 0,7,0,7,8,7,8,1,8,1,8,1,0,1,4,7,4,-1,-1
9. 1.0.7.0.7.0.7.8.7.8.1.8.1.0.1.4.1.4.7.4,-1,-1
fontH ASC a$ ),2)=cpt_n_data%
LOOP
' Format des DATA = "X* (caractère défini) .angle,rayon,
(Fin de définition)
segments:
insérer ici les DATA data "Fin"
RETORN
PROCEDURE draw_caract car$ ,x%,y%,coef_x,coef_y,angle%)
' car$ = chaine contenant le caractère à afficher (ex: "A")
' x,y = coordonnées pour afficher le caractère dans l'écran ' coef_x = coefficient de déformation horizontale (multiplication)
' (si 1 alors pas de changement)
' coef_y = coefficient de déformation verticale (multiplication)
' (si 1 alors pas de changement)
' angle = valeur en degrés (0 à 360) pour incliner le caractère ' (si 0 alors pas de changement,
' si 180 alors le caractère sera à l'envers)
LOCAL xl%,yl%,x2%,y2%,k%
a%=font%(ASC(car$ ),l) ! Indice de départ pour
font_data ()
b%=a%+font%(ASC(car$ ),2)-l ! Indice d'arrivée pcxir
font_data ()
' Lecture des segments et conversion des Coor Polaires en Coor Rectangulaires
FOR k%=a% TO b%
xl%=ROUND(fantidata(2)*coe f_x*COSQ(font_data(k%,1)+angle%),0) y1%=round(font_data(k%,2)*coef_y*SINQ(font_data(k%,1)+angle%),0) x2%= ROUND(font_data(4)*coef_x*COSQ(font_data(3)+angle%),0) y2%=ROUND(font_data(k%,4)*coef_y*SINQ(font_data()c%,3)+angle%),0) LINE X%+xl%,y%+yl%,x%+x2%,y%+y2%
NEXT k%
RETORN
PROCEDURE draw_line (phrase$ , X%, y%, coef_x, coef_y, angle%)
LOCAL largeur%,k%,xx%,yy% largeur%=0
' Utilise aussi les conversions Coor Pol Rec pour aligner les caractères
FOR k%=l TO LEN(phrase$ ) xx%=x%+largeur%*COSQ(angle%) yy%=y%+largeur%*SlNQ(angle%)
Mraw_caract(MID$ (phrase$ ,k%,1),xx%,yy%,coef_x,coef_y,angle%) largeur%=lau eur%+font_base%*coef_x NEXT RETORN
Programme 2 : conversion des coordonnées cartésiennes en coordonnées polaires.
CLS
PRINT "Programne pour convertir les coordonnées rectangulaires des caractères"
PRINT "en coordonnées polaires (angle,rayon)"
OPEN "i", 1,"VectorFont.data" ! Source OPEN "O", 2,"VectorFont.lst" ! Destination
WHILE NOT (EOF( l))
INPUT l,a$ ! Caractère défini
PRINT 2,"DATA ";CHR$ (34);a$ ;CHR$ (34);",
PRINT
PRINT "Définition du caractère : ";a$
PRINT
DO
INPUT l,x$ ,y$ J Couple de coordonnées rectangulaires EXIT IF x$ ="-l" AND y$ ="-l"
PRINT "Rec(";x$ ;",";y$ ;")";
x=VAL(x$ )
y=VAL(y$ )
rayon=SQR(xA2+yA2)
IF X=0 THEN x=I.0E-12 ENDIF
alpha=DBG(ATN(y x))
PRINT 2,STR$ (alpha);",";STRS(rayon)
PRINT " > Pol(";alpha;rayon;")"
LOOP PRINT 2,"-1,-1"
WEND
CLOSE
Exemples 3 : coordonnées cartésiennes, à convertir avec le programme 2 et à insérer dans le programme 1 au label "segments:".
2 utilitaires sinon rien!
Vous connaissez sans doute les raccourcis claviers Commodore-N et Commodore-? Qui permettent de passer Vécran du Workbench en avant ou en arrière de la pile d’écrans. Seulement voilà, il n’est pas possible, dans le cas où trois écrans sont utilisés, de faire apparaîti'e de cette manière celui du "milieu".
101
Le programme que je vous propose installe un nouveau raccouci clavier permettant la permutation circulaire des écrans. De cette manière, chaque écran deviendra accessible sans qu'il soit nécéssaire d'utiliser cette vilaine petite souris toujours ensevelie sous une montagne de documents. Et puisque c’est la mode, nous allons agrémenter ce programme d’un blanker. En supposant que les touches du raccourci soient choisies, voyons d'abord ce qu'il est possible de faire afin de tester si celle-ci sont actionnées.
Il y a énormément de possibilités sur un Amiga. Il serait possible d'utiliser les messages Intuition, mais l'inconvénient serait alors la nécéssité de la présence d’une fenêtre active. Le même inconvénient se présenterait avec les devices CON: et NEWCON:. Enfin la méthode "je programme Amstrad ou Atari" qui coasisterait à lire en permanence les registres hardware afin de savoir quelles touches sont pressées, ne vaut pas un clou sur Amiga. Car cela ruinerait les performances du multitâche.
Considérant que notre programme devra être une véritable tâche de fond totalement transparente, voici les deux bonnes possibilités qu il nous reste : utiliser le console.devicc ou utiliser l'input.device. Sans raisons particulières, j'ai choisi l'inpuLdevice.
INPUT.DEVICE
L’inpuLdevice est une tâche qui est toujours lancée dès que le système démarre. Elle communique en permanence avec le clavier et les gameports afin d'obtenir des événements "crus" en provenance du clavier, de la souris ou du joystick. De plus, le timer.device travaille en étroite collaboration avec l'inpuLdevice pour la gestion de la vitesse de répétition des touches. Comme tous les devices. L’inpuLdevice est programmé à l'aide des routines système, OpendeviceQ. CloseDevice(). DoIO(). SendlOO et AbortlCX).
Les commandes traditionelles START, STOP. INVALID et FLUSH sont implémentées et donc valides. Les autres commandes standard ne sont pas reconnues. En revanche, l'inpuLdevice supporte les commandes spécifiques suivantes : IN D_WRITEE VENT. IND_ADDHANDLER,
I ND_REM HANDLER. IND_S ETTHRES H. IND_SETPERIOD, IND_SETMPORT. IND_SETMTRIG et IND_SETMTYPE.
Ne paniquez pas, voici l’explication de ce charabia.
IND WRITEEVENT : nous commençoas là par une commande tout à fait curieuse qui permet à l'utilisateur non pas de lire un événement reçu par l'input-device, mais de lui en envoyer un fabriqué maison qui sera reconnu et traité de la même façon que tout événement extérieur. Application : il est de cette façon possible de s'amuser en enregistrant par exemple les événements souris à panir de l'inpuLdevice, puis de les "rejouer" en renvoyant les événemenLs à l'aide de cette commande dans le même inpuLdevice.
INLLADDHANDLER permet d'ajouter un handler à la chaîne. Késako ? Et bien un peu plus hauL j’ai dit qu’il était mauvais de lire en permanence l'état des registres-machine. J'ai également dit que l’input.device communiquait en permanence avec le clavier et les gameports... Je vois des vilains avec un sourire en coin qui pensent que je ne sais même pas ce que je dis. Mais si, car l’input.device surveille le clavier en permanence, mais à partir de routines
* Programme: CRBlanker.c
* Fonctions: - Eteindre moniteur si ordinateur inutilisé après
* délai réglé par utilisateur
* - Permuter écrans Intuition
* Utilisation: Ctrl - Help pour régler délai
* Amiga gauche - Help pour permuter écrans
* Compilateur: Lattice C 5.10 Compilation: le -cist -v
* Linkage: FROM LIB:cback.o+"CRBlanker.o"+"blankerhandler.o"
* TO "CRBlanker"
* LIB LIB:lc.lib LIB:amiga.lib
SMALLCODE
SMALLDATA
_main= tinymain
* Auteur: F MAZUE pour ANT le 18 11 90
include exec types.h>
Sinclude exec nodes.h>
include exec lists.h>
include exec memory.h>
include exec ports.h>
include exec io.h>
include exec interrupts.h> include exec devices.h>
include libraries dos.h>
include devices timer.h>
include devices input.h> ffinclude devices inputevent.h> Sinclude intuition intuitionbase.h> include intuition intuition.h> include intuition screens.h> include graphics gfxmacros.h> include hardware custcm.h>
Sinclude hardware dmabits.h> sinelude string.h>
Sifdef LATTICE include proto exec.h>
include proto dos.h>
include proto intuition.h>
include proto graphics.h>
endif
DECLARATION POUR CBACK
ifdef LATTICE extern BPTR _Backstdout; char *_procname = "Blanker" LONG _BackGroundIO = 1; LONG _stack = 4000;
LONG _priority - 20;
endif
Sdefine PORTNAME "Blanker_Port"
Sdefine TICK 5L * interval de 5 secondes *
define Message "CRBlanker 1.0 par F Mazué"
VARIABLES GLOBALES
struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase;
Stringlnfo pour gadget de chaîne
d’interruptions. Autrement dit. La surveillance est permanente mais ne s'effectue pas tout le temps, seulement au rythme des interruptions de la machine. De même, l’utilisateur qui veut avoir connaissance et pouvoir traiter les événements, doit lui même ajouter un handler d’interrupdon qui sera chaîné avec les autres selon sa priorité. La rapidité d’éxécution étant de rigueur dans ce genre d’activité, il est de bon ton d’écrire le handler en assembleur. De plus, les conditions d'entrée (registres aO et al) sont telles que l’utilisation du C ou d'un autre langage nécessiterait un exercice de style tout à fait inutile, comme on peut sans rendre compte en examinant le source de l'étemel PopCLi fourni avec toutes les versions passées, présentes et à venir du Lattice. A titre indicacheveu (c'est tout de même plus poli qu’indicatif) les handlers d'intuition ont une priorité de 50 et ceux du console.device. une priorité de 0. Ainsi, avec un handler de priorité
51. Il est possible de bidouiller les événements avant qu'intuition n'v touche pour par exemple inverser les mouvements de la souris (cf. Le programme du RKM "libraries and devices" page 700. Oh quelle belle idée de virus !).
Par Frédéric MAZUE
IND_REMHANDLER permet de supprimer un handler de la chaîne. C'est la commande inverse de la précédente (si!). IND_SEl'lHRESH permet de fixer le délai de répétition des touches._
IND_SETPERIOD permet de fixer le délai à partir duquel commence la répétition des touches.
IND_SETMPORT permet de déterminer le port souris. IND_SETMTRIG fixe les conditions qui généreront un événement souris.
IND SETMTYPE fixe le device associé au port de la souris.
COMMENT ECRIRE UN HANDLER ?
C’est très simple : il suffit de savoir qu’en aO, est passé le premier événement et qu’en al, est passé le champ Data de la structure d’interruption correspondant à votre handler. Pour ceux qui n'auraient pas tout compris, l'article "Sentinelle” dans Commodore Revue 29 explique les interruptions avec suffisamment de détails. Les bienheureux qui possèdent les RKM pourront également s'y reporter.
L’événement dit "InputEvent" répond d’une structure dont le premier élément pointe sur le prochain, s’il existe. Ceci permet très facilement d'examiner tous les événements en attente et d’agir en conséquence.
Comme condition de sortie, il suffit de placer la valeur initiale de aO dans dO et c'est tout.
Voyons un peu la structure InputEvent
struct InputEvent struct InputEvent *ie_NextEvent;
UBYTE ie_Class;
UBYTE ie_SiibClass;
UWORD ie_Qualifier: union struct
WORD ie_x;
WORD ie_y; }ie_xy;
APTR ie_addr;
} ie_position:
struct timeval ie_TimeStamp;
UBYTE Buffer[2]=""; struct Stringlnfo MyStringlnfo =
Buffer,
NULL,
1, 2, 0,
0, 0.
0,
0,0,
NULL,
NULL,
NULL,
* position *
* dimensions *
* couleur de fond et crayon *
* flag evenement *
* flags *
* pointeur sur gadget de chaîne *
Gadget de chaine
*
struct Gadget MyGadget=
NULL,
* pas d'autre gadget *
95,48,
* position dans la fenêtre *
20,10,
* largeur et hauteur *
GADGHCOMP,
* flags *
RELVERIFY,
* activation *
STRGADGET,
* type de gadget *
NULL,
NULL,
NULL,
NULL,
(APTR)&MyStringInfo.
* pointeur sur Stringlnfo *
NULL
);
* fenêtre
pour réglage délai
struct NewWindow Reglage =

100,100,
250. 70,
1*3,
GADGETUP,
ACTIVATEIGIMMEZEROZERO, &MyGadget,
NULL,
"Blanker 1.0 par F MAZUE", NULL,
NULL,
* dimensions mini * * dimensions maxi *
250. 70,
250. 70,
} ;
struct NewScreen NewScreen =
0,0,320,12,1,
0,0,
NULL,
NULL,
NULL,
NULL,
NULL
char *text_reglage[] =

"(1-9) nb de minutes avant" "extinction des feux",
"(x ou X) arrête programme"
};
BYTE InputSig =-1; BYTE PermutSig =-1; BYTE InitSig =-1;
Le premier élément est déjà expliqué. Ensuite :
struct Task *task = NULL;
LONG TimeSigMask = NULL;
- ie_Class indique la provenance de l’événement : clavier, souris, gadget, menu. Etc. :
- ie_SubClass nous intéresse peu aujourd'hui : ce champ concerne essentiellement Intuition et les menus ;
- ie_Code donne le code de la touche clavier ou du bouton de souris responsable de l'événement ;
- ie_Qualifier indique quelle touche spéciale (Shift, Ctrl, Alt, Amiga) est actionnée :
- imposition est une union dans laquelle on trouvera suivant le type d'événement, soit la position du pointeur de la souris, soit une structure correspondant aux événements temps.
Pour connaître le code de touches vous pouvez vous reporter au RKM "librarics and devices" page 658. Quelques valeurs intéressantes :
Help = $ 5f Esc =$ 45 Tab = $ 42 FlàF10 = $ 50à$ 59 flèches = $ 4c à $ 4e
Pour en terminer avec 1'input.device, une petite précision peut être nécessaire : il ne faut pas confondre la chaîne de handlers avec la chaîne d'événements. Chaque handler de la chaîne est une routine à laquelle est passée la chaîne de tous les événements. Autrement dit, les événements sont tous examinés par tous les handlers. Ce qui justifie le besoin de rapidité de traitement.
Finalement et pour résumer, ce que nous voulons faire, ce n'est que rajouter un handler au système, cette routine devant elle aussi examiner toute la chaine d'événements et prendre ses dispositions en coaséquence. Grâce à tout ceci, nous allons pouvoir écrire notre programme très facilement.
LE TIMER.DEVICE
Que vient-il faire ici celui-là ? Et bien dans notre programme de permutations d'écrans, je vous ai proposé d’ajouter un blanker. C'est à dire une routine qui se chargera d’éteindre l’écran si durant une certaine période, aucun événement clavier ou souris n'est apparu. Ceci permet d'économiser le phosphore du tube cathodique.
Pour ce faire, nous allons utiliser le timer.device. Nous n'en dirons pas grand chose aujourd'hui car ce n'est pas notre propos principal. Le timer.device a pour vocation d'envoyer un message au port avec lequel il a été ouvert pour signaler la fin d'un délai programmé.
Il est à remarquer que chaque fois que le timer.device décrémente le délai, un événement est engendré, ce qui signifie que l'on pourrait intercepter tout ceci dans notre routine de traitement des événements. Si cette possibilité peut être parfois intéressante, dans le cas qui nous occupe, la simplicité veut tout bonnement attendre de façon on ne peut plas classique, le signal sur le port message.
DEUX TIMERS SINON RIEN
LONG InputSigMask = NtJLL; LONG PennutSigMask = NtJLL; LONG InitSigMask = NtJLL; LONG Sig = NTJLL;
LONG Time_Limite =24; LONG Time_Count = NtJLL;
* soit deux minutes *
LONG Active = NtJLL;
struct MsgPort *port = NtJLL,
* inputdevice_port = NtJLL,
* timedevice_port = NTJLL ;
struct IOStdReq ‘inputreq = NtJLL; struct timerequest ‘timereq =NULL;
struct Interrupt ‘InputHandler;
extern struct Custcan custcan;
Struct Custcm »cust = Scustom;
define custcan (*cust)
DECLARATION DES FONCTIONS
extern VOID MyHandler ( ) ,- VOID Clean_Exit();
VOID LaunchTimer(struct timerequest *tr,LONG secondes); LONG InitLimite ( ) ;
PROGRAMME PRINCIPAL
VOID mam()

struct Screen *BlankScreen = NtJLL;
if (port=(struct MsgPort *)FindPort(PORTNAME)) (
Active = IL; Clean_Exit();
Sifdef LATTICE i f (_Backstdout)
Write(_Backstdout,Message,sizeof(Message));
Close (_Backstdout),- • on libère le CLI *
_Backstdout=0;
(fendif
Suis-je déjà là ?
Port = (struct MsgPort *)CreatePort(PORTNAME,OL); if (iport) Clean_Exit();
Ouvertures et Initialisations
Il y a en effet deux timer.devices dans notre cher Amiga :
- UNIT_VBLANK.timer. synchronisé avec le blanc vertical, de bonne précision, et généralement suffisant pour la plupart des applications :
- UNIT_MICROHZ.timer, doué d’une précision d'enfer pour ceux qui auraient cassé leur chronomètre.
Les deux timers se programment de la même façon, si ce n'est que UNIT_VBLA. 'K compte en secondes et UNIT_MICROHZ en microsecondes. Tout ceci étant dit. Voyons un peu...
LE PROGRAMME
La routine assembleur du handler tout d'abord Là encore, pas de grosses explications (je suis si fatigué). L'obser :ateur attentif y verra que si un événement souris est reçu, un signal est envoyé au
if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0))) Clean_Exit();
if !(GfxBase • (struct GfxBase *)
OpenLibrary("graphies.1ibrary”,0))) Clean_Exit();
if ( ! (inputdevice_port = CreatePort (NtJLL,NtJLL) ) ) Clean_Exit ( ) ; if (!(inputreq = (struct IOStdReq *)
CreateExtIO(inputdevice_port,sizeof(struct IOStdReq)))) Clean_Exit(); if (OpenDevice("input.device",NtJLL,
(struct IORequest *)inputreq,NtJLL)) Clean_Exit();
if ( ! (timedevice_port = CreatePort (NtJLL, NtJLL) ) ) Clean_Bxit ( ) ; if (!(timereq = (struct timerequest *)
CreateExtIO(timedevice_port,sizeof(struct timerequest))))
Clean_Exit();
if (OpenDevice(TIMERNAME, tJNIT_VBLANK,
(struct IORequest *) timereq, NtJLL)) Clean_Exit();
programme principal. Donc une petite touchette sur la souris suffira à réâllumer l'écran. Si vous jugez que cette sensibilité est excessive, il vous suffit de supprimer ce morceau de programme.
Ensuite, dans le cas d'un événement clavier, on regarde si la touche Help (S5f) est pressée. Dans ce cas, on examine alors si l’une des touches Ctrl ou Commodore (Amiga-gauche) est pressée. Le signal correspondant sera envoyé au programme principal le cas échéant, sinon ce sera un signal clavier "simple". Si l’événement est d’une autre nature, aucun signal n’est envoyé et on passe à l’examen de l’événement suivant s'il y en a un.
TimeSigMask = (IL timedevice_port->mp_SigBit);
if((InputSig = AllocSignal(-lL)) == -1) Clean_Exit(); InputSigMask = IL InputSig;
if((PermutSig = AllocSignal(-lL)) == -1) Clean_Exit(); PermutSigMask = IL PermutSig;
if((InitSig = AllocSignal(-lL)) == -1) Clean_Exit(); InitSigMask ¦ IL « InitSig;
task = (struct Task *)FindTask(NÜLL);
* Installation du Handler
if(!(InputHandler =(struct Interrupt *)
AllocNemf sizeof(struct Interrupt),MEMF_PUBLICIMEMF_CLEAR))) Clean_Exit();
InputHandler->is_Code=(VOID (*)())MyHandler; InputHandler->is_Data=NOLL;
InputHandler->is_Node.ln_Pri=51;
InputHandler->is_Node.ln_Name="MyInputHandler"; inputreq->io_Data=(APTR)InputHandler; inputreq-> io_Command=IND_ADDHANDLER;
DoIO((struct IORequest *)inputreq);
LaunchTimer(timereq,TICK);
Le programme principal maintenant : il est écrit en C car C plus facile. Voyez d'abond dans l’entête, pour le linkage, le DEFINE
main= tinymain (notez bien les deux caractères soulignés).
Ceci sert à remplacer le _main du C par une routine qui ne s’occupera d’aucune entrée sortie. C’est une des manières d’éviter, lorsque le programme est lancé depuis le Workbench, l’ouverture d'une fenêtre par défaut.
Viennent ensuite les déclarations pour le cback du Lattice, qui permet au programme de se décrocher du CLI. Si votre compilateur ne dispose pas d’une telle option, ça n'est pas grave, il vous suffira de lancer votre programme par Run.
Après les diverses déclarations, le mainO : d’abord, le programme teste s’il a déjà été lancé ; on recherche pour celà un port du nom défini par le programme. Si ce port n’existe pas, celà signifie que le programme est lancé pour la première fois. Dans ce cas, on crée le port et l’on continue. Sinon, si le port existe déjà, c’est que le | programme, est déjà lancé et on quitte immédiatement.
L'éternité c'est long ... surtout vers la fin
Ensuite, les librairies et devices nécéssaires sont ouverts et les signaux alloués. Puis le handler est installé et le timer est lancé une première fois. Le programme se met alors en attente des différents signaux.
While(task)

Sig = Wait(TimeSigMaskIInputSigMaskIPermutSigMaskIInitSigMask);
if ((Sig & InputSigMask) && (BlankScreen == NÜLL)) Time_Count = NÜLL;
if ((Sig & InputSigMask) && (BlankScreen 1= NÜLL))

CloseScreen(BlankScreen);
ON_DISPLAY;
BlankScreen = NÜLL;
Time_Count = NÜLL;
if (Sig & InitSigMask)

if (BlankScreen != NÜLL)

CloseScreen(BlankScreen) ;
BlankScreen = NÜLL;
ON_DISPLAY
}
WbenchToFront();
Time_Limite = InitLimite();
Time_Limite *= 12;
Time_Count = NÜLL;
}
if (Sig & TimeSigMask)

if (BlankScreen == NÜLL)

Time_Count++;
if (Time_Count > Time_Limite)

BlankScreen = (struct Screen *)OpenScreen(&NewScreen); if (BlankScreen != NÜLL)

SetRGB4(&(BlankScreen->ViewPort), 0,0, 0, 0 ) ;
OFF_DISPLAY
}
i
}
LaunchTimer (timereq, TICK) ;
L’extinction de l’écran est réalisée comme suit : on ouvre un écran Intuition de très petite hauteur (12) afin d’éviter le problèmes de mémoire. L’encre de fond est mise à 0, couleur noire. Il reste à éteindre le pointeur de souris. Il est possible d'utiliser pour ce faire les routines SetPointerQ et ClearPointerO d’intuition. J’ai choisi une autre solution qui consiste à couper les directement DMA dans le hardware avec la macro OFF_DISPLAY, histoire de vous donner un exemple de programmation des registres-machine en C.
UN BUG (ENORME ET MONSTRUEUX) DU LATTICE
La boucle qui attend les signaux est une boucle sans fin. Normallemenu une telle boucle s’écrit en C soit for(;;) soit while( 1 ) mais ne le faites pas ici, car le compilateur vous fabriquerait n’importe quoi sans pour autant vous envoyer de message d’erreur (normal, le programme n’en comporte pas). Pas même un petit waming. Rien.
Ce bug se manifeste comme suit :
- si les fonctions sont déclarées avant main() et définies après, le bug apparaît - si les fonctions sont exprimées avant le mainO. Le programme est parfois compilé correctement..
Pour remédier infailliblement à celà, j’utilise while(task). Task étant l'adresse de base de la tâche. C'est une constante ultra-sûre. En faisant ainsi, le while n’est plus sans test et le programme est toujours compilé correctement. Ce n'est bien sûr pas la seule solution et de loin, on aurait même pu écrire le programme tout autrement, mais je n’ai pas pu résister à la tentation de laisser libre cours à ma médisance. M’enfin, le Lattice n'en reste pas moins (à mon avis) le meilleur compilateur C disponible sur Amiga Pour le >
moment.
(Sig & PermutSigMask)
if
Cet énôôôôrme bug du Lattice 5.04 n’a pas été corrigé dans le 5.10 I
if (BlankScreen)

CloseScreen(BlankScreen);
BlankScreen = NULL;
ON_DISPLAY
)
Time_Count = NULL;
ScreenToBack(IntuitionBase->FirstScreen),
dumny_string[l] = Buffer[0]; nb_minute = atoi(dumny_string);
Jwhile((Buffer[0] > '9') | (Buffer[0] ’l')]
CloseWindow(MyWindow);
retum(nb_ minute) ;
}
VOID Clean_Exit()

if (timereq != NULL)
(
if (timereq->tr_node.io_Device != NULL)

CloseDevice((struct IORequest *)timereq);
)
DeleteExtXO((struct IORequest *)timereq);
}
if (inputreq != NULL)

if (inputreq->io_Device !=NULL)

inputreq->io_Command = IND_REMHANDLER; inputreq->io_Data= (APTR)InputHandler; DoIO((struct IORequest *)inputreq); CloseDevice((struct IORequest *)inputreq);
)
DeleteExtIO((struct IORequest *)inputreq);
Programme : BlankerhandJens Fonction : routine assembleur pour le programme CRBlanker .Assembleur : Devpac 2 Assemblage : produire un code linkable sous le nom blankerhandler.o Auteur : Frédéric Mazué pour ANT le 1&11 90
include "exec exec_lib.i"
inelude "exec io.i"
include "devices inputevent.i"
XREF _task XREF _InputSigMask XREF PemutSigMask XREF _InitSigMask
XDEF _MyHandler
_MyHandler
move.l a0,-(sp)
rempiler chaîne d'événement
if (InputHandler) FreeMem(InputHandler,sizeof(structlnterrupt));
if (InitSig != -1) FreeSignal(InitSig);
if (PermutSig != -1) FreeSignal(PermutSig);
if (InputSig != -1) FreeSignal(InputSig);
if (timedevice_port) DeletePort(timedevice port);
if (inputdevice_port) DeletePort(inputdevice_port);
if (GfxBase) CloseLibrary((struct Library *)GfxBase);
if (IntuitionBase) CloseLibrary((struct Library •)IntuitionBase);
if ((port) && (!Active)) DeletePort(port);
exit(O);
}
VOID LaunchTimer(struct timerequest *tr,LONG secondes)

tr->tr_node.io_Cotnmand = TR_ADDREQUEST; tr->tr_time.tvsecs = secondes; tr->tr_time.tv_micro = 0 ;
SendIO((struct IORequest *)tr);
LONG InitLimiteO (
struct Window «MyWindow;
LONG nb_minute = NULL; char dummy_string[2];
if ((Mywindow = (struct Window *)OpenWindow(&Reglage)) == Clean_Exit();
Move(KyWindow->RPort,10,10);
Text(Mywindow->RPort,text_reglage[0],strlen(text_reglage[0])) Move(MyWindow->RPort,10,20);
Text(KyWindow->RPort,text_reglage[1],strlen(text_reglage[1])) Move(Mywindow->RPort,10,40);
Text(MyWindow->RPort,text_reglage[2),strlen(text_reglage(2)))
do

strcpy(dunmy_string,"+0”);
ActivateGadget(tMyGadget,Mywindow,0);
Wait( IL Mywindow->UserPort->mp_SigBit);
if (Buffer[0] =='x' | Buffer[0) --'X')
(
CloseWindow(Mywindow);
Clean_Exit();
Loop
move.b ie_Class(aO),dl move.l _InputSigMask,dO cmp.b IECLASS_RAWMOUSE,dl bne no mouse bra envoie_signaI
;evenement souris ? ;oui -> envoi signal
no_mouse
cmp.b IECLASS_RAWKEY,dl bne Next
move.w ie_Code(a0),dl cmp.w $ 5f,dl bne envoie signal
; touche HELP pressée
;non -> envoi signal clavier simple
move.w ie_Qualifier(aO),dl
btst SIEQUALIFIERB CofTTROL,dl ;touche contrôle pressée ? Beq suite
move.l _InitSigMask,dO
bra envoie_signal ;envoi signal pour
;ouvrir fenêtre de réglage
suite
btst IEQUALIFIERB_LCCMMAND,dl;touche amiga gauche pressée ?
;non -> envoi signal clavier simple
beq envoie_signal move.l _PermutSigMask,dO
;pour envoi signal .•permutation d'écran
envoie_signal move.l a0,-(sp) move.l _task,al CALLEXEC Signal move.l (sp)+,a0
Next
move.l (a0),d0 move.l d0,a0 toe Loop move.l (sp)+,d0 rts
,-pour positionner flag Z
.•prochain événement
.•récupérer liste événement dans DO
Hé oui, déjà un sondage, dès le premier numéro ! Comprenez-nous : il faut bien que l’on sache avec exactitude ce que vous vous attendez à trouver dans TANT, pour que l’on puisse vous offrir le meilleur journal de programmation sur Amiga de la galaxie (banlieue comprise). Faites un petit effort : un tirage au sort parmi toutes les réponses reçues attribuera à trois gagnants, 5 heures de connection chacun en 3614 sur le futur serveur minitel de l’ANT (ouverture le 16 mars 1991).
1. Gassez les rubriques suivantes selon votre ordre de préférence de 1 à 12:
News .... :
Langages ..:
L’invité du mois .....:
Tool Box ..:
ExecBase ..
Sub Way ...
Concours listing permanent.... :
Le Coin des DemoMakers......:
L’utilitare du mois ..:
Forum (dès le mois prochain !)
Requester ..:
Le Club Dorotohée :
2. - Quelle(s) rubrique(s) vous semble(nt) trop importante(s) ou carrément de trop, et pourquoi ? ......
Pourquoi une fourmi ? ......
Hein ? ...:
6. Ce sondage est nul, vous n’avez pas pu dire tout ce que vous aviez sur le coeur, alors profitez-en :
7. Renseignements personnels
Nom :
Prénoms :
Adresse : Code Postal :..
Ville : .Pays : .. ......
Force : ...Intelligence : ..Sagesse : ....Points de vie :
8. J’ai choisi la formule d’abonnement suivante :
5 mois sans la disquette ZZ 5 mois avec la disquette ?
11 mois sans la disquette ?
11 mois avec la disquette
Je le lis chez un abonné et je copie sa disquette. ?
Et j’explique les raisons de mon choix :
9. J’ai un avis précis sur le contenu de votre disquette, et je ne vais pas me gêner pour vous le donner : ..
10. Et enfin, je possède :
,, , , Unité centrale :
3. Quelle rubrique aimeriez-vous voir se développer ou apparaître dans Mémoire :
TANT ? .. Périphériques :
4. Sachant qu'un train A part de la Gare de Lyon à 5 h 45 et qu’un avion B décolle de l’aéroport d’Orly à 18 h 12. Quel est l’âge du capitaine C ?
5. Denise, la fourmi-mascotte de l’ANT vous paraît :
Rigolotte .. :
Superflue ...
Je programme en : ...
Voilà, ça n’était pas bien sorcier ? Il ne vous reste plus qu'à découper ou à photocopier (merci de ne pas recopier à la main) ce sondage et à nous l’expédier le plus rapidement possible à :
Amiga News Tech
5. Rue de la Fidélité 75010 Paris
|H| l’Amiga et ses écrans
En tant qu’ordinateur multitâche. L'Amiga possède une gestion d’écran assez particulière, mais ô combien efficace. Oui 11 'a jamais été amusé ou surplis, la première fois, défaire défiler l'écran du Workbench du bout de sa souris ?
Cette série d’articles a pour but de vous faire mieux connaître deux des bibliothèques (libraries dans la langue de Shakespeare) de l’Amiga, à savoir Graphics et Intuition.
La graphics.library contient toutes les fonctions de gestion des objets graphiques de base (écrans, sprites. Bobs) ainsi que les primitives de dessin (points, droites, cercles, remplissage...). L’intuition.library quant à elle est une plate-forme permettant le développement d'interfaces conviviales à base de menus, gadgets variés et autres fenêtres.
Cette étude sera formée d'une partie théorique et d’une série d’exemples, pour la plupart en langage C. Une connaissance du C (ou de tout autre langage structuré) sera donc très utile, ainsi parfois que des rudiments d’assembleur.
Enfin, un certain nombre de termes anglo-saxons difficilement traduisibles en fiançais seront utilisés tout au long de cet article. En cas d'incompréhension, reportez-vous au lexique de fin.
LES CONCEPTS DE BASE
Lorsque l'on crée une zone de visualisation, il faut prendre en compte deux éléments essentiels, qui sont le playfield et les sprites. Le playfield représente la partie statique de la zone de visualisation, alors que les sprites peuvent se déplacer et interférer entre eux ou avec le playfield. Nous étudierons les sprites en détails dans un prochain article.
Pour projeter son affichage. L’Amiga utilise une technique de balayage vidéo connue sous le nom de "Raster Display". Cette image est formée d’un certain nombre de lignes horizontales, créées par le faisceau électronique du moniteur. En mode normal, c’est-à-dire non entrelacé, il est possible d’afficher 256 lignes horizontales (200 en Mode NTSC). En mode entrelacé, on peut afficher 512 lignes (400 en NTSC). Comment est-ce possible ? C’est assez simple : pour afficher 512 lignes. L'Amiga commence par afficher en l 60éme de seconde une première série de 256 lignes représentant les lignes paires de l’image à afficher, puis il affiche les 256 lignes impaires après avoir décalé la position verticale de départ d’une demie épaisseur de ligne. Il existe toutefois un inconvénient à ce mode : pour tracer une image en mode entrelacé, l’Amiga met deux fois plus de temps, soit l 30ème de seconde. Or ce délai est trop long pour obtenir un affichage de qualité visuelle standard, ce qui explique le scintillement, si disgracieux, du mode entrelacé.
Chaque ligne visualisée est composée d’un certain nombre de points. Deux modes de précision horizontale sont également proposés. En basse résolution, chaque ligne compte 320 points, alors qu’en haute résolution, il est possible d’avoir 640 points par ligne. L’affichage en haute résolution ne permet plus que d'obtenir 16 couleurs à l’écran alors que nous en avions 32 en basse résolution. A noter la présence des modes EHB et HAM qui permettent respectivement d’obtenir 64 et 4096 couleurs simultanément à l'écran avec toutefois quelques contraintes, mais nous y reviendrons plus tard.
Pour dessiner à l’écran, il est nécessaire d’écrire dans une portion de mémoire, portion qui représente la zone de visualisation qui va être affichée sur le moniteur. Cette zone de mémoire est organisée sous
* -----------------------------
* Ouverture d'un écran sous yu-yb- ~s
* Auteur Pascal AMIA3LE (c) 1551
* -
Sinclude "exec types.h”
Sinclude "graphies gfx.h¦
include "graphics rastport.h*
Sinclude "graphics copper.h"
Sinclude "graphics view.h"
Sinclude "graphics gels.h’
Sinclude "graphies régions.h"
Sinclude "graphics clip.h*
S include "exec exec.h"
Sinclude "graphics text.h*
Sinclude "graphics gfxbase.h"
Sinclude "hardware dmabits.h*
Sinclude "hardware custctn.h"
Sinclude "hardware blit.h*
Sdefine PLAN 2 * Nccibre de 3itplane îssar.
Sdefine COLOR 4 * Nccibre ce codeurs c~. S;
Sdefine HORIZONT 640 * Largeur ce l'écran
Sdefine VERT 512 * Hauteur de l'écran en :
Sdefine MODE_V LACE * Mode de Sdefine MODEJVP HIRES+LACE * Mode de * Haute résolution et entrelacé
int i;
struct View view; * view associé à 1' struct ViewPort viewport; struct Raslnfo rasinfo; struct BitMap bitmap; * : struct RastPort rastport,-
struct GfxBase *Gfx3ase; *
struct View *ecran_sauvegarde;
* de sauvegarder 1 ' e-c:
UWORD colortable[COLOR] = 1x1 * Table des couleurs, * couleur 1 = RCQGE, ex * couleur3 = 3L5C
char ‘boutongauche = (char *
* correspond au !
Void init(),ouvréeran(), :
* ----------------
* Programme prit
void main()

init ( ) ; ouvréeran();
Move(&rastport,100,100); Draw(&rastport,200,200) ; while(!((*bouton_gauche h jilZ * gauche de la souris n'est LoadView(ecran_sauvegarde ; *
libéré(); * libératicc des rt
.------------------
* Init() Ouvre !
* ---------------
void init()

if((GfxBase = (struct
par Her De. Von TRUC.
Forme de "bitplanes". Un bitplane représente une zone virtuelle de traçage, permettant d'afficher une seule couleur (mise à zéro ou à un de chaque bit de la zone). L'affichage avec plusieurs couleurs est possible en superposant plusieurs bitplanes. On obtient alors 2AN couleurs, où N représente le nombre de bitplanes. Cette gestion des couleurs par superposition de bitplanes est réalisée grâce à un circuit spécialisé portant le doux nom de Denise. Un maximum de 6 bitplanes superposés est autorisé, soit dans l'absolu 2 couleurs
(64) . Cette assemblage de bitplanes s'appelle une bitmap (cf Frg 1 ).
STRUCTURES ET FONCTIONS D’AFFICHAGE
L'Amiga produit une zone d'affichage à partir d'une série d'instruction; organisée sous la forme, d'une structure C et baptisée "View". Cette zone d'affichage peut être décomposée en plusieurs parties distinctes, séparées par au minimum une ligne horizontale (une ligne de "raster") : ce sont les "ViewPorts", qui forment donc- dès zones rectangulaires (cf. Fig 2). Le ViewPort correspond au CustomScreen d'intuition, que nous étudierons plus tard.
Pour définir un ViewPort. Il faut dans un premier temps initialiser quelques paramètres : sa taille (hauteur et largeur), sa profondeur (le nombre de bitplanes utilisés) qui indique le nombre de couleurs, son mode de visualisation (basse ou haute résolution, interlacement...), l'adresse de la zone de mémoire utilisée pour l'affichage, et enfin sa position par rapport au coin haut et gauche de l'écran.
La hauteur est associée au champ Dhcight de la structure ViewPort. Elle représente le nombre de lignes verticales du ViewPort.
La largeur est contenue dans le champ Dwidth. Elle représente le nombre de pixels (points) par lignes du ViewPort. Il est possible de définir pour chaque ViewPort des largeurs différentes.
Le nombre de Bitplanes utilisés pour la mémoire d'affichage, conditionne le nombre de couleurs affichables dans le ViewPort sous la forme déjà citée : nombre_couleurs = 2Anombre_bitplanes. A noter le cas particulier du mode HAM qui autorise avec une profondeur de 6 bitplanes. L'affichage de 4096 couleurs, avec toutefois des contraintes de proximité. La profondeur est codée dans le champ utilisé Depth.
A chaque ViewPort est associée une palette de couleurs. Cette palette est spécifiée dans une structure baptisée ColorMap et rattachée au ViewPort par son adresse. Nous verrons cela un peu plus loin.
D existe 9 modes possibles de visualisation, le mode par défaut étant la basse résolution. Pour choisir un autre mode il faut remplir le champ Modes avec les valeurs adéquates, suivant la liste ci-dessous
NULL)
exit(l); * La bibliothèque graphies ne veut pas s'ouvrir *
ecran_sauvegarde = GfxBase->ActiView; * sauvegarde du View actif *
* ouvréeran() initialise et ouvre un écran
* *
void ouvrecran()

InitView(&view); * Initialisation de la structure View * InitVPortt&viewport); * Initialisation de la structure ViewPort * view.ViewPort = fiviewport; * On lie le ViewPort au View *
view.Modes = MODE_V; * On indique le mode visualisation du View *
InitBitMap(fcbitmap,PLAN,HORIZONT,VERT); * On initialise la bitmap *
rasinfo.BitMap = fcbitmap; * liaison de la Bitmap avec le Raslnfo * rasinfo.RxOffset = 0; rasinfo.RyOffset = 0;
rasinfo.Next = NULL; * pas d'autre structure *
viewport.DxOffset =0; * On remplit la structure ViewPort * viewport.DyOffset = 0; * cf l'article ci-dessus * viewport. Ewidth = HORIZONT; viewport.DHeight = VERT;
viewport.Raslnfo = ürasinfo; * liaison entre le viewPort et *
* le Raslnfo *
viewport.Modes = MODEJVP; * mode de visualisation du ViewPort * viewport.Next = NULL; * Pas d'autre ViewPort * viewport.ColorMap = (struct ColorMap *)GetColorMap(COLOR);
* initialisation de la ColorMap du viewPort *
LoadRGB4(&viewport,&colortable[0],COLOR);
* Chargement des couleurs dans la ColorMap *
for ( i=0;i PLAN;i++) * Allocation des bitplanes *
if ((bitmap.Planes[i] = (PLANEPTR)AllocRaster(HORIZONT,VERT)) == NULL) exit(2);
BltClear ((UBYTE *)bitmap.Planes[i],RASSIZE(HORIZONT,VERT),0);
* effacement de bitplanes au Blitter *
}
InitRastPort(firastport); * initalisation du RastPort * rastport.BitMap - &bitmap; * on lie le RastPort à la *
* bitmap dans laquelle on dessine *
MakeVPort(&view,&viewport); * On crée la zone de visualisation *
MrgCop(frview); * et la CopperList associée *
LoadView(&view); * on affiche l'écran sur le moniteur *
*
. *
void libéré()

for(i = 0;i PLAN;i++) * on libère la mémoire des bitplanes * FreeRaster(bitmap.Planes[i],HORIZONT,VERT);
libéré() libéré la mémoire utilisée
libère la mémoire de la *
FreeColorMap(viewport.ColorMap) * ColorMap FreeVPortCopLists(&viewport);
* libération de la CopperList* CloseLibrary(GfxBase); * Fermeture de la bibliothèque graphies *
- basse résolution (NULL) : dans ce mode, une ligne normale
Ovcrscan :
- haute résolution (HIRES) : la résolution horizontale passe ici à 640 pixels, ou 704 en Overscan :
- entrelacé (LACE) : l'affichage s'effectue en mode entrelacé, soit 512 lignes par écran au lieu de 256. Attention ! Lorsque vous spécifiez le mode LACE dans le ViewPort. Vous devez impérativ ement le spécifier également dans le champ View .Modes.
- Hold & Modily (HAM) : mode spécial permettant l'affichage de 40% couleurs simultanées à l'écran :
- double playfield (DUALPF) : le ViewPort est traité comme possédant deux zones d'affichage superposées et indépendantes :
- avec Sprites (SPRITES) : cette v aleur est obligatoire pour indiquer à l'Amiga que l'on va utiliser des sprites hanJvvares :
- playfield 2 avant 1 (PFBA) : cette valeur est liée au mode DUALPF et permet de positionner le playfield 2 dev ant le premier ;
- ViewPort caché (VP_HIDE) : indique que le ViewPort est caché et par là même, que son contenu n'est pas visualisé à l'écran :
- mode 64 couleurs (EXTRA_HALFBRITE) : dans ce mode. 64 couleurs sont affichées, les 32 dernières étant dérivées des 32 premières.
Pour obtenir, par exemple, un écran en haute résolution entrelacée, on mettra HIRES+LACE dans le champ Modes.
Comme le Vicvvport est de taille égale ou inférieure à la zone de visualisation, il est nécessaire d'indiquer sa position à l’écran. Cette position est définie par les distances DxOffset et DyOffset entre le coin supérieur gauche de l'écran et le coin supérieur gauche du ViewPort (cf. Fig 3). DxOffset doit être compris entre -16 et +352 (-32 et +704 en HIRES). DyOffset entre -16 et +256 (-32 et +512 en mode LACE) sachant que (0.0) positionne le ViewPort strictement dans le coin Haut et Gauche de l'écran. DxOffset et DyOffset sont deux champs de la structure ViewPort.
La zone de mémoire réservée pour l'affichage peut être plus grande que l'écran de visualisation et ce jusqu'à la taille limite de 1024x1024 points. C’est justement pour cela qu'il faut spécifier la position du ViewPort dans cette zone d'affichage, suivant le même principe que ci-dessus et à l’aide des champs RxOffset et RyOffset (cf. Fig 4). Ces deux valeurs sont stockées dans les champs de la structure Raslnfo portant le même nom. Cette structure contient également un pointeur sur la Bitmap d’affichage (structure BitMap).
Nous en savons maintenant assez pour créer notre propre écran. L'exemple ci-joint va nous permettre de passer en douceur de la théorie à la pratique, en crcant un simple View Port d'une taille de 320*200 av ec une bitmap de même taille. Il démontre également la manière de placer ce ViewPort par rapport à la structure View. Le mois prochain, nous verrons la génération de playlîelds avec Intuition, ce qui nous permettra d'étudier les différences entre les deux méthodes.
Herr Doktor Von GlutenStimmellmDorf.
Fig. 1 - Organisation de l'affichage sur Amiga Fig. 2 - Décomposition d'une zone d'affivehage.
Fig. 3 - Position du ViewPort à l'écran.
Fig. 4 - Position du ViewPort par rapport à la BitMap.
PETIT LEXIQUE
Bitmap : assemblage de bitplanes. Permettant de créer un écran pour le traçage en multi-couleurs.
Bitplane : littéralement plan de bits. Il s'agit d'une zone de mémoire organisée sous forme rectangulaire, permettant de représenter un écran de traçage virtuel.
Bob : alors que le sprite est indépendant du plasileld. Le bob en fait partie intégrante. Ce qui signifie que l’on doit gérer son interaction avec ie playfield. C'est le principe des brosses dsïs is logiciel de dessin.
Copper : processeur spécialisé de Faniga. Synchronisé sur le spot vidéo, il a été conçu rvxr gérer la partie affichage de I'Airriga grâce isx e: d'instructions propres.
Library : en français, bibliothèque- Ce tenue es
uüsé vit vs---tt es TruTfci je- de jonctions de fv'æu; cf açàaaacB je ~ ~rga. Qu'dles soârr c: ROM -cr isjyg (ex:
'grjtaesJbnry '.
Sprifc : cuit s iançax I Ctr-gie un objet g-roLTy nmam ai zàr-riec. Jj çwa se v ic* sr g aaaaBoc ce .tu-c sans en «-terrer e jkb uea 2te«r Tcteserter. Par ecer-pe j; ot va*ecai -«£ Jenaorrr sr m fond
II9ESI
Beaucoup de lecteurs nous écrivait afin de connaître Vadresse du club informatique le plus proche de leur domicile Nous ne répondons pas à ces demandes car nous ne connaissons pas les addresses de tous les clubs informatiques de France et de Navarre Nous vous suggérons donc de vous renseigner auprès du syndicat d’initativede votre ville Quant aux clubs qui désirait se faire connaître du grand-public, qu'ils n'hésitent surtout pas à nous écrire
_E:
L'idée de vendre 1'ANT séparément de Commodore Revue est une bonne idée, pointant je déplore deux points : premièrement, le fait que Ton soit obligé de s'abonner pour le recevoir et deuxièmement, le fait qu’il coûte le même prix que Commodore Revue (...).
Voici en fait l'objet principal de ma lettre. Ayant acheté "le Livre du Langage-Machine", je fis quelque chose déconseillé par celui-ci, c'est-à-dire lire l'adresse SDFFOOA en faisant qSDFFOOA avec SEKA. Je sais bien que la curiosité est un vilain défaut, mais je n 'ai pas pu m’empêcher de le faire, et depuis, chaque fois que j'enlève la souris du port I. le personnage contrôlé par l’intermédiaire du poit 1 (avec le joystick) est irrémédiablement dirigé vers le haut, et ce pour tous les jeux. (FM : notre lecteur de nous raconter dans le détail et avec désespoir tous les déboires auxquels il doit faire face).
Roger Humbert (Finniny)
Bien sûr, nous aurions nous aussi préféré une diffusion en kiosque pour TANT... Mais il faut être réaliste : le mondre de la programmation sur Amiga n’est pas encore suffisamment développé pour permettre la création d'un journal de 200 pages, tout en couleurs, que l'on vendrait 10 francs à 50.000 exemplaires. Si nous avons choisi la formule de l'abonnement, c’est en espérant bien que tôt ou tard, nous pourrons arriver à une diffusion nationale en kiosque. Quant au prix, nous essayons de le compenser par des cadeaux et des offres promotionnelles incomparables. Vous n’avez pas encore tout vu !
Je vous rassure tout de suite, votre curiosité n'a pas détruit votre
ANTDos
ordinateur. Si le simple fait de lire une adresse pouvait casser une machine, où irions nous ? Les bons conseils de ce livre sont bien entendu erronés, mais après tout, pourquoi y aurait-il moins de bêtises ici que dans la Bible (NLDR : ceci est une opinion personelle de F. Mazué qui n'engage que lui) ? 11 est parfaitement possible d'accéder auxdites addresses... C'est en fait K-SEKA qui en est incapable et qui plante lamentablement, comme vous pourrez vous en rendre compte en utilisant un autre utilitaire (comme MonAm2 de Devpac. Tout-à-fait au hasard). Mais je l'ai toujours dit. K-SEKA c’est caca (il y a tout de même des noms prédestinés !).
Pour ce qui est de votre panne, peut-être faut-il faire réparer votre machine, mais il est probable qu'un simple dépoussiérage résoudra votre problème.
Enfin la bonne nouvelle de TANT. En même temps que ce courrier, j’envoie mon abonnement. Bravo !
Par contre, je suis déçu de ne pas avoir eu de nouvelles de la lettre que j’avais destinée à Max, il y a deux mois. D'autant plus que j'ai même glissé une enveloppe timbrée pour la réponse. Je demandais tout simplement la marche à suivre pour faire tourner le "lecteur IFF". Ce n 'est pas grand chose, hein !? Sniff (NDMax : Sn-IFF ?) ! Comment fait-on avec 1'Amiga pour programmer une fonction de nombres aléatoires ? Est-ce une routine dans une librairie ou doit-on utiliser les timers et le VHPOS par exemple, et faire quelques algorithmes savants nous-mêmes ?
Ce vieil habitué et impatient de Patrick Hurtrel (Vichy)
Salut Patrick. Ton enthousiasme nous fait toujours plaisir, mais il faut être patient et indulgent car :
- les réponses paraissent dans le Requester environ deux à trois mois après réception du courrier. En ce moment, tu lis le numéro de février, mais nous préparons déjà celui de mai :
- nous ne pouvons hélas pas répondre à toutes les lettres. 11 faut comprendre que nous ne manquons ni de timbres ni d'enveloppes, mais bel et bien de temps. Et crois bien, ainsi que vous tous les autres déçus, que nous en sommes désolés.
Tu as raison, pour programmer une fonction aléatoire, il faut utiliser les timers ou le VHPÔS. Il n’y a rien dans les libraries. Mais il est très intéressant de passer par le timer.device. Quant à falgorythme savant pour obtenir une suite de nombres aléatoires, voila celui que j’utilise : c’est la relation de congruence
X[n+1] = (a * X[n] + c ) mod m
Ainsi, on peut "tirer" un nombre à partir d'un précédent, sans continuité mathématique apparente, ce qui donne un bon aspect aléatoire, a et c sont des constantes choisi par le programmeur, m permet d'obtenir l'intervalle dans lequel se situeront les nombres. Exemple : avec m=7. On obtient des nombres entre 0 et 6. On filtre le 0 et ainsi on peut simuler le jet d'un dé. J'envisage de vous faire prochainement un article là-dessus.
Réponses fournies par Frédéric Mazué
Console-Device
Le port IDCMP (Intuition Direct Communication Message Port pour les ignares) de toute fenêtre Intuition est un moyen simple mais pas très efficace de recevoir des caractères en provenance du clavier et d’en écrire dans ladite fenêtre.
101
En effet, le flag RAYVKEY ne renvoie que les codes clavier des touches, nous obligeant pour la conversion en ASCII à l'emploi de tables minimisant la compatibilité internationale du programme, et le flag VANILLAKEY renvoie bien le code ASCII, mais oublie au passage de prendre en compte les touches spéciales telles que F1-F10 ou encore Help. La seule solution lorsque Ton désire traiter la console avec tous les égards quelle mérite consiste donc à utiliser le deviee qui lui est dédié, autrement dit le console.device.
DEVICE ? VOUS AVEZ DIT DEVICE?
Avant tout, un bref rappel de ce qu’est un device semble s’imposer. Un device a la même structure qu’une librarie : il est composé d’un bloc de données et d’un bloc de sauts à des routines internes. Vous trouverez la définition de la structure Device dans le fichier 'exec devices.h’ pour les programmeurs en C. et ’exec devices.i’ pour les 68000eurs.
Pour communiquer avec un quelconque device. On utilise une autre structure définie dans ’exec io.h’ (resp. ’exec io.i’) :
struct IOStdReq struct Message io_Message: struct Device *io_Device; struct Unit *io_Unit: UWORD io_Command; UBYTE io_Flags;
* structure message*
* réservé au device*
* réservé au device*
* Commande à effectuer* l* Flags particuliers*
* oO en cas d’erreur*
* nombre d’octeLs transférés*
* à transférer*
* pointeur sur le buffer 10*
* offset particulier*
BYTE io_Error.
ULONG io_Actual; ULONG io_Length: APTR io_Data;
ULONG io_Offset:
D est à noter que certains devices utilisent des structures 10 étendues ; c’est le cas du trackdisk.device par exemple, qui utilise une structure nommée IOExtTD et définie dans ’devices trackdisk.h’.
La structure Message est celle qui permet au device de communiquer avec la tâche qui l’a ouvert. La première étape à l'ouverture d’un device est donc la création d'un 'message port’. La fonction CreatePortO de l’Amiga.lib fait ça très bien pour noas :
struct MsgPort *messageport;
messageport=(struct MsgPort *)CreatePort("MonPort". 0);
Ce qui donne en assembleur :
XREF _CreatePort
CLR.L -(A7)
PEA NomDuPort(PC) JSR _CieatePort
***
'est parti .!
NomDuPort:
Compilation (Lattice 4.0) : le -csuw -d -r -b Console.c
Linkage :
FROM LIB:c.o,Console.o TO Console
LIBRARY LIB:le.lib,LXB:amiga.lib
SMALLCODE
SMALLDATA
VER30SE
NODSBÜG
include exec types.h>
include exec io.h>
Sinclude exec memory.h>
Sinclude intuition intuition.h> include libraries dos.h> include devices console.h> include proto all.h>
Sifdef LATTICE
int CXBRK(void) retura(O); } ftendif
* Ciao CTRL-C*
*** Commandes ANSI du console.device *
*** Note : 033 est la valeur octale de ESC (27 décimal) * define RESETCON"033c"
Sdefine CüRSOFF "033[0 p"
define CURSON "033[ pn define DELCHAR "033[P”
define COLOROl "033[31m"
define COLOR02 "033[32m"
define COLOR03 "033[33m"
define ITALICS “033[3mn define BOLD "033[lm"
define UNDERLINE "033[4m"
Sdefine NORMAL "033[0m"
*** Prototypes des fonctions * void maintint, char **),- void cleanexit(UBYTE *,LONG); void cleanup(void);
BYTE OpenConsole(struct IOStdReq *, struct IOStdReq *, struct Window ») ;
void CloseConsole(struct IOStdReq *);
void QueueRead(struct IOStdReq *, UBYTE *),-
UBYTE ConGetChar(struct MsgPort *, UBYTE *);
LONG ConMayGetChar(struct MsgPort *, UBYTE *); void ConPuts(struct IOStdReq *, UBYTE *); void ConWrite(struct IOStdReq *, UBYTE *, LONG); void ConPutChar(struct IOStdReq *, UBYTE);
*** Variables globales * struct NewWindow nw =
10, 11, 620, 180,
- 1, -1
CLOSEWINDOW,
WINDOWDEPTH|WINDOWDRAGIWINDOWSIZING|WINDOWCLOSEI SMART_RE FRESHIACTIVATEIRMBTRAP,
NULL, NÜLL, "Console Test", NÜLL, NULL,
100, 45, 640, 256,
WBENCHSCREEN
;
struct Library ‘IntuitionBase = NULL;
Struct Window *win = NULL;
struct IOStdReq "readReq = NULL, "writeReq = NULL; struct MsgPort *readPort = NULL, "writePort = NULL;
BOOL OpenedConsole = FALSE, FromWB;
dc. b "MonPort",0 even
D ne faudra pas oublier de détruire ce port une fois qu'on n'en aura plus besoin :
DeletePort(messageport):
La seconde étape consiste à initialiser correctement une structure IOStdReq - ou une structure 10 étendue pour les devices en utilisant une - ce qui se fait au moyen de la fonction CreateExtIOO de l’amiga-lib :
define EXTSIZE ((LONG)sizeof(struct IOStdReq))
struct IOStdReq * request. *CreateExüO();
request=(struct IOStdReq *)CreateExtICXmessageport. EXTSIZE);
Cette structure devra elle aussi être éliminée lorsqu’on n’en aura plas besoin :
DeleteExtIO(request);
Ce n’est qu’alors que l’on pourra appeler la fonction OpenDeviceQ d’exec.library :
BYTE erreur.
Erreur = OpenDeviceO'nom.du.device", unit, request. Flags);
- "nom.du.device" décrit devinez quoi ? Le nom du device que l’on veut ouvrir, oui. Ce peut être "trackdisk.device", "console.device". " keyboard.de vice' ’. Etc. :
- "unit" désigne l’unité concernée. Par exemple, le trackdisk.device contrôle quatre unités, à savoir DFO: à DF3:. Le keyboard.device. lui, n’en contrôle qu’une (et pour cause : l’Amiga ne possède qu'un seul clavier !). Dans le cas du console.device, l’unité pourra être 0 ou-1 ;
- "request" est le pointeur sur la structure IOStdReq - ou bien, encore une fois, sur une structure 10 étendue - créée plus tôt ;
- "flags" sera les trois quarts du temps mis à 0.
CONSOLE !
"Le terme "console" désigne en informatique le ou les périphérique(s) destiné(s) au dialogue homme machine, généralement le clavier pour les entrées et l’écran pour les sorties" (Petit Robert, édition 91).
Le console.device permet donc la saisie de caractères depuis le clavier et leur édition à l’écran, plus précisémment dans une fenêtre Intuition - car n’oublions pas que toute fenêtre est créée et gérée par Intuition, même les CON:, RAW: et autres NEWCON:.
Un programme peut désirer ne prendre connaissance que des entrées et effectuer les sorties lui-même au travers de la graphicsdibrary et de la fonction TextO- C’est le cas de ProWrite ou de GenAml, l’éditeur du Devpac, par exemple. Dans ce cas, on ouvre l’unité -1. Mais il est également possible de laisser le console.device éditer le texte dans la fenêtre. Dans ce dernier cas. Il faudra initialiser deux structures IOStdReq et deux message-ports, un pour chaque sens de la communication.
Pour lire le console.device :
struct MsgPort *readPort; struct IOStdReq * readReq;
if ( (readPort = CreatePort("conRead.port", 0)) = NULL ) clean_exit("Impossible de créer le port de lecture.");
if ( (readReq = CreateExtIO(readPort. EXTSIZE)) = NULL )
void main(argc, argv) int argc; char **argv;

struct IntuiMessage *winmsg;
ULONG signais, conreadsig, windowsig;
LONG lch;
SHORT InControl = 0;
BOOL Doae = FALSE;
ÜBYTEch, ibuf, obuf[200];
BYTE error;
FromWB = ((argc == 0) ? TRUE : FALSE);
*** Ouvre intuition.library * if (!(lntuition3ase=(struct Libray *)
OpenLibrary("intuition.library”, 0))) cleanexit(“Intuition", RETURN_FAIL);
*** Crée le WritePort et le WriteRequest * if (!(writePort=(struct MsgPort *)
CreatePort("consoleWrite.port", 0))) cleanexit("write port", RETURN_FAIL);
if (!(writeReq=(struct IOStdReq *)
CreateExtIO(writePort, (LONG)sizeof(struct IOStdReq)))) cleanexit("write request", RETORN_FAIL);
*** Crée le ReadPort et le
if (!(readPort=(struct MsgPort *)
CreatePort("consoleRead.port", 0))) cleanexit("read port", RETORN_FAIL);
if (1(readReq=(struct IOStdReq *)
CreateExtIO(readPort, (LONG)sizeof(struct IOStdReq)))) cleanexit("read request", RETORN_FAIL);
*** Ouvre la fenêtre *
if (!(win=(struct Window *)OpenWindow(&nw))) cleanexit("window", RETURN_FAIL);
*** Attache la console à la fenêtre *
if (error = OpenConsole(writeReq, readReq, win)) cleanexit("console.device", RETüRN_FAIL); else
OpenedConsole = TRUE;
*** on écrit quelques trucs *
ConPuts(writeReq,"Texte normal !");
sprintf(obuf, "%s%sCouleur 3, italiques" ConPuts(writeReq, obuf);
COLOR03, ITALICS)
ConPuts(writeReq, NORMAL);
ConPuts(writeReq, "On va effacer cette astérisque ; -*-“); Delay(50);
ConPuts(writeReq, " b b");
Delay(50);
ConPuts(writeReq, DELCHAR);
Delay(50);
QueueRead(readReq, Sibuf); * envoie un request de lecture
ConPuts(writeReq, "Maintenant, on lit la console "); ConPuts(writeReq, "Fermez la fenêtre pour terminer.");
conreadsig = 1 « readPort->mp_SigBit; windowsig = 1 win->UserPort->mp_SigBit;
while(IDone)
signais = Wait(conreadsig I windowsig);
if (signais & conreadsig) * Ca vient de la console *
if ((lch = ConMayGetChar(readPort, Sibuf)) 1= -1)
* La routine ci-dessous filtre les * caractères de contrôle qui peuvent * être tapés directement au clavier ch = lch;
if (InControl == -1)
if (ch=='[') InControl=2; else InControl=-2;
if ((ch==0x9b) II (ch==0xlb))
InControl=(ch==0xlb) ? 1 : 2;
clean_exit("lmpossible de créer le request de lecture."):
Pour écrire dans le consolc.device :
struct MsgPort * vritePort; struct IOStdReq *writeReq;
if ( (writePort = CreatePort("conWrite.port", 0)) = NULL ) clean_cxit("Impossible de créer le port d'écriture."):
if ( (writcReq = CreateExtICX writePort. EXTSIZE)) = NULL ) clcan_exit("Impossible de créer le request d'écriture.");
On ouvre ensuite la fenêtre, puis le console.device lui-même :
if ( (win = OpenWindowf&nexvWindow)) = NULL ) clcan_éxit("Impossible d'ouvrir la fenêtre.");
un te Req->i o_Data = (APTR)win; uriteReq->io_Length = sizeof( struct Window): if ( OpenDex iceC'coasole.device". 0L. WriteReq. 0L) ) clean_exit("lmpossible d'ouvrir le coasolc.device.");
Pour terminer, on relie les 2 requests ensemble sur le même de vice :
readReq->io_Device = uriteReq->io_De ice: readReq->io_Unit = uriteReq->io_Unit:
Panant de là. On peut commencer la lecture le port 'readPort' et l'écriture sur le port 'writePort'.
OPERATIONS |
D’ENTREES SORTIES
Quel que soit le device concerne, deux types d’échanges sont possibles : d’une part l'échange "synchrone" (le device ne rend la main qu’une fois sa mission accomplie) et d’autre part l’échange 1 "asynchrone" (le device travaille parallèlement au programme, en ' multi-tâche). Cette demicre possibilité est particulièrement utile lorsque, par exemple, on veut animer une présentation à l’écran tout en chargeant des données depuis le disque. La lâche incombe toutefois au programme de se renseigner auprès du device s’il a terminé son travail.
Pour en revenir au console.device. il est préférable d’effectuer les sorties (c.à.d l'édition de caractères) en mode synchrone. Les d'entrées (lecture de caractère!s) en provenance du clavier) peuvent être faites en n'importe quel mode, suivant que l'on désire attendre un caractère ou simplement le lire "au vol". Dans ce dernier cas. Il faudra déjà avoir lancé une requête asynchrone, de façon à pouvoir examiner le pon. Les fonctions C suivantes peuvent être utilisées :
Lancement d'une requête asynchrone :
void QucueRead(readreq. Whereto) struct IOStdReq *readreq:
UBYTE *whercto;

rcadreq->io_Command = CMD_READ: readreq->io_Datu = ( APTR ) whereto; readreq->io_Lcngth = 1;
SendIO(readreq):
}
Lecture "au vol" d'un caractère (sans attente : retourne -1 si aucun caractère n'a été frappé) : LONG ConMavGetChaitmsgport. Whereto) struct MsgPort *msgport; UBYTE * whereto:
ConPuts(writeReq, "=== Control Seq ===-);
)
if (((ch>=Oxlf) && (ch =0x7e)) Il (ch>=OxAO)) sprintf(obuf, "Reçu : hex H02x = %c". Ch, ch); else
sprintf obuf, "Reçu : hex%02x", ch);
ConPuts(writeReq, obuf);
if ((InControl==3) && ((ch>=0x40) && (ch =0x7e))) t InControl=-l;
if (InControl == 2) InControl=3;
if (InControl 0)
InControl = 0;
ConPuts(writeReq, "=«= End Control ===");
}
}
)
if (signais && Windowsig) * Ca vient de la fenêtre *
while (winmsg = (struct IntuiMessage *)GetMsg(win->OserPort)) switch(winmsg->Class)
case CLOSEWTNDOW :
Dote = TRUE; break;
* Il pourrait y en avoir d'autres, *
* comme par exemple MENUPICK •
default : break;
)
ReplyMsg((struct Message *)winmsg);
}
)
if (ï(ChecklO(readReq)))
AbortlO(readReq);
WaitIO(readReq);
cleanup ( ) ; exit(RETURN OK);
void cleanexit(s, n)
UBYTE «S;
LONG n;

if (*s & (!Frcc*îB)) printf("Erreur d'ouverture : %s n", s); cleanup(); exit(n);
void cleanup()

if (OpenedConsole)CloseConsole(writeReq); if (readReq) DeleteExtlO(readReq);
if (readPort) DeletePort(readPort);
if (writeReq) DeleteExtIO(writeReq);
if (writePort) DeletePort(writePort);
if (win) CloseWindow(win); if (IntuitionBase)CloseLibrary(IntuitionBase);
BYTE OpenConsole(writereq, readreq, window) struct IOStdReq *writereq; struct IOStdReq «readreq; struct Window «window;
(
BYTE error;
writereq->io Data = (APTR) window;
writereq->io Length = sizeof(struct Window);
error = OpenDevice("console.device", 0, writereq, 0);
readreq->io_Device = writereq->io_Device;
readreq->io_Unit = writereq->io_ünit;
return(error);
}
void CloseConsole(writereq) struct IOStdReq «writereq;

register temp:
struct IOStdRcq *rcadrcq;
if ( î(readreq = (struct IOStdReq * )GetMsg( msgport) )) retum(-l):
temp = *whereto;
QucucRcadf readreq. Whereto): retum(temp);
}
Lecture d'un caractère (avec attente) :
UBYTE ConGctChari msgport. Whereto) struct MssPort *mseport:
UBYTE *whereto;

register temp:
struct IOStdReq *readreq;
WaitPort(msgport);
readreq = (struct IOStdReq *)GetMsg( msgport): temp = *whereto;
QueueRead( readreq. Whereto): retum(( UBYTE )temp):
}
Ecriture d'un caractère sur la console :
void ConPutc(writereq, c) struct IOStdReq *writereq:
BYTE c:
writereq->io_Command = CMD_WRITE: writereq->io_Data = ( A PTR )&c: writereq->io_Lcngth = 1 :
DoIO(writc_io);
I
Ecriture d'une chai ne de caractères (terminée par '0') sur la console
void ConPuts(writcreq. String) struct IOStdReq *writereq:
UBYTE *strin«:

writereq->io_Command = CMD_ VRITE: writereq->io_Data = ( A PTR ) string: writereq->io_Length = -1:
DoICX writereq);
I
Ecriture d'un buffer de X caractères sur la console :
void Con Write) writereq. String. Length) struct IOStdReq *writcrcq:
UBYTE *string:
LONG lensth:

writcrcq->io_Command = CMD_WRITE: writcieq->io_I>dta = (APTR) string: writereq->io_Length = length:
DoIO(writereq):
}
A SUIVRE.-
Voilà. La deuxième et dernière partie de cet article traitera des commandes particulières du console.devicc, mais en attendant, je vous propose un petit programme de démonstration très largement inspire de l'exemple public dans les RKM. A bientôt pour de nouvelles aventures.
CloseDevice(writereq);
void ConPutChar(writereq, character) struct IOStdReq *writereq;
UBYTE character;

wr itereq-> io_Cornraanà = CMD_WRITE; writereq->io_Data = (APTR) ficharacter; writereq->io_Length = 1;
DoIO(writereq);
void ConWrite(writereq, string, length) struct IOStdReq *writereq;
UBYTE ‘string;
LONG length;

writereq->io_Command = CMD_WRITE; writereq->io_Data = (APTR) string; writereq->io_Length = length;
DoIO(writereq);
void ConPuts(writereq, string) struct IOStdReq «writereq;
UBYTE ‘string;

writereq->io_Command = CMD_writE; writereq->io_Data = (APTR) string; writereq->io_Length = -1;
DoIO(writereq);
}
void QueueRead(readreq, whereto) struct IOStdReq ‘readreq;
UBYTE ‘whereto;

readreq->io Command = CMD_READ; readreq->io Data = (APTR) v*ereto; readreq->io_Length =1;
SendIO(readreq);
}
LONG ConMayGetCnar(msgport, whereto) struct MsgPort •msgport;
UBYTE ‘whereto;

register temp;
struct IOStdReq ‘readreq;
if (!(readreq = (struct IOStdReq *)GetMsg(msgport))) return(-l);
temp = ‘whereto;
QueueRead(readreq, whereto); return(temp);
}
U3YTE ConGetChar(msgport, whereto) struct MsgPort ‘msgport;
UBYTE «whereto ;

register temp;
struct IOStdReq ‘readreq;
WaitPort(msgport);
readreq = (struct IOStdReq *)GetMsg(msgport); temp = ‘whereto;
QueueRead(readreq, whereto); retuml (UBYTE) temp) ;
A N T MODE D’EMPLOI
Magazine, sources et exécutables uniquement par abonnement...
Parmi les nouvelles rubriques »|g l. soggz de TANT, certaines vous ontSaiii B naa ®-’w . 3 =i e « peut-être intrigué, d’autres ® .a S 10 § ® a “J. 'g §¦’ 3 | 15 ® “-o
nécessitent votre collaboration o ®- 3 ® 5 8 N B » -o a. ®. E
... C ) • Q)' S C m (Q 09 CD rî
pour vivre. L occasion pour £ 2. S- Q 3 ® . .s _ ®.
Nous de les présenter, ainsi 0 ~ "g 5T -o S -3 -n “ v & i= .S
que celles que vous « & * § I “ jT § q? .. * $ 3 * £
retrouverez dans nos ® “ o -n i" ? » 01 S 13 Q -
prochains numéros.
Les news : hé oui, il en faut bien. Mais pas n’importe lesquelles, hein, seulement celles en rapport direct avec la programmation, cela va de soi.
D’ailleurs, si vous avez connaissance de quelque nouveau produit intéressant à venir, n’hésitez surtout pas à en faire profiter les autres lecteurs.
Les langages : nous avons choisi de parier des plus couramment utilisés sur l’Amiga, à savoir : le Basic (Amos et GfA), le C, l’assembleur et... Arrexx.
L’invité du mois : il y a des noms qui reviennent souvent, surtout des américains ou des
« ® • ® « S V 8 £.® xneo snoj e eewesej ‘uinj03 eo enb e6ueqoe,p eunquj eiqejueA eun jsep : wmoj eq i eiqesued
- spui sjueeurej sep e[A e| jaijüduiis jnod semiuej6ojd sjiied ep sei sep ejip-e-jsep ‘ejjej xneiui e| jies ||,nb eo suep anzeiAj joie ejjou enbuqru ejjeo suep zejsAnojjej snoA "dno| np eped uo puenb ‘sues : ejjeiiuin iusiue||euuo|seooo euieuj ‘jenqujuoo A jjOAnod zesued snoA js jepeiuoo snou e sed jnopns zejiseq,N j enzeiAJ ouepejj ep jpdsesep puei6 ne 'uopiuujej6ojd ep edÀj eo juejejejd jnb xneo jnod eiiej ouop jse enbuqru euaQ j soiuep ep je xnef ep eiosuoo eqiedns eun jueiue|e6e jsep ’eipejipiu eujqoeui eun jueuieines sed ise.u b&ujvj ‘ejeuuoq ep )nej n ‘jno ueq : sjapi y oiuea sep moo-ujOQ eq sireiep ep sn|d jnod 9l.-é6ed ue ejjA snoA-zepuey
• ojsegvfO ue sepuopeA £ sejuoj ep ejAneo ue esiw eun 3 73 « -g § .¦§ « ‘p-spiu eo ’seiejjueo se6ed
~l s. ? A. g ® c sou uopejo soa ep zejueunie
quelques français. Le but de cette rubrique est de vous faire découvrir les personnalités qui se cachent derrière ces noms, comme John Toebes (auteur entre autres du Lattice C 4.0), Fred Fish (père de la collection
jnod 9l.-é6ed ue ejjA snoA-zepuey
• ojsegvfO ue sepuopeA £ sejuoj ep ejAneo ue esiw eun 3 73 « -g § .¦§ « ‘p-spiu eo ’seiejjueo se6ed ~l s. ? A. g ® c sou uopejo soa ep zejueunie
quelques français. Le but de cette rubrique est de vous faire découvrir les personnalités qui se cachent derrière ces noms, comme John Toebes (auteur entre autres du Lattice C 4.0), Fred Fish (père de la collection

Click image to download PDF

AMIGA NEWS TECH numero 20 (03-1991)

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


Thanks for you help to extend Amigaland.com !
frdanlenfideelhuitjanoplptroruessvtr

Connexion

Pub+

55.3% 
9.7% 
3.7% 
3.5% 
3% 
2.2% 
2.1% 
1.3% 
1% 
0.9% 

Today: 17
Yesterday: 74
This Week: 181
Last Week: 732
This Month: 2107
Last Month: 2867
Total: 77495

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