PAMPUK Forth

L'interpréteur

Lorsque l'on démarre Forth, on se trouve dans un mode interactif dans lequel on peut taper des mots sur une ligne et valider cette ligne avec la touche entrée.

Un mot est une suite de caractères séparés des autres par des espaces. Lors de la validation de la ligne, l'interpréteur Forth va prendre chaque mot et les exécuter. Si le mot trouvé est dans son dictionnaire courant (nous verrons plus tard ce qu'est un dictionnaire), il va exécuter le code associé. Si aucun mot ne correspond, il va essayer de convertir le mot en nombre et le mettre sur la pile.

La pile

Si on ne précise pas de quelle pile on parle, c'est généralement de la pile de paramètres qu'il s'agit. C'est une pile LIFO (Last In First Out), c'est-à-dire que le dernier élément mis sur la pile est le premier à en sortir. Cette pile est un concept central du Forth.

Beaucoup de mots vont prendre leurs paramètres dans cette pile, et y laisser leurs résultats.

En opération simple pour voir le fonctionnement de la pile est d'empiler trois nombres puis des les affiches avec le mot . :

1 2 3 . . .

Le résultat affiché est :

3 2 1

Un autre exemple simple, qui est un peu le Hello World du Forth, est de taper 1000 2000 + . et de valider la ligne. Le résultat affiché est 3000.

Le déroulement de l'interprétation est le suivant :

  • 1000 n'est pas un mot reconnu et est mis sur la pile en tant que nombre,
  • 2000 n'est pas un mot reconnu et est mis sur la pile en tant que nombre,
  • + est un mot reconnu qui prend les deux premiers éléments de la pile, les additionne et met le résultat sur la pile,
  • . est un mot reconnu prend le premier élément de la pile et l'affiche.

Les mots

Comme indiqué plus haut, un mot est une suite de caractères. Ces caractères peuvent être quelconques, même s'il est conseillé de donner aux noms un sens.

Lorsque Forth démarre, il a déjà connaissance d'un certain nombre de mots, qui forment un vocabulaire. À chaque mot est défini un code à exécuter. Ce code peut être eux-même composés d'autres mots en Forth, mais il peut être aussi écrit en assembleur.

Il est possible de créer de nouveaux mots. Et c'est d'ailleurs la manière de programmer en Forth.

Les commentaires

Dans PAMPUK Forth, les commentaires commencent par ( et se terminent par ). Comme '(' est un mot, il est essentiel de mettre des espaces avant et après. Comme le mot ignore tout ce qui se trouve avant le prochain ), cette parenthèse fermante n'est pas un mot, et l'espace avant n'est pas nécessaire. Cependant, par soucis d'équilibre esthétique, il est conseillé de le mettre.

Le mot de commentaire \, qui ignore le texte jusqu'à la fin de la ligne, n'est pas disponible en standard sur ce Forth. Il est cependant utilisé dans les exemples donnés.

Les annotations

Les annotations sont des commentaires avec un format spécifique qui indique les opérations effectuées par un mot sur la pile de paramètres et si une chaîne de caractères est lue depuis le flot d'entrée.

Les annotations sont en commentaires et sont destiné à la lecture humaine, l'interpréteur/compilateur n'en fait pas usage.

Dans une annotation, ce qui doit se trouver sur la pile avant l'appel au mot se trouve avant un tiret -, ce qui y est laissé par le mot se trouve après le tiret. Si le mot lit une chaîne de caractères, celle-ci est indiquée entre signes inférieurs < et supérieurs > après le tiret et, s'ils existent, après les annotations de paramètres laissés par le mot.

Que ce soit avant ou après le tiret, les éléments sont représenté du plus profond à gauche, au plus haut (le sommet de la pile) à droite.

Par exemple DUP ( n - n n ) indique que le mot DUP prend un nombre sur la pile et en laisse deux.

Certaines conventions donnent plus de détails sur la nature de l'opération effectuée, ou bien sur la sémantique des paramètres. Dans ce manuel, seul le type des paramètres est indiqué.

Les abbréviations utilisées sont les suivantes :

Abbréviation Signification
n un entier 16 bits signé
u un entier 16 bits non signé
d un entier 32 bits signé
ud un entier 32 bits non signé
b un entier 16 bits représentant un booléen
addr une adresse mémoire sur 16 bits
<nom> une chaîne de caractères lu depuis le flot d'entrée

Lorsque plusieurs paramètres sont de même type, ils sont distingués par un nombre en suffixe. Par exemple, n1 n2 n3 indique trois entiers 16 bits signés.

