This document describes how the keyboard matrix is accessed on Amstrad CPC 464/6128 without the firmware. The two chips responsible for this are the Intel 8255 (PPI), and AY-3-8912 (PSG).


Intel 8255 (PPI), AY-3-8912 (PSG) and Keyboard Matrix Fig. 1 (source: Cpcwiki)

1 Intel 8255 (PPI)

8255 allows sharing the CPU bus with multiple I/O components. It has three 8-bit port registers, and a control register for setting the direction of these ports. For keyboard purposes, we are interested in Port A, Port C, and the control register.

Port A is connected to AY-3-8912's data pins. Port C's upper two bits are connected to AY-3-8912's control registers BDIR and BC1. These are outlined with a blue rectangle in Figure 1. Port C's lower 4 bits are connected to 74ls145 decoder, which then is connected to the keyboard matrix rows. Of the 4-bits, only from 0 to 10 are used for selecting the bit line. Keyboard columns are handled by the AY-3-8912. These are outlined with a green rectangle in Figure 1.

2 AY-3-8912 (PSG)

AY-3-8912 is a sound generator, but also contains two general purpose I/O port registers. One of the ports is connected to keyboard matrix columns. With the PPI's 10 bit lines, this allows sampling 10*8, 80 unique keys from the keyboard.

3 How Keyboard Matrix Bits Are Sampled

The main idea is to configure PPI and PSG so that we select the bit line we want to sample. This involves the following steps:

Set PPI's Port A and C as output:

ld     bc, #f782
out    (c), c

Select PSG's register 14 on Port A:

ld     bc, #f40e
out    (c), c

Latch PSG register:

ld     bc, #f6c0
out    (c), c
ld     bc, #f600
out    (c), c

Set PPI's Port A as input and C as output:

ld     bc, #f792
out    (c), c

Select the keyboard matrix row want to sample:

ld     bc, #f640
out    (c), c

Sample the value on Port A:

ld     b, #f4
in     a, (c)

This will have the first row of keyboard matrix in accumulator.

We can write a routine to sample all 10 rows into a buffer if necessary.

4 Keyboard Matrix

Bit Line
0 1 2 3 4 5 6 7 8 9
7f.f0Ctrl> ,< .SpaceVXZDel
6Enterf2` \? /MNBCCaps LockUnused
5f3f1Shift* :KJF / Joy 1 Fire 1DAJoy 0 Fire 1
4f6f5f4 + ;LHG / Joy 1 Fire 2STabJoy 0 Fire 2
3f9f8} ]PIYT / Joy 1 RightWQJoy 0 Right
2Cursor Downf7Return| @OUR / Joy 1 LeftEEscJoy 0 Left
1Cursor RightCopy{ [= -) 9' 7% 5 / Joy 1 Down# 3" 2Joy 0 Down
0Cursor UpCursor LeftClr£ ^_ 0( 8& 6 / Joy 1 Up$ 4! 1Joy 0 Up

Keyboard Scan Matrix (source:

5 Example

The below routine will check line 8, which contains ESC key.

keypres di
        ld      bc, #f782
        out     (c), c
        ld      bc, #f40e
        out     (c), c
        ld      bc, #f6c0
        out     (c), c
        ld      bc, #f600
        out     (c), c
        ld      bc, #f792
        out     (c), c
        ld      bc, #f648
        out     (c), c
        ld      b, #f4
        in      a, (c)

It can be used when firmware is not an option.