Table des matières

Le Sommaire du Quasar Net

Le BASIC

Le BASIC sur CPC est sans doute un des meilleurs BASIC disponible sur machines 8 bits et n'a pas à rougir face à ceux disponibles sur 16/32 bits. Nous allons ici l'étudier, non pas réellement en détail, mais par petites touches afin de vous en dévoiler différents aspects. Les premières sections s'adressent véritablement à des débutants alors que les dernières abordent des aspects un peu plus fouillés.

Préliminaires

Basé sur l'article publié dans Quasar CPC numéro 1, Basic au Berceau, par Zik.

Eh oui ! Nous avons décidé d'insérer cette rubrique dans Quasar pour enseigner le BASIC à ceux qui veulent se lancer dans la programmation 1) sans ouvrir le manuel de leur CPC 2).

Je vais commencer par vous expliquer comment afficher un mot (une phrase ou voir même une lettre). Il vous faut taper la commande PRINT suivie de ce que vous voulez afficher entre deux guillemets. Ainsi, si je veux afficher “Bonjour !”, je taperai la ligne de commande suivante : PRINT”Bonjour !”.

Cette commande sera bien sûr suivie d'une validation (appui sur la touche RETURN ou ENTER). On peut aussi afficher le contenu d'une variable, mais il faut lui attribuer un contenu. Une variable sans extension contient des nombres réels (exemple, des variables comme a, b, c, gaga ou cekevouvoulez) et une variable avec l'extension “$” contient une chaine de caractères (exemple, des variables comme a$, b$, c$, flop$ ou cometuveu$). Il y a quatre façons d'attribuer une valeur à une variable :

Alors, c'est pas compliqué... Donc, pour afficher “Bonjour !” en passant par une variable, on tapera la ligne suivante :

  a$="Bonjour !" (+ validation)

puis

  PRINT a$ (+ validation).

Il est gênant de devoir valider après chaque intruction, on met donc le signe ”:” pour les accorder entre elles. La ligne précédente deviendra ainsi :

  a$="Bonjour":PRINT a$.

On peut aussi créer un programme en faisant précéder les commandes d'un numéro qui est le numéro de ligne. Le programme sera exécuté grâce à la commande RUN. L'intérêt d'un programme est que les commandes qui le composent restent en mémoire (sauf initialisation) et peuvent êtres visualisées à l'aide de la commande LIST.

Maintenant, nous allons voir comment demander au gars qui est devant le clavier de taper quelque chose qui sera stocké dans une variable. Il faut pour celà utiliser la commande INPUT qui s'emploie de la manière suivante :

  INPUT a

ou

  INPUT a$

Ou, si l'on veut afficher une phrase :

INPUT"Entrez un nombre : ",a

ou

INPUT"Entrez une phrase : ",a$

Voici un petit programme d'exemple :

10 CLS                                    ' Efface l'écran
20 INPUT"Quel est votre age ";age         ' Devinez !
30 INPUT"Entrez l'année : ",annee         ' Mais encore ?!
40 naissance=annee-age                    ' Comme en Maths !
50 PRINT"Vous etes né(e) en ";naissance   ' Affichage date de naissance
RUN

Les types de variables

Les différents types

Basé sur l'article publié dans Quasar CPC numéro 2, Basic au Berceau, par Zik.

Nous allons ici brièvement parler des différents types de variable en BASIC. Il en existe 3 :

Et voilà, vous voyez, ça ne faisait pas mal !

Voici les différents types...

Déclaration de variables

Basé sur l'article publié dans Quasar CPC numéro 3, Initiation au Basic, par Zik.

Nous avons vu ce qu'étaient les types de variables qui sont au nombre de trois, à savoir : le type entier, le type réel, et enfin, le type chaîne de caractère (le type standard étant le second cité). Il est possible en BASIC de définir le type de variable par défaut (c'est-à-dire le type de variable quand on ne met pas de !, % ou $ après le nom de la variable).

Les trois commandes qui permettent cela sont DEFINT, DEFSTR et DEFREAL. La première installe le type entier par défaut (DEF pour “DEFault” et INT pour “INTeger”). La seconde met le type chaîne de caractères par défaut (STR pour “STRing”) et la dernière (c'est DEFREAL) place le type réel par défaut 'REAL signifie “réel”).

Mais voilà, ces commandes ont besoin d'être suivies de paramètres. Ceux-ci sont soit une liste d'initiales, soit une fourchette d'initiales (miam !). La syntaxe est :

Je précise tout d'abord que j'ai pris DEFSTR comme j'aurais pu prendre DEFINT ou DEFREAL (la syntaxe est la même pour les trois).

