Revision History
January 15, 2017: Added info about existing similar work in the intro section
January 11, 2017: Added info about the first demo clip
January 8, 2017: Added section with reference material, including similar projects
January 4, 2017: Initial version

Author: Adam Podstawczyński. Feel free to use any materials in this tutorial, please send me an email if you find it useful :)

key64tapper – Commodore 64 Keyboard Emulator

This project emulates the keyboard of Commodore 64. It allows one to send a string of characters, or interactively type in characters, from a PC/Mac/Linux computer, and have it displayed on the C64 screen.

The project is just another take on microcontroller + crosspoint switch + keyboard combination. When I built it, I was convinced nobody had had that idea before, but when I announced it I was made aware that I was not the first! Similar project are listed in the Reference Material section.

How it Works

A Python script on the computer accepts text to type in various forms (e.g. interactively typed-in, from command line, redirected from other command). The script maps the text to keys or key combinations, and then as another step maps those to 6-bit binary codes. Then the codes are passed via the serial interface (here USB) to the Arduino microcontroller. A listening program on the Arduino accepts the codes and sends them as 6-bit addresses to the write-only memory of an 8x8 crosspoint switch (MT8808), along with 1-bit data. A 6-bit address + 1-bit data are equivalent to "a specific key on" or "a specific key off" command. The command is latched in the crosspoint switch using a strobe signal which results in a particular column pin being shorted with a particular row pin, i.e. effectively pressing a specific key on C64. In case of key combinations, 2 or more such address/data "words" are latched. The Restore key which is activated by connecting to ground needs a separate handling using a transistor.

Possible Uses

Features / Work in Progress


Pre-typed Text Passed as Command Line Option

(This is an older version without the Restore transistor. Also, I mistyped mt8808 as mt8088 in the clip.)

Interactive Mode


What You Need


Make the following connections. If you want to use different digital pins on the Arduino, remember to adjust the numbers in the code later.


The Python script and Arduino code are currently incomplete, and have been written quickly to prove the concept. Use at your risk and expect many issues: download from github. More solid version will need some time to complete -- stay tuned.

Reference Material

MT8808 Crosspoint Switch Datasheet
PETSCII chars and corresponding key combinations

Similar Projects

After completing the first working prototype and announcing it on the Lemon C64 forum, I was advised of similar projects undertaken in the past (see below). All of them, however, are meant for connecting a PS/2 keyboard to C64 (either directly or via Arduino). The idea behind the project described here is to give control over C64 keyboard to the computer which opens more possibilities.

Key/Pin/Signal Mapping

C64 KeyC64 PinsC64 Ports8088AY2AY1AY0AX2AX1AX0
DEL13 12PA0 PB0X0Y0000000
319 12PA1 PB0X1Y0000001
518 12PA2 PB0X2Y0000010
717 12PA3 PB0X3Y0000011
916 12PA4 PB0X4Y0000100
+15 12PA5 PB0X5Y0000101
£14 12PA6 PB0X6Y0000110
120 12PA7 PB0X7Y0000111
Return13 11PA0 PB1X0Y1001000
W19 11PA1 PB1X1Y1001001
R18 11PA2 PB1X2Y1001010
Y17 11PA3 PB1X3Y1001011
I16 11PA4 PB1X4Y1001100
P15 11PA5 PB1X5Y1001101
*14 11PA6 PB1X6Y1001110
<-20 11PA7 PB1X7Y1001111
_13 10PA0 PB2X0Y2010000
A19 10PA1 PB2X1Y2010001
D18 10PA2 PB2X2Y2010010
G17 10PA3 PB2X3Y2010011
J16 10PA4 PB2X4Y2010100
L15 10PA5 PB2X5Y2010101
;14 10PA6 PB2X6Y2010110
CTRL20 10PA7 PB2X7Y2010111
F719 5PA1 PB3X1Y3011000
418 5PA2 PB3X2Y3011001
617 5PA3 PB3X3Y3011010
816 5PA4 PB3X4Y3011011
015 5PA5 PB3X5Y3011100
-14 5PA6 PB3X6Y3011101
Home14 5PA6 PB3X6Y3011110
220 5PA7 PB3X7Y3011111
F113 8PA0 PB4X0Y4100000
Z19 8PA1 PB4X1Y4100001
C18 8PA2 PB4X2Y4100010
B17 8PA3 PB4X3Y4100011
M16 8PA4 PB4X4Y4100100
.15 8PA5 PB4X5Y4100101
Right Shift14 8PA6 PB4X6Y4100110
Space20 8PA7 PB4X7Y4100111
F313 7PA0 PB5X0Y5101000
S19 7PA1 PB5X1Y5101001
F18 7PA2 PB5X2Y5101010
H17 7PA3 PB5X3Y5101011
K16 7PA4 PB5X4Y5101100
:15 7PA5 PB5X5Y5101101
=14 7PA6 PB5X6Y5101110
Commodore20 7PA7 PB5X7Y5101111
F513 6PA0 PB6X0Y6110000
E19 6PA1 PB6X1Y6110001
T18 6PA2 PB6X2Y6110010
U17 6PA3 PB6X3Y6110011
O16 6PA4 PB6X4Y6110100
@15 6PA5 PB6X5Y6110101
_14 6PA6 PB6X6Y6110110
Q20 6PA7 PB6X7Y6110111
_13 9PA0 PB7X0Y7111000
Left Shift19 9PA1 PB7X1Y7111001
X18 9PA2 PB7X2Y7111010
V17 9PA3 PB7X3Y7111011
N16 9PA4 PB7X4Y7111100
,15 9PA5 PB7X5Y7111101
/14 9PA6 PB7X6Y7111110
Run/Stop20 9PA7 PB7X7Y7111111