• Published on | Jul 21, 2013 | by FozzTexx

Making a Raspberry Pi into a unified retro peripheral

If you've been following along here or on Twitter or Google+ you've no doubt seen the experimenting I've been doing with interfacing a Raspberry Pi in various ways with several retro computers like the Atari 800 and Commodore 64. My first project was using the Raspberry Pi to act as a converter for a USB gamepad to turn it into an Atari 2600 style joystick.

After discovering Eric Nelson on Twitter and seeing all the games he was playing on the Commodore 64, I really wanted to try it myself. The first step though was finding a good game controller. Even though I grew up during the Atari 2600 era, I always hated those joysticks. Genuine Atari 2600 joysticks are absolutely awful, and the Sega Master and Genesis gamepads aren't a lot better. Modern gamepads are more responsive and comfortable, but they aren't going to talk to a Commodore or Atari. The first thing I needed to do if I was going to play old games was find a way to use a USB gamepad on these old computers.

After getting that to work (see my original article) the next thing on the list was dealing with the disk drives. I happen to have a big stack of Commodore 1541 floppy drives, but having to master real 5.25" disks and then sneakernet them around was just way too old school and tedious. After discovering that there was a program that would emulate Atari 800 disk drives and trying it out, it was clear that a floppy disk jukebox was the way to go.

All of the software that was written to allow modern computers to speak the Commodore IEC protocol either relied on DOS because they needed full control of the processor for timing issues, or used an external microcontroller to handle it. I felt that the Raspberry Pi should be able to do the IEC protocol directly without additional microcontrollers.

The best way to deal with the timing was to write a Linux Kernel Module which could handle interrupts when the IEC bus was signaling, and briefly disable interrupts to deal with the microsecond timing involved. The biggest setback was the documentation I found about the IEC protocol was wrong. Wrong in a lot of places. But I did get it figured out.

I've now got both the joystick conversion working and very simple file IO working over the IEC bus. The joystick support only works with one joystick and supports a single fire button. The CBM DOS emulation is limited to reading and writing .PRG files, it doesn't know anything about .d64 disk images. There's not even any directory listing or wildcard support.

I'm releasing it now though even though the functionality is somewhat limited. I think the kernel module source may be useful for people to look at to see how to handle GPIO interrupts on the Raspberry Pi. I also have a small gpio.h file which implements the GPIO basics all in macros, no functions.

The source code is being released as Open Source under GPL v2+, and it's available on github.

Join The Discussion

+1  Posted by Kevin Casteels • Mar.22.2016 at 20.14 • Reply

I would like to build the cable to hook up my Raspberry Pi to my c64 as a drive, but I'm not sure how to do so. I have a bi-directional level shifter (3.3V to 5V), so I've got that part covered, but I'm not sure about which GPIO pins to use for the IEC drive cable. Can you give me some help? Thanks!

+1  Posted by FozzTexx • Mar.22.2016 at 20.19 • Reply

The pin numbers are in the source to the driver.

+1  Posted by Kevin Casteels • Mar.23.2016 at 22.31 • Reply

Thanks! I found the pin assignments in the driver source. Can I change the GPIO pin assignment numbers? I'm using my Raspberry Pi to run my BBS (centronian.servebeer.com:6400) and I'm using the UART pins (6,8 and 10) for the RS232 connection to the C64. My goal is to also have the Pi act as the system drive.

+2  Posted by FozzTexx • Mar.23.2016 at 22.49 • Reply

It should be fine to choose other pins. The built-in UART is on pins 14 and 15 which is why I chose the pins I did becauseI use the UART with sio2pi to act as a disk drive for my Atari 800.

+1  Posted by Kevin Casteels • Mar.24.2016 at 18.43 • Reply

+1  Posted by FozzTexx • Mar.24.2016 at 18.59 • Reply

Yah there's 3 different pin numbering schemes for the Pi so it can be rather confusing.

+1  Posted by Kevin Casteels • Mar.24.2016 at 18.44 • Reply

+1  Posted by Kevin Casteels • Mar.24.2016 at 20.52 • Reply

OK, so I've cloned the repo and built complied the source. I also had to install wiringPi to get it to work, but it now compiles without errors. You say there is a userspace program and a kernel module. How is the kernel module installed? Maybe you could included some instructions on github about exactly how to install this software.

+1  Posted by FozzTexx • Mar.24.2016 at 21.21 • Reply

insmod iec.ko

+1  Posted by Kevin Casteels • Mar.24.2016 at 21.42 • Reply

Thanks, but that file hasn't been created after the build. I run 'make' in the main 'ninepin' directory. There is also a Makefile in 'ninepin/iec'. Do i need to build the module separately?

+1  Posted by FozzTexx • Mar.24.2016 at 22.39 • Reply

Yes you have to build the iec module in the iec folder.

+1  Posted by Kevin Casteels • Apr.14.2016 at 00.50 • Reply

I have been unable to install the kernel module on the latest Raspbian (kernel 4.1.20-v7+). Do you know how to get this working?

+1  Posted by FozzTexx • Apr.14.2016 at 02.02 • Reply

Unfortunately compiling the kernel module is one of the hardest things. Raspbian seems to go out of their way to make it harder than they need to. You can check this older blog post for some hints, but things may have changed since then.


+1  Posted by Alan • Apr.02.2016 at 16.19 • Reply

Hi, Chris. Do you know whether anyone has attempted to use a Pi to emulate the C64 tape datacorder? And if not, do you have any views on whether this would be more or less technically feasible than your brilliant 1541 project?

+1  Posted by FozzTexx • Apr.02.2016 at 17.04 • Reply

I haven't looked for any projects of interface a Pi to the cassette port so I don't know if anyone has done it. I doubt it would be very hard to do though, you'd just need some level shifting to connect the GPIO.