2022-05-05 Bit banging on a Tandy CoCo1

From Wikistix

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
120 458 &H1CA
300 180 &HBE
600 87 &H57 default at boot
1200 41 &H29
2400 18 &H12
4800 6 &H6 undocumented
9600 1 &H1 undocumented

Looking at an oscilloscope trace for 9600 baud operation from BASIC on a CoCo1, the waveform appears quite clean and nicely square:

CoCo1 9600 baud oscilloscope trace

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:

Instruction cycles
NOP 2
BRN xxx 3
LBRN xxx 5
EXG A,A 7

Using combinations of these, you can generally form loops of any cycle count.

So, let's go faster!

CoCo1 19200 baud oscilloscope trace

Right, that's 19200 baud, and everything still looks good. Maybe faster?

CoCo1 38400 baud oscilloscope trace

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:

CoCo1 57600 baud oscilloscope trace

See also