L'exemple 1 indique au langage que toutes les variables dont le nom commence par d, j ou h doivent être considérées comme des chaînes de caractères par défaut. Le second exemple indique que toutes les variables dont la première lettre est située de f à p (tous deux inclus) contiennent des chaînes par défaut. Le troisième exemple est un combiné des précédents : toutes les variables dont le nom commence par h et toutes celles dont la première lettre est comprise dans la fourchette m-x sont alors du type chaîne de caractères par défaut.

Les tableaux de variables

Basé sur l'article publié dans Quasar CPC numéro 1, Perfectionnement au Basic, par Zik.

Principes de base

Salut ! Comme le souligne le titre ci-dessus, nous allons donc parler des tableaux de variables. Vous pouvez dès lors remarquer qu'il y a un programme d'exemple que je vous commenterai. Mais tout d'abord, un tableau de variables qu'est-ce que cette bébête ? Eh bien, c'est tout simplement 3) un ensemble de variables ordonnées et désignées par des nombres. Je m'explique : si vous faites un ”DIM a(10)” vous venez de créer un tableau nommé “a” qui contient 11 variables numérotées de 0 à 10. C'est bien beau de savoir déclarer un tableau de variables, mais encore faut-il savoir le remplir de données. Et moah, je vais vous l'expliquer 4). Par exemple, pour mettre le nombre 153 dans la case x de ce tableau, il faut tapoter sur votre cher clavier : a(x)=153. Simple isn't it ?

Qui a dit que le BASIC était réservé aux clochards de l'informatique ? Voici comment se présente un tel tableau :

Cases(x) 0 1 2 3 4 5 6 7 8 9 10
Contenus

Ce type de tableau s'appelle un tableau à une dimension. Mais on peut aussi faire un tableau à deux dimensions dont voici le schéma.

Cases 0 1 2 3 4 5 6 7 8 Etc.
1
2
3
4
5
Etc.

Ce type de tableau se déclare de la manière suivante : DIM a(x,y) :

Pour attribuer une valeur à une case, c'est comme pour un tableau à une dimension sauf qu'il faut aussi préciser le numéro de la case de la 2ème dimension. C'est à dire comme suit : a(x,y)=valeur à attribuer.

Je ne vous représenterai pas un tableau à 3 dimensions, et je vous laisse réfléchir à un tableau à 13 dimensions qui est le plus complexe qu'accepte le BASIC.

Mise en pratique

Je vais maintenant commenter le programme. Celui-ci prend des codes ASCII au hasard et les stocke dans un tableau à deux dimensions (lignes 110 à 140). La 1ère dimension de ce tableau représente les colonnes de l'écran, et la 2ème dimension représente le nombre de lignes. Le programme affiche les codes ASCII à l'écran à l'aide du tableau de variable ainsi constitué (lignes 180 à 220) puis, suivant les touches du clavier enfoncées, il déplace un pointeur et réaffiche le décor en se servant du tableau (lignes 260 à 370).

Listing : les tableaux

Télécharger le listing BASIC.

10 ' Programme d'exemple de tableau de variables pour la gestion d'un écran 
20 ' 
30 DEFINT a-z:RANDOMIZE TIME 
40 ' 
50 ' Déclaration du tableau à deux dimensions 
60 ' 
70 DIM CASE(20,25) 
80 ' 
90 ' Remplissage aléatoire du tableau par des codes ASCII 
100 ' 
110 FOR x=1 TO 20 
120 FOR y=1 TO 25 
130 CASE(x,y)=FIX(RND*255)+1 
140 NEXT y,x 
150 ' 
160 ' Affichage du tableau à l'écran 
170 ' 
180 MODE 0 
190 FOR x=1 TO 20 
200 FOR y=1 TO 25 
210 LOCATE x,y:PRINT CHR$(1)+CHR$(CASE(x,y)); 
220 NEXT y,x 
230 ' 
240 ' Test des touches de déplacement du pointeur sur le décor 
250 ' 
260 x=1:y=1 
270 LOCATE x,y:PEN 2:PRINT CHR$(255); 
280 LOCATE x,y:PEN 1:PRINT CHR$(1)+CHR$(CASE(x,y)); 
290 IF INKEY(8)<>-1 THEN x=x-1 
300 IF INKEY(1)<>-1 THEN x=x+1 
310 IF INKEY(2)<>-1 THEN y=y+1 
320 IF INKEY(0)<>-1 THEN y=y-1 
330 IF x<1 THEN x=20 
340 IF x>20 THEN x=1 
350 IF y<1 THEN y=25 
360 IF y>25 THEN y=1 
370 GOTO 270

Il fait chaud hein ?

La gestion des fichiers

Basé sur l'article publié dans Quasar CPC numéro 2, Perfectionnement au Basic, par Zik.

