Adding Analog Support for the Apple II to ninepin
A week ago I was craving some Apple II gaming, but my experience of jittery flakey analog joysticks on the Apple II kind of deterred me. Joystick reading tends to be very sensitive on the Apple II and often the joystick would suddenly jump back and forth between reading up or down. You might be tempted to blame dirty potentiometers, but even back then when the joysticks were brand new this was a problem. The Apple II was originally designed to use paddles as the gaming interface, and uses a system of timing how long it takes to charge a capacitor. It works fine for paddles, but when using two potentiometers as a joystick it tends to be a little flakey. The problem is that when using pots for the joystick, the center of the stick can vary from one computer to another.
To try to work around that joysticks provided little tuning adjustments, but they never worked that well. You fiddle with the adjustment to get the joystick to seem centered, but the dead zone would often drift during play and the Apple II would suddenly see the joystick shift just enough that it would mess up your game. Some games tried to deal with the problem by having you go through a calibration screen before game play. When playing Lode Runner we got used to always having to keep the joystick at the top when moving because otherwise it was likely that you'd fall off horizontal bars when moving left or right.
On top of the problems with the analog joysticks I’m also so used to using d-pads and little thumb sticks I don't know how we ever used to game using those monstrous joysticks. It seemed to me that if I could control the inputs to the Apple II that I could eliminate the jitter, at least for 8 way games. There would be no chance that values could accidentally jump if I was setting them to exactly what I want from the Raspberry Pi.
In order to control the paddle input on the Apple II from the Raspberry Pi I decided to use an Analog Devices dual channel digital potentiometer . It uses an I2C interface which has a Linux kernel module. The device I used works with 3v3 logic levels so it wasn't necessary to mess with level shifting. After loading the kernel module and instantiating the device a file entry appears in /sys where you can simply write ASCII numbers to set the value you want.
To calibrate the controls I wrote a quick & dirty 4 line BASIC program to continuously display the paddle values on screen. I moved the thumb stick back and forth and kept adjusting the formula in ninepin until the full motion of the thumb stick mapped from 0 to 255 on the Apple II.
One problem I ran into was with the buttons on the Apple II. Instead of the button pulling the input to ground like most every other system, it connects to 5V instead. I tried using a CD4016 to control the switch but there was so much resistance in the CD4016 that the Apple II never saw a button press. I don't currently have any CD4066 so I'm not sure if the lower resistance will work with an Apple II or not. As a workaround I used a diode from the 74HC595 shift register directly into the Apple II button inputs.
With the full range of the potentiometers mapped and the buttons working I started trying out my old games. It worked great! Not only did 8 way games work perfectly, but I had smooth control in games that used the full range of the potentiometers. I was actually able to play quite a few paddle games with the thumbstick on my USB game pad, something I could never do with the Apple II joystick.
It’s amazing how much better games are with not only a comfortable controller, but with controls that do what you tell them! I was able to get to the 4th level in Miner 2049er without rage quitting, I didn't keep falling off the bars in Lode Runner, and rescue survivors without accidentally flying the wrong way. I found myself completely immersed in playing old favorites and many hours had passed without even realizing it.
I’m still working on the circuit layout and the software, with plans to make ninepin work on more computers that used analog joysticks. Stay tuned for updates!