Site logo

Triceraprog
La programmation depuis le Crétacé

Mattel Aquarius, scan des touches en assembleur ()

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