Friday, 10 January 2014

Joysticks'n'stuff

I have dismantled a Cheetah joystick interface circuit board for the ZX Spectrum. This is pretty much identical to the original Kempston joystick interface, which allows Atari-style joysticks. Better yet, it only has one joystick port with no additions. (Some interfaces have loudspeakers and multiple joystick ports.)


The interface is stuck directly to the ZX Spectrum edge connector. The Kempston joystick can be read from Basic via the IN 31 function. The joystick needs five bits to deliver the status of each direction and the fire button. When used in BASIC, the IN 31 defaults to 0, which does not necessarily tell much of how the port works electronically. (I think in z80 Assembler this is achieved with IN A,#31) These things in mind, I started looking inside the interface.


Contents:
  • 1 x 74LS138N chip = 3-line to 8-line decoder / De - Multiplexer
  • 1 x 74LS366AN chip = Hex Bus Driver
  • 5 x 10000R resistors
  • 1 x 0R resistor
  • 2 x diodes (1N4148 seems to be it)
  • 44-pin edge connector
  • 9-pin (joystick) connector
I then searched for datasheets for the two chips to complete the picture. I combined the overall information to one (messy) whole, so that I don't have to refer to different documents to make sense of the interface. The logical diagrams of the chips are overlaid to the pins, and all the edge connector pins are named. The names for the edge pins are taken from here.

Click to make bigger.

The picture can be a bit confusing as the chips are pictured from "below", as they are obviously on the other side of the board. I wanted to portray the Cheetah circuit as it appears, and show the pin order as it is from the outside the ZX Spectrum.

For clarity, I've coloured the various lines, red for +5 and blue for ground. The green indicates the interrupt pins at the Spectrum end whereas the black are used for the address and data pins.The yellow refers to the joystick connections. It's quite simple to track how the chips are powered and how the joystick pins relate to the chips.

I've also tested the individual chip functionality on a breadboard, connecting their output to a LED and triggered the inputs manually and with an Arduino just to make sure I've understood how they work. As the HIGH/LOW signals get reversed within the logic in a few places, picturing the whole can become a bit confusing.

The five 10K resistors to the left act as pull-up resistors for each of the joystick directions/fire. The 0 resistor is, I think, simply a way to go over a few circuit paths. I suppose it could be changed to a jumper wire. The diodes apparently keep the non-relevant data pins unambiguously "off". The D5 line might also be made this way, but the makers opted to connect it to the chip.

The chips

The CPU basically has to tell the interface when it is appropriate to bring the joystick status back to the computer via the data lines. Otherwise the CPU could be messed with, as the same address and data lines are needed for its other operation. Catching the "good moment" is achieved with the chip on the left, which takes the interrupt pins and three address lines as inputs. The chip on the right is connected to the data lines and uses the information from the other chip to enable or cut off the joystick status.

The 74LS138 pins and truth table. Only Y0 is used as output in the Cheetah adapter.
Looking at the 74LS138N chip, it has 8 outputs and six inputs. The datasheet gives a truth table showing that only one of the 8 outputs can be LOW at a time, whereas the rest are always HIGH. Now, as only one of the outputs is used, it is enough to check the input combinations that are relevant for that pin.

The truth table says that G1 has to be HIGH and the rest of the inputs LOW to achieve LOW output on the y0 pin. If any of the input statuses are otherwise, the output will be HIGH.

So, looking from the edge connector, !M1 has to be HIGH, whereas all others, A5, A6, A7, !IORG and !RD at the Spectrum end have to be LOW, for this chip to output the LOW signal that "lets through" the joystick status.

The bus driver chip. The E1 and E2 are both connected to the Y0 output of the other chip, and control the output of all the gates.
The single output is connected from both sides to an AND gate within the bus driver chip. The (reversed) AND gate controls whether the chip outputs are active. Only if both inputs are LOW then the gates are operational. The outputs of the bus driver are tri-state, they can be "off", HIGH or LOW. The gates also reverse the signal, if the input is LOW the output will be HIGH and vice versa.

The interface's main purpose, apart from channeling the joystick states to IN 31, is to "chop" the joystick pin connection signals and make the information available to the CPU port at the proper moment. Funnily enough, the joystick status can be read from any port including 31 and below. It's just that if the bits 5-7 of the port number are high, a value will not be read.

Additional notes

I did not include everything in my above image. Of course, a more complete picture would also show the connections within the Spectrum. The picture below shows the Z80 CPU and the pins that are used in the Cheetah (Kempston) interface.
The relevant pins at the Z80 CPU. 

So, I learned a bit about how the joystick interface works, and how this simple peripheral works. A couple of logic chips seem clearer to me now, too. Far more could be done to understand the interrupt timing from the CPU end and visualise the process of the whole thing.

Thanks for Marq for insights. Clever people are welcome to give better explanations, as long as they are understandable to the layman :)

No comments:

Post a Comment