Clavier_exe: A Québécois Keyboard

See all articles from QL_DOC n7
Author(s): Réal Gagnon
Publication: QL_DOC
Pub Details: QL_DOC n7 (Issue 7)
Date: December 1988-January 1989
Pages: 7-14

In English: CLAVIER_EXE, a multitasking 68000 job by Réal Gagnon that makes French accents easy to type in Quill, typewriter-style: an apostrophe, double quote or caret before a vowel produces the grave accent, diaeresis or circumflex, and the £ and ~ keys give é and ç. The article explains the QDOS job header, MT_PRIOR and MT_SUSJB, the keyboard system variables and IO.QIN, and why the fixed addresses will not work on a Thor. The commented assembler source and a SuperBASIC DATA loader that saves the job with SEXEC are listed, followed by short notes on QDOS multitasking (EXEC, EXEC_W, SEXEC, RESPR).

Printed title: CLAVIER_EXE. The article below is in French, as printed in QL_DOC n7 (December 1988-January 1989).


Il est toujours intéressant de concevoir un programme utile, quelque chose dont on va se servir très souvent. Le programme suivant fait partie de cette catégorie si vous êtes un utilisateur fréquent de QUILL. Son but est de faciliter l’entrée des caractères français au clavier en redéfinissant certaines touches. Le principe utilisé est celui de la machine à écrire, c’est-à-dire que si nous voulons une lettre accentuée, nous faisons l’accent en premier puis nous faisons la lettre. Par exemple, si nous voulons le “ê”, nous tapons le “^” puis le “e”.

L’apostrophe devient l’accent grave pour les lettres suivantes:

'e pour è
'a pour à
'u pour ù

Nous tapons 2 fois sur l’apostrophe si nous voulons vraiment avoir une apostrophe à l’écran, ” donnera seulement ‘.

Le guillemet devient un tréma pour les lettres suivantes:

"e pour ë
"i pour ï
"u pour ü
"o pour ö

Nous tapons 2 fois sur le guillemet si nous voulons avoir vraiment un guillemet à l’écran, “” donnera seulement “.

Le petit chapeau ^ (SHIFT 6) devient un accent circonflexe pour les lettres suivantes:

^e pour ê
^a pour â
^u pour û
^o pour ô
^i pour î

Nous faisons encore ^^ pour obtenir seulement ^ à l’écran.

Les touches ” £ ” et ” ~ ” donnent respectivement les caractères ” é ” et ” ç “.

On charge le programme avec la commande EXEC xxxx_CLAVIER_EXE où xxxx est le support qui contient le programme CLAVIER_EXE.

Pour utiliser CLAVIER_EXE avec QUILL, insérez simplement l’instruction EXEC xxxx_CLAVIER_EXE avant celle qui charge le programme QUILL (EXEC_W xxxx_QLWP ou EXEC_W xxxx_QUILL).

Pour obtenir ce programme, vous avez 3 alternatives.

.Envoyez $6 à QL_DOC, et vous recevrez par le retour du courrier le programme prêt à être utiliser. Spécifiez si vous voulez le programme sur µdrive, sur disquette 5.25″ (40 tracks) ou 3.5″. QL_DOC fournira le µdrive ou la disquette.

.Tapez le programme SuperBASIC suivant pour créer le fichier CLAVIER_EXE.

.Si vous possedez un ASSEMBLEUR, tapez le programme-source ASSEMBLEUR et compilez-le.

PROGRAMMATION

CLAVIER_EXE fonctionne en multi-tâche, c’est-à-dire qu’il se déroule en même que d’autres programmes. Le programmeur a la responsabilité d’initialiser son programme pour qu’il devienne un JOB. La procédure est toujours la même.

1 -En-tête descriptif du JOB qui contient un long mot égale à 0, le préfixe $4AFB, puis sur un mot il y a le nombre de lettre pour le nom du JOB, et enfin le nom du JOB.