La gestion des fichiers. C'est donc de cela dont nous allons parler. Voyons tout d'abord les commandes d'ouverture et de fermeture des fichiers. Suivant que vous vouliez ouvrir un fichier ASCII en lecture ou en écriture, vous utiliserez deux jeux de commandes distinctes.

Écriture

Moultipass ? Tout d'abord, je vais traiter l'ouverture en écriture. OPENOUT”nomfich” sert à créer un fichier et à l'ouvrir en écriture. PRINT#9 et WRITE#9 inscrivent dans le fichier les données spécifiées après ladite instruction. Si vous voulez voir la différence entre ces deux commandes, tapez ceci sous BASIC :

WRITE"Bonjour"

puis

PRINT"Bonjour"

… et constatez vous-même la différence. Pour sauver le fichier, il faut le fermer, et pour cela, il suffit d'utiliser CLOSEOUT.

Lecture

Pour relire le fichier sauvé, on doit l'ouvrir en lecture. Je ne dirai qu'un nom : OPENIN”nomfich”. Bon, maintenant qu'il est ouvert, il faudrait peut-être le lire non ? Et pour ce faire, on emploie INPUT#9 qui lit la donnée courante dans le fichier, la stocke dans la variable spécifiée, et pointe sur la donnée suivante. Il vaut mieux ensuite le fermer grâce à CLOSEIN.

Quoi plus ?

Il est impossible d'ouvrir deux fichiers en écriture ou en lecture ; mais, en revanche, on peut ouvrir un fichier en écriture et un autre en lecture simultanément.

Meuk ! Voyons, voyons… Ah oui ! EOF (End Of File) ! Voilà, cette commande (EOF) renvoie 1 lorsque toutes les données du fichier courant ont été lues et 0 dans tous les autres cas. La plupart du temps, on l'utilise de la manière suivante :

10 WHILE NOT EOF
20 INPUT#9,variable
30 WEND

Ainsi, toutes les données du fichiers seront lues.

L'exemple

Voici pour terminer un petit programme d'exemple qui illustre tout cela.

Télécharger le programme BASIC.

5 MODE 2
10 OPENIN"donnee"
20 INPUT#9,a
30 CLOSEIN
40 IF a=0 THEN GOTO 60 ELSE GOTO 140
45 '
50 ' ** Saisie des données **
55 '
60 OPENOUT"donnee"
70 INPUT"Entrez un nombre : ",nbr
80 INPUT"Entrez un mot    : ",mot$
90 WRITE#9,1,nbr,mot$
100 INPUT"Voulez-vous continuer la saisie (O/N) ";a$
110 IF UPPER$(a$)="O" THEN GOTO 70
120 CLOSEOUT:END
125 '
130 ' ** Lecture et affichage des données du fichier **
135 '
140 OPENIN"donnee"
150 WHILE NOT EOF
160 INPUT#9,a,nbr,mot$
170 PRINT"Nombre :";nbr
180 PRINT"Mot    : ";mot$
190 WEND:CLOSEIN
200 OPENOUT"donnee"
210 WRITE#9,0
220 CLOSEOUT
230 END

Bidouilles hardware

Basé sur les articles publiés dans Quasar CPC numéro 3 et numéro 4, Perfectionnement au Basic, par OffseT.

Youpi ! Nous allons ici utiliser le BASIC de façon plutôt incongrue, en tapant directement dans le hard. Le but est de bidouiller un peu afin de produire des effets - certes très imparfaits - normalement réservés aux programmeurs en assembleur.

Ondulations d'écran

Nous allons ici voir comment réaliser depuis notre bon vieux BASIC des ondulations d'écran, technique normalement réservée aux programmeurs en assembleur. Attention toutefois, n'espérez pas réaliser de beaux plasmas en BASIC, il s'agit simplement de réaliser des ondulations hardware grâce aux registres du CRTC ; ça n'est techniquement pas très joli, mais parfaitement efficace.

Ondulations classiques

J'assure grave ! Nous allons donc aborder la gestion des registres du CRTC qui permettent de modifier la position de l'écran (le CRTC est le contrôleur vidéo du CPC).

Ces registres sont le 2 et le 7, ils modifient respectivement la position en X et en Y de l'écran. En standard, la valeur des abscisses est de 46 et celle des ordonnées est de 30. L'adressage du CRTC se fait sur deux ports : ce sont les ports &BC00 et &BD00. On place tout d'abord le numéro du registre dont on veut changer la valeur sur le port &BC00, puis on indique la nouvelle valeur sur le port &BD00. Pour cela, on fait appel à la commande OUT de notre cher BASIC. La syntaxe de cette opération est donc :

OUT &BC00,r:OUT &BD00,v

r et v étant bien évidemment le numéro du registre et la valeur à y mettre.

