Difference between revisions of "Programming:Keyboard scanning"

From CPCWiki - THE Amstrad CPC encyclopedia!
Jump to: navigation, search
(See)
 
(39 intermediate revisions by 6 users not shown)
Line 1: Line 1:
== Hardware scancode table ==
+
== Hardware scancodes ==
 +
 
 +
=== English table ===
 
{|{{Prettytable|width: 700px; font-size: 2em;}}
 
{|{{Prettytable|width: 700px; font-size: 2em;}}
 
|'''Bit:<br>Line''' || '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''
 
|'''Bit:<br>Line''' || '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''
Line 7: Line 9:
 
|'''&41''' || F0 || F2 || F1 || F5 || F8 || F7 || COPY || CURLEFT
 
|'''&41''' || F0 || F2 || F1 || F5 || F8 || F7 || COPY || CURLEFT
 
|-
 
|-
|'''&42''' || CONTROL || \ || SHIFT || F4 || ] || RETURN || [ || CLR
+
|'''&42''' || CONTROL || \ ` || SHIFT || F4 || ] } || RETURN || [ { || CLR
 
|-
 
|-
|'''&43''' || . || / || : || ; || P || @ || - || ^
+
|'''&43''' || . > || / ? || : * || ; + || P || @ ¦ || - = || ^ £
 
|-
 
|-
|'''&44''' || , || M || K || L || I || O || 9 || 0
+
|'''&44''' || , < || M || K || L || I || O || 9 ) || 0 _
 
|-
 
|-
|'''&45''' || SPACE || N || J || H || Y || U || 7 || 8
+
|'''&45''' || SPACE || N || J || H || Y || U || 7 ' || 8 (
 
|-
 
|-
|'''&46''' || V || B || F || G (Joy2 fire) || T (Joy2 right) || R (Joy2 left) || 5 (Joy2 down)|| 6 (Joy 2 up)
+
|'''&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
+
|'''&47''' || X || C || D || S || W || E || 3 # || 4 $
 
|-
 
|-
|'''&48''' || Z || CAPSLOCK || A || TAB || Q || ESC || 2 || 1
+
|'''&48''' || Z || CAPSLOCK || A || TAB || Q || ESC || 2 " || 1 !
 
|-
 
|-
|'''&49''' || DEL || - || - ||Joy1 Fire||Joy1 right||Joy1 left||Joy1 down||Joy1 up
+
|'''&49''' || DEL || Joy1 fire3 || Joy1 fire2 ||Joy1 fire1||Joy1 right||Joy1 left||Joy1 down||Joy1 up
 
|}
 
|}
  
 +
=== Danish table ===
 +
{|{{Prettytable|width: 700px; font-size: 2em;}}
 +
|'''Bit:<br>Line''' || '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''
 +
|-
 +
|'''&40''' || F Dot || ENTER || F3 || F6 || F9 || CURDOWN || CURRIGHT || CURUP
 +
|-
 +
|'''&41''' || F0 || F2 || F1 || F5 || F8 || F7 || COPY || CURLEFT
 +
|-
 +
|'''&42''' || CONTROL || ; + || SHIFT || F4 || : * || RETURN || @ \ || CLR
 +
|-
 +
|'''&43''' || . > || / ? || Æ || Ø || P || Å || - = || ^ £
 +
|-
 +
|'''&44''' || , < || M || K || L || I || O || 9 ) || 0 _
 +
|-
 +
|'''&45''' || SPACE || 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
 +
|}
 +
 +
=== Spanish table ===
 +
{|{{Prettytable|width: 700px; font-size: 2em;}}
 +
|'''Bit:<br>Line''' || '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''
 +
|-
 +
|'''&40''' || F Dot || INTRO || F3 || F6 || F9 || CURDOWN || CURRIGHT || CURUP
 +
|-
 +
|'''&41''' || F0 || F2 || F1 || F5 || F8 || F7 || COPIA || CURLEFT
 +
|-
 +
|'''&42''' || CONTROL || \ ` || MAYS || F4 || ] + || RETURN || [ * || CLR
 +
|-
 +
|'''&43''' || . > || / ? || Ñ || ; : || P || @ ¦ || - = || ^ ₧
 +
|-
 +
|'''&44''' || , < || M || K || L || I || O || 9 ) || 0 _
 +
|-
 +
|'''&45''' || SPACE || 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
 +
|}
 +
 +