2 -On détermine la priorité du JOB en utilisant la routine QDOS MT_PRIOR (TRAP#1), comme nous lisons le clavier, nous n’avons pas vraiment besoin d’une grande priorité à moins d’avoir affaire à la secretaire la plus rapide au monde…

3 -Le programme proprement dit débute.

La boucle principale du programme lit la système variable à l’adresse $2808B qui contient le code de la dernière touche appuyée. On vérifie si celle-ci est une des touches qu’on veut traduire. Si il s’agit d’une touche traduisable, on efface le dernier caractère en envoyant le code de DELETE ($C2). On attend la deuxième touche, on vérifie si celle-ci est permise. Si elle ne correspond pas à un caractère accentué on laisse faire, si oui, on efface encore le caractère et on envoie le bon code pour le caractère français. Et on recommence à scruter le clavier.

Le programme ASSEMBLEUR est amplement commenté pour faciliter la compréhension du processus.

NB. Quoique que fonctionnel, ce programme ne respecte pas une règle du QDOS, il assume que les variables-système sont à une adresse fixe. Ceci n’est pas un problème sur le QL, mais CLAVIER_EXE ne fonctionnera pas tel quel sur un ordinateur THOR parce que les variables-système sont à une adresse différente sur ce dernier. Le programmeur averti devrait utiliser la routine QDOS MT_INF pour trouver l’adresse des variables-système, mais par souci d’économie d’espace, j’ai laissé tomber cette précaution.

* programme     CLAVIER QUEBECOIS   version .05
* Auteur Réal Gagnon Montréal oct 88
* But Redéfinir certaines touches du clavier pour permettre
* un accès plus facile aux caractères français.
*
*
* Table de traduction
* Touche au clavier A l'écran Touche au clavier A l'écran
* ' e è ^ e ê
* ' a à ^ a â
* ' u ù ^ u û
* ' ' ' ^ i î
* " e ë ^ o ô
* " i ï ^ ^ ^
* " u ü £ é
* " o ö ~ ç
* " " "
*
*
* Exécution EXEC xxxx_CLAVIER_EXE où xxxx est le support contenant
* le programme CLAVIER_EXE
*
MT_PRIOR equ $0B routine QDOS qui détermine la priorité d'un JOB
SV_ARBUF equ $2808B variable sys. avec le code ASCII de la dernière touche
SV_KEYQ equ $2804C pointeur pour le BUFFER du clavier
IO_QIN equ $E0 routine vector. pour mettre un caractère dans le "QUEUE"
MT_SUSJB equ 8 routine QDOS qui suspend un JOB
*
* Initialisation du JOB
START bra.s SET_PRIO saut de l'entête standard d'un JOB
dc.l 0 entête standard
dc.w $4AFB d'un JOB sous QDOS
dc.w 4 nombre de lettre du nom du JOB
dc.b 'CQ05' nom du JOB
* on détermine maintenant
* la priorité du JOB
SET_PRIO moveq #MT_PRIOR,d0 appel de la routine QDOS pour la
moveq #-1,d1 priorité de ce JOB D1=-1
moveq #1,d2 priorité de 1
trap #1
* impression du message de bienvenue
MESSAGE lea.l INTRO,a1 A1= adresse contenant le message
MES_LOOP move.b (a1)+,d1 charge la lettre dans le registre D1
cmpi.b #'*',d1 est-ce '*'?
beq KEY_SCAN oui: on saute à KEY_SCAN
bsr CAR_OUTPUT non: on imprime la lettre
bra MES_LOOP on recommence pour la lettre suivante
*
* Boucle.principale
*
KEY_SCAN move.b SV_ARBUF,d3 D3= dernière touche pressée
cmpi.b #$27,d3 vérification de apostrophe, $27 = code ASCII
beq OK_APOS
cmpi.b #'"',d3 vérification du guillemet
beq OK_GUIL
cmpi.b #'^',d3 vérification de accent circonflexe
beq OK_CIRC
cmpi.b #'£',d3 vérification de £ ( pour é )
beq OK_SPEC1
cmpi.b #'~',d3 vérification de ~ ( pour ç )
beq OK_SPEC2
bra SUSPEND
* traitement de l'apostrophe qui peut
* devenir un accent grave
OK_APOS bsr EFF_CAR efface l'apostrophe
bsr NXT_SCAN lecture de la touche suivante
lea.l ACCENT,a1 A1= table de traduction pour l'apostrophe
bra TRADUIT on va faire la traduction
* traitement du guillemet qui peut
* devenir un tréma
OK_GUIL bsr EFF_CAR efface le guillemet
bsr NXT_SCAN lecture de la touche suivante
lea.l TREMA,a1 A1= table de traduction pour le guillemet
bra TRADUIT on va faire la traduction
* traitement du "petit chapeau" qui
* peut devenir un accent circonflexe
OK_CIRC bsr EFF_CAR efface le "petit chapeau"
bsr NXT_SCAN lecture de la touche suivante
lea.l CIRCONF,a1 A1= table de traduction pour le "petit chapeau"
bra TRADUIT on va faire la traduction
*
* La traduction se fait içi.
* D3= le code de la dernière touche appuyée
TRADUIT move.b (a1)+,d0 D0= caractère traduisable
cmp.b #'*',d0 est-ce '*'?
beq KEY_SCAN oui: la table est terminée, -> boucle principale
cmp.b d3,d0 est-ce traduisable?
bne TRADUIT non: on passe au prochain caractère de la table
bsr EFF_CAR oui: on efface la dernière touche pressée
move.b (a1),d1 D1= le caractère résultant de la traduction
bsr CAR_OUTPUT impression de celui-ci
bra KEY_SCAN retour à la boucle principale
* Traitement du caractère '£' pour
* devenir le caractère 'é'
OK_SPEC1 bsr EFF_CAR efface le caractère '£'
move.b #'é',d1 D1= code de 'é'
bsr CAR_OUTPUT on imprime celui-ci
bra KEY_SCAN retour à la boucle principale
* Traitement du caractère '~' pour
* le caractère 'ç'
OK_SPEC2 bsr EFF_CAR efface le caractère '~'
move.b #'ç',d1 D1= code de '~'
bsr CAR_OUTPUT on imprime celui-ci
bra KEY_SCAN retour à a boucle principale
*
* Sous-programmes utilitaires
*
* NXT_SCAN lit le caractère suivant
* le registre D3 retourne le caractère
* appuyé
NXT_SCAN move.b SV_ARBUF,d3 D3= code de la dernière touche appuyée
cmpi.b #0,d3 est-ce toujours égal à 0?
beq NXT_SCAN oui: on refait la lecture
rts fin , D3= code de la dernière touche appuyée
CAR_OUTPUT move.l SV_KEYQ,a2 position du BUFFER
move.w IO_QIN,a0 routine VECTORIELLE IO.QIN
jsr (a0) saut à cette routine
rts fin de la routine
*
* SUSPEND ce job pendant 1/10 de seconde pour ne pas
* ralentir inutilement le programme principal
*
SUSPEND moveq #MT_SUSJB,d0 Routine QDOS pour suspende un JOB
moveq #-1,d1 D1=-1 signifie ce JOB
moveq #5,d3 D3= le temps de suspension (5*20ms)
suba.l a1,a1 A1= 0
trap #1
bra KEY_SCAN retour à la boucle principale
* EFF_CAR efface le dernier caractère tapé en
* envoyant le code de DELETE ( équivalent de CTRL <- )
*
EFF_CAR move.b #0,SV_ARBUF met la variable système à 0
move.b #$C2,d1 D1= code de DELETE
bsr CAR_OUTPUT on l'imprime
rts fin de la routine
*
* La routine CAR_OUTPUT met un caractère dans le QUEUE
* du clavier et celui-ci est "imprimé" à l'écran
* On appelle cette routine avec dans le registre D1
* contenant le code ASCII du caractère à imprimer
*
* Table de traduction
* 1er lettre est la touche appuyée
* 2ième lettre est le caractère qui sera obtenu
* '*' montre la fin de la liste
*
ACCENT dc.b 'eèaàuù''''**'
TREMA dc.b 'eëiïuüoö""**'
CIRCONF dc.b 'eêaâuûiîoô^^**'

INTRO dc.b 'REMark >> Clavier Québécois actif '
dc.b 'version 0.5 écrit par Réal Gagnon, Montréal 88',$0A,'*'

end
100 REMark Creation du fichier CLAVIER_EXE
110 :
120 CLS
130 INPUT "Ou sauver CLAVIER_EXE (ex: mdv1_)?",sauve$
140 IF LEN(sauve$)=0: sauve$="flp1_"
150 PRINT "Un instant s.v.p."
160 :
170 RESTORE 300:a=RESPR(1000):basr=a
180 compte=0
190 REPeat l
200 IF EOF:EXIT l
210 AT 3,0:PRINT "> "
220 READ x: POKE a,x : a=a+1
230 AT 3,0:PRINT " <";
240 compte=compte+1
250 END REPeat l
260 :
270 PRINT "Une touche pour sauver CLAVIER_EXE.": PAUSE
280 SEXEC sauve$&"clavier_exe",basr,compte,128
290 :
300 DATA 96, 12, 0, 0, 0, 0, 74, 251, 0, 4
310 DATA 67, 81, 48, 53, 112, 11, 114, 255, 116, 1
320 DATA 78, 65, 67, 250, 1, 22, 18, 25, 12, 1
330 DATA 0, 42, 103, 0, 0, 10, 97, 0, 0, 200
340 DATA 96, 0, 255, 240, 22, 57, 0, 2, 128, 139
350 DATA 12, 3, 0, 39, 103, 0, 0, 38, 12, 3
360 DATA 0, 34, 103, 0, 0, 46, 12, 3, 0, 94
370 DATA 103, 0, 0, 54, 12, 3, 0, 96, 103, 0
380 DATA 0, 92, 12, 3, 0, 126, 103, 0, 0, 100
390 DATA 96, 0, 0, 160, 97, 0, 0, 124, 97, 0
400 DATA 0, 104, 67, 250, 0, 162, 96, 0, 0, 34
410 DATA 97, 0, 0, 108, 97, 0, 0, 88, 67, 250
420 DATA 0, 156, 96, 0, 0, 18, 97, 0, 0, 92
430 DATA 97, 0, 0, 72, 67, 250, 0, 152, 96, 0
440 DATA 0, 2, 16, 25, 176, 60, 0, 42, 103, 0
450 DATA 255, 150, 176, 3, 102, 0, 255, 242, 97, 0
460 DATA 0, 60, 18, 17, 97, 0, 0, 72, 96, 0
470 DATA 255, 130, 97, 0, 0, 46, 18, 60, 0, 131
480 DATA 97, 0, 0, 56, 96, 0, 255, 114, 97, 0
490 DATA 0, 30, 18, 60, 0, 136, 97, 0, 0, 40
500 DATA 96, 0, 255, 98, 22, 57, 0, 2, 128, 139
510 DATA 12, 3, 0, 0, 103, 0, 255, 244, 78, 117
520 DATA 19, 252, 0, 0, 0, 2, 128, 139, 18, 60
530 DATA 0, 194, 97, 0, 0, 4, 78, 117, 36, 121
540 DATA 0, 2, 128, 76, 48, 120, 0, 224, 78, 144
550 DATA 78, 117, 112, 8, 114, 255, 118, 5, 147, 201
560 DATA 78, 65, 96, 0, 255, 36, 101, 144, 97, 141
570 DATA 117, 154, 39, 39, 42, 42, 101, 143, 105, 146
580 DATA 117, 135, 111, 132, 34, 34, 42, 42, 101, 145
590 DATA 97, 142, 117, 155, 105, 149, 111, 152, 94, 94
600 DATA 42, 42, 82, 69, 77, 97, 114, 107, 32, 62
610 DATA 62, 32, 67, 108, 97, 118, 105, 101, 114, 32
620 DATA 81, 117, 131, 98, 131, 99, 111, 105, 115, 32
630 DATA 97, 99, 116, 105, 102, 32, 118, 101, 114, 115
640 DATA 105, 111, 110, 32, 48, 46, 53, 32, 32, 131
650 DATA 99, 114, 105, 116, 32, 112, 97, 114, 32, 82
660 DATA 131, 97, 108, 32, 71, 97, 103, 110, 111, 110
670 DATA 44, 32, 77, 111, 110, 116, 114, 131, 97, 108
680 DATA 32, 56, 56, 10, 42, 0, 0, 0

PETITES REFLEXIONS SUR LE MULTI-TACHES DU QDOS

QDOS est un système d’exploitation qui permet au programmeur de réaliser des programmes multi-tâches.

On appelle multi-tâche un système d’exploitation capable d’assurer le déroulement de plusieurs programmes (“JOBS”) dans une apparente simultanéité, les programmes étant en fait exécutés l’un après l’autre durant de très faible intervalles de temps, ces intervalles sont déterminés par la priorité que possède le JOB.

Un JOB constitue un bloc logiciel indépendant pouvant partager le temps de l’unité centrale et les ressources du système avec d’autres programmes. Un JOB peut disposer des ses propres canaux d’entrée-sortie ou les partager avec d’autres JOBS.

Le QL de base (128K) peut faire fonctionner jusqu’à 55 JOBS différents en même temps, avec une extension de mémoire de 512K ce nombre augmente à 120 JOBS. A partir du SuperBASIC, qui est lui-même un JOB, il est possible de faire démarrer des JOBS avec les commandes EXEC et EXEC_W.

Ces commandes ne peuvent être utiliser qu’avec des programmes binaires qui ont été sauvegardés avec la commande SEXEC. La commande SEXEC effectue les mêmes opérations que SBYTES sauf que: l’en-tête du fichier sauvegardé contient un drapeau mis à 1 (comparativement à 0 si SBYTES) et en plus, il y a dans l’en-tête un long mot pour indiquer le nombre d’octets devant être réservés pour la zone de données du JOB.

La commande EXEC sert à charger et à démarrer un JOB, tout en gardant le JOB appelant actif. Tandis que EXEC_W charge et démarre un JOB et suspend le JOB appelant.

Ainsi, en SuperBASIC si vous appellez un JOB 1 par EXEC puis un JOB 2 par EXEC_W, le JOB 1 continue à s’exécuter durant le JOB 2, bien que le SuperBASIC, JOB appelant de 2 (par EXEC_W) soit lui-même suspendu.

Il est impossible de réserver de l’espace mémoire par RESPR, à partir du moment où un JOB autre que le SuperBASIC est exécuté (et même suspendu). Un JOB occupe en effet un espace de mémoire indéplacable dans la zone des programmes transitoires et une réservation de mémoire par RESPR, provoquant un décalage de cette zone, ne peut donc être effectuée.


Trucs & Astuces

Nous avons vu dans le numéro précédent de QL_DOC qu’il était possible de “lister” un programme SuperBASIC à l’imprimante avec la commande suivante: SAVE ser1 .

Ce truc marche très bien aussi avec l’éditeur de METACOMCO ou celui de TALENT. Au lien de faire la commande SA /nom_du_fichier nous faisons la commande SA /ser1 et notre texte sera transmis à l’imprimante qui est branchée à SER1. Ce truc est très utile car ces éditeurs ne possède pas de commande spéciale pour l’impression de fichier.

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.