Revenons-en aux registres 2 et 7. Après quelques essais, vous pourrez vous rendre compte que plus vous augmentez la valeur du registre 2, plus l'écran se décale vers la gauche (si vous la diminuez, l'écran se déplace donc vers la droite, plutôt logique non ?!). Si vous êtes perspicace (je n'en doute pas), vous remarquerez que plus la valeur du registre 7 augmente, plus l'écran se décale vers le haut (et comme par hasard, si vous la diminuez, l'écran retourne plus bas5) ).

En jouant sur ces registres, vous pourrez obtenir différents effets, notamment une ondulation d'écran en changeant la position en X de l'écran plusieurs fois lors d'un balayage. Un petit programme d'exemple réalisant cette prouesse technique (qui est une ondulation d'écran en BASIC) se trouve juste là, dessous, si si, regardez bien.

Télécharger le listing BASIC.

Tocard ! Tu sais même pas ce que tu fais, c'est rien que du rip !

10 '
20 ' Ondulations en BASIC
30 '   par Futurs' 1991
40 '
50 OUT &BC00,2:OUT &BD00,46
60 OUT &BC00,2:OUT &BD00,47
70 OUT &BC00,2:OUT &BD00,48
80 OUT &BC00,2:OUT &BD00,49
90 OUT &BC00,2:OUT &BD00,49
100 OUT &BC00,2:OUT &BD00,49
110 OUT &BC00,2:OUT &BD00,48
120 OUT &BC00,2:OUT &BD00,46
130 OUT &BC00,2:OUT &BD00,45
140 OUT &BC00,2:OUT &BD00,44
150 OUT &BC00,2:OUT &BD00,43
160 OUT &BC00,2:OUT &BD00,43
170 OUT &BC00,2:OUT &BD00,43
180 OUT &BC00,2:OUT &BD00,44
190 OUT &BC00,2:OUT &BD00,45
200 GOTO 50

Ondulations affinées

Je vous mets minables quand je veux ! 'Faut juste que je retrouve ma Sony noire... En complément de la section précédente, vous trouverez ici un deuxième programme d'ondulation d'écran en BASIC. Celui-ci utilise le registre 3 du CRTC. Ce registre permet un réglage fin de la position en abscisse de l'écran en modifiant la largeur de la HBL6) ; le programme envoie des valeurs de 0 à 7. Il a exactement la même structure que celui du paragraphe ci-dessus, et c'est pourquoi je ne prendrai pas la peine de le commenter une seconde fois (non mais !). Je précise tout de même que, pour avoir une ondulation idéale, il faudrait combiner les registres 2 et 3.

10 '
20 ' Ondulations en BASIC
30 '   par Futurs' 1991
40 '
50 OUT &BC00,3:OUT &BD00,4
60 OUT &BC00,3:OUT &BD00,5
70 OUT &BC00,3:OUT &BD00,5
80 OUT &BC00,3:OUT &BD00,6
90 OUT &BC00,3:OUT &BD00,6
100 OUT &BC00,3:OUT &BD00,7
110 OUT &BC00,3:OUT &BD00,7
120 OUT &BC00,3:OUT &BD00,7
130 OUT &BC00,3:OUT &BD00,7
140 OUT &BC00,3:OUT &BD00,7
150 OUT &BC00,3:OUT &BD00,7
160 OUT &BC00,3:OUT &BD00,6
170 OUT &BC00,3:OUT &BD00,6
180 OUT &BC00,3:OUT &BD00,5
190 OUT &BC00,3:OUT &BD00,5
200 OUT &BC00,3:OUT &BD00,4
210 GOTO 50

C'est pas gagné !

Rasters

Quelle surprise ! Eh oui, encore plus fort que l'ondulation d'écran, voici en exclusivité pour Quasar, des rasters en BASIC (je pense que j'y crois un peu trop) ! La technique est très simple (façon de parler…). Vous avez sûrement remarqué (mais si, puisque je vous le dis !) que les lignes 80 et 90 du programme sont assez chargées (je veux dire par là que j'ai écrit un maximum de commandes sur la même ligne). Et cela pour la seule raison que des commandes placées sur une même ligne sont enchaînées plus rapidement que placées sur des lignes différentes. On gagne donc ainsi du temps machine lors de l'exécution (ce qui est important pour pouvoir obtenir de beaux rasters).

Voyons maintenant le programme lui-même. On trouve d'abord un SPEED INK 1,1 qui installe une “remise à jour” des couleurs à chaque balayage écran, comme ça on n'est pas gênés par des changements de couleurs inattendus. Le BORDER 1 est là pour l'esthétique et voilà ensuite les OUT.

Le Gate Array est le nom d'un des composants de votre ordinateur ; ce cher boîtier de silicium permet de gérer les interruptions, les connexions de ROM et de banks, le mode écran et… les couleurs ! Le port d'adressage de ce circuit se situe en &7Fxx, on lui envoie des ordres à l'aide de deux bits de contrôle7) et donc six bits de commande8). Les bits de contrôle permettent de sélectionner quatre registres, nous allons nous intéresser aux registres PENR (mode 00) et INKR (mode 01). Je vais vous faire un petit schéma pour que vous compreniez au moins quelque chose à mes articles. Voilà tout d'abord la disposition des divers bits qui composent l'octet à envoyer au Gate Array.

Adressage sur le port &7Fxx (Gate Array) :

Pourquoi tant de haine ? Adressage du Gate Array sur CPC old (sur CPC+ nous avons 3 bits de contrôle, le bit de poids fort de la partie "commande" étant toujours à 0 sur CPC old)

Tant que j'y suis, je vous fais aussi le schéma pour les registres PENR (mode 00) et INKR (mode 01)…

Les registres PENR (mode 00) et INKR (mode 01)

Les cases numérotées de 0 à 7 représentent les huits bits qui composent un octet (c'est le codage binaire : 0 ou 1). Si les bits 6 et 7 sont mis à 0, on sélectionne le mode 00 qui correspond au registre PENR ; si le bit 6 est à 1 alors que le 7 est à 0, on valide le mode 01 qui correspond au registre INKR.

Pour faire nos rasters, nous devons indiquer l'encre donc on veut modifier la couleurs (registre PENR) et quelle couleur on veut lui affecter (registre INKR). On va d'ailleurs changer cette couleur plusieurs fois pendant le balayage vidéo pour que ce qu'on va faire soient des rasters et pas un bête changement de couleur.

Dans notre exemple, c'est sur la bordure écran qu'agit notre raster et c'est pourquoi on envoie le nombre 16 en &7Fxx (16 = 00010000 en binaire) ; il n'est pas nécessaire de renouveller cette “initialisation” sur le registre PENR qui restera actif tant qu'une autre encre n'aura pas été sélectionnée. Les autres commandes OUT envoient les couleur sur le registre INKR (on additionne 64 au numéro de la couleur pour être en mode 01 et les couleurs sont, je le répète, codées en hardware ; il y a des tableaux ci-dessous).

Couleurs Software Hardware
Noir 0 20
Bleu 1 4
Bleu Vif 2 21
Rouge 3 28
Magenta 4 24
Mauve 5 29
Rouge Vif 6 12
Violet 7 5
Magenta Vif 8 13
Couleurs Software Hardware
Vert 9 22
Turquoise 10 6
Bleu Ciel 11 23
Jaune 12 30
Blanc 13 0
Bleu Pastel 14 31
Orange 15 14
Rose 16 7
Magenta Pastel 17 15
Couleurs Software Hardware
Vert Vif 18 18
Vert Marin 19 2
Turquoise Vif 20 19
Vert Citron 21 26
Vert Pastel 22 25
Turquoise Pastel 23 27
Jaune Vif 24 10
Jaune Pastel 25 3
Blanc Brillant 26 11

Vous savez donc maintenant faire des rasters (en théorie…). Il reste toutefois un détail (très important) dont je ne vous ai pas parlé : le CALL &BD19. C'est un vecteur système qui sert à se synchroniser par rapport au balayage écran (ça se passe tout les 50ème de seconde). Après avoir été lancé, ce vecteur rend la main au BASIC quand notre cher canon à électron commence un nouveau rafraîchissement de l'écran. Ce vecteur est donc très pratique pour nos rasters. Je tiens à indiquer (eh oui !) que ce CALL &BD19 est équivalent à la commande FRAME du BASIC qui n'est d'ailleurs pas présente sur toutes les générations du BASIC.

Ce CALL étant placé dans la boucle parmi les OUT, on obtient des rasters fixes. C'est-à-dire que les mêmes couleurs se retrouvent toujours aux même emplacement sur l'écran. Mais, si l'on veut changer le comportement de nos rasters, nous avons la possibilité de les faire se déplacer. Il suffit pour cela de supprimer le CALL de la ligne 60 ; ainsi, à la fin la séquence de couleurs, le programme revient tout de suite en ligne 60. De cette manière, nos rasters se meuvent gaiement… mais surtout chaotiquement ! Il va falloir bidouiller un peu pour retrouver un peu d'élégance ; d'après les essais que j'ai tenté, c'est en ajoutant deux couleurs (deux OUT) dans la liste que l'on obtient le plus beau mouvement. À vous d'essayer de trouver mieux !

Baston !

Une autre possibilité nous est offerte puisque, si vous regardez de nouveau les schémas des registres du Gate Array, vous verrez qu'en modifiant la valeur envoyée au Gate Array par le premier OUT, on peut facilement changer l'encre sur laquelle agiront les couleurs des rasters et obtenir des effets intéressants.

10 '
20 ' Rasters en Basic
30 '
40 SPEED INK 1,1
50 BORDER 1
60 CALL &BD19:OUT &7F00,16:OUT &7F00,68:OUT &7F00,85:OUT &7F00,93:OUT &7F00,87:OUT &7F00,95:OUT &7F00,83:OUT &7F00,75:OUT &7F00,67:OUT &7F00,74:OUT &7F00,78:OUT &7F00,76:OUT &7F00,92:OUT &7F00,86:OUT &7F00,94:OUT &7F00,82:OUT &7F00,74:OUT &7F00,82
70 OUT &7F00,94:OUT &7F00,86:OUT &7F00,88:OUT &7F00,77:OUT &7F00,79:OUT &7F00,83:OUT &7F00,64:OUT &7F00,70:GOTO 60

L'accès aux banks

Extrait de l'article publié dans Quasar CPC numéro 4, Perfectionnement au Basic, par OffseT.

Je vais ici vous parler brièvement des connexions de banks qui vont vous permettre de casser la limite des 64Ko9) du BASIC sur les CPC6128. Vous devez savoir qu'une bank se connecte uniquement sur la page mémoire qui se situe de &4000 à &7FFF. Une page mémoire fait 16Ko, donc vous possédez 4 pages de banks et 4 en mémoire centrale (128Ko en tout). Les 4 banks sont numérotées de 0 à 3. Voici des exemples pour aider à comprendre…

Connexion de la bank 1 en &4000 :

OUT &7F00,&x11000101

    

Remise en place de la ram centrale :

OUT &7F00,&x11000000

Quand on met les bits 2, 3 et 4 à 0, on sélectionne la ram centrale. Et quand on choisit l'extension 1 (on compte toujours en partant de 0) on connecte les banks supplémentaires du CPC6128. Sur un CPC464 il faudra ajouter une extention mémoire et si vous ne l'avez pas, il vous est alors inutile de comprendre tout ceci !

Hein ? Commutation des banks, registre MMR (mode 11)

Vous voici désormais avec 64Ko de mémoire supplémentaire, accessible directement depuis le BASIC, libre à vous de les exploiter à l'aide de PEEK et de POKE habiles.

Utiliser une matrice en RAM

Basé sur l'article publié dans Quasar CPC numéro 12, Basic, par SNN.

Oh, je sais ce que vous allez dire… il se foule pas l'ami SNN. Que des rubriques faciles, pas vraiment “prise de tête”. Détrompez-vous, amis lecteurs… ne trouve pas un sujet intéressant qui veut10) !

Nous allons ici voir une manière originale de coder des informations en mémoire et faire un petit tour du côté du COPYCHR$. Beurk !

Le but du jeu : mettre en mémoire tous les caractères d'un écran mode 2 (soit 80×25 = 2000 caractères). Comme la place est limitée en RAM, nous allons coder un caractère par un octet et non par une valeur réelle (8 octets si mes souvenirs sont bons)… Vous me direz, c'est plus que logique vu que tous les caractères existants sont codés sur 8 bits (du moins sur CPC). On passera donc d'un écran de 16000 octets11) à un écran de 2000 octets12). 87,5% en moins. Fort encourageant !

C'est par là que ça se passe ! Pour stocker nos valeurs, nul besoin d'ouvrir un fichier ASCII ni de faire un DIM monstrueux ! Un simple MEMORY ADR-1 suffira.

Mettons arbitrairement ADR à 38000. On disposera virtuellement la mémoire de cette façon :

X/Y 1 2 3 4 78 79 80
1 38000 38001 38002 38003     …     38077 38078 38079
2 38080 38081 38082 38083 38157 38158 38159
3 38160 38161 38162 38163 38237 38238 38239
. . . . . . . .
. . . . . . . .
. . . . . . . .
25 39920 39921 39922 39923 39997 39998 39999

Cette organisation, je le répète, ne reflète pas l'organisation réelle de la RAM (linéaire), mais va seulement nous permettre de déterminer une adresse en fonction d'une coordonnée X et Y (c'est le principe dont je me sers dans la partie labyrinthe d'Aventury13) pour savoir dans une table avec X et Y, où je me trouve et quel octet s'y trouve ; en fonction de cela, j'affiche le décor ad hoc).

La formule hyper simple est alors : A = ADR + (Y - 1) * 80 + (X - 1)

Pour stocker l'écran, le programme sera donc :

10 ADR=38000
20 FOR X=1 TO 80
30 FOR Y=1 TO 25
40 LOCATE X,Y
50 A$=COPYCHR$(#0)
60 A=ADR+(Y-1)*80+(X-1)
70 POKE A,ASC(A$)
80 NEXT Y,X

COPYCHR$ lit le caractère qui se trouve aux coordonnées actuelles du curseur en tant que caractère alphanumérique (et non pas son code ASCII, il est utile de le préciser !). C'est une fonction qui m'a bien servi quand je programmais en BASIC : pour être sûr que l'ordinateur avait bien été reseté avant le lancement de mon programme, je testais les caractères de l'écran d'initialisation14). J'avoue que c'est pas très fiable comme méthode.

Concernant le COPYCHR$, une petite précision, le #0 représente la fenêtre BASIC dans laquelle le symbole doit être lu ; à savoir la fenêtre principale dans notre cas.

Bien. À présent, voyons l'affichage aléatoire d'un écran texte. On mettra un 0 à la place des caractères déjà affichés.

10 ADR=38000
20 FOR R=1 TO 2000
30 X=INT(RND*80)+1
40 Y=INT(RND*25)+1
50 A=ADR+(Y-1)*80+(X-1)
60 B=PEEK(A)
70 IF B=0 THEN GOTO 30 ELSE POKE A,0:LOCATE X,Y:PRINT CHR$(B);
80 NEXT R

Sympa, non ?

Programme BASIC autogénéré

Basé sur l'article publié dans Quasar CPC numéro 13, Basic, par SNN.

L'art et la manière de mettre de grosses digits pour donner l'illusion que les articles de SNN ne sont pas si courts que ça Mon Dieu, je m'amuse comme une petite folle (le premier qui rigole se prend une baffe, pas vrai Madram, Siou, Mik'ro et les autres traites15) ; depuis que mon PC roule sous Linux… je n'arrive plus à me connecter à l'internet, quelle joie ! Et comme ma confiance envers mon rédac'chef est sans limite, je me suis débarrassé de Windaube 95. Lourde erreur. Merci donc à Fifou qui m'a conseillé ce système d'exploitation. Merci, merci encore.

De quoi allons-nous parler ? Eh bien, au moment où je rédige ces quelques lignes, je n'en ai pas la moindre idée. Réfléchissons donc. Ah, oui, le “DATA MAKER” que je vous avais proposé dans les “deulignes” de Quasar CPC numéro 5, souvenez-vous. En fait, il va nous permettre d'étudier un certain nombre de fonctions du BASIC. Entre autres : VAL, LEN, OPENOUT, PRINT#9, CLOSEOUT.

Étudions donc pas à pas ce petit programme d'exemple.

Le début

Oh, un GOSUB 1000 ! Comme vous le savez tous (j'espère), un GOSUB a le même rôle (les accents circonflexes !) qu'un GOTO sauf que la partie de programme auquel il envoie doit se terminer par un RETURN. Le BASIC retourne alors à la ligne qui a appelé le sous-programme et poursuit l'exécution à ce niveau. Ici, notre sous-programme permet de centrer sur un écran de 40 caractères de large une chaîne nommée A$.

La fonction LEN nous donne la longueur de cette chaîne (en caractères bien sûr). De là, on va calculer le décalage en X de la chaîne. Or, ce décalage doit être de 20 (le milieu de 40) moins la moitié de la longueur de la chaîne. Magie ? Non, génie (arfff !). Vient ensuite un TAB, vous connaissez ? C'est l'instruction qui permet d'afficher l'argument du PRINT avec une certaine TABulation. Le VAL à présent. Il s'agit d'une fonction dont l'usage est assez limité. Elle sert à la conversion en numérique de chaînes alphanumériques. Ces chaînes alphas peuvent représenter soit une valeur binaire, soit une valeur hexadécimale (dans le cas qui nous intéresse). Le tout est de présenter un argument alpha précédé du signe désiré : & ou %.

Le milieu

Un gros intérêt des fichiers ASCII est de pouvoir fabriquer automatiquement des fichiers BASIC. Si on respecte la longueur des lignes et la numérotation, y'a pas de raison que ce con de BASIC ne prenne pas ça pour un vrai programme (je retire ce que j'ai dit sur le BASIC).

Vous voyez donc comment marche le programme ?

Un OPENOUT ouvre dehors (la disquette) un fichier du nom de votre choix. PRINT#9 imprime les infos de votre choix. Ici, il s'agit de lignes de BASIC cohérentes, joie ! CLOSEOUT ferme dehors le fichier, donc ajoute un petit code, le CHR$(26) qui signifie EOF, fait deux ou trois calculs et inscrit le fichier définitivement sur le DIRectory. Nous y sommes, le programme est fait.

Je voudrais revenir à la ligne 200 (en espérant que ce cher Fifou n'aura pas eu l'idée de faire un RENUM à la con). Pourquoi ce CHR$(34) ? Comme vous le savez, le symbole 34, c'est les guillemets. Ok ? Vous voyez bien que nous sommes entre les guillements du PRINT#9. Et notre programme BASIC doit contenir ”&”. Si on met , le PRINT se referme, on est bien d'accord. La soluce, c'est de sortir du PRINT (par un guillemet), de forcer un symbole (le guillemet), de revenir dans le PRINT (par un …), de mettre &, de refaire pareil que pour le premier, de ne pas poser de question sinon j'explose (ma haine sur Tony qui n'a rien fait mais bon…).

Le fin de le fin

Vous pourrez facilement remarquer l'analogie entre le programme autogénéré entre les lignes 170 et 260 et le programme générateur (à la fin). Pour parler un tout petit peu du checksum, je vous dirai seulement : débrouillez-vous. Un enfant de deux ans pourrait comprendre comment il marche.

Vous savez, faire les initiations BASIC, c'est vraiment pas facile quand on sait pas ce dont vous avez besoin. Alors donc, c'est décidé. Il n'y aura plus d'initiations tant que je n'aurai pas reçu une lettre avec écrit dessus un sujet précis16) (le premier qui m'envoie “disjonteur”17)).