=== French table ===
 +
{|{{Prettytable|width: 700px; font-size: 2em;}}
 +
|'''Bit:<br>Line''' || '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''
 +
|-
 +
|'''&40''' || F Dot || ENTER || F3 || F6 || F9 || CURDOWN || CURRIGHT || CURUP
 +
|-
 +
|'''&41''' || F0 || F2 || F1 || F5 || F8 || F7 || COPY || CURLEFT
 +
|-
 +
|'''&42''' || CONTROL || $ @\ || SHIFT || F4 || # > || RETURN || * < || CLR
 +
|-
 +
|'''&43''' || : / || = + || M || ù % || P || ^ ¦ || ) [ || - _
 +
|-
 +
|'''&44''' || ; . || , ? || K || L || I || O || ç 9 || à 0
 +
|-
 +
|'''&45''' || SPACE || 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 || CAPSLOCK || Q || TAB || A || ESC || é 2 || & 1
 +
|-
 +
|'''&49''' || DEL || Joy1 fire3 || Joy1 fire2 ||Joy1 fire1||Joy1 right||Joy1 left||Joy1 down||Joy1 up
 +
|}
 +
 +
Note: Fire3 only work on Amstrad CPC, not on Amstrad Plus.
 +
 +
== Computing key code ==
 +
 +
System key codes (codes that are writted on the top of the disc drive on 664/6128 or in the CPC user manual) can be computed with the formula : (Line*8)+bit
 +
 +
Example : for key SHIFT , Line = 2 , bit = 5 so (2*8)+5 = 21
  
 
== Keyboard clash ==
 
== Keyboard clash ==
  
 
This is the name of the phenomenon when a "ghost" or "phantom" key is generated when you press some combinations of keys.
 
This is the name of the phenomenon when a "ghost" or "phantom" key is generated when you press some combinations of keys.
It is caused by the design of the keyboard hardware.
+
It is caused by the design of the keyboard hardware. It has been tested and confirmed that keyboard clash doesn't occur on an English CPC664 keyboard.
  
 
For example, pressing Q,A,P will also generate :.
 
For example, pressing Q,A,P will also generate :.
Line 36: Line 120:
 
The problem is much bigger in 2 player games.
 
The problem is much bigger in 2 player games.
  
It is possible to avoid or minimise the problem by carefully choosing the controls. The problem also occurs when using digital joysticks because these are part of the keyboard matrix.
+
It is possible to avoid or minimize the problem by carefully choosing the controls. The problem also occurs when using digital joysticks because these are part of the keyboard matrix.
  
 
If you visualize a rectangle in the keyboard matrix above, where 3 of the corners are 3 keys you have pressed. Then the key in the fourth corner will also be pressed this is the "ghost" key.
 
If you visualize a rectangle in the keyboard matrix above, where 3 of the corners are 3 keys you have pressed. Then the key in the fourth corner will also be pressed this is the "ghost" key.
Line 51: Line 135:
  
 
'''Destroyed:''' BC
 
'''Destroyed:''' BC
<pre>LD A,kbdline ; from 0 to 9 with bdir/bc1=01
+
<pre>LD A,kbdline ; from &40 to &49 with bdir/bc1=01
 +
LD D,0
 
LD BC,#F782 ; PPI port A out /C out  
 
LD BC,#F782 ; PPI port A out /C out  
 
OUT (C),C  
 
OUT (C),C  
 
LD BC,#F40E ; Select Ay reg 14 on ppi port A  
 
LD BC,#F40E ; Select Ay reg 14 on ppi port A  
 
OUT (C),C  
 
OUT (C),C  
LD BC,#F6CO ; This value is an AY index (R14)  
+
LD BC,#F6C0 ; This value is an AY index (R14)  
 
OUT (C),C  
 
