2022-05-05 Bit banging on a Tandy CoCo1
Like many personal computers of its age, the Tandy Color Computer (CoCo) didn't have any dedicated hardware drivers for its built in RS-232C serial port, and relied on so called software bit banging. What is bit banging? Instead of relying on a hardware driver to drive the voltage on the physical lines with the appropriate timing, software directly manipulates the line state, high or low, and relies on carefully coded software timing loops for the bit transitions. In the case of the CoCo, bit 1 of PIA1 at address &HFF20 directly controls the RS-232C transmit line.
Timing in BASIC
The serial output routine in BASIC uses a 16-bit big-endian value stored at 149,150 (&H95,&H96) to control the BASIC ROM serial output timing loop, and hence the serial port speed. Several values are documented in the manuals, and some searching or experimentation uncovers more:
|bps||16-bit value decimal||hexadecimal||notes|
|600||87||&H57||default at boot|
Looking at an oscilloscope trace for 9600 baud operation from BASIC on a CoCo1, the waveform appears quite clean and nicely square:
Can we go faster than 9600 baud? Sure!
Using custom assembly
Writing our own m6809 assembly we can beat 9600 baud. Interestingly, it's not the processor that limits the speed for the CoCo1, as we'll see.
When writing assembly, the cycle count of each instruction must be determined, and the length of any loop precisely controlled to set the desired bit rate. In writing my own routines, I found myself needing precise delays, and found quickly that NOP isn't the only do-nothing instruction of use for padding out delays. Indeed, you can use several instructions:
Using combinations of these, you can generally form loops of any cycle count.
So, let's go faster!
Right, that's 19200 baud, and everything still looks good. Maybe faster?
Well, 38400 baud is starting to look a bit rough. The rise time of a pulse is now shorter than the bit duration (about 26µs at 38400 bps). The RS-232 decoder in the oscilloscope is still managing to figure things out.
And, yes, we can even attempt 57600 bps, at which point the oscilloscope gives up: