We have emulated the Fuller Joystick interface correctly, haven't we?
05/12/2025
05/12/2025
Back in 2024, I was investigating all the different joystick configurations that were possible. I tried a number of games, but I found that quite a lot of them didn't work with my Fuller emulation.
Interestingly, some games were just plain broken but some expected the joystick bits to be "active low" (0 = pressed), while I had implemented it "active high" (1 = pressed).
I decided to test a real Fuller Box... The interface was "active low", so my emulation was wrong. So... why did it work with some games and why were so many games "broken"?
A little bit about the Fuller Joystick
Fuller released their interfaces quite early in the Spectrum era, 1983-1984, and they're clearly shaped to fit the original rubber-keyed models.
The Fuller Box contained a joystick port, an AY-3-8912 chip (years before the Spectrum 128K existed, so it uses different I/O ports and a slightly different clock speed), a speaker (with adjustable volume) to output everything (including amplifying the internal speaker), and an expansion port on the back (to connect other interfaces).
The Fuller Orator contained a joystick port, an SP0256-AL2 speech synthesis chip, and a speaker to output everything (including amplifying the internal speaker), and an expansion port on the back (to connect other interfaces).
The Fuller Master Unit contained all of the above, in a single interface.
Unusually, the interfaces have a power socket and ear/mic sockets on the back. It passes power and the cassette signals through the expansion bus, so nothing is plugged into those Spectrum sockets (and the shape of the interface actually blocks any possibility of connecting anything to those sockets).
That sounds good...
In some respects it's better than the ZX Interface 2, particularly with respect to sound. It was an impressive upgrade for 1983.
But those audio outputs were not particularly well supported, only a handful of games used them. Games like Andy Capp, Bosconian '87, Invasion of the Body Snatchas, Mega Apocalypse, Motos, Plum Duff, Ultimate Combat Mission, and Vixen support the AY chip. (Mostly later games that supported the ZX Spectrum 128K's AY sound chip, but could also send the same data to the Fuller I/O ports). Chuckie Egg is one of very few titles that supported the speech chip.
However, the joystick part of the interface did receive some support. Not a great deal (perhaps 100 titles), but it's clearly the number 4 ZX Spectrum joystick (after Kempston, Interface 2, and Cursor, which are supported by thousands of titles). All other interfaces drop to single-figure levels of support.
Support for the Fuller joystick goes from 1983-1991, with the last (working) commercial title possibly being Super Monaco GP (1991). It's an impressively long time period, supporting a less-common joystick interface made by a company that folded in 1984, with Nordic Keyboards selling the last of Fuller's leftover stock from December 1984 into 1985.
The joystick may be read from I/O port $7F, with the format F111RLDU (active low) (bit 7 = F, bit 0 = U). Note, that if you read this port while the interface is not present, then you might read the floating bus and receive variable results, so it's a good idea to read it during the vertical blank, unless you are certain that it is present.
So you fixed the emulation then?
I fixed the emulation, and checked it. Everything was now working as it should. Except... it wasn't. A lot of games still did not work. They did not work on other emulators, or even the original hardware!
I decided to investigate and I found a number of games from 1985-1991 that used the same (or very similar code) to read the Fuller Joystick, incorrectly.
These games were often linked to Quicksilva, Binary Design and, later, Big Red Software.
Let's start with Death Wake (Quicksilva/Binary Design, 1985):
36749 LD B,016 36751 IN A,(127) ; F111RLDU 36753 CPL ; F000RLDU 36754 RLCA ; 000RLDUF 36755 RL B 36757 RRCA ; F000RLDU 36758 RRCA ; 1st -> UF000RLD -> 2nd -> DUF000RL -> 3rd -> LDUF000R 36759 RL B 36761 JR NC,36758 ; Three loops before Cf is set. 36763 AND 031 36765 LD C,A ; A should be 000FUDLR (active high) 36766 RET
This routine is returning LDUF000R (active high) instead of 000FUDLR (active high), so only Fire and Right can work. Note that the C register is being set, but is discarded immediately.
The same code is in Lightfarce (hidden inside Zub 128) (Mastertronic/Binary Design, 1986), Zarjas (Binary Design, 1988), and Vectorball (Mastertronic/Binary Design).
Then we move on to Double Dragon (Mastertronic/Binary Design, 1988):
57722 LD B,016 57724 IN A,(127) ; F111RLDU 57726 CPL ; F000RLDU 57727 RLCA ; 000RLDUF 57728 RL B 57730 RRCA ; F000RLDU 57731 RRCA ; 1st -> UF000RLD -> 2nd -> DUF000RL -> 3rd -> LDUF000R 57732 RL B 57734 JR NC,57731 ; Three loops before Cf is set. 57736 AND 031 57738 OR C ; A should be 000FUDLR (active high) 57739 RET
The same code is in Double Dragon 2 (Virgin Mastertronic/Binary Design, 1989), Shinobi (Virgin Games/Sales Curve/Binary Design, 1989), and Raster Runner (Mastertronic/Big Red Software, 1990). The C register is now being ORed with the A register, but it has no effect whatsoever.
Then we move on to Hard Drivin' (Domark/Binary Design, 1989):
65155 LD B,016 65157 IN A,(127) ; F111RLDU 65159 CPL ; F000RLDU 65160 RLCA ; 000RLDUF 65161 RL B 65163 RRCA ; F000RLDU 65164 RRCA ; 1st -> UF000RLD -> 2nd -> DUF000RL -> 3rd -> LDUF000R 65165 RL B 65167 JR NC,65164 ; Three loops before Cf is set. 65169 RET
The same code is in New York Warriors (Virgin Games/Big Red Software, 1989), Wacky Darts (Codemasters/Big Red Software, 1991), Kamikaze (Codemasters/Big Red Software, 1991), Panic Dizzy (Codemasters/Big Red Software, 1991). Finally, the unused C register is being left alone.
Which leads us to...
Max Headroom and the mystery of the "Don't Know" joystick
The imposing Network 23 building towers over the city, everything else made insignificant by comparison
Ah, Max Headroom, he was so big in the 80s. The depiction of a corporate, high-tech, dystopian future was very much in vogue, but it turned out to be completely inaccurate. I mean, a world where you do nothing but consume media that's filled with millions of tiny adverts? What could be further from our reality!
Anyway...
I bought Max Headroom in late 1986 or early 1987, I think it was from Littlewoods (there were so many places on the high street to buy games in the mid-80s). It's a fairly easy game, and it was one of the earliest games (with a proper ending) that I ever finished. (The first game I ever finished might have been Alchemist).
There was one thing that I was always curious about...
How strange!
Max Headroom (Quicksilva/Binary Design, 1986) offers all the usual control options of a ZX Spectrum game from that time. Keyboard, Define keys, Kempston, Interface 2, Cursor, and Don't Know. Huh..? "Don't Know"?
Hmm... Is this an option that detects which kind of joystick interface you have? Nope. It doesn't respond to the fire button of any of the Keyboard, Kempston, Interface 2, or Cursor controls. So what is it?
Let's take a look at the "Don't Know" routine:
30597 LD B,016 30599 IN A,(127) ; F111RLDU 30601 CPL ; F000RLDU 30602 RLCA ; 000RLDUF 30603 RL B 30605 RRCA ; F000RLDU 30606 RRCA ; 1st -> UF000RLD -> 2nd -> DUF000RL -> 3rd -> LDUF000R 30607 RL B 30609 JR NC,30606 ; Three loops before Cf is set. 30611 AND 031 30613 LD C,A ; A and C should be 000FUDLR (active high), at this point, but they're not. They're LDUF000R (active high) 30614 RET
I think you recognise it by now! It's the same broken Fuller routine from Death Wake! Fire and Right work, but Up, Down, and Left are always zero. You can get into the game, but do little else.
So where does this routine come from? The earliest example I could find was in Commando (1985).
The joystick options. Keyboard and define keys are there, just not in this menu
It's difficult to tell the exact release date of Commando and Death Wake (both 1985). Commando seems to be slightly before Death Wake, based on magazine references. Both were probably released in late 1985, then Commando was reviewed in January-February 1986, while Death Wake was reviewed in February-March 1986.
Let's look at Commando's Fuller routine:
30074 LD B,016 30076 IN A,(127) ; F111RLDU 30078 RLCA ; 111RLDUF 30079 RRCA ; 1st F111RLDU -> 2nd UF111RLD -> 3rd DUF111RL -> 4th LDUF111R 30080 RL B 30082 JR NC,30079 ; Loop 4 times until Cf is set 30084 CPL 30085 LD C,A ; LDUF000R ??? (should be 000FUDLR) 30086 RET
My, that looks rather familiar.
Commando has a neat routine with a jump table, which converts multiple forms of input into the A register, in the 000FUDLR (active high) format that a Kempston joystick would normally return, thus simplifying in-game controls considerably. It also uses the C register to figure out whether the fire button is held down, so that it can launch a grenade.
This explains why the C register is being needlessly set in the other games, even though they don't have this feature!
Perhaps the routines all have an earlier, common source, but it does look like the broken code in all those other games paid homage to the broken code from Commando.
Since so many Binary Design games use this bit of code, I suspect it was "house" code that was introduced into the codebase at some point, then used by anyone working on a game. Since the joystick is listed as "Don't Know" and includes the unnecessary use of the C register, it seems that none of the programmers of Max Headroom had written that piece of code or knew what it was supposed to do.
(I'm not wishing to accuse anyone of anything, the world is an unpleasant enough place as it is).
Umm... Are you sure?
The ZX Spectrum conversion of Commando is credited to Keith Burkhill and Nigel Alderton. Given that Nigel Alderton is solely credited for Kong Strikes Back (1985), and that uses a completely different joystick routine (with Fuller support that doesn't work because it only accepts active high input), I will guess that the Commando routine was written by Keith Burkhill.
This form of "Broken/Don't Know" Fuller is probably the 5th most supported ZX Spectrum joystick type, having at least 15 different games!
Although, to be fair, I have to add that Binary Design were far from alone in producing games with broken Fuller joystick support (and at least Binary Design did support the Fuller AY chip in some of their later games).
Ah Diddums (early version), Kong Strikes Back, Mantronix, Incredible Shrinking Fireman, Cagara, (and who knows how many more) are all broken in some way. Sometimes there are bits swapped round, sometimes there's missing checks for the fire button, sometimes there isn't any code there at all! Basically, a lack of testing.
(At some point I will put a link here to some fixes...)
So what is wrong with it?
The problem with the Fuller section of the code is that it rotates the A register into the B register (to reverse the bit order of RLDUF), but then doesn't use the value in the B register for anything! The Commando version is one loop short of completing the B register, which the other games try to fix by adding additional rotate instructions.
Perhaps it was a bit harder to test because Fuller had already gone out of business by 1984 and the Fuller Box is a bit fiddly. You need to unscrew the case in order to feed the aerial wire through it, so you can't just connect and disconnect it simply when testing.
This is probably what the code should've been:
30074 LD C,008 30076 IN A,(127) ; F111RLDU 30078 CPL ; F000RLDU 30079 RLCA ; 000RLDUF 30080 RRCA ; 1st F000RLDU -> 2nd UF000RLD -> 3rd DUF000RL -> 4th LDUF000R -> 5th RLDUF000 30081 RL C ; Reverse the order of the five bits in A and put into C 30083 JR NC,30080 ; Loop 5 times until Cf is set 30085 LD A,C ; A and C are now 000FUDLR (active high) 30086 RET
Basically, a 17 byte fix that can be applied to the correct address in each of the games using this routine (30597 for Max Headroom).
014, 008, 219, 127, 047, 007 015, 203, 017, 048, 251, 121 201
But Max requires one more fix before we can, truly, say that he has been rescued from the Network 23 building...
We need to change "3..Don't Know" to "3..Fuller ", which can be achieved by changing these 10 bytes.
28639 070, 117, 108, 108, 101, 114 28645 032, 032, 032, 032
Now you can play the game (with Fuller joystick) and get that little control menu ditty stuck in your head.
Do know!
Just one more question...
But that still hasn't answered the question as to why my "active high" emulation was working for some games...
Here is the Fuller joystick routine from Quondam (Ocean/Denton Designs, 1989, but clearly written closer to the Imagine era):
44573 LD BC,00127 44576 IN A,(C) ; F111RLDU 44578 LD BC,00000 44581 BIT 4,A 44583 JR Z,44586 ; If bit 4 is 1, then it's active low - complement all the bits! 44585 CPL 44586 RRA ; U 44587 JR NC,44591 44589 LD C,001 44591 RRA ; D 44592 JR NC,44596 44594 LD C,002 44596 RRA ; L 44597 JR NC,44601 44599 LD B,003 44601 RRA ; R 44602 JR NC,44606 44604 LD B,006 44606 AND 008 ; F 44608 JR Z,44612 44610 LD A,009 ; A can be 0 or 9, depending on the F bit. 44612 ADD A,B ; B can be 0, 3, or 6, depending on the LR bits. 44613 ADD A,C ; C can be 0, 1, or 2, depending on the UD bits. 44614 RET ; A is 0 (no direction) or 1-8 (direction) without fire. A is 9-17 with fire.
Incredibly, it detects whether the interface is active high or active low by checking bit 4 and it supports both possibilities!
Similar routines were used in most Imagine and Denton Designs games (the routine was possibly written by John Gibson).
Imagine and Fuller did have links. Both were Merseyside-based and Imagine games were amongst the earliest to support their interfaces. Did Imagine have access to some early prototype hardware that was active high and wrote a routine that could support both it and the later version of the hardware? Additionally, Kong Strikes Back (Ocean, 1984) will only work with an active high interface.
Were early versions of the Fuller interface released to the public and are still out there? It is a mystery.
(C) Jane McKay, 2025