OUT (C),C  
OUT (C),0 ; Validate!!
+
OUT (C),D ; Validate!! out (c),0
 
LD BC,#F792 ; PPI port A in/C out  
 
LD BC,#F792 ; PPI port A in/C out  
 
OUT (C),C  
 
OUT (C),C  
Line 68: Line 153:
 
OUT (C),C  
 
OUT (C),C  
 
DEC B ; Reset PPI Write  
 
DEC B ; Reset PPI Write  
OUT (C),0
+
OUT (C),D ; out (c),0
 
+
  
 +
Register A now holds the value of requested keyboard row
 
Now check for the value from the table e.g. with''''bit x,A''''and a condition e.g.''''jp z,xxxx''''or''''call z,xxxx''''
 
Now check for the value from the table e.g. with''''bit x,A''''and a condition e.g.''''jp z,xxxx''''or''''call z,xxxx''''
 
</pre>
 
</pre>
Line 95: Line 180:
 
         ld d,b          ;1
 
         ld d,b          ;1
 
         out (c),c      ;4
 
         out (c),c      ;4
         ld c,0          ;2
+
         xor a          ;1
         out (c),c       ;4
+
         out (c),a       ;4
 
         ld bc,#f792    ;3
 
         ld bc,#f792    ;3
 
         out (c),c      ;4
 
         out (c),c      ;4
 
         ld a,#40        ;2
 
         ld a,#40        ;2
         ld c,#4a        ;2 44
+
         ld c,d          ;1 (+42)
 
loop    ld b,d          ;1
 
loop    ld b,d          ;1
 
         out (c),a      ;4 select line
 
         out (c),a      ;4 select line
Line 106: Line 191:
 
         ini            ;5 read bits and write into KEYMAP
 
         ini            ;5 read bits and write into KEYMAP
 
         inc a          ;1
 
         inc a          ;1
         cp c           ;1
+
         inc c           ;1
         jr c,loop       ;2/3 9*16+1*15=159
+
         jr nz,loop     ;2/3 (9*16+1*15 = 159)
 
         ld bc,#f782    ;3
 
         ld bc,#f782    ;3
 
         out (c),c      ;4
 
         out (c),c      ;4
         ei              ;1 8 =211 microseconds
+
         ei              ;1 (+8 = 209 microseconds)
 
         ret
 
         ret
 
</pre>
 
</pre>
Line 118: Line 203:
 
In the CPC world it is more common that a game supports both keyboard and digital joystick for those users who don't own joysticks.
 
In the CPC world it is more common that a game supports both keyboard and digital joystick for those users who don't own joysticks.
 
In addition, it is also nice if the keys could be redefined but that is not necessary.
 
In addition, it is also nice if the keys could be redefined but that is not necessary.
 +
 +
The standard CPC can support 3 buttons per joystick, though many CPC joysticks only have 1 button.
 +
 +
The CPC+ and GX4000 only support 2 buttons per joystick, and the included Amstrad joypads have 2 buttons.
  
 
There are some common keyboard configurations used:
 
There are some common keyboard configurations used:
 +
 +
