This small side project started by buying a Diamond Lady pinball machine with a defective display. We had to find out why the display wasn't working.
Gottlieb, a pinball manufacturer active from 1927 to 1996, used the Rockwell 10941/10939 chipset in their System 80B pinball controllers for driving two 20 character, 16 segment displays. These chipsets consisted of one 10941 chip, responsible for driving the individual segments, and one or more 10939 chips for enabling any one of the characters (or grids).
The Rockwell 10941/10393 chipset is not manufactured any more. That, in combination with the still existing demand for these chips, causes the prices of these chips to be quite high. Just replacing all the chips on the display board would have been a waste of money.
Because of the price of the replacement chips, we first wanted to make sure the problem did not lie in an external component, like the power supply or MPU board. We first verified the voltages using a multimeter. The voltages should be as follows:
- +5V DC for logic components
- 32V AC rectified to -45V DC and -15V DC for the display
- 6.2V AC for the display filament voltage
All the voltages checked out, so it was time to look further. Another simple thing to do was replacing the 7417 Hex Buffer present on the display board. This buffer is located between the incoming data lines from the MPU and the Rockwell chips. This did not solve the problem either, so we had to verify the data coming from the MPU was not corrupted. This cannot be done with a simple multimeter as the signals change too fast for a multimeter to pick up. An alternative would have been a oscilloscope, but we do not (yet) own one.
The MPU does not run at a very high clock speed, so I thought it should be possible to read the data with an Arduino and output the data to a PC. For this we made a small adapter board on which we could plug in the existing display connector (Molex edge connector). From this board we led some wires to an Arduino Nano (based on the ATMEGA328 chip). We programmed the Nano to decode the commands normally send from the MPU board to the Rockwell 10941/10939 chipset, effectively emulating the receiving part of the chipset. The commands were then send to a computer via the standard Arduino serial connection.
Connecting the Arduino
Connecting the Arduino to the MPU board was very simple. Both systems are 5V based. The connector coming from the MPU board contains eight data lines and two LD lines, apart from +5V, common ground and the high voltages for the displays. We wired the Arduino as shown in this table:
|Connector pin number||Arduino pin number||Function|
|2||N.C.||6.2V AC Return|
|4||N.C.||32V AC Return|
|7||N.C.||+5V DC (VSS)|
|9||2 (interrupt, external 10KΩ pulldown resistor)||LD1|
|10||3 (interrupt, external 10KΩ pulldown resistor)||LD2|
|11||8 (I)||Data 0|
|19||Any Arduino ground pin||GND|
Operation of the chipset
The chipset receives its data via 8 parallel data lines. For each 10939 chip there is a LD line. When this LD line goes high, the corresponding 10939 chip will load any data present on the eight data lines into its Display Data Buffer. After loading in the data, the 10939 chip checks if the data is character data or a command. Commands are used for configuring the chipset and moving the cursor.
The chipset provides its own clocking and protocol for communication between the 10939 and the 10941 chips, and for driving the displays.
To capture the data sent by the MPU board I used interrupts to keep in sync with the data sent by the MPU. An interrupt gets triggered when something happens on a specific pin. This, for example, can be the pin going from ground (0V) to +5V.
To enable a pin on the Arduino to trigger an interrupt, call the
attachInterrupt() function like this:
// Attach interrupt attachInterrupt(digitalPinToInterrupt(pinNumber), interruptFunction, RISING);
attachInterrupt() function requires three parameters. The first one is the pin number of the pin which should trigger the interrupt. This pin number is not the actual pin number found printed on the Arduino board. Therefore the
digitalPinToInterrupt() function should be used to translate the Arduino pin number to the chips internal pin number. For more information about the Arduino interrupts, see the Arduino attachInterrupt() documentation. Note that ATMEGA328 based Arduino boards only have two interrupt pins available.
Unfortunately, the ATMEGA328 does not have eight GPIO pins available in one 8-bit register when you also want to use the USB serial connection (0 and 1) and the two interrupt pins (2 and 3). Therefore I had to use some bitwise operators to get a single byte out of two different registers while reading the 8 bits.
incomingData = (PINB & B00001111) | (PIND & B11110000);
(PINB & B00001111) part gets the last 4 bits from the PINB register (pin 8 to 11). The other bitwise and gets the first 4 bits from the PIND register (pin 4 to 7). The bitwise or operator joins both sets of 4 bits together into a single byte.
I read the values from the 8 data lines directly from the pin registers to omit the overhead of the
digitalRead() function. I did not test the performance of reading via
digitalRead(). Also, reading directly from the pin registers only took me three bitwise operators to create a full byte. Merging 8 individual bits into a single byte takes a lot more operations. All this is done during the interrupt.
The main loop checks if there is any new data available every iteration. When new data is available, this data is put in the display buffer. For debugging purposes, I discarded all the command codes while doing this. When the buffer is full, the contents of the buffer will be converted to ASCII characters and send to the PC via the serial connection. The character data corresponds to standard ASCII for the most part, except for some 16 segment specific characters. These characters are outputted as
This project and its code can also be used to mod your own pinball machine. The code can be altered to support other types of displays, like 16-segment LED displays. The data present in the display buffer should be translated in commands for any driver chip of choice, instead of writing characters to the serial connection.
The code I wrote for this project is freely available and can be found at my Github page. For more pinout diagrams visit PighiXXX (not mine). The full Rockwell 10939/10941 datasheet can be found here.