Le scan du clavier, sur Mattel Aquarius, à lieu dans la ROM à l'adresse $1e80
. Cette fonction traite les minuscules, les majuscules mais aussi les raccourcis BASIC, en injectant au fur et à mesure les touches nécessaires comme si elles avaient été tapées au clavier.
C'est beaucoup trop pour un scan de clavier dans un jeu, et peut même poser quelques soucis. Mais c'est une bonne base pour écrire une routine de lecture de clavier, car la lecture des valeurs des touches n'est pas forcément très simples.
Ce que nous apprends la lecture de la routine en ROM est qu'il semble falloir attendre une stabilité dans les valeurs avant d'accepter la touche. En effet, la routine fait plusieurs lectures et ne considère la touche appuyée que si cette lecture est stable.
Voici une version de la routine, où j'ai enlever ce qui était traitement de raccourcis BASIC, ainsi que le traitement des touches de modifications. Ainsi, la traduction ne se fait qu'avec les touches minuscules.
Attention, je n'ai pas encore testé cette routine sur du matériel réel !
La routine
Dans cette version, le décodage de la touche est faite par rapport aux minuscules. En changeant vers la fin la valeur de HL de lower_key_table-1
vers upper_key_table-1
, il est possible d'obtenir un décodage avec des majuscules.
Il est aussi possible de ne traiter que des codes de touches, sans traductions. Dans ce cas là, il suffit de remplacer les trois instructions après accept_key
par un simple LD A, E
.
Les deux emplacements en RAM, qui commencent ce code source, doivent être en RAM et être adaptés à votre programme.
latest_keycode_pressed: EQU 0380eh
keyword_delay_value: EQU 0380fh
lower_key_table: EQU 01f38h
upper_key_table: EQU 01f66h
check_key:
EXX
LD BC,0xff
IN A,(C)
CPL
AND 0x3f
LD HL,latest_keycode_pressed
JR Z,no_key_scanned ; ?No row were selected, quick skip?
LD B,0x7f ; Input row 7
IN A,(C)
CPL
AND 0xf ; Only 4 keys in lower bits
JR NZ,decode_key_scan
LD B,0xbf ; Input rows 6 to 0
loop_input_rows:
IN A,(C)
CPL
AND 0x3f ; 5 keys in lower bits
JR NZ,decode_key_scan
RRC B
JR C,loop_input_rows
no_key_scanned:
INC HL
LD A,0x46
CP (HL) ; Compare with delay
JR C,return_no_key_value
JR Z,reset_latest_key
INC (HL) ; Increment delay
return_no_key_value:
XOR A
EXX
RET
reset_latest_key:
INC (HL)
DEC HL
LD (HL),0x0
JR return_no_key_value
decode_key_scan:
LD DE,0x0
count_row:
INC E
RRA
JR NC,count_row
LD A,E ; E is the active row
count_add_column:
RR B
JR NC,keycode_found
ADD A,0x6 ; Add 6 for each column
JR count_add_column
keycode_found:
LD E,A
CP (HL) ; HL = 0380eh
LD (HL),A
INC HL
JR NZ,new_key_delay ; That's a new key, we need a bit of selay
LD A,0x4
CP (HL)
JR C,commit_key_delay_continued
JR Z,accept_key ; Wait if over, accept key!
INC (HL) ; Increment delay from 4 to 6 iteratively
JR return_no_key_value
commit_key_delay_continued:
LD (HL),0x6 ; Set the delay for the second pass
JR return_no_key_value
new_key_delay:
LD (HL),0x0
JR return_no_key_value
accept_key:
LD IX,lower_key_table-1
ADD IX,DE
LD A,(IX+0x0) ; Read decoded Key value
return_key_value
EXX
RET