* '''Joystick''' - This configuration is compatible with all Amstrad machines, even the GX4000 and you need to scan only one keyboard line (this means you can't be faster)
  
 
* '''Cursor keys & SPACE''' - This configuration is often used and is great for the CPC6128 and Plus and playing using emulators. This is '''not''' good for CPC 464 and 664 (which have uncomfortably arranged cursor keys)
 
* '''Cursor keys & SPACE''' - This configuration is often used and is great for the CPC6128 and Plus and playing using emulators. This is '''not''' good for CPC 464 and 664 (which have uncomfortably arranged cursor keys)
  
 
* '''Q,A,O,P,SPACE''' - (Q up, A down, O left, P right, SPACE fire) This is a good solution, and it's a sort of standard (used by many games). It is best for english QWERTY keyboards, on french AZERTY it'd be A-Q-O-P (but because the decoding of the keys is done in software, normally by the OS, the bits in the keyboard matrix are actually the same).
 
* '''Q,A,O,P,SPACE''' - (Q up, A down, O left, P right, SPACE fire) This is a good solution, and it's a sort of standard (used by many games). It is best for english QWERTY keyboards, on french AZERTY it'd be A-Q-O-P (but because the decoding of the keys is done in software, normally by the OS, the bits in the keyboard matrix are actually the same).
 +
 +
The standard CPC has only 1 digital joystick port (and no analog joystick port). But it was possible to daisy chain the official Amstrad joysticks. And a common accessory, the joystick port doubler, offered 2 digital joystick ports.
 +
 +
The CPC+ and GX4000 have 2 digital joystick ports built-in (and 1 analog joystick port).
 +
 +
== See Also ==
 +
 +
* [[Digital Joysticks]]
 +
* [[Keyboard Versions]]
  
 
[[Category:Programming]][[Category:CPC Internal Components]]
 
[[Category:Programming]][[Category:CPC Internal Components]]

Latest revision as of 08:09, 8 June 2024

Hardware scancodes

English table

Bit:
Line
7 6 5 4 3 2 1 0
&40 F Dot ENTER F3 F6 F9 CURDOWN CURRIGHT CURUP
&41 F0 F2 F1 F5 F8 F7 COPY CURLEFT
&42 CONTROL \ ` SHIFT F4 ] } RETURN [ { CLR
&43 . > / ?  : *  ; + P @ ¦ - = ^ £
&44 , < M K L I O 9 ) 0 _
&45 SPACE 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

Danish table

Bit:
Line
7 6 5 4 3 2 1 0
&40 F Dot ENTER F3 F6 F9 CURDOWN CURRIGHT CURUP
&41 F0 F2 F1 F5 F8 F7 COPY CURLEFT
&42 CONTROL  ; + SHIFT F4  : * RETURN @ \ CLR
&43 . > / ? Æ Ø P Å - = ^ £
&44 , < M K L I O 9 ) 0 _
&45 SPACE 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

Spanish table

Bit:
Line
7 6 5 4 3 2 1 0
&40 F Dot INTRO F3 F6 F9 CURDOWN CURRIGHT CURUP
&41 F0 F2 F1 F5 F8 F7 COPIA CURLEFT
&42 CONTROL \ ` MAYS F4 ] + RETURN [ * CLR
&43 . > / ? Ñ  ; : P @ ¦ - = ^ ₧
&44 , < M K L I O 9 ) 0 _
&45 SPACE 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

French table