Si la même abbréviation, eventuellement avec le même suffixe, est présent des deux côtés du tiret, cela signifie que la valeur est identique avant et après l'appel du mot.

Les nombres

Par défaut, les nombres sont entrés en simple précision, c'est-à-dire sur 16 bits.

Il est possible d'entrer des nombres double précision dans l'instruction en les faisant suivre par un .. Plus exactement, le . peut-être n'importe où dans le nombre.

Forth peut comprendre et afficher des nombres en n'importe quel base. Pour cela, il suffit de préciser la base soit en utilisant les mots prédéfinis DECIMAL et HEX, soit en manipulant la variable BASE.

PAMPUK Forth, comme beaucoup de Forth de base, ne connaît que les nombres entiers.

Les expressions

Du fait du fonctionnement du Forth avec une pile, les expressions sont écrites de manière postfixée. Cela signifie que l'opérateur suit les opérandes.

Par exemple, l'expression 4 + 3 en notation usuelle mathématique (infixée) devient 4 3 + en notation postfixée.

Exemple plus complexe :

5 7 * 3 +

Cette expression est équivalente à 5 * 7 + 3 en notation usuelle et donne le résultat 38.

Les constantes

Forth peut créer des mots dont l'exécution met une valeur sur la pile. Ces mots sont appelés des constantes. Pour créer une constante, on utilise le mot CONSTANT. Ce mot est suivi du nom de la constante. La valeur associée est celle qui est sur la pile lors de la création de la constante.

Exemple :

5 CONSTANT CINQ

Ce code crée une constante CINQ qui met la valeur 5 sur la pile. On peut utiliser cette constante de la manière suivante :

CINQ .

Le mot CINQ met la valeur 5 sur la pile, puis le mot . prend cette valeur et l'affiche.

Les variables

Forth peut créer des mots qui mettent sur la pile l'adresse d'une variable. Pour cela, on utilise le mot VARIABLE. Ce mot est suivi du nom de la variable. Lors de l'exécution de ce mot, l'adresse de la variable est mise sur la pile.

Cela permet par la suite de stocker des valeurs à des adresses mémoires spécifiquement allouées et associé à un nom.

Exemple :

10 VARIABLE X

Ce code crée une variable X initialisée à 10. On peut utiliser cette variable de la manière suivante :

X @

Le mot X met l'adresse de la valeur de la variable X sur la pile, puis le mot @ prend cette adresse et met la valeur à cette adresse sur la pile. Cela permet de lire la valeur de la variable X.

11 X !

Le mot 11 met la valeur 11 sur la pile, puis le mot X met l'adresse de la variable X sur la pile et enfin le mot ! prend la valeur et l'adresse sur la pile et met la valeur à cette adresse. Cela permet de changer la valeur de la variable X.

Les chaînes de caractères

(?TODO?) absence de S" et comment ajouter ce mot.

La création de mots

La manière la plus standard de créer un mot en Forth est d'utiliser le mot :. Ce mot est suivi du nom du mot à créer, séparé par un espace bien entendu. Suit le code qui sera associé à ce mot, c'est-à-dire le code qui sera exécuté lorsque le mot sera interprété. Enfin, le mot ; est utilisé pour indiquer la fin du code et terminer la définition du mot.

En Forth, cette opérations est appelée la compilation. Le code est compilé dans le dictionnaire courant à la suite des autres mots.

Exemple :

: BONJOUR ." BONJOUR A TOUS" ;

Ce code crée un mot BONJOUR qui affiche BONJOUR A TOUS à l'écran.

: *2 DUP + ;

Ce code crée un mot *2 qui double la valeur sur la pile. En effet, DUP duplique la valeur sur la pile, et + ajoute les deux premières valeurs de la pile. Le résultat se retrouve sur la pile. On peut utiliser ce mot de la manière suivante :

5 *2 .

Qui affiche 10.

Comme on peut le voir, les mots créés peuvent être nommés avec des caractères spéciaux. Forth ne connaît que les mots et ne cherche pas à les interpréter autrement que par leur nom. 5 *2 n'est pas une expression mathématique, mais deux mots à exécuter.

Structure d'un mot

Comprendre comment est formé un mot en Forth est important pour comprendre comment fonctionne le langage en interne. Cela aide lorsque l'on veut comprendre comment un mot est exécuté, ou comment un mot est compilé. Et cela aide aussi à comprendre comment fonctionnent les mots de définition.

