# Scanning the Keyboard and Joysticks

The keyboard and joysticks are scanned using the AY-3-8912 PSG and the 8255 PPI.

It is necessary that you understand how to use these before you continue to read this document.

The keys on the keyboard, and the joystick directions and buttons, are arranged in an 10 by 8 matrix. Each element of the matrix is a switch and represents the state of a key or a joystick button.

The matrix is read a column at a time, each column is read as a byte, and this holds the state of 8 switches.

When the matrix is read, a switch will be "0" or "1".

- If the switch is "0" then the key/joystick button corresponding to that bit is pressed,
- If the switch is "1" then the key/joystick button is not pressed,

Joystick 0 occupies it's own space in the matrix and is accessed at line 9. Joystick 1 shares line 6 with the keyboard. As a result, it is possible to simulate the state of joystick 1 by pressing the appropiate keys on the keyboard.

## The matrix

The position of each key/joystick button in the matrix is shown in the table below.

Bit | Line
--- | ---
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
7 | f. | f0 | Ctrl | > , | < . | Space | V | X | Z | Del
6 | Enter | f2 | ` \ | ? / | M | N | B | C | Caps Lock | Unused
5 | f3 | f1 | Shift | * : | K | J | F / Joy 1 Fire 1 | D | A | Joy 0 Fire 1
4 | f6 | f5 | f4 | + ; | L | H | G / Joy 1 Fire 2 | S | Tab | Joy 0 Fire 2
3 | f9 | f8 | } ] | P | I | Y | T / Joy 1 Right | W | Q | Joy 0 Right
2 | Cursor Down | f7 | Return | | @ | O | U | R / Joy 1 Left | E | Esc | Joy 0 Left
1 | Cursor Right | Copy | { [ | = - | ) 9 | ' 7 | % 5 / Joy 1 Down | # 3 | " 2 | Joy 0 Down
0 | Cursor Up | Cursor Left | Clr | £ ^ | _ 0 | ( 8 | & 6 / Joy 1 Up | $ 4 | ! 1 | Joy 0 Up

Note:

- Bit 6 on lines 9 and 6, may be used to report a third fire button on a joystick. This bit is also used as the middle button on an AMX compatible mouse.
- For CPC464 and CPC664 users: Those keys prefixed with an "f" are located on the numeric keypad.
- "f." is the "." key on the numeric keypad.
- For CPC464 and CPC664 users:
  - ENTER is the small ENTER key,
  - RETURN is the large ENTER key
- If matrix line 11-14 are selected, the byte is always &ff. After testing on a real CPC, it is found that these never change, they always return &FF.
- Watch out for KEYBOARD CLASH!

## Algorithm for reading the keyboard and joysticks

The matrix is connected to PSG I/O port A, and PPI Port C. (PSG Port A is accessed through PSG register 14).

Bits 3..0 of PPI Port C are used to define the matrix line to read. The data of the selected matrix line will be present at the inputs to PSG Port A.

The PSG is accessed through PPI Port A and PPI Port C. PPI port A is a databus. PPI Port C bit 7 and 6 are used to define the PSG access function:

PSG access function selection:

PPI Port C Bit | PSG Function | Notes
--- | --- | ---
7 | 6
0 | 0 | Inactive |
0 | 1 | Read from selected PSG register. | The data from the PSG register will be present at PPI port A.
1 | 0 | Write to selected PSG register. | The data at PPI port A defines the data to write to the PSG register.
1 | 1 | Select PSG register. | The data at PPI port A defines the PSG register index.

To read the keyboard and joystick is a long task.

The following sequence is required to read one or more matrix lines:

1. Write 14 to PPI Port A, (This is the index of the I/O Port A register of the PSG)
2. Select PSG operation: write register index, by setting bit 7="1" and bit 6="1" of PPI port C.

   (At this stage the PSG will have selected the register specified by the data at PPI Port A).

3. Select PSG operation: inactive, by setting bit 7="0" and bit 6="0" of PPI Port C.

   (This stage is required by the CPC+. If it is missing the scanning operation will fail)

4. Set Port A of the PPI to input (use PPI Control register),

   (At this stage it is possible to read from PSG register 14)

5. Write matrix line into bit 3-0 of PPI Port C.

   (At this stage the matrix line data will be presented to PSG register 14).

6. Select PSG operation: read register data, by setting bit 7="0 and bit 6="1" of PPI Port C.

   (At this stage the matrix line data will be presented to PPI port A)

7. Read matrix data from PPI port A.
8. If more lines are to be read go to step 5,
9. Set Port A of the PPI to output (use PPI Control register),

   (At this stage it is possible to write data to the PSG. This algorithm assumes that port A is in this state when it starts)

10. Select PSG operation: inactive, by setting bit 7="0" and bit 6="0" of PPI Port C.

    (This stage is required by the CPC+. If it is missing the scanning operation will fail)

Commented dissassembly of the system function to scan the keyboard and joysticks: [ highlighted | original ] h2>Keyboard clash

There is a problem with the matrix which is called "Keyboard clash".

If you press more than one key at the same time, another key (a "ghost" key), which has not been pressed, will often be reported. (The rules explaining when this problem occurs are shown below).

This problem is more obvious in two player games, because more buttons will be pressed together at the same time.

The solution is to choose a combination of keys/buttons which will not cause this problem when they are pressed together.

The problem will only occur in the following circumstances:

Using a coordinate system to identify a unique matrix line and bit within that line, (linex, bity), where x is a number between 0 and 10 and y is a number between 0 and 7, the following is observed:

1. if (linex1,bity1) is pressed AND (linex2,bity1) is pressed AND (linex2,bity2) is pressed THEN (linex1,bity2) will be reported as pressed.
2. OR: if (linex1,bity1) is pressed AND (linex1,bity2) is pressed AND (linex2,bity1) is pressed THEN (linex2,bity2) will be reported as pressed.
3. OR: if (linex1,bity1) is pressed AND (linex1,bity2) is pressed AND (linex2,bity2) is pressed THEN (linex2,bity1) will be reported as pressed.
4. OR: if (linex1,bity2) is pressed AND (linex2,bity1) is pressed AND (linex2,bity2) is pressed THEN (linex1,bity1) will be reported as pressed.

   e.g.

   - if C,W and N are pressed then Y is reported as pressed.
   - if K,J and Y are pressed then I is reported as pressed.

   If many keys are pressed then many "ghost" keys will be reported as pressed following the rules above.

   This problem occurs with any combination of keys/joystick buttons pressed in this way.

   Interestingly, keyboards on other computers also have keyboard clash, even some PC keyboards. In more modern computers, the keyboard is controlled by a special keyboard processor and this can detect "ghost" keys and prevent them from being reported.