Listing : programme autogénéré

Télécharger le listing BASIC

10 MODE 1 
20 A$="DATA MAKER / (C) QUASAR 1998" 
30 GOSUB 1000 
40 PRINT 
50 A$="* * * * *" 
60 PRINT:INPUT"NOM DU FICHIER EN SORTIE : ",NOM$ 
70 LIGNE=100 
80 PRINT:INPUT"ADRESSE DE DEPART : &",HEXA$ 
90 ADR=VAL("&"+HEXA$) 
100 PRINT:INPUT"LONGUEUR : &",LONG$ 
110 LONG=VAL("&"+LONG$) 
120 PRINT:INPUT"EXECUTION : &",EXEC$ 
130 EXEC=VAL("&"+EXEC$) 
140 PRINT:INPUT"TITRE DU PROGRAMME : ",TITRE$ 
150 PRINT:A$="CREATION DU FICHIER DATA":GOSUB 1000 
160 OPENOUT NOM$ 
170 PRINT#9,"10 ' "+TITRE$ 
180 PRINT#9,"20 ' " 
190 PRINT#9,"30 FOR R=&"+HEXA$+" TO &"+HEX$(ADR+LONG)+" STEP 8:SOM=0" 
200 PRINT#9,"40 FOR S=0 TO 7:READ A$:A=VAL("+CHR$(34)+"&"+CHR$(34)+"+A$)" 
210 PRINT#9,"50 SOM=SOM+A:POKE R+S,A:NEXT S:READ CHK" 
220 PRINT#9,"60 IF SOM<>CHK THEN PRINT "+CHR$(34)+"ERREUR LIGNE"+CHR$(34)+";110+L*10:END" 
230 PRINT#9,"70 L=L+1:NEXT R" 
240 PRINT#9,"80 '" 
250 PRINT#9,"90 ' EXECUTION = CALL &"+EXEC$ 
260 PRINT#9,"100 '" 
270 FOR R=ADR TO ADR+LONG STEP 8 
280 SOM=0 
290 LIGNE=LIGNE+10 
300 PRINT#9,LIGNE;"DATA "; 
310 FOR T=0 TO 7:SOM=SOM+PEEK(R+T):PRINT#9,HEX$(PEEK(R+T),2);",";:NEXT T:PRINT#9,SOM 
320 NEXT R 
330 END 
1000 A=LEN(A$) 
1010 B=20-2/2 
1020 PRINT TAB(B);A$ 
1030 RETURN
1) c'est haut !
2) Bou ! Les faineants !
3) Hum !
4) si, si !
5) Je considère que l'écran est posé à l'endroit sur votre bureau
6) pour plus d'informations sur les registres du CRTC allez lire la section qui lui est dédiée
7) en fait, il n'y en a trois, mais le troisième bit n'est utilisé que sur CPC+
8) en fait, il n'y en a que 5, le 6ème étant le 3ème bit de contrôle, toujours à zéro sur CPC old
9) dont seulement environ 40Ko sont effectivement disponibles
10) NDOffseT : séquence auto-satisfaction
11) 80x25x8
12) 80×25
13) NDOffseT : séquence publicité
14) NDOffseT : séquence mélancolie
15) NDOffseT : ceci fait référence à des événements malheureux survenues lors du Ze Meeting 97
16) NDOffseT : de fait, cet article fut le dernier consacré au BASIC dans Quasar CPC
17) NDOffseT : encore une référence au Ze Meeting 97 que seuls les présents à l'époque comprendront