ninepin: A utility to adapt computers of the past to modern times.
C Makefile C++
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


ninepin: A utility to adapt computers of the past to modern times.
Copyright 2013 by Chris Osborn <>

See COPYING file for detailed information on terms of copying.


Ninepin is about interfacing retro computers to modern peripherals. It
currently offers two features: converting a USB joystick so it can be
used as an Atari style 9-pin joystick (hence the name), and the
ability to emulate a disk drive.

The joystick interface will work with most any USB HID compliant
joystick and uses the GPIO to open/close switches to act as a simple
Atari 2600 joystick, which works on a variety of platforms, such as
the Commodore 64, Atari 2600, and Sega Master System. It currently
only maps the directional and a single button for player 1. Additional
chips are required to be connected to the GPIO. I'm using a couple of
CD4016 switches and a 74HC595 shift register.

In order to use the joystick interface, the program needs to be run as
root. If the program is not run as root the joystick routines will be
disabled, although the disk functionality will still work. Eventually I
plan to move the GPIO for handling the ninepin switching into another
kernel module.

The disk interface support works with the Commodore 64 IEC serial
bus. It is a combination of a user space program and kernel module
which implements the protocol on the Raspberry Pi using GPIO. The
signaling is implemented in a Linux Kernel Module in order to use
interrupts. There are only 2 places where interrupts are disabled
during processing. I had to use looping for delays since there was no
way to do microsecond delays in the kernel.

The driver supports both a 3 wire and a 5 wire interface, depending on
what kind of level shifters you have available (and how brave you
are). Switching between 3 wire and 5 wire currently requires
recompiling the module, it should probably be an option when doing the

If you are using the 3 pin mode, then the CLK and DATA pins are used
for both input and output. You can either use a bidirection 3.3V to 5V
level shifter, or do what I did and use some resistors to make a
voltage divider (see VoltageDivider.png). The voltage divider works
fine for me, but I only have the C64 and the Raspberry Pi on the
bus. Adding other devices could cause the voltage levels to increase
to more than the Raspberry Pi GPIO pins can tolerate. For each pin I'm
using a 1k and 1.5k resistor.

In 5 pin mode, 3 pins are used to read the signals, and 2 others are
used to send output. This allows the use of unidirectional level
shifters such as a 74HCT245 and CD4050.

The disk drive emulation works with directories and .d64 images. Files
in regular directories are automatically mapped to C64 file
types. Directories can be changed from the C64 side. It is also
possible to mount and unmount .d64 images from the C64. There is no
emulation of a real 1541 so fastloaders will not work.

To change directories:

  LOAD "/newpath",8

The leading slash will be ignored. The C64 will print an error but as
long as the directory exists the change directory will be successful.

To mount a .d64 disk image:

  LOAD "#filename.d64",8

The C64 will print an error but filename.d64 will be mounted
read only.

To unmount a .d64 disk image and use the native directory:

  LOAD "#",8


Future plans include adding more CBM DOS capabilities. I also want to
add supporting two joysticks and the ability to use the extra buttons
on a USB gamepad for changing settings. I want to support several
different platforms which used varying pot sizes (1Meg on the 2600,
500k on the C64, 150k on the Apple II, and 100k on the IBM PC), but so
far haven't found a suitable digital potentiometer. A 12-bit dual 1Meg
would be ideal.

Currently I'm using a 200k AD5282 which works fine for Apple II and
IBM PC joysticks, as well as any system that uses a voltage divider
such as the BBC Micro or TRS-80 Color Computer. Digital joystick mode
has also been tested on MSX, VIC-20, Commodore 64, Sega Master, Atari
2600, Commodore Amiga, Coleco Adam, and TI-99/4A.

Another joystick feature that is missing is the ability to swap
joystick 1 & 2 with a button on the USB gamepad. This seems like it
would be very useful on the C64 since some software uses port 1 and
some uses port 2. Being able to switch without unplugging cables would
be quite useful!