One machine that I haven’t gotten hold of until recently is the venerable C64, the machine that I cut my coding teeth on. I first discovered binary when I needed to learn how to design sprites for C64 games and I can probably attribute some of my success in my career to this incredible device and learning platform. At any rate, a good mate of mine recently emigrated and bequeathed his childhood C64 to me (big up to Mr +Craig Bettridge for that). Along with the C64 came his Datasette, 1541 drive and several boxes of disks. Unfortunately no tapes, and the 1541 drive seems to require significant restoration.
This left me with a C64 and nothing to load! Looking around the ‘net I found various solutions to this problem: The 1541 Ulitimate, SD2IEC etc. for disk emulation and the DC2N and devices similar to the Cassadapt for tape emulation. The 1541 Ultimate is an incredible piece of hardware but very expensive. Implementations of the SD2IEC also seem to be on the expensive side. The same goes for the tape emulators unless you look at the Cassadapt variety and those did not appeal. At this point I had decided to try and build something myself. Inspired by the Uno2Tap firmware, I wondered if I could move the PC part of that solution onto an MCU and create something standalone. My grand goal was to try to build my own fully functional (at least in terms of playback) tape emulator and so the Tapuino was born.
What I wanted to build was a full playback emulator, including motor signal handling, which would allow the user to choose a TAP file from an SD Card via an LCD and then interact with the C64 in a manner indistinguishable from a real Datasette. As I started this project I had the stated aim that I would try to build the device for under $20 and use common components that were easy for anyone to put together. With this in mind I went shopping on eBay and came up with this component list:
- Arduino Nano Clone $5.87
- MicroSD breakout board $1.96
- 16x2 LCD with I2C backpack $5.16
For a total of $12.99, not too shabby! Additionally I obtained the following bits and pieces:
- Opto-coupler: 4N25
- 5x 10K resistors
- 1x 330 Ohm resistor
- 4x tactile buttons
- Some jumper wire
I’ve written firmware for various MCUs including the ATMega328 and so had a basis to start from which included having a good idea of the capabilities of the chip and how to interface it with an SD Card and LCD display. For SD Card access I used the amazing PetitFatFs library from Chan, which I modified to support the current directory code from FatFS (PetitFS’ bigger brother).
As the LCD I chose came with an I2C backpack, interfacing to it was relatively easy and reduced the required pin count down to only 4 pins (which came in handy later on). An alternative would be to use a shift register circuit, but at the price, an I2C solution was a no-brainer.
The most expensive part to source was the Datasette connector, which cost over $7 in single quantities from the usual parts suppliers. As I had an existing Datasette at hand I chose to remove the cable and use this. I am still looking for an alternative and inexpensive solution.
|The Datasette Victim / Donor|
With the connector removed I proceeded to slap together some code from a previous bit of firmware I had written for an ATMega128 based MP3 player and got some filenames displaying on the LCD via the SD Card:
|First base firmware actually doing something|
Now that I had the basics in place I wired up the sense, read and ground lines from the Datasette connector to the Nano and got the sense line working. From here on out there was a huge amount of firmware hacking and slog to get a game loading. The first success was one of my favourites: Uridium, but while the game loaded flawlessly I couldn’t get anything else to load, specifically any Novaload games.
|First bitter / sweet success!|
With that problem solved (which incidentally had caused me to rewrite the interrupt handler part of the code three times whilst trying to find the bug!) I was onto a stable base. The firmware still required a serial port to issue commands to the Nano as I hadn’t wired in any buttons yet, but was good enough to demo to a few mates at work. The response was gratifying :)
|YEAH! Its finally working!|
The next port of call was to get the motor signalling working. I wanted to provide full emulation for fastloaders that stopped the motor during decrunching and for the usual pause when the first part of the tape loaded. This proved (and continues to prove) somewhat tricky. Firstly in terms of wiring details:
I hooked the motor line up to the Nano via a transistor switch. While this worked, current leaked via the transistor into the Nano causing the Nano to become powered via the input pin when the motor was on. This didn’t seem like a great idea so I switched to an opto-coupler which cleanly separated the signal from the Nano. Then came the headaches… The previously mentioned interrupt routine was altered to check the motor signal and exit if the motor was off. This worked… except for Rambo First Blood Part II. This game for some reason seems to switch the motor off before the TAP file is complete which in turn caused the main loading code to loop endlessly waiting for the TAP to complete (you get the picture). The current code has some rather “interesting” ways to mitigate this behaviour and I am not yet satisfied with the result. Unfortunately testing these outcomes is a rather laborious process when you take into consideration the length of a tape load.
Finally I threw together some button reading code, polished up the interface a bit and the standalone unit was finally ready!
The next steps are to build a nice housing using a project box and find an alternative connector for the C64 Datasette port. However, that said, the code is functional if not clean and I’d be interested to see if anyone else would like to give this a go.
Code can be found at https://github.com/sweetlilmre/tapuino on GitHub. Please feel free to send me a pull request if you have some suggestions on how to improve it. I would like to get to the stage where I can provide full instructions and a veroboard schematic so those less comfortable with the technical details can build one. Here is a Fritzing diagram of how I wired things up, I think its correct, but there may be errors :).
Stay tuned for further updates.