Bit:
Line
7 6 5 4 3 2 1 0
&40 F Dot ENTER F3 F6 F9 CURDOWN CURRIGHT CURUP
&41 F0 F2 F1 F5 F8 F7 COPY CURLEFT
&42 CONTROL $ @\ SHIFT F4 # > RETURN * < CLR
&43  : / = + M ù % P ^ ¦ ) [ - _
&44  ; . , ? K L I O ç 9 à 0
&45 SPACE 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 CAPSLOCK Q TAB A ESC é 2 & 1
&49 DEL Joy1 fire3 Joy1 fire2 Joy1 fire1 Joy1 right Joy1 left Joy1 down Joy1 up

Note: Fire3 only work on Amstrad CPC, not on Amstrad Plus.

Computing key code

System key codes (codes that are writted on the top of the disc drive on 664/6128 or in the CPC user manual) can be computed with the formula : (Line*8)+bit

Example : for key SHIFT , Line = 2 , bit = 5 so (2*8)+5 = 21

Keyboard clash

This is the name of the phenomenon when a "ghost" or "phantom" key is generated when you press some combinations of keys. It is caused by the design of the keyboard hardware. It has been tested and confirmed that keyboard clash doesn't occur on an English CPC664 keyboard.

For example, pressing Q,A,P will also generate :.

The ':' key is the "ghost" key.

The problem is much bigger in 2 player games.

It is possible to avoid or minimize the problem by carefully choosing the controls. The problem also occurs when using digital joysticks because these are part of the keyboard matrix.

If you visualize a rectangle in the keyboard matrix above, where 3 of the corners are 3 keys you have pressed. Then the key in the fourth corner will also be pressed this is the "ghost" key.

On Plus it is possible to avoid it mostly by having one player on analogue joystick and the other on keyboard/digital joystick.

One line scanning routine

This is a routine which scans one line of the keyboard directly. It is approximately 8% faster than the firmware routine and doesn't enable interrupts.

Input: A = line (&40 - &49)

Output: A = hardware keyboard value

Destroyed: BC

LD A,kbdline ; from &40 to &49 with bdir/bc1=01
LD D,0
LD BC,#F782 ; PPI port A out /C out 
OUT (C),C 
LD BC,#F40E ; Select Ay reg 14 on ppi port A 
OUT (C),C 
LD BC,#F6C0 ; This value is an AY index (R14) 
OUT (C),C 
OUT (C),D ; Validate!! out (c),0
LD BC,#F792 ; PPI port A in/C out 
OUT (C),C 
DEC B 
OUT (C),A ; Send KbdLine on reg 14 AY through ppi port A
LD B,#F4 ; Read ppi port A 
IN A,(C) ; e.g. AY R14 (AY port A) 
LD BC,#F782 ; PPI port A out / C out 
OUT (C),C 
DEC B ; Reset PPI Write 
OUT (C),D ; out (c),0

Register A now holds the value of requested keyboard row
Now check for the value from the table e.g. with''''bit x,A''''and a condition e.g.''''jp z,xxxx''''or''''call z,xxxx''''

Please note:

  • Bit = 0: Key is pressed
  • Bit = 1: Key is not pressed

Complete keyboard scanning routine

This routine scans the complete keyboard and writes all key status bits in a map.

keymap  ds 10  ;map with 10*8 = 80 key status bits (bit=0 key is pressed)

keyscan di              ;1 ##%%## C P C   VERSION ##%%##
        ld hl,keymap    ;3
        ld bc,#f782     ;3
        out (c),c       ;4
        ld bc,#f40e     ;3
        ld e,b          ;1
        out (c),c       ;4
        ld bc,#f6c0     ;3
        ld d,b          ;1
        out (c),c       ;4
        xor a           ;1
        out (c),a       ;4
        ld bc,#f792     ;3
        out (c),c       ;4
        ld a,#40        ;2
        ld c,d          ;1 (+42)
loop    ld b,d          ;1
        out (c),a       ;4 select line
        ld b,e          ;1
        ini             ;5 read bits and write into KEYMAP
        inc a           ;1
        inc c           ;1
        jr nz,loop      ;2/3 (9*16+1*15 = 159)
        ld bc,#f782     ;3
        out (c),c       ;4
        ei              ;1 (+8 = 209 microseconds)
        ret

Developing programs that use joystick

In the CPC world it is more common that a game supports both keyboard and digital joystick for those users who don't own joysticks. In addition, it is also nice if the keys could be redefined but that is not necessary.

The standard CPC can support 3 buttons per joystick, though many CPC joysticks only have 1 button.

The CPC+ and GX4000 only support 2 buttons per joystick, and the included Amstrad joypads have 2 buttons.

There are some common keyboard configurations used:

  • Joystick - This configuration is compatible with all Amstrad machines, even the GX4000 and you need to scan only one keyboard line (this means you can't be faster)
  • Cursor keys & SPACE - This configuration is often used and is great for the CPC6128 and Plus and playing using emulators. This is not good for CPC 464 and 664 (which have uncomfortably arranged cursor keys)
  • Q,A,O,P,SPACE - (Q up, A down, O left, P right, SPACE fire) This is a good solution, and it's a sort of standard (used by many games). It is best for english QWERTY keyboards, on french AZERTY it'd be A-Q-O-P (but because the decoding of the keys is done in software, normally by the OS, the bits in the keyboard matrix are actually the same).

The standard CPC has only 1 digital joystick port (and no analog joystick port). But it was possible to daisy chain the official Amstrad joysticks. And a common accessory, the joystick port doubler, offered 2 digital joystick ports.

The CPC+ and GX4000 have 2 digital joystick ports built-in (and 1 analog joystick port).

See Also