Nom Signification Taille Contenu
NFA Name Field Address 1 octet bit 7 : 1
bit 6 : PRECEDENCE
bit 5 : SMUDGE
bit 4-0 : longueur du nom
n octets nom du mot, le dernier octet a le bit 7 à 1
LFA Link Field Address 2 octets adresse du mot précédent
CFA Code Field Address 2 octets adresse du code à exécuter
PFA Parameter Field Address n octets code à exécuter, adresses de mots, valeurs...

NFA

Le Name Field Address commence un mot et décrire ses caractéristiques. Le bit 7 du premier octet est à 1. Les bits 4 à 0 de ce même premier octet indiquent la longueur du nom du mot. C'est pourquoi un mot Forth a une limite à 31 caractères.

PRECEDENCE : si le bit 6 est à 1, cela signifie que le mot est de type IMMEDIATE. Lors de la compilation d'un mot, un mot immédiat est exécuté sur le moment, plutôt que compiler. (?TODO? Cf. le fonctionnement de la compilation)

SMUDGE : si le bit 5 est à 1, cela signifie que le mot est valide. C'est le mot ; qui place ce bit à 1 lors de la fin de la compilation d'un mot.

Les octets qui suivent forment le nom du mot. Le dernier octet de ce nom a le bit 7 à 1.

LFA

Le Link Field Address pointe vers le mot précédent dans le dictionnaire. L'intégralité des mots du dictionnaire courant forment ainsi une liste chaînée. Le premier mot défini, LIT dans cette implémentation, a un LFA à 0, indiquant la fin de la chaîne.

CFA

Le Code Field Address pointe vers le code à exécuter lors de l'exécution du mot. Lors de l'exécution d'un mot, Forth prend l'adresse du CFA et y saute pour exécuter le code.

Cette adresse peut-être tout simplement l'adresse du PFA. C'est le cas pour les mots écrits en assembleur directement. Ce code aura la charge de rappeler la routine qui passe au mot suivant. Sur cette implémentation, il suffit de faire un JP (IX).

L'adresse du CFA peut aussi pointer vers un code qui va lire successivement des adresses de mots présentes dans la PFA. C'est le cas pour les mots écrits à partir d'autres mots Forth.

Note : PAMPUNK Forth est un Forth avec une implémentation ITC (Indirect Threaded Code), ce qui est un type d'implémentation usuel sur les machines 8 bits. Dans d'autres types d'implémentations (DTC/Direct Threaded Code, STC/Subroutine Threaded Code, TIC/Token Threaded Code,...), le contenu du CFA peut être différent. Cependant, sa sémanitque reste la même : c'est ce qui indique ce qui doit être exécuté.

PFA

Le Parameter Field Address est l'endroit où sont stockés les paramètres du mot. Cela peut être :

  • du code assembleur lors que le CFA pointe directement vers le PFA,
  • des adresses de mots Forth lorsque le mot a été défini par :,
  • des valeurs quelconques utilisées par d'autres types de mots (variables, constantes,...).

Exemples

Le mot EXECUTE prend une adresse sur la pile et continue l'exécution à cette adresse. Le mot est situé à l'adresse 2026h.

Champ Valeurs en mémoire Signification
NFA 87h Bit 7 à 1 et longueur du nom du mot : 7
45h 58h 45h 43h 55h 54h C5h Les octets ASCII du nom du mot qui forment EXECUTE, le dernier octet a son bit 7 à 1.
LFA 15h 20h Adresse du mot précédent : 2015h, l'adresse du NFA de LIT
CFA 32h 20h Adresse du PFA de EXECUTE, qui suit juste après
PFA Le code machine qui prendre l'adresse sur la pile, la place dans le registre HL puis saute à cette adresse.

Le code assembleur dans le PFA :

POP   HL
LD    E,(HL)
INC   HL
LD    D,(HL)
EX    DE,HL
JP    (HL)

Le mot ALLOT qui réserve de la place dans le dictionnaire, est un mot écrit avec d'autres mots Forth. Il est situé à l'adresse 2774h.

Champ Valeurs en mémoire Signification
NFA 85h Bit 7 à 1 et longueur du nom du mot : 5
41h 4Ch 4Ch 4Fh D4h Les octets ASCII du nom du mot qui forment ALLOT, le dernier octet a son bit 7 à 1.
LFA 69h 27h Adresse du mot précédent : 2769h, l'adresse du NFA de HERE
CFA 32h 20h Adresse du code d'exécution des mots définis par :.
PFA Liste de CFA des mots qui composent ALLOT.

