Revenir au plan du site


Lire une ligne du clavier


Comment ça, lire UNE ligne du clavier?

Le clavier du CPC est composé de 10 lignes sur 8 colonnes, ce qui donne la possibilité de gérer 80 touches. En pratique, le clavier du CPC en a 73 (si on ne compte pas le SHIFT deux fois, qui est branché en parallèle). Reste 6 'touches' pour le Joystick 1 (le deuxième joystick se trouve sur la 6è ligne et partage ses accès avec les lettres B, F, G, T, R, 5 et 6). On arrive à 79 sur 80, car le troisième bouton feu n'est pas câblé sur nos machines.

Lire la matrice clavier se fait avec le PPI qui est le seul à pouvoir utiliser le 15è registre de la puce audio. Ce registre n'est pas du tout dédié à l'audio mais aux entrées/sorties d'un clavier (comment ça? on peut sortir des choses sur un clavier?). Ce registre trouve son origine dans l'utilisation qu'on pouvait faire de cette puce audio dans des petits jeux électroniques qui devaient gérer quelques boutons au passage.

L'idée générale est de sélectionner la ligne du clavier et lire les 8 colonnes (en fait 8 bits) d'un coup avec un IN.

Le code ne s'invente pas, on reprend les nombreux exemples disponibles. Voici le source pour lire une seule ligne (par exemple celle du joystick sur GX4000, inutile de scanner les autres).
; on assume qu'au moment où on rentre dans cette routine, le port A est en sortie
; comme c'est ce qu'on configure à la fin de cette routine, c'est ce qui se passe
; dès le deuxième appel à cette routine, si ce n'était pas le cas
ld a,#49 ; ligne 9 de la matrice, c'est le joystick!
ld bc,#F40E
out (c),c ; sélectionner le registre 14 sur le port A
ld bc,#F6C0
out (c),c ; la valeur qu'on va envoyer est un registre
out (c),0 ; validation obligatoire sur Plus sinon bug!
ld bc,#F792
out (c),c ; mettre le port A en lecture
dec b ; B=#F6
out (c),a ; envoyer la ligne clavier (nous c'est #49)
ld b,#F4 ; adresse de lecture du port A
in a,(c) ; lecture de la ligne!
ld bc,#F782 ; PPI configuré port A en sortie
out (c),c
dec b
out (c),0
ret

Vous serez étonné de voir en trace que si une touche n'est pas enfoncée, le bit y référant est à 1. Un clavier qu'on ne touche pas renverra donc #FF partout.

Lire toutes les lignes du clavier ne prendra qu'environ 200 nops
lectureMatriceClavier
di ; Vous n'avez pas besoin de couper les interruptions
   ; si il n'y a pas de routine sonore sous interruption
ld hl,matriceClavier
ld bc,#f782
out (c),c
ld bc,#f40e
ld e,b
out (c),c
ld bc,#f6c0
ld d,b
out (c),c
out (c),0
ld bc,#f792
out (c),c
ld a,#40
ld c,d
.loop ld b,d
out (c),a ; sélectionner la ligne
ld b,e
ini ; lire et stocker dans notre tableau
inc a
inc c
jr nz,.loop
ld bc,#f782
out (c),c
ei ; pas besoin d'activer les interruptions si on ne les a pas coupées
ret

matriceClavier defs 10,#FF

Bon, c'est bien sympa tout ça, mais où sont nos touches?

Les touches sont positionnées dans la matrice de façon physique, c'est à dire qu'un clavier QWERTY est câblé de la même façon qu'un clavier AZERTY. C'est la ROM du firmware qui comporte une fonte légèrement différente selon les langues (mais le code ASCII de la lettre A reste le même qu'on soit en AZERTY ou QWERTY) ainsi que la table de mapping.
C'est cette dernière table qui réalise la conversion d'un code de touche physique vers un caractère ASCII. En patchant cette table, l'émulateur ACE peut mapper n'importe quel clavier sur la ROM du CPC.

Bon, un exemple pratique plutôt? Si je veux tester la touche Espace, je fais comment?

Hé bien tu regardes sa position dans l'une des matrices suivantes (c'est pareil sur toutes), la touche Espace est sur la ligne #45 et le bit 7.
; lire toutes les lignes
call lectureMatriceClavier
; tester la touche Espace
ld a,(matriceClavier+5) : and (2>>7) : call z,toucheEspaceEnfoncee ; si le bit vaut 0, touche enfoncée

Je vous conseille de vous créer des variables plus explicite qu'écrire directement des numéros de ligne et des décalages de bit dans votre code, ce sera plus facile à relire et à changer en cas de besoin, par exemple, vous pourriez écrire.
OCTET_TOUCHE_ESPACE equ matriceClavier+5 ; BIT_TOUCHE_ESPACE equ (2>>7)
OCTET_TOUCHE_ESC equ matriceClavier+8 ; BIT_TOUCHE_ESC equ (2>>2)

; lire toutes les lignes
call lectureMatriceClavier
; tester la touche Espace
ld a,(OCTET_TOUCHE_ESPACE) : and BIT_TOUCHE_ESPACE : call z,toucheEspaceEnfoncee ; si le bit vaut 0, touche enfoncée

Matrice du clavier AZERTY Français de France

Bit:
Ligne
7 6 5 4 3 2 1 0
#40 F Dot Entrée F3 F6 F9 Curseur Bas Curseur Droite Curseur Haut
#41 F0 F2 F1 F5 F8 F7 Copie Curseur Gauche
#42 Contrôle $ @\ Shift F4 # > Retourne * < CLR
#43  : / = + M ù % P ^ ¦ ) [ - _
#44  ; . , ? K L I O ç 9 à 0
#45 Espace N J H Y U è 7  ! 8
#46 V B (Joy2 fire3) F (Joy2 fire2) G (Joy2 fire1) T (Joy2 right) R (Joy2 left) ( 5 (Joy2 down) ] 6 (Joy2 up)
#47 X C D S Z E " 3 ' 4
#48 W CAPS-LOCK Q TAB A Échappe é 2 & 1
#49 DEL Joy1 fire3 Joy1 fire2 Joy1 fire1 Joy1 right Joy1 left Joy1 down Joy1 up

Matrice du clavier QWERTY britannique

Bit:
Ligne
7 6 5 4 3 2 1 0
#40 F. ENTER F3 F6 F9 Curseur Bas Curseur Droite Curseur Haut
#41 F0 F2 F1 F5 F8 F7 COPY Curseur Gauche
#42 Contrôle \ ` SHIFT F4 ] } RETURN [ { CLR
#43 . > / ?  : *  ; + P @ ¦ - = ^ £
#44 , < M K L I O 9 ) 0 _
#45 Espace N J H Y U 7 ' 8 (
#46 V B (Joy2 fire3) F (Joy2 fire2) G (Joy2 fire1) T (Joy2 right) R (Joy2 left) 5 % (Joy2 down) 6 & (Joy2 up)
#47 X C D S W E 3 # 4 $
#48 Z CAPSLOCK A TAB Q ESC 2 " 1 !
#49 DEL Joy1 fire3 Joy1 fire2 Joy1 fire1 Joy1 right Joy1 left Joy1 down Joy1 up

Matrice du clavier Danois

Bit:
Ligne
7 6 5 4 3 2 1 0
#40 F Dot ENTER F3 F6 F9 Curseur Bas Curseur Droite Curseur Haut
#41 F0 F2 F1 F5 F8 F7 COPY Curseur Gauche
#42 Contrôle  ; + SHIFT F4  : * RETURN @ \ CLR
#43 . > / ? Æ Ø P Å - = ^ £
#44 , < M K L I O 9 ) 0 _
#45 Espace N J H Y U 7 ' 8 (
#46 V B (Joy2 fire3) F (Joy2 fire2) G (Joy2 fire1) T (Joy2 right) R (Joy2 left) 5 % (Joy2 down) 6 & (Joy2 up)
#47 X C D S W E 3 # 4 $
#48 Z CAPSLOCK A TAB Q ESC 2 " 1 !
#49 DEL Joy1 fire3 Joy1 fire2 Joy1 fire1 Joy1 right Joy1 left Joy1 down Joy1 up

Matrice du clavier Espagnol

Bit:
Ligne
7 6 5 4 3 2 1 0
#40 F Dot INTRO F3 F6 F9 Curseur Bas Curseur Droite Curseur Haut
#41 F0 F2 F1 F5 F8 F7 COPIA Curseur Gauche
#42 Contrôle \ ` MAYS F4 ] + RETURN [ * CLR
#43 . > / ? Ñ  ; : P @ ¦ - = ^ ₧
#44 , < M K L I O 9 ) 0 _
#45 Espace N J H Y U 7 ' 8 (
#46 V B (Joy2 fire3) F (Joy2 fire2) G (Joy2 fire1) T (Joy2 right) R (Joy2 left) 5 % (Joy2 down) 6 & (Joy2 up)
#47 X C D S W E 3 # 4 $
#48 Z FIJA MAYS A TAB Q ESC 2 " 1 !
#49 BORR Joy1 fire3 Joy1 fire2 Joy1 fire1 Joy1 right Joy1 left Joy1 down Joy1 up