The Amazing Mac Plus Mouse

This is a schematic for a device that pretends to be a mouse for a Macintosh Plus. It is NOT an ADB mouse, and it will not work on any Mac newer than a Plus.

PDF PS.gz gschem

[top] Why?

I was once a comptroller for Dabney House. We had an old Mac Plus, which we used for poetry, but no mouse. Hence, this device. It has four buttons for up, down, left, and right and a button for clicking, plus a knob to adjust the speed.

[top] How?

The thing that makes a mouse go is an optical encoder. It's basically a wheel with slots in it that rotates between an infrared LED and two light sensors. There are two of them so that the mouse can tell which direction the wheel is spinning. When you move the mouse, the ball turns the wheel and the light sensors generate two square waves that are 90 degrees out of phase.

In modern mice, there is a chip that converts the square waves into some complicated protocol so that the mouse can talk to the computer. In pre-ADB macs like the Plus, however, there is no such thing. The mouse simply sends the square waves from the optical encoders into the computer. One goes on the "interrupt" line, and one goes on the "quadrature" line.

The following diagram shows the signals that the mouse sends to the computer when it's moving at a constant velocity. I may have left and right mixed up.

            _______     _______     _______     _______
Interrupt:  |     |     |     |     |     |     |     |
            |     |_____|     |_____|     |_____|     |

               _______     _______     _______     ___
Quadrature:    |     |     |     |     |     |     |
 (left)     ___|     |_____|     |_____|     |_____|

            ____     _______     _______     _______
Quadrature:    |     |     |     |     |     |     |
 (right)       |_____|     |_____|     |_____|     |__

The interrupt line is called what it is called because an interrupt occurs whenever the line changes state. When there's an interrupt, the Mac checks the status of the quadrature input. What it does is summarized in the following table, which was yanked from this page, which contains another good explanation of this whole business.

Interrupt lineQuadrature lineMotion
Rising edgeLowLeft/Down
Rising edgeHighRight/Up
Falling edgeLowRight/up
Falling edgeHighLeft/Down

[top] The Circuit

Note: I used 74LS series chips because they're nicely multi-purpose and TTL compatible and I have a lot of them lying around. So when I say a part number starting with 74, I mean 74LS. For example, the "7474" that I talk about is a 74LS74. Another common family is 74HCT; these are TTL-compatible CMOS, so they use less power, but they're slightly slower. Also seen are 74HCxx (CMOS chips with the same pinouts as the 7400 series but non-TTL-compatible outputs), plain old 74xx, and less-common things like 74Sxx and 74Fxx. For this circuit it shouldn't matter what logic family you use; you can probably even substitute the 7400 series chips with their 4000 series equivalents. Note however that mixing TTL and CMOS chips without understanding the consequences is not good design practice and your mileage may vary; in particular, CMOS outputs may not be able to drive TTL inputs without some form of buffering. If you have no idea what I'm blathering about, see the Wikipedia article on logic families and also the articles on the 4000 and 7400 series.

But anyway, the circuit. Since both axes are the same, let's just talk about the horizontal axis for now.

Basically we need something to generate two square waves that are out of phase, and invert one of the square waves (which is equivalent to shifting it 180°) when we want to go the other way.

In the circuit, U1 is a 555 in the standard astable configuration. This generates a square wave. (The duty cycle isn't 50% in the configuration that I used, but it doesn't really matter). If you want to understand 555s, you should google the part number.

The output of the 555 is connected directly to the clock input of the first flip-flop on a 7474. It's also connected, through one of the inverters on a 7404, to the other flip-flop on the 7474. (I could have used a single NPN transistor, such as a 2N3094 or a 2N2222, instead of a 7404.)

The flip-flop works by putting whatever is at the input (D) pin (high or low) on the output (Q) pin on the rising edge of its clock signal. It also has an inverted output (Q\) pin; by connecting this to the input we can make the flip-flop toggle its output whenever it is clocked. This generates one of the square-wave signals to be fed to the Mac.

The other flip-flop's D pin is connected to the Q pin of the first flip-flop, which means that its state is the same as the state of the first flip-flop when it is clocked. However, the signal from the 555 goes through an inverter before going to the second flip-flop, so it transitions half a 555 cycle later than the first one. (This assumes the 555 generates a square wave with a 50% duty cycle; it doesn't, but we can pretend, since it doesn't really matter.)

Now we have two square waves that are out of phase. However, we can only move the pointer one way, which will get boring fast. We need to invert one of the signals (inverting is the same as shifting by 180 degrees) when we want to go the other way. It doesn't actually matter which one we pick, so let's just say we invert the quadrature signal. To do this, we use another chip, the 7486, which contains four XOR gates. An XOR gate has two inputs and one output, and its output is high only when the two inputs are different. One of the inputs on one XOR gate is connected to the signal we want to invert; the other is connected to one of the buttons. This inverts the signal only when the button is not pressed. Do you understand why?

Well, actually, it might help for me to explain exactly how the buttons work. A button is just a kind of switch; in this example, we use normally open momentary pushbuttons. That means that the switch is normally an open circuit, and when the button is pushed the terminals are connected. The button is set up so that when you push it, it connects the input of the 7486 to ground. When you don't push it, the input is "pulled high" by a resistor connected to Vcc, which is called, fittingly, a pull-up resistor. Pull-ups work because the input draws very little current, so the voltage drop across the resistor is negligible.

Now we have a mouse that can go both ways, but we don't have any way to make it not move when nobody is pressing any buttons. We do this by connecting both buttons to the inputs of another XOR gate. The output is connected to the CLR\ signal for the first flip-flop. When the PRE\ signal is high (which it is, because it is connected directly to Vcc, the CLR\ signal works like an enable: if CLR\ is low, the flip-flop's output is always low instead of flipping and flopping. The result is that unless exactly one button is pressed the flip-flops don't go and the mouse doesn't move.

We can use the same clock and inverted clock signals for the other axis, which works in the same manner as the first.

All that's left is the mouse button. This is easy; we just use a pull-up resistor to pull the button line high normally and have a switch to pull it to ground, just like we did for the inputs to the XOR gates. The firmware on the mac is slow enough that no debouncing is needed. (When a switch is pushed, the connection is unreliable for a fraction of a second before it settles down. Electronics connected directly to the switch can interpret this as several pushes instead of just one. This phenomenon is known as "bounce," and getting rid of it is debouncing.)

The pinout for the Mac Plus mouse connector is here. I'll reproduce it below in case that link dies.

1   Chassis ground
2   Vcc (+5V DC)
3   Signal ground
4   X2 ("quadrature" signal for X axis)
5   X1 ("interrupt" signal for X axis)
6   no connect
7   Mouse button
8   Y2 ("quadrature" signal for Y axis)
9   Y1 ("interrupt" signal for Y axis)

According to that page, this mouse should also work for the Macintosh 128K, 512K, and 512K Enhanced.

Creative Commons License All content licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License, unless otherwise noted.
Hosted by UGCS