Le code Forth dans le PFA :

  DP    \ met sur la pile la dernière adresse allouée
  +!    \ prend la valeur en seconde position sur la pile et l'ajoute à la valeur pointée par l'adresse en première position de la pile
  ;     \ termine le mot et retourne à la boucle d'exécution Forth

Les mots de définition

Les mots de définition sont des mots qui créent d'autres mots. Le plus utilisé est :, central au Forth. Mais on y trouve aussi CONSTANT et VARIABLE. À chaque fois que l'exécution d'un mot en ajoute un nouveau au dictionnaire, ce mot est un mot de définition.

Pour comprendre les mots de définition, il est nécessaire d'avoir compris la structure d'un mot en Forth. Un mot de définition a en effet en charge de remplir les champs du mot créé.

Ainsi, le mot CONSTANT crée un NFA avec le nom qui suit, lier le nouveau mot au précédent du dictionnaire courant, mettre dans le CFA l'adresse d'un code qui mettra la valeur trouvée dans le PFA sur la pile, et enfin mettre dans le PFA la valeur trouvée sur la pile lors de l'exécution de CONSTANT.

Le nouveau mot créé, lorsqu'il sera exécuté, aura donc pour CFA l'adresse du code qui mettra la valeur sur la pile, et pour PFA la valeur à mettre sur la pile.

On peut voir que le mot CONSTANT est associé à deux codes exécutables : le code de CONSTANT en soi, exécuté lors de son appel et qui en charge de construire l'autre mot ; mais aussi le code qui sera « donné » à chacun des mots créés. À chacune des constantes dans ce cas-ci.

Il est possible de créer ses propres mots de définitions, et pour cela, Forth offre deux mots pour aider à ces manipulations : <BUILDS et DOES>.

<BUILDS se charge de créer un mot avec le nom qui suivra le mot de définition lors de son appel. Les mots qui suivent servent ensuite à opérer sur ce mot afin de le construire, de le mettre en forme.

Il est possible par exemple de stocker des informations dans le PFA du mot créé.

DOES> se charge de modifier le CFA du mot créé pour exécuter le code qui suit DOES>. Le code qui suit DOES> est donc exécuté lors de l'appel du mot créé. À noter que le système met sur le pile l'adresse du PFA+2 lors de cette exécution.

Par exemple, CONSTANT qui est un mot de définition, pourrait être définit de la manière suivante :

: CONSTANT
  <BUILDS ,
  DOES> @
  ;

Lorsque le mot CONSTANT est appelé, l'exécution de <BUILDS crée un mot avec le nom qui suit l'appel de CONSTANT. Puis , est exécuté. Ce mot prend la valeur sur la pile est l'ajoute à la fin du dictionnaire, c'est-à-dire, à ce moment-là, au PFA+2 du mot en train d'être créé.

Note : la première adresse de PFA est utilisée par le fonctionnement interne de la définition. (?TODO? détailler).

Ensuite, DOES> est exécuté. Ce mot modifie le CFA du mot créé pour exécuter le code qui suit DOES>. Ce code est ici @, qui prend l'adresse sur la pile et met la valeur à cette adresse sur la pile. L'adresse sur la pile est l'adresse du PFA+2, qui est l'adresse où se trouve la valeur qui a été mise là lors de la création du mot par ,.

(?TODO? Que se passe-t-il avec la pile lors de l'exécution de DOES> ? Est-ce qu'il est obligatoire de consommer le PFA+2 ?)

Les mots immédiats

Les mots immédiats sont des mots qui sont exécutés immédiatement lors de la compilation, plutôt que compilés.

Normalement, lors de la compilation, les adresses des mots spécifiés sont ajouté au code du mot en cours. Cependant, lorsqu'un mot immédiat est rencontré, plutôt que compilé, il est exécuté. Cela permet d'agir sur la compilation en cours.

(?TODO?) Donner un exemple

Les conditions

Le mot principal pour définir un branchement conditionnel en Forth est IF. Ce mot prend la valeur sur la pile et si celle-ci est non nulle, continue l'exécution du code du mot en cours. Dans le cas contraire, l'exécution se poursuit après le mot ELSE s'il est présent, ou après le mot THEN sinon.

D'un point de vue syntaxique, la lecture d'une condition en Forth est un peu étonnante lorsque l'on vient de langages plus usuels.

