Turbo-Forth pour IBM PC et compatibles a besoin pour communiquer avec les organes physiques de cet ordinateur de faire très souvent appel aux fonctions de son système d'exploitation MS-DOS. Cette partie du langage, bien évidemment très dépendante du système, utilise largement un grand nombre d'opérations élémentaires spécifiques à la machine.
Toutes ces opérations élémentaires sont accessibles au moyen d'interruptions logicielles, sortes de routines en code exécutables depuis n'importe quel programme en mémoire. On distingue classiquement:
les fonctions primitives du BIOS (Basic Input Output System) résident en mémoire morte, placées par le constructeur en fonction de la configuration matérielle, des fonctions MS-DOS formant une couche supérieure plus générale et standardisée mais nécessitant au préalable le chargement en mémoire vive du système d'exploitation.
Schématiquement, Turbo-Forth fait appel au système d'exploitation MS-DOS pour cinq grandes classes d'actions.
Elle s'effectue préférentiellement par le biais du gestionnaire MS-DOS dans un souci de compatibilité. Le BIOS n'est qu'exceptionnellement utilisé.
Cette partie du Forth se charge notamment des entrées au clavier, des sorties vers l'écran, et de toutes les entrées-sorties vers les périphériques (imprimante, sortie auxiliaire etc...).
Pour gérer ses périphériques, MS-DOS suppose l'installation au démarrage d'un certains nombre de "drivers" qui pilotent les opérations d'entrées-sorties pour chacun d'entre eux. Outre les drivers standards toujours installés, Turbo-Forth suppose que soit installé le driver ANSI ce qui lui permet notamment de modifier les attributs d'affichage à l'écran. Votre fichier CONFIG.SYS lu à l'allumage du système doit donc comporter la ligne DEVICE = ANSI.SYS pour exploiter ces possibilités.
La mémoire externe de l'ordinateur ou mémoire de masse est un ensemble complexe possédant une double organisation: une organisation physique sous forme d'un support -le disque- divisé en pistes, secteurs et groupes de secteurs (clusters) et une organisation logique en fichiers regroupés dans des répertoires et des sous-répertoires. L'accès aux fichiers depuis Forth passe par un jeu complet de primitives d'exploitation du MS-DOS.
Sous le seul angle de vue Disk Operating System, MS-DOS possède une gestion hybride. Une première architecture, directement héritière du système CP/M 80, exploite les fichiers au travers de zones tampons de contrôle (FCB ou File Control Buffer) maintenues en mémoire. Les entrées-sorties n'y sont pas communes avec celles des périphériques et ne peuvent être redirigées. Ce type de gestion des fichiers persiste dans les versions ultérieures à la V1.0 de MS-DOS mais à partir de la V2.0 est apparue une deuxième architecture, de type UNIX, pour laquelle périphériques et fichiers ont les mêmes opérations d'entrées-sorties. Chaque destinataire de ces opérations est défini par un numéro propre, que l'on appelle généralement ticket en français ou handle en anglais. Turbo-Forth utilise la gestion par tickets et la notion de HANDLE prend ainsi une grande importance en Forth.
La première utilisation de la mémoire de masse par Forth consiste à gérer sa mémoire virtuelle c'est-à-dire cet espace mémoire où sont stockés les programmes que compile le langage. Virtuelle car cet espace très vaste, apparemment totalement accessible au programme, n'occupe en fait qu'une petite partie de la mémoire centrale: les tampons. Par l'intermédiaire de ceux-ci, les échanges avec la mémoire de masse s'opèrent de façon transparente.
Turbo-Forth a choisi de gérer des fichiers textes séquentiels au format standard ASCII plutôt que des fichiers blocs en accès direct comme ses prédécesseurs Forth. Ce choix s'imposait dans une politique générale d'ouverture sur l'environnement MS-DOS usuel. Les tampons Forth sont alors limités à des tampons de lignes.
Avec l'apparition des microprocesseurs 16 bits permettant l'adressage d'une vaste mémoire centrale, les nouveaux systèmes d'exploitation permettent la cohabitation de plusieurs programmes, certains d'entre eux pouvant rester résidents. MS-DOS dispose dans ce but d'un système d'allocation de la mémoire centrale auquel Forth accède lui-même. Cette mémoire centrale est organisée par le microprocesseur 8086 en segments de 64 kilo-octets disposés en paragraphes de 16 octets. Turbo-Forth peut être confiné dans un seul segment. Ses opérateurs extra-segment lui donnent par ailleurs accès à toute la mémoire adressable.
Turbo-Forth introduit le concept fondamental d'intégration. On entend par là la possibilité pour un logiciel de lancer l'exécution d'un programme ou d'une commande externe sans quitter ce logiciel qui reste présent en mémoire centrale et auquel le système retourne dès la fin de la procédure externe qu'il a lui-même lancée. La première application de l'intégrateur Turbo-Forth est l'utilisation d'un éditeur de texte quelconque laissé au libre choix de l'utilisateur.
(IN) | fun --- c |
Lecture d'un caractère depuis un périphérique d'entrée MS-DOS. Le code de fonction en appel se réfère aux interruptions MS-DOS et peut prendre en pratique les valeurs suivantes:
fun: | caractère lu: |
1 | STDIN (le clavier) avec écho sur STDOUT (l'écran), test d'un Break et traduction éventuelle des codes étendus (Ctrl,Alt,Esc etc.) |
3 | AUX (interface série) avec écho sur STDOUT |
7 | Comme la fonction 1 sans écho ni test Break ni traduction |
8 | Comme la fonction 1 sans écho |
11 | Test tampon STDIN c = 0 si le tampon est vide |
STDIN, STDOUT, AUX sont des dénominations MS-DOS de tickets de périphériques qui peuvent faire l'objet de redirections: il ne faut pas y voir des entités FORTH.
(OUT) | c fun --- |
Écriture d'un caractère sur un périphérique de sortie MS-DOS. Le code de fonction en appel se réfère aux interruptions MS-DOS et peut prendre en pratique les valeurs suivantes:
fun: | caractère écrit: |
2 | STDOUT c'est-à-dire le plus souvent l'écran |
4 | AUX, la sortie série active |
5 | STDPRN, l'imprimante |
6 | l'écran si c <> 255 |
9 | STDOUT mais c doit être l'adresse d'une chaîne terminée par le caractère $ (le Forth n'utilise pas ce type de chaînes) |
STDOUT, AUX, STDPRN sont des dénominations MS-DOS de tickets de périphériques qui peuvent faire l'objet de redirections: il ne faut pas y voir des entités FORTH.
(CONS) | c --- |
Primitive d'écriture d'un caractère sur l'écran. Équivaut à 6 (OUT)
(CONSOLE) | c --- |
Affiche le caractère c sur le terminal. Le mot autorise la gestion multitâche et compte le nombre de caractères émis dans la variable #OUT . Il peut donc servir de vecteur pour EMIT si on renonce à utiliser une sortie imprimante:
' (CONSOLE) IS EMIT
(PRINT) | c --- |
Affiche un caractère c sur l'imprimante seulement. Ce mot peut être utilisé par le mot d'exécution vectorisée EMIT.
ASCII A (PRINT)
(EMIT) | c --- |
Affiche le caractère c sur le terminal avec éventuel écho sur l'imprimante. Ce mot est le vecteur par défaut du mot d'exécution vectorisée EMIT. Si la variable booléenne PRINTING contient une valeur non nulle le caractère c est envoyé sur le terminal et sur l'imprimante, sinon il n'est affiché qu'à l'écran. Le contenu de la variable #OUT est incrémenté de une unité dans les deux cas.
PRINTING ON ASCII A (EMIT) PRINTING OFF ASCII B (EMIT)
(KEY) | --- c |
Attend qu'une touche du clavier soit activée et dépose le code ASCII de celle-ci sur la pile de données. A l'initialisation, ce mot est utilisé par le mot d'exécution vectorisée KEY.
(KEY) . et appui sur la touche 'A' affiche 65 (KEY) (KEY) . . et appui sur la touche 'F1' affiche 59 0
(KEY?) | --- f |
Renvoie un flag booléen vrai si l'utilisateur active une touche du clavier, sinon renvoie un flag booléen faux. Ce mot est utilisé par le mot d'exécution vectorisée KEY?.
PRINTING | --- adr |
Variable booléenne dont le contenu est vrai si (EMIT)[par conséquent en général EMIT] doit envoyer un caractère en écho sur l'imprimante.
PRINTING ON active l'imprimante PRINTING OFF désactive l'imprimante
PR-STAT | --- f |
Mot de contrôle de l'imprimante que Turbo-Forth n'utilise pas en temps ordinaire. Délivre un flag booléen toujours 'vrai' à l'initialisation. Sans être un mot vectorisé, peut être facilement redéfini par l'usager selon l'équipement particulièrement dans un environnement multitâche:
: PRET? CR ." L'imprimante est-elle connectée et allumée ?" KEY UPC ASCII O = ; ' PRET? IS PR-STAT
Avec un BIOS compatible IBM et une imprimante parallèle, on peut tester l'état de l'imprimante n°0 avec le mot suivant:
DECIMAL CODE (PR-STAT) 2 # AH MOV 0 # DX MOV 23 INT 144 # AH XOR 0= IF -1 # AX MOV ELSE 0 # AX MOV THEN 1PUSH END-CODE ' (PR-STAT) IS PR-STAT
Dans ce cas PR-STAT ne délivre un flag vrai que si l'imprimante est connectée et prête à imprimer.
KEY | --- c | F83 |
Mot d'exécution vectorisée. Attend qu'une touche du clavier soit activée, puis délivre le code ASCII de cette touche. Ce mot exécute par défaut (KEY) . La revectorisation de cette fonction permet de modifier profondément l'accès au système, voire de le commander depuis un périphérique différent du clavier (modem ou RS232 pour exemple). Exemple:
: DECODE-CLAVIER ( ---) BEGIN CR ." Appuyez sur une touche du clavier (ESC pour finir) " KEY CR ." Vous venez d'appuyer sur la touche de code " DUP . 27 = UNTIL ;
Notez à l'exécution de DECODE-CLAVIER les codes retournés par certaines touches spéciales (fonctions, contrôles, touches alternes): il faudra parfois exécuter deux KEY pour accéder à ces touches.
KEY? | --- f |
Mot d'exécution vectorisée. Délivre un flag booléen vrai si une touche a été activée au moment de l'exécution de ce mot. KEY? exécute par défaut (KEY?).
: ARRETEZ-MOI ( -- ) BEGIN CR ." frappez une touche..." KEY? UNTIL KEY DROP ;
STOP? | --- f |
Ce mot se met en attente d'une touche dès qu'une première touche est pressée puis délivre un booléen vrai s'il s'agit de la touche de retour-chariot. STOP? est utilisé pour suspendre momentanément ou sortir d'un processus répétitif:
: JE-COMPTE ( -- ) 0 BEGIN CR DUP . 1+ STOP? UNTIL DROP ;
EMIT | c --- |
Mot d'exécution vectorisé. Affiche le caractère de code ASCII c sur le périphérique sélectionné. Le mot EMIT peut être vectorisé par l'un des mots suivants:
(CONSOLE) | Affichage sur le moniteur |
(PRINT) | Affichage sur l'imprimante |
(EMIT) | Affichage sur le moniteur et l'imprimante si PRINTING est vrai, sinon n'affiche que sur le moniteur. |
Selon le matériel utilisé, le code ASCII du caractère c peut être compris dans l'intervalle 0<=c<127 ou 0<=c<255. L'interprétation des codes compris entre 0 et 31 dépend du matériel utilisé, mais en règle générale, ce sont les codes ASCII standards qui sont exécutés. Attention, si votre système dispose d'options de sélection de mode d'affichage ou de couleurs par l'intermédiaire du code ASCII ESC (27 en décimal), les commandes resteront spécifiques à votre système.
Le mot EMIT peut aussi être revectorisé sur un mot défini par l'utilisateur. Exemple:
: UP-EMIT ( c ---) UPC (EMIT) ; \ transformation majuscule ' UP-EMIT IS EMIT
A partir de ce moment, TURBO-Forth refuse d'afficher les caractères minuscules. En fait, UP-EMIT convertit tout caractère minuscule en caractère majuscule
BACKSPACES | n --- |
Envoie n fois le code ASCII 8 de recul d'une colonne sans effacement sur le terminal de sortie. Attention, seul le code 8 est envoyé, ce qui peut poser des problèmes sur certaines imprimantes.
BEEP | --- |
Provoque l'émission d'un bip sonore sur la majorité des terminaux et imprimantes.
CR | --- |
Mot d'exécution vectorisée. Exécute par défaut le mot CRLF. Exécute un retour chariot et le passage à la ligne suivante du curseur sur la console ou l'imprimante. Le contenu du compteur de caractères #OUT est remis à zéro et le contenu du compteur de lignes #LINES est incrémenté d'une unité.
CRLF | --- |
Exécute un retour chariot avec saut de ligne sur le terminal de sortie. Ce mot est exécuté par défaut par le mot CR. Il émet les codes ASCII 13 et 10. En impression, certaines imprimantes exécutent ces deux fonctions à la seule réception du code ASCII 13, ce qui provoque une impression en double interligne. Pour éviter ceci, il faut revectoriser CR comme suit:
: (CR) 13 EMIT ; : PRINTER ['] (PRINT) IS EMIT ['] (CR) IS CR ; : CONSOLE ['] (EMIT) IS EMIT ['] CRLF IS CR ;
Et à partir de maintenant, tapez simplement PRINTER pour déclencher une séance d'impression. Tapez ensuite CONSOLE pour ramener l'affichage vers l'écran exclusivement. Si vous désirez une impression simultanée sur l'imprimante et l'écran, il faudra remplacer (PRINT) par (PEMIT) dans la définition de PRINTER.
REPLICATE | n car --- |
Reproduit n fois le caractère de code ASCII car. Le mot SPACES utilise REPLICATE dans sa définition. Pour rappel, le standard n'interdit pas de définir un mot standard à l'aide de mots non standards, pourvu que le fonctionnement de ce mot reste standard. Exemple d'utilisation de REPLICATE:
: LIGNE 80 ASCII - REPLICATE ;
SPACE | --- | F83 |
Envoie un caractère 'espace' vers le terminal (console, imprimante ou les deux) déterminé par EMIT.
ASCII A EMIT ASCII B EMIT affiche AB ASCII A EMIT SPACE ASCII B EMIT affiche A B
SPACES | n --- | F83 |
Envoie n caractères 'espace' vers le terminal.
ASCII A EMIT 3 SPACES ASCII B EMIT affiche A B
TYPE | adr long --- | F83 |
Envoie vers le terminal une chaîne explicite de caractères débutant à l'adresse adr et longue de long octets:
: BALBUTIEMENT ( -- ) " Ceci est un test " ( adr n -- ) 0 DO CR DUP I TYPE LOOP DROP ;
A l'exécution ce petit exemple va afficher des chaînes de plus en plus longues:
C Ce Cec Ceci ...etc.
Comme pour tous les mots envoyant un ou plusieurs caractères sur le terminal, c'est le mot d'exécution vectorisée EMIT qui détermine sur quel(s) périphérique(s) de sortie sont envoyés les caractères:
' (PRINT) IS EMIT BALBUTIEMENT ' (EMIT) IS EMIT BALBUTIEMENT
>TYPE | adr long --- |
Version sécurisée multi-tâche de TYPE : n'affiche une chaîne qu'après l'avoir déplacée dans la zone mémoire temporaire PAD .
LTYPE | seg adr long --- |
Version multisegment de TYPE : l'adresse de la chaîne est exprimée sur 32 bits en segment et adresse offset. (seg adr)
#OUT | --- adr |
Variable gardant le nombre de caractères déjà envoyés sur une ligne: #OUT est remis à zéro à chaque retour à la ligne ou effacement de page vidéo provoqué par DARK.
#LINE | --- adr |
Variable gardant le nombre de lignes déjà envoyées: incrémentée à chaque retour à la ligne, elle est remise à zéro par DARK.
LMARGIN | --- adr |
Variable donnant le nombre d'espaces jusqu'à la marge de gauche. Sa valeur initiale est nulle. Le mot WORDS est un exemple de mise en page:
10 LMARGIN ! WORDS
RMARGIN | --- adr |
Variable donnant le nombre de colonnes jusqu'à la marge de droite. Sa valeur initiale est de 70. Le mot WORDS est un exemple de mise en page:
0 RMARGIN ! WORDS
?LINE | n --- |
Réalise un passage à la ligne sur la marge gauche s'il reste moins de n colonnes jusqu'à la marge de droite. Permet de "wrapper" une chaîne qui serait coupée en fin de ligne:
: NE-ME-COUPEZ-PAS ( -- )10 0 DO " ne-me-coupez-pas " DUP ?LINE TYPE LOOP ;
?CR | --- |
Réalise un passage à la ligne sur la marge gauche si la marge de droite est dépassée. Est utilisé par WORDS .
?TAB | len --- |
Réalise une tabulation à espacement régulier: un nombre suffisant d'espaces est émis pour que l'affichage (ou l'impression) reprenne sur une colonne multiple de len. Est utilisé notamment par WORDS .
: JOLIE-TABLE ( -- ) CR 100 0 DO ?CR 8 ?TAB I . LOOP ;
(AT) | col lig --- col lig |
Primitive de AT positionnant le curseur sur une ligne et une colonne de l'écran vidéo. Utilise une interruption compatible BIOS (10 hexa). Colonne et ligne sont laissés sur la pile.
AT | col lig --- |
Positionne le curseur clignotant sur une ligne donnée (de 0 à 24 sur un écran usuel) et une colonne donnée (de 0 à 79 généralement). Les variables #OUT et #LINE prennent les valeurs col et lig.
: ESCALIER ( -- ) DARK 20 0 DO I I AT ." Écriture en escalier" LOOP ;
(CURSOR) | --- col lig |
Donne la position courante du curseur clignotant en colonne (de 0 à 79 généralement) et numéro de ligne (de 0 à 24 sur un écran usuel). Fait appel à une interruption compatible (10 hexa) BIOS.
: PETIT-COMPTEUR (CURSOR) 1000 0 DO 2DUP AT I . LOOP 2DROP ;
(FRAME) | frame1 frame2 --- |
Fixe la taille du curseur clignotant: frame1 est la première ligne- pixel, frame2 la dernière ligne-pixel du pavé clignotant. Selon les cartes vidéo ces paramètres pourront varier de 0 à 7 (carte couleur) ou de 0 à 13 (carte monochrome) le plus souvent. Si frame2 est inférieur à frame1, le curseur disparaît. Fait appel à une interruption compatible (10 hexa) BIOS.
0 7 ( ou 0 13 ) (FRAME) : gros pavé curseur 0 0 (FRAME) : curseur fin "en haut" 7 7 (FRAME) : curseur fin "en bas" ou "au milieu"
GRMODE | --- adr |
Variable conservant le mode vidéo d'affichage graphique. Consultez votre documentation technique pour savoir quels sont les modes supportés par votre équipement. La valeur initiale de GRMODE est 2 ce qui correspond à l'affichage texte monochrome en 80*25 caractères.
(MODE) | --- |
Primitive de MODE : fixe le mode d'affichage vidéo graphique tel qu'il est défini dans la variable GRMODE. Fait appel à une interruption compatible (10 hexa) BIOS.
MODE | n --- |
Change le mode d'affichage vidéo graphique. La valeur n (comprise entre 0 et 7 le plus souvent) est conservée dans la variable GRMODE. Consultez votre documentation technique pour connaître les modes supportés par votre équipement.
DARK | --- |
Efface l'écran vidéo en réinitialisant le mode d'affichage vidéo. Remet à zéro les variables #OUT et #LINE de mise en page. Bien qu'il ne s'agisse pas d'un mot vectorisé, DARK est accessible à une redéfinition selon le terminal utilisé. Exemple: pour un terminal de type imprimante, l'action de DARK serait de réaliser un saut de page:
L'option DARK quand PRINTING est ON provoque un saut de page: FORM-FEED 12 (PRINT) \ 12 code saut de page le plus fréquent ; ' FORM-FEED IS DARK
' (MODE) IS DARK \ pour rétablir l'action usuelle de DARK sur l'écran
Dans TURBO-Forth, le mot DARK a été pseudo-vectorisé. A la méta- compilation, le premier mot de sa définition a été NOOP, c'est à dire 'ne rien faire'. Mais le principe de revectorisation exécuté par IS a substitué le mot (MODE) à NOOP en début de définition.
ATTRIBUTS | --- adr |
Variable délivrant un flag booléen autorisant ou non l'envoi d'une séquence ESCape à l'affichage par les mots utilisant (ATTRIB). Les séquences ESC sont normalement gérées par le fichier système driver ANSI.SYS. Si celui-ci n'a pas été appelé à l'initialisation du système, les attributs risquent de ne pas être gérés correctement. Dans ce cas, on neutralise les effets indésirables en tapant:
ATTRIBUTS OFF
A partir de maintenant, les mots BOLD, UNDERL, BLINK et INVERS deviennent inopérants. Pour bénéficier des attributs d'affichage par séquences ESC, il faut que votre fichier CONFIG.SYS (le créer au besoin) contienne la ligne texte suivante:
DEVICE = ANSI.SYS
et que le fichier ANSI.SYS soit présent dans le répertoire actif lors du Boot du système. Turbo-Forth suppose à son lancement que c'est bien le cas et c'est donc l'option ATTRIBUTS ON qui est active: vous le remarquez par l'affichage gras (bold) du message 'OK'.
(ATTRIB) | n --- |
Envoie l'attribut numéro n. Cette valeur vient s'intégrer dans une séquence ESC et modifie les attributs d'affichage en mode texte (surintensité, inversion, clignotement, etc...). Pour les possesseurs d'une carte couleur, ce mot permet d'ajouter d'autres commandes d'attributs en plus des mots BLINK BOLD INVERS UNDERL déjà définis:
: RED 31 (ATTRIB) ; \ affichage en caractères rouges : -BLUE 44 (ATTRIB) ; \ affichage sur fond bleu
Consultez votre documentation technique sur les codes de contrôle ANSI de votre terminal: 30 à 37 pour les couleurs de l'avant-plan et 40 à 47 pour les couleurs du fond sont des valeurs habituelles. Certaines séquences risquent de ne pas fonctionner correctement sur tous les systèmes, notamment si vous êtes en mode CGA, EGA ou HERCULES.
BLINK | --- |
Envoie une séquence d'attributs. Provoque le clignotement de tout caractère émis par la suite sur le moniteur si ATTRIBUTS est ON.
BOLD | --- |
Envoie une séquence d'attributs. Provoque la surintensité de tout caractère émis par la suite sur le moniteur si ATTRIBUTS est ON.
INVERS | --- |
Envoie une séquence d'attributs. Provoque l'inversion vidéo de tout caractère émis par la suite sur le moniteur si ATTRIBUTS est ON.
UNDERL | --- |
Envoie une séquence d'attributs. Provoque le soulignement de tout caractère émis par la suite sur le moniteur si ATTRIBUTS est ON.
ATTOFF | --- |
Envoie une séquence d'attributs. Provoque le retour en affichage normal et annule donc les attributs d'affichage précédemment demandés par BOLD, UNDERL, BLINK ou INVERS si ATTRIBUTS est ON.
20 STRING TEST$ " Test des attributs vidéo" TEST$ $! : VARIATIONS ( -- ) CR BOLD TEST$ TYPE ( en gras ) ATTOFF CR UNDERL TEST$ TYPE ( souligné ) CR BOLD TEST$ TYPE ( gras et souligné ) ATTOFF CR TEST$ TYPE ( normal ) ; ATTRIBUTS OFF VARIATIONS ATTRIBUTS ON VARIATIONS
PATHWAY | chemin\nom --- adr0 |
Interprète dans le flot d'entrée un chemin d'accès à un fichier. Délivre pour MS-DOS une adresse ascii0. La chaîne à interpréter doit être d'un seul tenant sans espace et peut comporter toutes les composantes d'un nom de fichier: lettre d'un lecteur suivi de ':', succession de répertoires et sous-répertoires séparés par '\', nom du fichier (8 caractères maximum), extension du nom ( '.' et 3 caractères maximum). MS-DOS accepte des chemins-noms de fichiers pouvant totaliser 64 caractères. Exemples:
PROG PROGRAMM.$$$ C:FORTH\GRAPHICS\DESSINS\SCHEMAS\MOTIFS\LUTIN.PIC
Note: Une chaîne ascii0 est une formulation de chaîne de caractères que TURBO-FORTH n'a pas l'habitude d'utiliser pour son compte. Elle est définie par une adresse de début et se termine obligatoirement par le caractère nul (octet zéro). Ce type d'expression d'une chaîne est en général moins pratique que les chaînes explicites (adresse,longueur) ou les chaînes implicites (adresse avec la longueur codée sur le premier ou les deux premiers octets) car il n'est pas possible d'en connaître la longueur sans l'explorer caractère par caractère. Il en est de même pour un autre type de chaîne parfois utilisées par MS-DOS, les chaînes ascii$ où c'est le caractère '$' qui signale la fin de la chaîne avec comme contrainte supplémentaire l'interdiction d'utiliser ce caractère à l'intérieur d'une chaîne.
EXT$ | --- adr long |
Variable chaîne (voir le mot STRING) donnant une extension par défaut pour des noms de fichiers. Sa longueur maximale est de 4 caractères compte tenu du point '.' qui reconnaît le début d'une extension de nom.
EXT$ TYPE affiche '.FTH'
.FTH est l'extension habituelle des fichiers exploités par Turbo- Forth.
FILENAME | <chemin\nom[.ext]>--- adr0 |
Interprète dans le flot d'entrée un chemin d'accès à un fichier. Délivre pour MS-DOS une adresse ascii0. Ce mot réalise la même fonction que le mot PATHWAY à la différence qu'il incorpore dans la chaîne l'extension par défaut EXT$ si aucune extension n'est précisée. Pour accéder à un fichier sans aucune extension par FILENAME, il suffit de faire suivre le nom par un point seul. Exemples:
PROG est interprété PROG.FTH PROG.BAS PROG.BAS PROG. PROG
?DOS-ERR | err --- |
Traite le code erreur en retour d'un appel à une fonction MS-DOS. Ce code est égal à zéro si l'opération s'est déroulée correctement sans erreur. Dans le cas contraire MS-DOS fournit un code compris entre 1 et 18 (variable selon les versions) dont la signification est commune aux diverses fonctions appelées. Ainsi le code 2 signifie 'fichier non trouvé'.
?DOS-ERR affiche le dernier mot interprété suivi d'un message explicatif de l'erreur et provoque l'arrêt du traitement (voir ABORT) si le code err est non nul.
Toute erreur provoquant un ABORT du traitement en cours a pour effet de fermer tous les fichiers ouverts par Turbo-Forth.
?DOS-ERR doit suivre la plupart des primitives DOS quand elles délivrent un code err sur la pile.
(OPEN) | adr0 access --- hndl err |
Ouvre un fichier existant et en autorise donc l'accès. Adr0 est une adresse de chaîne ascii0 (voir ci dessus PATHWAY ou FILENAME) qui peut contenir un chemin de répertoire. Access est un code d'accès MS-DOS qui doit prendre l'une des valeurs suivantes:
access=0 : accès au fichier en lecture seule access=1 : accès au fichier en écriture seule access=2 : accès au fichier en lecture ou écriture
En retour hndl est le ticket (handle) d'accès au fichier et err le code de retour d'appel MS-DOS.
Le ticket est un numéro d'ordre qui représente un canal d'entrée- sortie pour MS-DOS. Les tickets sont attribués dans un ordre croissant dans la limite des fichiers ouvrables par le DOS. Le premier ticket attribué à un fichier est 5 car les tickets 0 à 4 sont toujours déjà attribués:
hndl=0 : périphérique standard d'entrée (le clavier en principe) hndl=1 : périphérique standard de sortie (l'écran en principe) hndl=2 : sortie des erreurs (l'écran ; non utilisé par Forth) hndl=3 : périphérique auxiliaire (port série en général) hndl=4 : imprimante hndl=5 : premier fichier ouvert
... Par défaut MS-DOS fixe à 8 le dernier ticket attribuable mais cette valeur peut être modifiée par la commande FILES=xx dans le fichier CONFIG.SYS au lancement du système.
Le code de retour err sera non nul si le fichier n'est pas trouvé, si la chaîne du nom est incorrecte, s'il n'y a plus de ticket disponible ou si l'accès est refusé. Cette dernière erreur survient quand le code d'accès d'ouverture n'est pas compatible avec l'attribut du fichier comme par exemple vouloir ouvrir en lecture- écriture un fichier d'attribut lecture-seule.
Si l'ouverture est réalisée (err=0), le pointeur de fichier MS-DOS pointe sur le premier octet du fichier.
: OUVRE ( <fichier> -- ) CR FILENAME 0 (OPEN) ?DOS-ERR HERE COUNT TYPE ." ouvert avec le ticket " . ; OUVRE TURBO.COM TURBO.COM ouvert avec le ticket 5 OUVRE ALEPH ALEPH.FTH ouvert avec le ticket 6 OUVRE MACHIN MACHIN.FTH fichier non trouvé OUVRE CLOCK CLOCK.FTH ouvert avec le ticket 5 ...
(CLOSE) | n --- |
Ferme le fichier ouvert au ticket n. Le ticket n est libéré. Ce mot ne laisse pas de code err en retour et n'a donc pas à être suivi de ?DOS-ERR.
(CREATE) | adr0 att --- hndl err |
Crée un nouveau fichier et l'ouvre en lecture-écriture. Adr0 est une adresse de chaîne ascii0 (voir ci dessus PATHWAY ou FILENAME) qui peut contenir un chemin de répertoire. Att est l'attribut que MS-DOS doit assigner au nouveau fichier. Il s'agit d'un octet dont les bits 0 à 5 ont chacun une signification:
bit 0 à 1 : fichier en lecture seule (protégé contre l'écriture ou l'effacement) bit 1 à 1 : fichier caché (non affiché par DIR) bit 2 à 1 : fichier système (recopié par SYS) bit 3 à 1 : pseudo-fichier nom du volume bit 4 à 1 : pseudo-fichier nom d'un répertoire bit 5 à 1 : fichier modifié (bit d'archivage) (utilisé par la commande externe BACKUP)
Lors de la création d'un fichier par (CREATE) c'est généralement l'attribut zéro (tous bits à zéro) qui doit être utilisé. En retour hndl est le ticket (handle) d'accès au fichier ainsi créé et err le code de retour d'appel MS-DOS: voir (OPEN).
Si le fichier à créer existe déjà dans le même répertoire, il est recréé sans code d'erreur et son ancien contenu est entièrement vidé (sauf s'il est protégé). Le pointeur de fichier est placé en début de fichier (ou en fin puisqu'il s'agit toujours d'un fichier vide)
: CREER-FICHIER-VIDE (<fichier> -- ) FILENAME 0 (CREATE) ?DOS-ERR (CLOSE) ; CREER-FICHIER-VIDE INUTILE DIR
affiche l'existence d'un fichier INUTILE.FTH 0
(SEEK) | ddép hndl sens --- dpos err |
Déplace le pointeur de fichier dans un fichier déjà ouvert pour des opérations de lecture ou d'écriture en accès direct. Comme un fichier peut avoir plus de 64 kilo-octets, ce mot utilise des arguments entiers 32 bits (deux cellules sur la pile):
Ddép est le nombre 32-bits d'octets de déplacement du pointeur de fichier. Hndl est le ticket du fichier concerné. Sens détermine le sens du déplacement: sens=0 : déplacement depuis le début du fichier sens=1 : déplacement depuis la position actuelle du pointeur sens=2 : déplacement depuis la fin du fichier
Au retour dpos donne sur 32 bits la nouvelle position du curseur et err est le code de retour MS-DOS.
L'argument de retour dpos peut être exploité pour connaître la taille d'un fichier:
: FILESIZE ( <filename>-- dlen ) FILENAME 0 (OPEN) ?DOS-ERR DUP 0 0 ROT 2 (SEEK) ?DOS-ERR ROT (CLOSE) ; FILESIZE TURBO.COM D.
affiche la taille du fichier TURBO.COM
(GET) | seg adr len hndl --- len' err |
Primitive de lecture séquentielle dans un fichier: charge dans un tampon intra ou extra-segment len octets depuis le fichier (ou le périphérique) ouvert au ticket hndl.
Le tampon de lecture est donné par son adresse étendue seg (segment) et adr (offset adresse). Si le tampon de lecture est dans le segment Forth, on utilisera le mot DSEGMENT comme premier argument. Au retour, len' donne le nombre d'octets effectivement lus et err est le code de retour d'appel MS-DOS. Len' peut être inférieur à len si la fin du fichier a été atteinte sans que le code err soit celui d'une erreur.
La lecture s'effectue à la position courante du pointeur de fichier; celui-ci est déplacé en avant de len' octets pour poursuivre une lecture séquentielle.
: LIT-DEBUT ( <fichier> -- ) FILENAME 0 (OPEN) ?DOS-ERR >R DSEGMENT PAD 10 R@ (GET) ?DOS-ERR PAD SWAP TYPE R> (CLOSE) ; LIT-DEBUT ESSAI
affiche les 10 premiers caractères de ESSAI.FTH
(PUT) | seg adr len hndl --- len' err |
Primitive d'écriture séquentielle dans un fichier: sauve len octets depuis un tampon intra ou extra-segment dans le fichier (ou le périphérique) ouvert au ticket hndl.
Le tampon d'écriture est donné par son adresse étendue seg (segment) et adr (offset adresse). Si le tampon est dans le segment Forth, on utilisera le mot DSEGMENT comme premier argument.
Au retour, len' donne le nombre d'octets effectivement écrits et err est le code de retour d'appel MS-DOS. Len' peut être inférieur à len si le support n'a plus de place pour allonger le fichier sans que le code err soit celui d'une erreur.
L'écriture s'effectue à la position courante du pointeur de fichier; celui-ci est déplacé en avant de len' octets pour poursuivre une écriture séquentielle.
: ECRIT-DEBUT ( <fichier> string -- ) FILENAME 1 (OPEN) ?DOS-ERR >R DSEGMENT -ROT R@ (PUT) ?DOS-ERR DROP R> (CLOSE) ; " \ essai de (put)" ECRIT-DEBUT ESSAI
inscrit \ essai de (put)' en tête du fichier ESSAI.FTH (à tester sur un fichier sans importance bien entendu)
DMA | --- adr |
Donne l'adresse de la DMA (direct memory address) aussi appelée DTA (Disk transfer area) qui est la zone de la mémoire RAM dont MS-DOS se sert pour les transferts d'enregistrements sur disque quand les accès sont de type FCB (File control block) ou pour placer des informations sur les fichiers. La DTA n'est pas utilisée pour la gestion par tickets (handles).
Lors du lancement d'un programme, MS-DOS fixe par défaut sa DTA à l'adresse 128 dans le préfixe du segment de programme (PSP) avec une taille utilisable qui ne peut dépasser 128 octets sous peine d'écraser le début du programme lui-même.
SET-DMA | adr --- |
Change l'adresse de la DMA (voir ci dessus) avec l'adresse adr. Utilisable notamment si la DMA doit avoir plus de 128 octets. Il ne peut y avoir qu'une DMA active. Le mot est de peu d'intérêt dans une gestion par tickets (handles).
(SEARCH0) | adr0 att --- fl |
Recherche un fichier dans un répertoire: délivre un flag vrai si le fichier est trouvé et charge en DMA des informations à son sujet.
Adr0 est une adresse de chaîne ascii0 (voir PATHWAY ou FILENAME) qui peut contenir un chemin de répertoire si la recherche doit s'effectuer en dehors du répertoire courant. Cette chaîne peut contenir des caractères jokers comme '*' ou '?'. Dans ce cas seul le premier fichier trouvé correspondant au masque demandé est pris en compte. Il faut utiliser (SEARCH) pour accéder aux suivants.
Att permet d'étendre la recherche selon les attributs de fichier. Voir au mot (CREATE) la codification de l'attribut d'un fichier. Si Att=0 la recherche ne porte que sur les fichiers normaux. Quand un bit de Att est mis à un la recherche comporte en plus les fichiers désignés par ce bit d'attribut. Exemple: si Att=18 (2:bit caché + 16:bit répertoire), la recherche portera aussi bien sur les fichiers usuels que sur les fichiers cachés ou les pseudo-fichiers noms de répertoires.
Si un fichier spécifié a pu être trouvé, MS-DOS charge dans la DMA 43 octets qui fournissent des informations sur ce fichier:
octets 0-20 : réservés à MS-DOS pour la recherche
octet 21 : attribut du fichier
octets 22-23 : heure de la dernière écriture
octets 24-25 : date de la dernière écriture
octets 26-29 : taille du fichier (26-27:partie basse,28- 29:partie haute)
octets 30-42 : nom complet du fichier sous forme de chaîne ascii0
Le fichier trouvé n'est pas ouvert.
(SEARCH) | --- fl |
Recherche un autre fichier dans un répertoire après une première recherche par (SEARCH0) ou après une précédente reprise de recherche par (SEARCH): dépose un flag vrai si un autre fichier spécifié a pu être trouvé et charge en DMA des informations à son sujet.
Il n'est pas besoin de répéter les arguments de la recherche par (SEARCH0) qui doit toujours précéder un ou plusieurs (SEARCH). Il faut juste veiller à ce que la DMA n'ait pas été modifiée entre (SEARCH0) et (SEARCH) car elle contient les informations pour que MS-DOS poursuive la recherche.
: COMBIEN-DE-FICHIERS ( <masque> -- ) 0 PATHWAY 0 (SEARCH0) IF BEGIN 1+ (SEARCH) NOT UNTIL THEN . ; COMBIEN-DE-FICHIERS B:\FORTH\*.FTH
affiche le nombre de fichiers répondant au masque '*.FTH' dans le répertoire FORTH de B:
BDOS | adr fun --- err |
Primitive d'appel de certaines fonctions MS-DOS (adr désigne généralement une adresse, fun est un numéro de fonction pour l'interruption 21H, err est le code de retour MS-DOS signalant une éventuelle erreur).
MS-DOS n'ayant pas un accès normalisé aux sous-fonctions de l'interruption 21H, ce mot n'est guère utilisable en dehors des fonctions qu'il sert à définir: SELECT (fun=14), SET-DMA (fun=26), MKDIR (fun=57), RMDIR (fun=58), CHDIR (fun=59) ou DEL (fun=65).
Voici à titre d'exemple un mot qui permet d'effacer dans le répertoire courant un groupe de fichiers (ce que n'autorise pas DEL) avec sélection au clavier des fichiers à effacer:
: ERA ( <masque> -- ) 0 PATHWAY 0 (SEARCH0) IF BEGIN CR .NAME ." Effacer ? O/N " KEY UPC DUP EMIT ASCII O = IF DMA 30 + 65 BDOS ?DOS-ERR 1+ THEN (SEARCH) NOT UNTIL THEN CR . ." fichiers effacés" ; ERA *.*
Affiche successivement tous les fichiers qu'il propose d'effacer puis affiche le nombre total de fichiers effacés.
DRV | --- n |
Délivre le numéro du lecteur (drive) courant. Le code empilé n=0 pour désigner le lecteur A: , n=1 pour le lecteur B: etc...
SELECT | n --- |
Sélectionne un numéro de lecteur (drive) courant: n=0 pour sélectionner le lecteur A: , n=1 pour le lecteur B: etc...
(FREE) | n --- b/sec #clusters sec/cluster |
Primitive pour le calcul de la capacité restant libre sur un lecteur. Le code n=0 désigne le lecteur courant, n=1 le lecteur A: , n=2 le lecteur B: etc... Attention donc: MS-DOS n'utilise pas ici le même codage que pour les fonctions DRV et SELECT. En retour sont empilés trois valeurs 16 bits:
b/sec est lenombre d'octets par secteur sur le disque. #clusters est le nombre de clusters (groupe de secteurs) restant libres. sec/cluster est le nombre de secteurs par cluster ou -1 si n est invalide.
L'espace mémoire disponible sur le support se calcule en multipliant (en double précision) les trois valeurs si le lecteur est valide: voir FREE.
(REN) | adr01 adr02 --- err |
Primitive pour renommer un fichier ou le transférer dans un autre répertoire du même lecteur:
Adr01 est l'adresse d'une chaîne ascii0 (voir PATHWAY pour l'explication de ce type de chaîne) désignant l'ancien nom d'un fichier, comportant éventuellement un chemin d'accès. Adr02 est l'adresse d'une chaîne ascii0 désignant le nouveau nom ou le nouveau chemin\nom pour ce fichier.
Les chaînes adr01 et adr02 ne peuvent contenir de caractères jokers '*' ou '?'ni désigner des noms de sous-répertoire ou de volume. Le code err est celui de retour d'appel MS-DOS signalant une éventuelle erreur.
A:--- Rend le lecteur de disque A: courant.
B: --- Rend le lecteur de disque B: courant s'il existe.
C: --- Rend le lecteur de disque C: courant s'il existe. C: est en général la
dénomination du disque dur.
D: --- Rend le lecteur de disque D: courant s'il existe. D: est souvent la dénomination
d'un disque virtuel en mémoire vive.
E: --- Rend le lecteur de disque E: courant s'il existe. E: peut être la dénomination
d'un disque virtuel en mémoire vive.
Change le répertoire courant avec le mot (au sens Forth) qui suit. Emet l'erreur
'chemin incorrect' si le répertoire n'existe pas ou n'est pas accessible. CHDIR
C:\FORTH\IA\EXPERT CHDIR \ (pour retourner dans un répertoire racine) La commande
CHDIR peut être obtenue en interprétation en frappant la touche de fonction
F6.
Crée un nouveau sous-répertoire avec le 'mot' qui suit. Ce mot peut comporter
un nom de lecteur et un chemin si le nouveau sous- répertoire est à créer en
dehors du répertoire courant. MKDIR POUBELLE
Supprime un sous répertoire désigné par le 'mot' qui suit. Ce mot peut comporter
un nom de lecteur et un chemin si le sous-répertoire n'appartient pas au répertoire
courant. RMDIR POUBELLE Cette commande est refusée par MS-DOS si le sous-répertoire
n'est pas vide de fichiers.
Efface le fichier désigné par le 'mot' qui suit. Ce mot peut comporter un nom
de lecteur et un chemin si le fichier n'est pas dans le répertoire courant.
Un seul fichier peut être effacé: les caractères jokers '*' ou '?' ne sont pas
acceptés. L'extension du nom de fichier doit être précisée car elle n'est pas
interprétée par défaut. DEL C:\FORTH\INUTILE.FTH
Renomme un fichier nom1 (ancien nom) en nom2 (nouveau nom). REN interprète
les deux 'mots' qui le suivent dans le flot d'entrée. Ces mots peuvent comporter
un nom de lecteur et un chemin d'accès jusqu'au fichier. Il est possible d'utiliser
REN pour transférer un fichier d'un répertoire dans un autre à condition qu'il
s'agisse du même lecteur. Les extensions des noms de fichiers peuvent être omises
dans le cas de l'extension par défaut (voir EXT$).
Délivre le nombre d'octets restant libres sur le lecteur courant. Ce nombre
est codé sur 32 bits (entier double précision). FREE D.
Primitive de DIR affichant le nom d'un fichier et sa taille en octets. L'information
est lue dans la DMA après une recherche de fichiers par (SEARCH0) ou (SEARCH)
(voir ces mots).
Primitive de DIR affichant la liste des fichiers d'un répertoire selon le masque
donné par une chaîne explicite débutant en adr et longue de long octets. Cette
chaîne peut comporter un nom de lecteur, un chemin de répertoire, des caractères
jokers '*' ou '?'.
affiche un directory des fichiers .FTH du répertoire courant. Commande d'affichage du directory (liste des fichiers) d'un répertoire. DIR
interprète dans le flot d'entrée le mot qui le suit comme chemin d'accès et
masque. Ce mot est facultatif (frapper DIR puis touche La commande DIR seule peut être obtenue en interprétation en frappant la touche
de fonction F5. Constante donnant le nombre maximal de tickets pouvant être ouverts simultanément
par Turbo-Forth. La valeur 8 correspond à la valeur par défaut de MS-DOS et
permet d'ouvrir 4 fichiers (tickets 5 à 8, les tickets 0 à 4 étant réservés
aux périphériques standards).
Ce nombre peut se révéler insuffisant d'autant que 8 est le nombre total de
tickets ouverts y compris quand plusieurs programmes différents sont susceptibles
d'ouvrir des fichiers (voir les commandes d'intégration).
Pour modifier le nombre de tickets utilisables, il faut d'abord changer la
variable MS-DOS FILES (c'est le même nom) dans le fichier CONFIG.SYS en y plaçant
une ligne 'FILES=xx' avec xx compris entre 8 et 255. La variable FILES peut
atteindre 255 globalement, mais il faut savoir qu'un programme ne peut utiliser
plus de 20 tickets (soit 14 fichiers) à lui tout seul.
Si FILES de MS-DOS permet plus de 8 tickets, FILES de Turbo-Forth peut être
modifié jusqu'à 20 en le traitant comme une pseudo- constante:
autorise 14 tickets (soit 10 fichiers). Délivre le nombre de tickets actuellement utilisés par Turbo-Forth. Ce nombre
est au plus égal à la constante FILES.
Assure que Turbo-Forth peut utiliser un nouveau ticket pour ouvrir un fichier.
Un message d'erreur 'Trop de fichiers ouverts pour TURBO-Forth' est émis si
le programme ne peut ouvrir un nouveau fichier. Ce type d'erreur survient le
plus souvent quand trop de commandes INCLUDE (voir ce mot) sont imbriquées les
unes dans les autres.
Voir le mot FILES pour savoir comment étendre la multi-ouverture de fichiers
aussi bien au niveau de MS-DOS qu'au niveau de Turbo- Forth.
Variable USER contenant le ticket (handle) courant. Le ticket courant désigne
le périphérique d'où sont lues toutes les commandes au langage (flot d'entrée
de l'interpréteur: voir le mot SOURCE):
HANDLE ?
affiche 0 si cette commande est entrée au clavier affiche 5 (ou plus) si elle
est contenue dans un fichier interprété.
Toutefois Turbo-Forth utilise aussi HANDLE pour désigner un flot d'entrée
dans une chaîne interprétée (voir $EXECUTE). Dans ce cas la valeur contenue
dans HANDLE est négative ce qui n'a plus de sens en terme de "ticket" MS-DOS
mais reste le témoin du niveau d'imbrication de l'interpréteur:
HANDLE ne peut pas être modifié directement par l'utilisateur: vouloir écrire
5 HANDLE ! provoquera une erreur même si un fichier est ouvert au ticket 5.
Voir plus loin au mot GETLINE un exemple qui montre comment doit être utilisé
HANDLE.
Ouvre un fichier en lecture et initialise un tampon de ligne. Le nom du fichier
est interprété dans le flot d'entrée avec le mot qui suit: ce nom peut comporter
l'indication d'un lecteur et d'un chemin de répertoire; l'extension du nom est
facultative s'il s'agit de l'extension par défaut.
Le ticket courant n'est pas modifié: OPEN laisse sur la pile le ticket du fichier
ouvert par MS-DOS. Voir plus loin au mot GETLINE un exemple d'utilisation de
OPEN.
Ferme le fichier ouvert au ticket courant (voir HANDLE). Ce mot ne doit pas
être utilisé sans être immédiatement suivi d'une réaffectation de HANDLE. Voir
plus loin au mot GETLINE un exemple d'utilisation de CLOSE.
Ferme tous les fichiers ouverts par TURBO-FORTH. Ce mot peut éventuellement
être exécuté seul mais uniquement au clavier (quand HANDLE contient le ticket
zéro).
Il importe de savoir que toute erreur d'interprétation même sans rapport avec
la gestion de fichiers provoque ALLCLOSE ; c'est le cas des mots (?ERROR) ?ERROR
?DOS-ERR ABORT" . Constante codée donnant la longueur d'un tampon de fichier. Turbo-Forth gère
un ensemble de textes divers qui forme sa mémoire virtuelle de programmes tantôt
interprétés tantôt compilés. Cette mémoire virtuelle n'est plus organisée en
blocs sur le support disque comme dans les anciennes versions du langage mais
en fichiers ASCII standards dont nous avons vu qu'ils bénéficient de toutes
les fonctionnalités d'un système d'exploitation structuré.
Turbo-Forth lit ses fichiers séquentiellement ligne par ligne et affecte donc
pour chaque fichier ouvert un tampon de ligne situé au sommet de sa mémoire
segment (juste en deçà des piles). Chaque tampon contient l'espace suffisant
pour charger une ligne plus un certain nombre d'informations indispensables,
le tout occupant 322 octets. Voici la répartition de ces 322 octets:
Cette organisation amène à poser deux questions:
Constante codée donnant la longueur maximale du nom d'un fichier tel qu'il
est conservé dans le tampon. Cette valeur de 64 caractères est celle qu'autorise
MS-DOS. Rappelons qu'un fichier peut être désigné par une chaîne relativement
longue comportant un nom de lecteur et un chemin d'accès dans les répertoires
et sous- répertoires. Exemple:
Délivre l'adresse du tampon du fichier courant. Cette adresse pointe directement
sur la chaîne implicite de la dernière ligne chargée. Voir au mot LBUF l'organisation
d'un tampon.
Affiche la ligne contenue dans le tampon du fichier courant. Ce mot est exécuté
à chaque GETLINE si la variable ECHO est ON. Voir plus loin au mot GETLINE un
exemple d'utilisation de .LINE.
Délivre une adresse dans le tampon courant contenant sur 16 bits le numéro
de la dernière ligne chargée. Voir au mot LBUF l'organisation d'un tampon.
Délivre une adresse dans le tampon courant contenant le chemin\nom du fichier
en cours de lecture. Voir au mot LBUF l'organisation d'un tampon. A cette adresse
débute une chaîne explicite fixe de 64 caractères; le nom complet du fichier
est éventuellement complété à droite par des espaces.
Enregistre le chemin\nom (PATHNAME) d'un fichier dans la zone tampon réservée
à ce fichier. Ce mot est exécuté par OPEN. Il n'y a pas lieu de l'utiliser en
pratique.
Note sur les tampons de lignes: nous avons vu que les tampons étaient
alloués ticket par ticket dans la mémoire haute du segment de programme (voir
la carte mémoire de Turbo-Forth en annexe) et ceci de façon descendante, le
tampon du ticket n+1 étant situé sous le tampon du ticket n .
Il peut être utile de savoir que tous les tickets y compris les numéros 0 à
4 réservés aux périphériques disposent d'un tampon de ligne Forth. Ils ne sont
guère utilisés en pratique. Leur existence se justifie par les possibilités
de redirections des entrées-sorties par MS-DOS qui peuvent également être exploitées
par Turbo-Forth comme dans le module PIP.FTH . Ces tampons additionnels sont
également à la disposition de l'utilisateur. Variable booléenne dont le contenu est vrai s'il n'y a plus de ligne à lire
dans le fichier courant.
Force la variable EOF? à la valeur 'vrai' ce qui provoque une fin de fichier
artificielle pour l'interpréteur.
EOF est utile pour placer un texte de commentaires à la fin d'un fichier source:
toutes les lignes placées après celle contenant EOF ne seront pas interprétées
et le fichier sera refermé par le système dès qu'il aura fini d'interpréter
la ligne contenant EOF.
Ce mot permet également de vous faciliter la mise au point de programmes délicats.
Pour exemple, si la compilation d'un programme source plante votre système et
que vous soyez obligé de couper l'alimentation ou de relancer le DOS pour avoir
à nouvau la main, éditez le programme incriminé et placez EOF à l'endroit supposé
de l'erreur. Ensuite, compilez à nouveau votre programme. Si la compilation
réussit jusqu'à EOF, c'est que l'erreur est plus loin. Si la compilation plante
à nouveau le système, rééditez le fichier source et déplacez votre EOF vers
le début du fichier. Après plusieurs essais, vous aurez localisé l'erreur.
Lit un seul caractère dans le fichier courant. Equivaut à KEY si HANDLE (ticket
courant) est nul c'est-à-dire quand l'interpréteur est justement branché sur
le clavier. GET n'est pas utilisé par le système lui-même; son emploi permet
la lecture séquentielle octet par octet de fichiers divers en utilisant l'organisation
des tampons Forth.
Primitive de GETLINE : lit une ligne de texte dans le fichier ouvert au ticket
hndl. La ligne est placée dans un tampon à l'adresse adr sous forme de chaîne
implicite, le premier octet étant affecté à la longueur effective de la ligne
chargée. Le flag de retour est positionné à vrai si la lecture atteint la fin
du fichier, si survient une erreur de lecture ou encore si le code de retour-
chariot n'est pas rencontré une fois lue la limite des 255 caractères. Tous
les caractères de contrôle lus sont remplacés par des espaces dans le tampon.
Lit une ligne de texte dans le fichier courant. La ligne est placée dans le
tampon de ligne du fichier courant et éventuellement affichée si la variable
ECHO est ON. Le compteur de ligne du tampon est incrémenté et la variable EOF?
mise ON si la fin du fichier est atteinte.
GETLINE réalise chaque opération élémentaire de lecture d'un fichier lors
de son interprétation par INCLUDE.
Voici un exemple relativement simple de l'utilisation conjointe des mots OPEN
HANDLE GETLINE .LINE et CLOSE pour définir un mot VIEW listant un fichier à
partir de la rencontre d'un mot quelconque. La syntaxe en est:
et comme la première occurence d'un mot Forth dans un fichier est généralement
sa définition (hors commentaires), on utilisera VIEW pour retrouver le source
d'un mot puis voir son utilisation dans le reste du fichier. La commande VIEW
<fichier> seule est équivalente à LIST <fichier>:
Notez dans cette définition de VIEW la façon habituelle de gérer HANDLE: il
faut d'abord en conserver la valeur courante, ici sur la pile, avant de le diriger
sur le fichier ouvert par OPEN et ne pas oublier de le restituer après la fermeture
de ce fichier. On aura pris garde à diriger HANDLE qu'après l'utilisation du
flot d'interprétation en cours: ici la séquence BL WORD qui interprète encore
un mot après le nom du fichier doit précéder la séquence HANDLE ! sinon ce mot
serait pris dans le tampon nouvellement ouvert...
Interprète un fichier source. Le mot qui suit INCLUDE est interprété comme
un nom de fichier: celui-ci peut contenir le nom d'un lecteur et un chemin d'accès
de répertoire; l'extension du nom de fichier est facultative quand il s'agit
de l'extension par défaut (voir EXT$). Le fichier ainsi défini est ouvert puis
immédiatement interprété ligne par ligne: les instructions sont exécutées et
les nouvelles définitions compilées selon le concept habituel au langage de
la dualité interprétation-compilation. En fin de fichier -qu'elle soit naturelle
ou provoquée par le mot EOF- le fichier interprété est fermé et l'interpréteur
rendu à la source appelante. Le texte interprété par INCLUDE est affiché ligne
par ligne pour un traçage visuel de contrôle si la variable ECHO est ON. Si
une erreur survient dans le texte, celle-ci est localisée dans le fichier, l'appel
à un éditeur externe est préparé pour une correction immédiate au site de l'erreur,
l'ensemble du processus d'interprétation est arrêt, et tous les fichiers refermés.
Ce mot est le plus important du concept de mémoire virtuelle interprétée tel
qu'il est conçu dans Turbo-Forth. Par rapport au concept de blocs qui utilisait
une syntaxe de type n°-de-bloc LOAD (éventuellement à l'intérieur d'un seul
fichier global ouvert par un mot OPEN) INCLUDE apporte au principe de la gestion
des programmes sources deux innovations fondamentales au langage Forth:
La propriété fondamentale de INCLUDE est en effet la ré-entrance: un fichier
interprété par INCLUDE peut lui-même comporter une ou plusieurs commandes INCLUDE
d'interprétation d'autres fichiers. L'interpréteur est alors dérouté dans un
autre fichier avant de revenir automatiquement dans le fichier appelant immédiatement
après la commande INCLUDE La commande INCLUDE MAIN va interpréter (et/ou compiler) les séquences de
programmes: [prog] [sub1] [sub2] [fin_sub1] [fin_prog] dans cet ordre avant
de rendre la main à l'utilisateur.
La ré-entrance de INCLUDE admet deux limites dans l'imbrication des programmes
les uns dans les autres qu'il convient parfois de se rappeler:
Nous venons de parler des limites d'imbrication des INCLUDE. Il n'est peut-être
pas inutile de préciser qu'il ne faut pas y voir une limite aux appels successifs
du mot INCLUDE. Imaginons en effet un fichier PROG.FTH contenant un grand nombre
d'appels du type:
Si nous supposons que les fichiers SUBx.FTH ne réalisent pas eux- mêmes d'opérations
INCLUDE, il faut comprendre que la commande INCLUDE PROG n'utilisera jamais
l'ouverture que de deux fichiers simultanément et n'a guère besoin que de 4
octets sur la pile de retour: chaque ticket ouvert pour un fichier SUBx sera
refermé avant d'être réutilisé pour le suivant. L'imbrication n'est qu'un aspect
particulier de la ré-entrance. Le mot INCLUDE peut être obtenu au clavier en
frappant la touche de fonction F3. Liste un fichier texte ASCII sur le ou les périphériques de sortie (écran et/ou
imprimante selon le vecteur EMIT). Cette commande est utilisée pour connaître
ou vérifier le contenu d'un fichier que ce soit un fichier source Forth ou tout
autre fichier texte. Le mot qui suit LIST est interprété comme un nom de fichier: il peut comporter
un nom de lecteur et un chemin d'accès de répertoire; l'extension du nom de
fichier est facultative s'il s'agit de l'extension par défaut. Le listage est
suspendu par l'appui d'une touche puis repris par une autre frappe ou interrompu
par la touche retour (contient le mot STOP?). Délivre sur 16 bits l'adresse segment de Turbo-Forth. Cette adresse est la
valeur courante du registre de segment DS (Data-Segment) du micro-processeur.
Les microprocesseurs de la famille 8086 peuvent en effet adresser un méga-octet
de mémoire. Toute adresse physique est définie par une adresse 16 bits de segment
et une adresse 16 bits d'offset dans ce segment. Un segment débute toujours
à une adresse multiple de 16 (on parle de paragraphe pour un bloc de 16 octets)
et permet d'adresser une zone d'au plus 64 kilo-octets (correspondant à l'adressage
16 bits d'un offset). On notera qu'une même adresse physique peut être exprimée
sous plusieurs couples segment-offset équivalents dans la mesure où les segments
de 64K se chevauchent tous les 16 octets.
Pour simplifier l'adressage, le microprocesseur manipule des adresses 16 bits
d'offsets en prenant pour base de segments les valeurs inscrites dans quatre
registres de segments:
Lorsque Turbo-Forth est lancé par le système, son code est chargé dans le
premier segment libre. Celui-ci varie selon les programmes déjà chargés, les
drivers installés, les allocations résidentes (un disque virtuel ou un programme
résident par exemple) qui occupent la mémoire basse du système. C'est ce segment
que donne DSEGMENT car pour Turbo-Forth les registres CS DS et SS doivent être
tenues aux mêmes valeurs (l'usage du segment ES est libre).
Toute la mémoire disponible à partir de DSEGMENT est allouée à Turbo-Forth
lors de son lancement par MS-DOS. En fait, le programme n'a besoin que des 64K
octets de DSEGMENT pour son propre usage: le dictionnaire, les piles, les tampons
sont tous contenus dans ces 64K (voir la carte mémoire en annexe). Ceci n'empêche
pas Turbo- Forth d'avoir accès à toute la mémoire par l'usage d'opérateurs extra-segments
(voir des mots tels que L@ L! LCMOVE etc où le préfixe 'L' rappelle un adressage
'Long' 32 bits segment+offset).
Dans DSEGMENT les 256 premiers octets sont construits par MS-DOS: ils constituent
le PSP (Préfixe du Segment de Programme) qui contient des informations pour
le système. Après le PSP est chargé le code contenu dans le fichier TURBO.COM
constituant le programme proprement dit (le dictionnaire). Ils peut être utile
de connaître ce que contient le PSP dont toutes les adresses, par définition
intra-segment, sont aisément accessibles par le langage:
Ainsi:
affiche en paragraphes de 16 octets la mémoire disponible pour Turbo-Forth.
Variable destinée à contenir une adresse d'extra-segment. Sa valeur est initialisée
à DSEGMENT. Est utilisée par les utilitaires LDUMP et DUMP de vidage mémoire.
Quitte Turbo-Forth en exécutant un retour au programme appelant: c'est le processeur
de commandes COMMAND.COM le plus souvent avec soit affichage du 'prompt' (type
'A:\>') ou poursuite de l'interprétation d'un fichier BATch de commandes.
Toute la mémoire allouée à Turbo-Forth est restituée au système: il s'agit
d'un retour simple par opposition à un retour laissant tout ou partie du programme
résident (voir programmation avancée). Les tampons sont vidés et les fichiers
laissés ouverts refermés.
BYE admet sur la pile un paramètre facultatif: il s'agit d'un octet servant
de code de retour transmis au programme appelant. Pour COMMAND.COM cet octet
est récupéré dans ERRORLEVEL qui peut être testé dans un fichier batch. Exemple:
Ensuite, après compilation, taper ' MENU IS BOOT SAVE-SYSTEM MENU et complétez
le fichier AUTOEXEC.BAT de votre DOS avec le court programme suivant, valable
pour un système équipé d'un disque dur:
Et maintenant, au démarrage de votre DOS, un petit menu permettra d'accéder
directement aux différents programmes utilitaires de votre système. Quitte Turbo-Forth (voir BYE) après avoir demandé à l'utilisateur confirmation
par l'appui d'une touche. BYE? est obtenu en exécution directe par l'appui de
la touche de fonction F8. Constante délivrant une taille en paragraphes (blocs de 16 bits) que le système
doit allouer à Turbo-Forth. La valeur 4096 paragraphes équivaut à 64K octets
qui est la taille minimale que peut s'allouer Turbo-Forth puisque toutes ses
composantes (dictionnaire,piles,tampons) sont dans le même segment DSEGMENT.
HEIGHT précède ALLOC (voir ce mot) chaque fois que Turbo-Forth a besoin de
réduire sa propre allocation (toujours maximale au lancement) pour d'autres
programmes: voir les commandes d'intégration. Si une application nécessite à la fois un espace extra-segment de travail
et la possibilité de libérer de la place pour d'autres programmes, on modifiera
HEIGHT comme une pseudo-constante. Pour réserver 128K à Turbo-Forth dont 64K
extra-segments on écrira par exemple: Modifie la taille mémoire allouée à Turbo-Forth: n est le nombre de paragraphes
(blocs de 16 octets) qui doivent être alloués; ce nombre ne doit pas être inférieur
à 4096 (valeur courante de HEIGHT pour 64K octets alloués).
Au retour, ALLOC laisse sur la pile l'adresse segment du dernier bloc alloué
(c'est normalement DSEGMENT) pour permettre éventuellement de calculer la mémoire
restant libre (en cas d'impossibilité d'allocation par MS-DOS la valeur empilée
est celle d'un code d'erreur d'un octet égal à 7, 8, ou 9). Sauve dans un fichier une zone mémoire extra-segment. Le nom du fichier est
interprété avec le mot qui suit LSAVE: il peut comporter un nom de lecteur et
un chemin d'accès de répertoire; l'extension du nom est facultative avec l'extension
'.COM' prise par défaut. La zone mémoire à sauvegarder est comprise entre les
adresses offset adr1 et adr2 dans le segment seg. Ce mot permet
donc de sauvegarder un fichier binaire d'au plus 64K octets. Avant de réaliser la sauvegarde LSAVE teste l'espace mémoire restant libre
sur le lecteur destination et émet un message d'erreur sans faire de sauvegarde
si la totalité de la zone ne peut y être logée. Sauve dans un fichier une zone mémoire intra-segment. Le nom du fichier est
interprété avec le mot qui suit SAVE: il peut comporter un nom de lecteur et
un chemin d'accès de répertoire; l'extension du nom est facultative avec l'extension
'.COM' prise par défaut. La zone mémoire à sauvegarder est comprise entre les
adresses adr1 et adr2.
Avant de réaliser la sauvegarde SAVE teste l'espace mémoire restant libre sur
le lecteur destination et émet un message d'erreur sans faire de sauvegarde
si la totalité de la zone ne peut y être logée.
Sauve dans un fichier le dictionnaire Turbo-Forth actuel. Le nom du fichier
est interprété avec le mot qui suit SAVE-SYSTEM: il peut comporter un nom de
lecteur et un chemin d'accès de répertoire; l'extension du nom est facultative
avec l'extension '.COM' prise par défaut.
Avant de réaliser la sauvegarde SAVE-SYSTEM teste l'espace mémoire restant
libre sur le lecteur destination et émet un message d'erreur sans faire de sauvegarde
si la totalité du dictionnaire ne peut y être logé.
La zone sauvegardée va de l'adresse 256 (début du programme après le PSP)
jusqu'à l'adresse pointée par HERE (voir ce mot). Est ainsi placée dans un nouveau
fichier une nouvelle version de Turbo-Forth:
TFF.COM est ici une nouvelle version de Turbo-Forth contenant les fonctions
précompilées de calcul en virgule flottante. Ainsi l'utilisateur peut-il utiliser
un langage Forth adapté à ses besoins sans avoir à compiler au préalable ses
bibliothèques de programmes.
SAVE-SYSTEM sauvegarde toutes les variables en l'état, les mots éventuellement
en cours de traçage (fonction DEBUG) et les vocabulaires sélectionnés. Exemple:
Charge TURBO-Forth, sélectionne la base numérique hexadécimale, sauvegarde
TURBO en l'état et retourne sous MSDOS. Au prochain chargement de TURBO, vous
serez d'office en base numérique hexadécimale. Cette faculté du langage à s'étendre
lui-même fait partie de la philosophie fondamentale du Forth, au risque de rendre
difficile la définition d'un standard.
SAVE-SYSTEM permet aussi de créer des modules d'applications compilées sous
forme de fichiers .COM exécutables: une application est compilée dans le dictionnaire,
l'exécution du programme est vectorisée sur la procédure de démarrage et l'ensemble
sauvé dans un fichier de commande "fermé". Supposons que vous ayez écrit un
superbe programme FLIGHT de simulateur de vol. Le simulateur est lancé par un
mot SIMULATOR qui gère toutes les phases du jeu:
Nous écrirons alors les quelques lignes suivantes:
Vous venez de créer un programme FLIGHT.COM de simulation de vol qui fera les
délices du service marketing...
Notez comment, avant SAVE-SYSTEM, on a "fermé" l'application FLIGHT entre la
revectorisation de BOOT (voir ce mot) et le BYE (voir ce mot) qui termine la
définition de SIMULATOR.
Certaines techniques avancées permettent de compiler des applications très
compactes, faisant abstraction des en-têtes des mots Forth et des bibliothèques
inutilisées du langage.
SAVE-SYSTEM est obtenu en exécution au clavier par la touche F4.
Primitive de chargement et d'exécution d'un autre programme. Cette fonction
MS-DOS (notée souvent EXEC dans les manuels) est très puissante car elle permet
à un programme "père" de commander l'exécution d'un programme "fils" quelconque
avec retour au programme père dès la fin d'exécution du programme fils. On dit
du programme père qu'il possède des fonctions d'intégration: il est capable
de se comporter lui-même comme un système d'exploitation.
Cette primitive réclame trois arguments sur la pile:
Une table de paramètres doit être préalablement constituée à l'adresse passée
en second argument. Elle présente un format de 14 octets pour le mode 0 qui
doit respecter la signification suivante:
Pour le mode 3 (overlay), la table de paramètres est limitée à 4 octets:
Pour le mode 0, il importe de préciser que le programme fils dispose toujours
des tickets (voir HANDLE) du programme père. Ceci est particulièrement important
quand le programme père a procédé à des redirections d'entrées-sorties.
Au retour de (PROGRAM) qui est aussi le retour du programme exécuté en mode
0, la pile contient le code de retour d'une éventuelle erreur MS-DOS. Ce flag
peut être testé par ?DOS-ERR (voir ce mot).
(PROGRAM) ne peut être utilisé par un programme père .COM comme Turbo-Forth
qui prend par défaut toute la mémoire disponible qu'après un ordre ALLOC (voir
ce mot) libérant un espace suffisant pour le programme fils sous peine d'une
erreur 'mémoire insuffisante'. Cet espace sera restitué en sortie du programme
fils: l'allocation mémoire HEIGHT ALLOC peut être limitée à la première utilisation
de (PROGRAM).
Adresse d'une table de paramètres de 14 octets pour l'exécution d'une commande
d'intégration: voir sa signification au mot (PROGRAM). Cette table est initialisée
avant chaque lancement par PROGRAM. Elle est réutilisable et peut être limitée
aux 4 premiers octets pour un chargement d'overlay.
Variable-chaîne (voir le mot STRING) d'une longueur maximale de 32 octets destinée
à contenir temporairement une chaîne de commande passée à un programme externe
par l'intégrateur.
Rappelons que cette chaîne est celle que vous avez l'habitude de placer après
un nom de fichier pour indiquer au programme ce qu'il doit faire dès son lancement.
Sa syntaxe varie d'un programme à l'autre et peut contenir des séparateurs divers
(espace,virgule,caractère '/' etc):
Primitive du mot PROGRAM: initialise la table PARAM d'intégration avec l'environnement
de Turbo-Forth, charge dans la zone PAD le contenu de la variable chaîne COMMAND$,
place dans PARAM+2 l'adresse PAD comme étant la ligne de commande à passer au
programme fils, initialise des FCB par défaut et vide la variable chaîne COMMAND$
pour qu'une prochaine commande PROGRAM n'ait par défaut aucune chaîne de commande.
Enregistre dans la variable chaîne COMMAND$ une chaîne de commande d'au plus
32 caractères qui doit être passée au programme fils lors de la prochaine commande
PROGRAM.
Ce passage d'une ligne de commande est facultative avant PROGRAM. Par défaut
PROGRAM lance un programme sans ligne de commande. Si un programme doit être
lancé plusieurs fois, il convient de répéter la séquence PASS.
ajoute B:TEST.FTH dans la file d'attente d'impression "spoolée".
Intègre l'exécution d'un programme externe. Le mot qui suit PROGRAM est interprété
comme un nom de fichier; il peut comporter un nom de lecteur ou un chemin d'accès
de répertoire, mais pas de caractère joker; l'extension du nom doit être précisée
comme .COM ou .EXE.
Le programme est exécuté immédiatement avec éventuellement le passage d'une
chaîne de commande si une instruction PASS a précédé PROGRAM. Le retour d'exécution
du programme fils s'effectue dans Turbo-Forth juste après la commande PROGRAM
<fichier>.
Le mot PROGRAM se charge de libérer le maximum de mémoire pour charger le programme
fils (voir HEIGHT et ALLOC) et veille à tester l'occurence d'une erreur dans
la demande de procédure d'intégration.
Le concept d'intégration qu'introduit PROGRAM ouvre des horizons nouveaux au
langage Forth: le langage n'est plus un simple interpréteur ou un compilateur
fermé sur lui-même mais un gestionnaire qui intègre tout le monde logiciel extérieur.
Il est difficile de donner ici un aperçu de l'étendue du concept d'intégration.
Prenons l'exemple imaginaire d'un tableur - appelons-le MP.EXE -, d'un programme
Forth capable de traiter les données d'un fichier *.MP pour établir des histogrammes
quadri-dimensionnels (?) dans un fichier image H4D.PIC et d'un logiciel HSPLOT.COM
seul capable d'imprimer un dessin sur une table traçante HISPANO-SUIZA V12 ...Turbo-Forth
ne va avoir aucune peine à construire une application très personnalisée "intégrant"
aussi bien le tableur mondialement utilisé que le plus exotique des traceurs
graphiques:
PROGRAM, nous l'avons vu est une commande (mode exécution) qui interprète un
nom de fichier. Il est aisé en Turbo-Forth de compiler une commande interprétée:
si notre application doit intégrer le tableur MP.EXE à l'intérieur de définitions
compilées, nous définirons un mot MP compilable qui intégrera le tableur:
Une séquence " commande-chaîne" PASS peut être aussi compilée avant la séquence
" PROGRAM XXX" $EXECUTE si le programme doit être lancé avec une chaîne de commande.
FORMAT A:/S formate et initialise une disquette dans A: Une utilisation particulière de PROGRAM consiste à intégrer un second (et
de là un troisième etc...) module TURBO-FORTH piloté par le premier ou dédié
à une tâche spéciale: Le programme ESSAI.FTH est testé dans un deuxième Turbo-Forth puis on retournera
dans le premier Turbo-Forth non modifié par une commande BYE. Enfin l'intégrateur PROGRAM est utilisé pour lancer un éditeur externe de
fichiers textes laissé au libre choix de l'utilisateur. Ainsi, TURBO-Forth s'affranchit
d'un environnement tendant à évoluer vers la performance. Intègre une commande du processeur de commandes MS-DOS COMMAND.COM. La chaîne
explicite (adr,long) placée sur la pile est une ligne de commande (30 caractères
compte tenu du /C inséré en tête par SHELL) exprimant une commande MS-DOS: commande
interne (comme DIR,COPY etc), commande externe (comme PRINT,DISKCOPY etc), lancement
d'un programme .EXE ou .COM, lancement d'un fichier lot de commandes .BAT...
Le fichier COMMAND.COM est chargé et lancé avec l'exécution de cette commande.
Le retour est immédiat dans Turbo-Forth après l'exécution de la commande. Dans
certains cas, le retour au Forth depuis MS-DOS se fera avec la commande EXIT. Le fichier COMMAND.COM est chargé depuis le répertoire courant: il convient
de s'assurer de sa présence ou modifier le chemin du répertoire courant avec
la commande CHDIR. L'espace occupé par COMMAND.COM et les programmes qu'il peut
lui-même intégrer est restitué au retour de SHELL. " DIR | SORT > CATALOG " SHELL Une commande SHELL peut être compilée telle quelle: TIME affiche l'heure et propose sa modification. Nous vous renvoyons à votre manuel pratique MS-DOS pour connaître toutes les
commandes auxquelles SHELL donne accès; certaines sont fort méconnues des utilisateurs
même chevronnés! Pour ce qui est du lancement de programmes externes, il est
plus économique en mémoire et en temps de chargement d'utiliser PROGRAM qui
se passe du chargement intermédiaire de COMMAND.COM. Variable chaîne (voir le mot STRING) d'une longueur maximale de 12 caractères
destinée à conserver le nom du fichier de l'éditeur externe. Cette variable
chaîne est initialement vide: dans ce cas EDIT lance par défaut le fichier EDIT.COM
du répertoire courant. Une façon d'utiliser un éditeur quelconque consiste à
le renommer EDIT.COM (à condition qu'il s'agisse d'un fichier .COM). Variable chaîne (voir le mot STRING) d'une longueur maximale de 32 utilisée
par EDIT pour lancer l'éditeur externe. Variable chaîne (voir le mot STRING) d'une longueur maximale de 20 caractères
destinée à conserver le nom d'un fichier source dans lequel est survenu une
erreur d'interprétation. Variable pointant le numéro de la ligne d'un fichier source dans laquelle est
survenu une erreur d'interprétation. Variable pointant la position atteinte par l'interpréteur dans une ligne d'un
fichier source victime d'une erreur d'interprétation. Commande de lancement de l'éditeur externe. Pour l'histoire, les concepteurs
de TURBO-Forth ont d'abord été partagés entre la création d'un éditeur de programme
intégré à FORTH et un éditeur externe. La première solution nécessitait la création
d'un éditeur écrit en FORTH, donc de passer un certain temps à concevoir et
écrire cet éditeur. Finalement, c'est l'option éditeur externe qui l'emporta.
Outre le gain de place mémoire, il offrait l'avantage d'être déjà écrit (en
TURBO-Pascal pour les curieux), donc de faire gagner du temps aux concepteurs.
Mais également, le choix d'un éditeur externe ne contraint pas l'utilisateur
à apprendre de nouvelles commandes d'édition s'il est habitué à travailler avec
un autre produit. Il suffit de changer le contenu de la variable alphanumérique
EDIT$ avec le nom du nouvel éditeur s'il ne s'appelle pas EDIT.COM. L'intégration d'un programme externe d'édition de fichiers textes au format
standard permet au programmeur Turbo-Forth d'écrire ses programmes sources et
de les modifier selon ses habitudes. Il existe en effet de très nombreux programmes
d'édition depuis le rustique EDLIN de MS-DOS jusqu'aux traitements de textes
les plus sophistiqués qui la plupart admettent l'édition (ou la conversion)
de fichiers textes ASCII. EDIT répond à deux procédures de lancement d'un éditeur selon les circonstances
de son emploi: Pour bénéficier pleinement de la faculté de reprendre un fichier source au
site-même d'une erreur, il est supposé que l'éditeur externe accepte une ligne
de commande à trois paramètres séparés par des espaces de la forme: Où <nom-du-fichier> est le chemin\nom d'un fichier à éditer et <ligne>
<colonne> la position du curseur dans le texte à fixer dès le lancement. Si votre éditeur n'accepte pas plus d'un paramètre (celui du fichier à éditer),
il faudra retrouver l'erreur en vous aidant du message de localisation délivré
par l'interpréteur. Si votre éditeur accepte de se positionner au lancement
sur une ligne, ou mieux sur une ligne et une colonne, selon une syntaxe différenteé
il est préférable de redéfinir le mot EDIT de façon appropriée en construisant
dans la variable chaîne COMMAND$ la chaîne de paramètres pour votre éditeur
(après une erreur le mot (WHERE) charge dans COMMAND$ le nom du fichier incriminé): EDIT est ici redéfini pour un éditeur externe EDT.EXE acceptant une syntaxe
de lancement: EDT [fichier][/L=xxx][/C=yyy] avec xxx et yyy pour la ligne et
la colonne du curseur où débuter l'édition. La commande EDIT (même redéfinie) est obtenue au clavier par la touche F2. Change l'éditeur externe chargé par EDIT. Ce mot demande à l'utilisateur le
nom du fichier (préciser l'extension .COM ou .EXE) qui doit être intégré comme
éditeur. Ce nom de fichier est conservé dans la variable chaîne EDIT$. Il n'y
a pas lieu de modifier EDIT si cet éditeur accepte une syntaxe <fichier-à-éditer><ligne>
<colonne>. NEW-EDITOR est obtenu au clavier par la touche Shift-F6.
-- hautdepage -- page
d'accueil --
CHDIR
---
MKDIR
<répertoire>---
RMDIR
<répertoire> ---
DEL
<chemin\fichier.ext>---
REN
---
REN TRUC MACHIN renomme TRUC.FTH en MACHIN.FTH
REN C:\DOS\COMMAND.COM C:\FORTH\COMMAND.COM
transfère COMMAND.COM dans le sous-répertoire FORTH
FREE
--- d
.NAME
---
(DIR)
adr long ---
" A:\FORTH\*.FTH" (DIR)
: CAT " *.FTH" (DIR) ;
CAT
DIR
[<chemin\masque>] ---
DIR
DIR B:*.*
DIR C:\FORTH\ESSAI?.F*
D. LA MEMOIRE VIRTUELLE DE TURBO-FORTH.
1. Tickets de fichiers ouverts par Turbo-Forth.
FILES
--- 8
14 IS FILES
#FILES
--- n
?OPEN
---
HANDLE
--- adr
: NIVEAU1 " HANDLE ?" $EXECUTE ;
: NIVEAU2 " NIVEAU1" $EXECUTE ;
NIVEAU1 affiche -1
NIVEAU2 affiche -2
OPEN
<fichier[.ext]>--- hndl
CLOSE
---
ALLCLOSE
---
2. Les tampons de lignes.
LBUF
--- 322
C/PATH
--- 64
'C:\FORTH\MATH\CALCUL\SQR.FTH'
BUFFER
--- adr
.LINE
---
LINE#
--- adr
PATHNAME
--- adr
PATHNAME!
adr long ---
3. Lecture des lignes d'un fichier.
EOF?
--- adr
EOF
---
GET
--- c
(GETLINE)
adr hndl --- f
GETLINE
---
VIEW <fichier> <mot>
: VIEW ( <fichier[.ext]><mot> -- )
ECHO @ \ conserve l'état courant de ECHO
HANDLE @ \ conserve le HANDLE courant
ECHO OFF \ pas d' ECHO pour commencer
OPEN \ ouvre le fichier
BL WORD DROP \ isole le mot à chercher du flot actuel
HANDLE ! \ attribue le ticket courant au fichier
BEGIN \ commence à lire le fichier:
GETLINE \ prend une ligne
ECHO @ 0= \ ECHO est encore OFF ?
IF HERE COUNT \ si oui: chaîne du mot à chercher
BUFFER COUNT \ chaîne chargéedans le tampon
SEARCH \ recherche le mot dans le tampon
NIP \ la positiondu mot est inutile
IF .LINE \ si trouvé: affiche la ligne
ECHO ON \ et oncontinue en ECHO ON
THEN \ si pas trouvé: on continue comme ça
THEN \ si non: on continue sans chercher le mot
EOF? @ STOP? OR \ jusqu'à fin de fichier ou stop au clavier
UNTIL \ c'est fini:
CLOSE \ on ferme le fichier
HANDLE ! \ on rétablit le HANDLE ECHO ! ; \ on rétablit ECHO
INCLUDE
<fichier[.ext]>--- imm.
INCLUDE B:\FORTH\CALCUL\COMPLEX.FTH
INCLUDE TIMER
INCLUDE MAIN
fichier main.fth : [prog] ( séquence de programme)
INCLUDE MODUL1
[fin_prog]
fichier modul1.fth : [sub1]
INCLUDE MODUL2
[fin_sub1]
fichier modul2.fth : [sub2]
INCLUDE SUB1
INCLUDE SUB2
...
INCLUDE SUBx
LIST
<fichier[.ext]>---
LIST A:AUTOEXEC.BAT
LIST C:\FORTH\LISEZ.MOI
LIST CLOCK (pour CLOCK.FTH)
E. ALLOCATION MEMOIRE.
1. Segments et paragraphes utilisés par Turbo-Forth.
DSEGMENT
--- u
instruction INT 20h de retour à l'appelant (COMMAND.COM en
général)
dernière adresse segment allouable
nombre d'octets valides dans le segment
adresse offset-segment de retour à l'appelant
adresse offset-segment de branchement Break
adresse offset-segment d'erreur fatale (saut à l'habituel
"Abort,Retry,Ignore")
Table des 20 tickets (handles) utilisables
Adresse segment environnement (zone contenant les variables
de MS-DOS)
Instruction INT 21h d'appel de fonctions
premier bloc de contrôle fichier (FCB)
deuxième FCB (Turbo-Forth préfère utiliser les tickets)
chaîne implicite passée en paramètres d'appel et zone DMA
(voir ce mot) par défaut. (les autres adresses du PSP sont réservées à MS-DOS)
2 @ ( dernier segment ) DSEGMENT ( premier segment ) - U.
SEGMENT>
--- adr
BYE
[o] ---
: MENU ( ---)
CR ." 1..EXECUTION WORDSTAR"
CR ." 2..EXECUTION MULTIPLAN"
CR ." 3..EXECUTION TURBO-FORTH"
CR CR ." Votre choix:"
BEGIN
ASCII 1 = IF 1 BYE THEN
ASCII 2 = IF 2 BYE THEN
ASCII 3 = IF 3 BYE THEN
AGAIN ;
...partie initialisation de AUTOEXEC.BAT...
:debut
MENU
IF ERRORLEVEL=3 GOTO choix3
IF ERRORLEVEL=2 GOTO choix2
IF ERRORLEVEL=1 GOTO choix1
:choix1
C:\WS\WS2000
GOTO debut
:choix2
C:\MP\MP3
GOTO debut
:choix3
C:\TF83\TURBO.COM
GOTO debut
BYE?
---
HEIGHT
--- 4096
HEIGHT 2* IS HEIGHT
ALLOC
n --- seg
2. Sauvegardes de zones mémoire sur disque.
LSAVE
<fichier[.ext]>seg adr1 adr2 ---
SAVE
<fichier[.ext]>adr1 adr2 ---
SAVE-SYSTEM
<fichier[.COM]>---
F83
INCLUDE FLOAT
SAVE-SYSTEM TFF
TURBO HEX SAVE-SYSTEM TURBO.COM BYE
: SIMULATOR
INITIALISE-PLAN-DE-VOL
BEGIN PLANTE-LE-DECOR
ATTEND-UNE-COMMANDE
DEPLACE-LE-ZINC
ARRGH-CRASH?
UNTIL BYE ;
(Un jeu diabolique qui ne s'arrête que lorsqu'on est mort !)
INCLUDE FLIGHT.FTH
' SIMULATOR IS BOOT
SAVE-SYSTEM FLIGHT.COM
F. COMMANDES D'INTEGRATION.
1. Principes et primitives d'intégration MS-DOS.
(PROGRAM)
adr0 adr_params mode --- fl
octets 0-1
adresse segment de l'environnement (variables MS-DOS). La
valeur 0 attribue au programme fils le même bloc environnement que celui
du programme père.
octets 2-3
adresse offset d'une chaîne implicite (1er octet pour sa longueur)
passée comme ligne de commande au programme fils.
octets 4-5
adresse segment de la chaîne de commande.
octets 6-7
adresse offset du premier FCB (File Control Block)
octets 8-9
adresse segment du premier FCB
octets 10-11
adresse offset du second FCB
octets 12-13
adresse segment du second FCB
octets 0-1
adresse segment de chargement de l'overlay
octets 2-3
facteur de relocation à savoir toujours 0 pour un fichier
.COM ou l'adresse segment de départ d'un fichier .EXE qui doit être ajoutée
aux adresses relogeables.
PARAM
--- adr
COMMAND$
--- adr long
Chaîne de commande
B:\TEST.FTH /P
A:AUTOEXEC.BAT 100 0
2 2 + . BYE
PARAM!
---
2. Commandes utilisateur d'intégration.
PASS
adr long ---
" B:TEST.FTH /P" PASS PROGRAM A:PRINT.EXE
PROGRAM
---
PROGRAM C:\MP\MP.EXE
" B:H4D.PIC /H /T=2000"
PASS PROGRAM A:HSPLOT.COM
: MP ( -- ) " PROGRAM C:\MP\MP.EXE" $EXECUTE ;
: FORMAT ( <lecteur:> -- )
BL WORD COUNT PASS
" PROGRAM C:\DOS\FORMAT.EXE" $EXECUTE ;
" INCLUDE ESSAI" PASS PROGRAM TURBO
SHELL
adr long ---
crée un fichier texte CATALOG. contenant le directory trié.
" COPY B:TEST.FTH A:" SHELL
copie le fichier TEST.FTH de B: en A:
" MENU" SHELL
lance le programme MENU.EXE ou MENU.COM ou encore la procédure MENU.BAT
: TIME ( -- ) CR " TIME" SHELL ;
3. Lancement d'un éditeur externe.
EDIT$
--- adr long
PROGRAM$
--- adr long
IN-FILE
--- adr long
IN-LINE
--- adr
IN-CHAR
--- adr
EDIT
---
EDIT <nom-du-fichier> <ligne> <colonne>
: EDIT ( -- )
DECIMAL COMMAND$ NIP
IF " /L=" COMMAND$ APPEND$
IN-LINE @ (.) COMMAND$ APPEND$
" /C=" COMMAND$ APPEND$
IN-CHAR @ (.) COMMAND$ APPEND$
ELSE CR ." Fichier à éditer:"
COMMAND$ INPUT$
THEN " PROGRAM EDT.EXE" $EXECUTE ;
NEW-EDITOR
---