The ’80s called. They want their autofire back.
It’s been a while, so I figured I’d try to bore some of you with some old computer stuff. Who knows, maybe someone will find this either useful or interesting 🙂
I rescued a bunch of old consoles and computers from my parents’ place last time I was over, among them a Spectrum +3 (yes, I know, it’s really an Amstrad…) with a bunch of 3″ disks, tapes, and a Cheetah 125+ joystick.

Cheetah 125+ joystick
The joystick needed some work doing, and while I was on with that I took a look at its autofire, which as far as I knew had never worked.
Joysticks of this age operated as a simple set of normally-open switches connecting a common line to each of the direction and trigger signals. There were a number of different wiring schemes, but the Cheetah boasted dual connectors for Kempston and Sinclair-compatible. This particular unit had lost its original connectors but was correctly wired (minus some broken wires) for the +3’s joystick ports.
Autofire circuits, then, had to sit inline with the trigger signal and toggle between high impedance and near-short – unless the computer system provided a logic supply. As the spectrum port didn’t, the 125+ used an astable multivibrator built out of a couple of transistors and some passives, with an on-off switch; this presented alternately high and low impedance to the port. However, tracing the circuit, it couldn’t possibly work with the Spectrum’s common-positive port. Presumably it was designed to work with interfaces where the common line was ground, and even after reversing the circuit’s terminals it was finnicky at best.
The Spectrum +2 and +3 joystick ports are just scanned in parallel with the top keyboard row – that meant it was easy to take joystick input in BASIC, but it meant the ports only received voltage briefly during the keyscan for that row.
Scoping out the keyscan timing is near-impossible because the row lines are driven off the memory address lines (not the Z80’s bus – another one on the other side of the ULA) – so as well as keyscan signals, you also see memory half-addresses on the lines. The design was a nice way to keep within the pin count of the ULA, but did make me feel a little ill.
With a vague idea of timing requirements (maybe up to a few MHz), I set out to design a more reliable autofire circuit. The built-in circuit oscillates in the kHz range, but I wanted something more “human” – say 20 triggers per second.
I did a bit of measuring on the port; all of the signals are pulled low by 680 ohm resistors, and they reliably switch at around 1.5k between common and each signal pin. With that in mind, I designed a circuit to scavenge power from all of the signals via 3.3k resistors (and diodes), allowing plenty of headroom, store this on a capacitor, and use that to supply a multivibrator a bit like the original. Then, the output of that switches a PNP transistor which is in series with the autofire switch and both in parallel with the triggers. The multivibrator just runs continuously.

Autofire circuit schematic in LTSpice
The design wasn’t too difficult, but I had a bit of an issue with the PNP not fully switching off at high scan frequencies – likely conducting via one of the capacitors – so I added an extra NPN as a buffer. I also had some fun constructing the circuit to fit in between existing case elements, and dealing with a dead short that I couldn’t see at all, even with a backlight, but which presented itself during debugging, and eventually went away simply by wiping between the tracks with an iron.
I did have to modify the internal board to put the autofire switch in a slightly different circuit position, but that was quite easy. The circuit it connected mostly by soldering onto the top of existing crimp terminals. If I’d had a bunch of ring crimps, I’d have used them instead. I needed to take off the switched-common from the internal board anyway, so I wasn’t too bothered soldering to things.
In the end, the result was pleasing, the stick works, and the original circuit is still there (in its original configuration). Because of the design, both circuits present as open when reverse-polarised, so this should be quite happy even in a common-negative port. It triggers somewhere in the low tens of Hz.

Cheetah 125+ with new autofire board fitted

Cheetah 125+ with components refitted
Something I was tempted by but couldn’t be bothered with in the end was to set the two base buttons as turbofire – this would connect across the autofire switch, such that the main triggers on the stick fire once, the base buttons fire continuously when held, and the autofire switch makes the unit fire continuously with no input. This would have meant making more changes to the board inside than I really wanted.