La condition se trouve en effet avant le mot IF. Et THEN est à comprendre comme un « puis ensuite », terminant la clause conditionnelle.

: IS<3 3 < IF ." INFERIEUR A 3" ELSE ." PAS INFERIEUR A 3" THEN ;
2 IS<3  \ Affiche "INFERIEUR A 3"
4 IS<3  \ Affiche "PAS INFERIEUR A 3"

IF, ELSE et THEN étant des mots immédiats, leur utilisation n'est valide que pendant la compilation d'un mot.

Les boucles

(?TODO?) ajouter ce paragraphe

La mémoire

La mémoire de la machine est entièrement accessible. Il est bien entendu important de connaître sa structure pour savoir où lire, où écrire et aussi surtout où ne pas écrire n'importe quoi.

Il y a des espaces mémoire importants et nommés en Forth. Par exemple, HERE pointe vers la prochaine adresse libre dans le dictionnaire, TIB pointe vers le buffer de texte, PAD pointe vers un espace mémoire temporaire.

Les mots principaux pour la mémoire sont @ et !. Le premier permet de lire une valeur à une adresse, le second d'écrire une valeur à une adresse.

Pour manipuler des octets, on utilise les mots C@ et C!. Pour manipuler des valeurs de 32 bits, on utilise les mots 2@ et 2!.

Il est aussi possible d'accéder à la mémoire vidéo avec les mots V@ et V!.

Les adresses importantes s'obtiennent à partir de mots spécifiques. Par exemple, un mot construit par VARIABLE donne l'adresse de la variable ainsi créée.

Il est aussi possible de réserver de la mémoire avec le mot ALLOT.

Plan de la mémoire du HRX

Mémoire principale

----  --------------------------- -----
0000  ROM
      Système d'exploitation et
      routines graphiques
1FFF
----  --------------------------- -----
2000  ROM FORTH
3FFF
----  --------------------------- -----
4000  Pile images (empile vers
      les addresses hautes)

      Pile des paramètres
      (empile vers les addresses
5E00  basses)
----  --------------------------- -----
5FF0  Début de la pile des        S0 @
      paramètres
----  --------------------------- -----
6000  Dictionnaire (empile vers
      les addresses hautes)

DDBC  10 buffers d'édition        FIRST
      ...
      ...                         LIMIT
FE00  TIB                         TIB @

      Pile des appels (empile
      vers les addresses basses)
FF42  Variables FORTH             R0
FF8E  Mot FORTH en RAM
FFA0  Adresse de départ
FFF0  Autres variables et pile
      système (?TODO?)

Variables FORTH

