CoCo PS/2 Mouse Adapter
After breaking my CoCo 3 back out of its box and using it for awhile, I remembered how awful the orginal Color Computer Mouse was to use. You've heard the old saying "Necessity is the mother of invention"?? Well, for me, it was a necessity to replace the old one with something a bit more current...
Here's a picture of my original CoCo mouse
Now You Have an idea why I wanted to replace it! Here's a shot of the magical prototype that lets me do this!
FYI, its successor is a Microsoft Intellimouse that attaches to this PCB via a PS/2 mouse connector
Basic Theory of Operation
The CoCo PS/2 mouse adapter is basically modelled after its predecessor. It interfaces in exactly the same way as well(cassette port & rt. joystick port).
The basic idea behind the original is this. There were 2 RC timing circuits in the High-Res Joystick Adapter, one for the X-axis, and one for the Y-axis. These 2 timers have a common reset line, that is the cassout line of the casssette port. When the cassout line goes high, the 2 joyout lines of the high-res adapter go low. These 2 lines attach to the appropriate axis in the right joystick port. I should make special note that the orginal Color Computer Mouse was the "R" in those RC timing circuits. It had 2 potentiometers (pots) in it, one for each axis.
The timers operate in the following manner, the farther you are down a particular axis, the longer before that timer signal goes high.
We'll do a simple X-axis example: When you are at coordinate 0 of the x axis (left edge of screen) with the mouse, the timer line goes high almost immediately. When you are at coordinate 639 of the x axis (right edge of screen) with the mouse, the timer takes much longer before it goes high. From what I remember of my initial study of the adapter, it take approximately 1 ms for the timer to go off when at the far edge of the screen. This all, of course, applies to the Y-axis as well.
Of Mice and Code
Now that I had a basic understanding of how the joystick adapter worked, I needed to research the mouse. I found out there are MANY standards for mice operation, as well as mice data format! I picked the PS/2 format since in "my opinion" it is the closest thing to a true standard out there. Let me tell you, theres not a whole lot out there of any true substance on how to talk to a mouse! I found a few scattered notes on various web pages, and some decent info about mice data byte streams, but not much as far as control signals when talking to the mouse. My best find was a document on the Cypress Semiconductor website for one of their microcontrollers! It gave the basics of how to handshake the serial commands TO the mouse, and receive the position info we need FROM the mouse. I first prototyped the code in C on my PC talking out the parallel port to the mouse. Once I was able to establish communications, I rewrote the code in PIC assembler to achieve the same process.
Now to emulate this behavior!
Since I am the proud owner of a PICStart Plus microcontroller programmer (a gift from Christmas past), I naturally chose PIC parts! I initially started the design with 1 microcontroller, the PIC 16c505. It's, pretty much, the bottom of their line of microcontrollers. I chose this part for 2 main reasons.
Anytime you can get a 5 MIPS microcontroller for a little over a buck, its a good deal! One of the other nice things about this microcontroller is it has a built in 4 Mhz RC oscillator. With this it can generate its own clock with no external parts. I was figuring, at the time, the simpler the better. Anyway, to make a long story a bit shorter, I finished my first pass at the mouse adapter with 1 16c505. It worked but it was WAY too jittery. One of the drawbacks of this microcontroller is that it has no interrupts. This means that I have to poll the mouse for data, as well as poll the internal 8 bit timer, and do the math for my 16-bit software timer that I use to maintain the mouse Timing. Those little calculations would cause me to be late in tripping timers. This meant mouse cursor would pop about 10+ pixels in any direction in the "general vicinity" of where I was trying to be.
So, after taking a LONG break (most of the summer), I decided that TWO PICs would probably fix my problem! Part of the problem of the original design problem is that a large part of the time is spent waiting on the mouse. This is because the mice themselves actually generate the clock signal when sending mouse data. This means you have to wait for them to finish before you could check on your timers to see if the right amount of time had elapsed. The solution I chose was to split the mouse polling code and the timer code apart. The mouse polling code was on a 16c505 running with the built in RC timer, and the other PIC that handled the timers was running at 14MHz. After being dissatisfied with the first attempt, I decided to skip the RC timing for this one and go straight for the horsepower! This microcontroller can actually be run up to 20 MHz, and the circuit is designed such that most parts can be substituted pretty freely. For instance, if you had a 16MHz crystal, that would work just fine too. What ends up happening is that the timer gets a bit more precise, and theres a little less "over-run" on the right side of the screen. If you take it all the way to 20MHz, I'm not sure if you'll make the right side, the X-coordinate "lock" may be too narrow for that. Either way, if it can't make the edge, its a couple line code change!
The Final Solution
This final 2 PIC combo worked great! I had one PIC clocking in mouse data and maintaining mouse position, and one maintaining timers! The two microcontrollers communicate with each other serially. The mouse controller receives the data from the mouse, updates its internal set of "global" screen coordinates and holds that data, ready to be clocked, for the other PIC to receive at its leisure. This way the timers arent left to be a secondary issue.
In addition to just a simple solution, I threw in a couple of nice features. These are "sensitivity jumpers" in case your mouse pointer doesn't move across the screen fast enough for you, and a way to "tri-state" both the microcontrollers off the joystick and cassette ports, in case you wanted to make this an INTERNAL mouse adapter instead of external.
Show Me The Stuff!
Well, after learning a bit about old CoCo hardware and new mice, I have a bunch of drawings and source code to share. Please remember I release these on an AS-IS BASIS. There are NO WARRANTIES EXPRESSED, OR IMPLIED. Also please note that I am NOT RESPONSIBLE FOR ANY DAMAGE, DIRECTLY OR INDIRECTLY, AS RESULT OF USING WHAT IS FOUND HERE! These drawings, schematics and source are purely for educational and recreational purposes. With this in mind, here they are!
2 PIC assembler files:
mousetmr.asm - This is the sourcecode for the controller that handles all joystick port timing
mouse.asm - This is the sourcecode for the controller that reads in the mouse data and maintain global mouse pointer position.
schematic - Warning! This drawing is over 1400x1000 pixels! (And the version drawn is untested as of today!)