Adresse Contenu
FF42 NFA du dernier mot du vocabulaire éditeur
FF44 Nombre de lignes par « screen » (21)
FF46 Adresse d'exécution de BLOCK
FF48 Adresse d'exécution de R/W
FF4A Adresse du CFA de R/W
FF4C Variable USE (prochain buffer)
FF4E Variable PREV (buffer courant)
FF50 Variable OFFSET
FF52 Nombre de caractères pour le nom des « screens »
FF54 Nombre de caractères par ligne pour l'éditeur
FF56 Variable FIRST (DDBCh)
FF58 Variable LIMIT (FE00h)
FF5A Nombre d'octets par buffer
FF5C Variable R0
FF5E Variable TIB
FF60 Variable WIDTH
FF62 Variable FENCE
FF64 Variable DP
FF66 Variable VOC-LINK
FF68 Variable BLK
FF6A Variable IN
FF6C Variable SCR
FF6E Variable CONTEXT
FF70 Variable CURRENT
FF72 Variable STATE
FF74 Variable BASE
FF76 Variable DPL
FF78 Variable CSP
FF7A Variable R
FF7C Variable HLD
FF7E Variable ASSADR qui contient le CFA du vocabulaire d'assembleur (?TODO?). Pointe sur QUIT s'il n'y a pas de vocabulaire d'assembleur.
FF80 Adresse de NUMBER
FF82 Adresse de ERROR
FF84 Adresse de (chaînage d'un autre langage ?TODO?)
FF86 Adresse de FWADR, adresse du premier mot Forth exécuté. Pointe sur ABORT.
FF88 Graine pour RND et RANDOM
FF8A Pointeur vers le dernier MESSAGE
FF8C Pointeur vers la pile des appels
FF8E Le mot FORTH compilé
FF9C Variable LATEST
FFA1 Variable S0

Mémoire vidéo

----  --------------------------- -----
C000  Écran vidéo

----  --------------------------- -----
F900  Alphabet spécial

----  --------------------------- -----
FD00  Alphabet standard

----  --------------------------- -----
FE61  Variables graphiques

----  --------------------------- -----
FFF0  Autres variables et pile
      système (?TODO?)
----  --------------------------- -----
Adresse Contenu
FE8A calibrage 50ième de seconde (horloge)
FE8B calibrage secondes (horloge)
FE8C calibrage minutes (horloge)
FE8D calibrage heures (horloge)
FE8E 50ième de seconde (horloge)
FE8F secondes (horloge)
FE90 minutes (horloge)
FE91 heures (horloge)

Les mots de vocabulaire

Il existe pour Forth deux vocabulaires actifs : le vocabulaire courant et le vocabulaire de contexte. Le vocabulaire courant est celui dans lequel les mots compilés sont ajoutés. Le vocabulaire de contexte est celui dans lequel les mots sont cherchés lors de l'interprétation et de la compilation.

Les vocabulaires sont chaînés, c'est-à-dire qu'un vocabulaire nouvellement défini pointe vers le vocabulaire courant. Ainsi, les mots de ce vocabulaire « parent » sont disponibles pour le nouveau vocabulaire.

Lors de l'utilisation du mot : celui-ci commence par changer le vocabulaire de contexte pour le vocabulaire courant. Ainsi, après une définition, le contexte est revenu au vocabulaire courant.

Exemple :

VOCABULARY MONVOC           \ Crée un nouveau vocabulaire MONVOC
: BONJOUR ." BONJOUR" ;     \ Crée un mot BONJOUR dans le vocabulaire FORTH et non MONVOC
MONVOC DEFINITIONS          \ Change le vocabulaire courant et de contexte pour MONVOC
: AUREVOIR ." AUREVOIR" ;   \ Crée un mot AUREVOIR dans le vocabulaire MONVOC

BONJOUR                     \ Affiche BONJOUR
AUREVOIR                    \ Affiche AUREVOIR

FORTH                       \ Change le vocabulaire de contexte pour FORTH

BONJOUR                     \ Affiche BONJOUR
AUREVOIR                    \ Erreur, le mot AUREVOIR n'est pas dans
                            \ le vocabulaire de contexte
                            \ ??? Et pourtant ça fonctionne. AUREVOIR est trouvé. Pourquoi ?

: BYE ." BYE" ;             \ Le mot BYE est ajouté au vocabulaire MONVOC, qui est
                            \ toujours le vocabulaire courant. Au passage, le vocabulaire
                            \ de contexte est changé pour MONVOC

BYE                         \ Affiche BYE
AUREVOIR                    \ Affiche AUREVOIR

Le mini-éditeur

PAMPUK Forth est livré en ROM avec un éditeur de texte rudimentaire. Celui-ci permet de manipuler et de mettre au point des mots puis de les compiler, les sauvegarder, les charger.

L'éditeur manipule des SCREEN de 38 colonnes par 21 lignes, ce qui fait 798 octets. Ces screens sont stockés dans des buffers de 826 octets dont la structure est détaillée plus bas. Il y a de la place réservée pour 10 screens simultanés dans la mémoire de l'ordinateur. Lorsque cette mémoire est pleine et qu'un nouveau screen est demandé, un plus ancien sera retiré de la mémoire, après sauvegarde si nécessaire.

Un buffer peut contenir du code source afin de le compiler, mais il peut tout aussi bien contenir des données brutes afin de les sauver et charger depuis une mémoire de masse.

Attention, du au fonctionnement du Forth, il est important d'oublier (FORGET) les versions précédentes d'un mot avant d'en compiler une nouvelle version. Si le compilateur PAMPUK Forth affiche un message lorsqu'un mot est redéfini, ce n'est qu'un avertissement, le mot est effectivement redéfini.

Manipulations dans le mini-editeur

Pour pouvoir changer le contenu d'un écran il faut utiliser le vocabulaire de contexte EDITOR.

Format interne des screens et buffers

Un buffer est composé de 826 octets.

Offset   Contenu
------   -------
0-1      Numéro du buffer, le bit de poids fort est à 1 si le buffer a été modifié.
2-25     Nom du buffer. Initialisé avec des zéros.
         Lorsque le nom est modifié, il est complété avec des espaces.
26-823   798 octets de données.
824-825  Deux octets à 0 ?

Les buffers se situent entre les adresses FIRST et LIMIT.

Note : lors de la première utilisation de OPEN, le buffer ouvert est le suivant par rapport à PREV. Ce qui fait que le premier buffer n'a l'air utilisé qu'après avoir rempli tous les autres.

Il y a deux variables qui indiquent quel est le buffer courant : l'une est PREV, qui sert pour les manipulations de buffers par le système et indique une adresse. L'autre est SCR, qui est utilisée pour les manipulations par l'utilisateur et indique un numéro.

L'éditeur pleine page

Il existe aussi un éditeur pleine page, disponible sur cassette (et disquette pour le Hector HRX/MX uniquement ?TODO?).

Il se loge en adresse 4000h, ce qui permet de laisser libre l'espace mémoire usuel de compilation de mots, au détriment de la place pour manipuler les images.

Se lance avec EDIT (n - ) ou E (pour le screen courant).

Ajoute les mots GLUPS ( - n1 n2) (pour les erreurs de compilation), WHERE (pour afficher le screen au niveau de l'erreur), LLIST pour un listing sur imprimante, COPY ( n1 n2 - ) pour copier le contenu d'un buffer vers un autre, :MOT qui permet d'ajouter des raccourcis clavier d'édition et KILL_EDITOR qui supprime l'éditeur pleine page de la mémoire.

Des commandes d'édition sont ajoutées aux commandes usuelles (?TODO? les lister ici ?).

On quitte l'éditeur avec CTRL + RETURN.

Fonctionnement avec une cassette

Lors d'un FLUSH avec une cassette, le système va proposer des opérations pour chacun des buffers modifiés.

Par exemple :

ECRAN NO      1
SUR K7 ?

Les commandes possibles à ce moment sont :

  • R pour rembobiner la cassette
  • P pour passer un bloc (nom pour la représentation d'un buffer sauvegardé) de la cassette. Son numéro est affiché mais il n'est pas chargé en mémoire.
  • O oui, sauve le buffer sur cassette
  • N non, ne sauve pas le buffer sur cassette

Lors d'un LIST ou un LOAD, si le buffer n'a pas été ouvert, le système va automatiquement charger depuis la cassette le premier bloc trouvé et l'insérer dans le buffer avec le numéro indiqué.

Fonctionnement avec une disquette

Afin de pouvoir utiliser une disquette, il est nécessaire de charger les mots supplémentaires depuis la disquette PAMPUK Forth. Celle-ci doit être insérée dans le lecteur A puis l'entrée « disquette » doit-être sélectionnée dans le menu de démarrage.

Une fois les mots chargés, le forth est initialisé et se trouve avec le vocabulaire DISK actif. Les nouveaux mots sont donc disponibles.

Le mot R/W est aussi redirigé pour fonctionner avec la disquette.

(?TODO?) ajouter ce paragraphe

Affichage graphique

La surface d'affichage de l'Hextor HRX fait 243 x 228 pixels adressables individuellement, chaque pixel pouvant prendre une couleur dans une palette de 4 couleurs. Ces couleurs sont choisis parmi 18couleurs en deux luminosités.

L'origine de l'écran est en bas à gauche.

La mémoire vidéo se situe entre les adresses C000h et FFFFh. Ces adresses sont partagés avec les adresses de la RAM, il est donc nécessaire de choisir le mapping de la mémoire pour accéder à la mémoire vidéo.

La partie affichée de la mémoire vidéo se situe entre les adresses C000h et F8FFh incluses. Chaque pixel est représenté par 2 bits, ce qui permet les 4 index de couleurs simultanés possibles. Cela signifie aussi qu'un octet encode 4 pixels consécutifs. Les 2 bits de poids fort de l'octet représentent le pixel le plus à droite de l'écran, et inversement, les 2 bits de poids faible représentent le pixel le plus à gauche.

La mémoire d'affichage est linéaire, partant du coin haut gauche de l'écran et décrivant l'affichage ligne par ligne. Chaque ligne utilise 64 octets. Cela donne une largeur en pixels théorique de 256. Cependant, seuls les 243 premiers sont affichés.

Couleurs

Code Pleine luminosité Demi-luminosité
0 Noir Noir
1 Rouge Rubis
2 Vert Olive
3 Jaune Marron
4 Bleu Marine
5 Magenta Violet
6 Cyan Turquoise
7 Blanc Gris

La palette se change avec le mot COLOR.

Modes d'affichage graphique

Il y a deux modes d'affichages, le mode BIG et le mode LITTLE. Dans le mode BIG, les opérations sur la surface graphiques sont effectués par groupe d'octets, ce qui permet un accès rapide. Dans le mode LITTLE, les opérations sont effectuées pixel par pixel, ce qui permet plus de précision, au détriment de la vitesse.

Système d'images

Il est possible de définir des images avec le mot IMAGE. Ce mot est un mot de définition, qui va en créer un autre. Celui-ci aura la capacité de s'afficher à l'écran.

Exemple :

4 BASE !        \ passe en base 4
1111 1111       \ défini la forme de l'image
1000 0001
1222 2221
1111 1111
DECIMAL         \ passe en décimal
2 4 IMAGE CARRE \ défini le mot CARRE de 2 octets par 4 lignes

3 INK 25 25 75 75 BOX  \ affiche un rectangle
50 50 0 CARRE   \ affiche l'image entièrement

Il est possible de créer un masque associé à une image. La définition de MASK est similaire à celle de IMAGE et doit suivre sa définition afin d'y être associé.

Exemple :

4 BASE !        \ passe en base 4
0111 1110       \ défini la forme de l'image
1000 0001
1000 0001
0111 1110
DECIMAL         \ passe en décimal
2 4 IMAGE ROND  \ défini le mot ROND de 2 octets par 4 lignes

4 BASE !        \ passe en base 4
3000 0003       \ défini la forme du masque
0000 0000
0000 0000
3000 0003
DECIMAL
2 4 MASK        \ défini le masque de l'image précédente

3 INK 25 25 75 75 BOX \ affiche un rectangle
50 50 1 ROND    \ affiche l'image avec son masque
30 30 2 ROND    \ affiche l'image en mode « dessus »
30 50 3 ROND    \ affiche l'image en mode « dessous » (et donc n'apparait pas, car dans le rectangle)
100 100 3 ROND  \ affiche l'image en mode « dessous » (et ici, en dehors du rectangle, apparait)

Les modes 4 à 7 permettent de copier le morceau d'image cible (là où l'image s'affiche) dans une pile d'images. Il est ensuite possible de rappeler ces images, ce qui permet une gestion de l'affichage en plusieurs couches, ou de faire des sprites de manière aidée.

Exemple

50 50 0 CARRE     \ affiche CARRE
50 50 4 ROND      \ affiche ROND au même endroit avec copie de l'image cible
BPOP              \ le dessin de CARRE est restauré
Mode Effet
0 Affichage de l'image telle quelle, y compris la couleur d'index 0.
1 Affichage de l'image associée à son masque. Les couleurs d'index 3 du masque laissent voir le fond.
2 Mode « dessus ». Affiche tous les points dont l'index est différente de celle de PAPER.
3 Mode « dessous ». Affiche tous les points si le pixel de dessin est d'index de couleur égale à PAPER.
4 Comme le mode 0, plus copie dans la pile image
5 Comme le mode 1, plus copie dans la pile image
6 Comme le mode 2, plus copie dans la pile image
7 Comme le mode 3, plus copie dans la pile image

Modes texte

L'alphabet SPECIAL affiche les caractères s'affichent toujours en mode plein et en mode BIG. Les caractères ne peuvent être placés que sur des multiples de 4 pixels. Il y a 28 colonnes dans ce mode et l'affichage du texte est rapide.

L'alphabet spécial a des représentations pour les caractères ASCII de 32 à 95.

L'alphabet STANDARD affiche les caractères en mode calque par défaut et en mode LITTLE. Les caractères peuvent être placés au pixel près. Il y a 38 colonnes dans ce mode et l'affichage du texte est plus lent.

Les modes d'affichage texte et les modes d'affichages graphiques sont indépendants. On peut être en STANDARD et en BIG par exemple, ou bien en SPECIAL et LITTLE.

Caractères de contrôles

Les caractères de contrôles s'utilisent avec EMIT. Par exemple 11 EMIT est l'équivalent de CLS.

Code Effet
1 HOME
7 Émet un bip
8 Recule le curseur du mode texte
9 Avance le curseur du mode texte
11 CLS
12 PAGE
13 CR
14 Place le curseur en haut à gauche de l'écran sans l'effacer
15 CLS HOME
23 Mode vidéo inverse, valable en SPECIAL et STANDARD, en mode papier
24 Mode normal, valable en SPECIAL et STANDARD (annule 23)
25 Mode papier, valable en STANDARD
26 Mode calque, valable en STANDARD
27 AT (0 0 25 EMIT met le curseur en haut à gauche de l'écran)
28 SCALE
29 WINDOW
30 PEN
31 PAPER