I reverse engineered the RC702 bios on the system I got from DIKU when they upgraded their computer terminal rooms in the early eighties to get keyboard and serial buffering (otherwise the 19.2k modem was too fast).
This is the various files I've found on the 8" floppies I still had around in 2021. It turned out that since I printed out the listing on 1993-04-19 I added LaTeX, Disk and ISO-8859-1 keyboard support labelled 1993-07-25 (most likely for QTERM modem communications to IMADA).
To get the utilities on MacOS, run
curl -O http://www.retroarchive.org/cpm/lang/MASM-80.ZIP
unzip MASM-80.ZIP '*.COM'
Manuals at http://www.jbox.dk/rc702/manuals.shtm and http://www.cpm.z80.de/manuals/zsid-m.pdf
I've used RunCPM (https://github.com/MockbaTheBorg/RunCPM) to run the build on my Mac. What took five minutes now takes 1-2 seconds.
To build inside CP/M (or an emulator), run
m80 =ccore/z/c
m80 =c/z/c
l80 ccore,c,c/n/y/e
cref80 =c
A m.sub file for compiling, linking and debugging:
m80 =$1
link $1
zsid $1.com $1.sym
Documentation:
- m80 - http://www.retroarchive.org/cpm/lang/MACRO-80.PDF
- l80 - http://www.retroarchive.org/cpm/lang/LINK-80.PDF
Note about CREF80 .CRF file:
- ^A marks start of "identifier defined on this line"
- ^B marks start of "identifier referred to on this line". They come in the same order as in the source.
- ^C rest of the line is a source line, copy it, and increment the line number.
so
dummy2: DW terminit+linelength-printbyte
becomes
^BDUMMY2^ATERMINIT^ALINELENGTH^APRINTBYTE^C E927 003E dummy2: DW terminit+linelength-printbyte
SUBMIT is a simple tool to submit multiple commands at once from a file.
From http://www.gaby.de/cpm/manuals/archive/cpm22htm/ch1.htm#Section_1.6.7:
Command line parameters are on the form $1..$9. $ is $$. Control characters are on the form ^X.
The `$$$.SUB´ file written contains one 128-byte record pr line in reverse order. Each record starts with a byte indicating the length of that command line, and the command line, and a ASCII zero. The rest is padding.
Work in progress:
(echo DIR A:; echo DIR B:; echo submit b) |perl -e 'print reverse <>' | perl -ne 's/[\r\n]//g; printf "%-128s", chr(length($_)).$_.chr(0)' > '../RunCPM/RunCPM/A/0/$$$.SUB'
A long while back I spent some time making 22DISK from Sydex read/write the CP/M 5¼ diskettes I had laying around.
The following definitions worked with version 1.40 of 22DISK:
BEGIN R702 Rc702 Piccolo - SSDD 48 tpi 5.25"
DENSITY MFM ,LOW
CYLINDERS 36
SIDES 2
SECTORS 9,512
SIDE1 0 1,3,5,7,9,2,4,6,8
SIDE2 1 1,3,5,7,9,2,4,6,8
BSH 4 BLM 15 EXM 1 DSM 135 DRM 127 AL0 0C0H AL1 0 SOFS 36
END
BEGIN LINE RC Piccoline - 5.25" DSHD
DENSITY MFM ,HIGH
CYLINDERS 77
SIDES 2
SECTORS 8,1024
SIDE1 0 1,2,3,4,5,6,7,8
SIDE2 1 1,2,3,4,5,6,7,8
ORDER SIDES
BSH 4 BLM 15 EXM 0 DSM 616 DRM 511 AL0 011111111b AL1 0 SOFS 32
END
For a serial connection to a Unix machine listening with a login prompt, a termcap entry is needed on the Unix machine. If the terminal is set to be "rc" the following entry works:
setenv TERMCAP "rc|rc700|Rc700 Piccolo Th 901219:co#80:li#25:am:bs:cl=^L:cm=^F%r%+ %+ :ho=^]:ce=^^:cd=^_:dl=^B:al=^A"
(found in my old .login file saved from back then).
Both SIO channels have hardware handshake enabled via WR3 Auto Enables (bit 5).
TERMINIT byte sequence: 18 04 44 03 E1 05 60 01 1B
| Register | Value | Meaning |
|---|---|---|
| WR0 | 18h | Channel reset |
| WR4 | 44h | 1 stop bit, no parity, x16 clock (8-N-1) |
| WR3 | E1h | 8 bits/char, Auto Enables ON, RX enable |
| WR5 | 60h | 8 bits/char, DTR=0, RTS=0, TX disable (initial) |
| WR1 | 1Bh | RX int all chars, TX int enable, Ext/Status int enable |
Auto Enables (WR3 bit 5 = 1) activates SIO hardware flow control:
- CTS gates the transmitter — SIO won't send unless remote asserts CTS
- DCD gates the receiver — SIO ignores incoming data unless DCD is asserted
When the port is activated (AuxGet/AuxOut), WR5 is dynamically set to
TermBits + DTR + RTS + XENABL = 60h + 80h + 02h + 08h = EAh,
asserting RTS and DTR and enabling the transmitter. The TX interrupt
handler (ATxBEmpty) resets TX pending after each character.
The 256-byte ring buffer (siosize equ 256 in CDEF.MAC) in the ARxChar
ISR provides receive buffering. Combined with Auto Enables, this gives
reliable modem communication at 19200 baud — CTS prevents TX overrun,
and the ring buffer prevents RX data loss between interrupt service.
PRINTINIT byte sequence: 18 02 10 04 44 03 60 05 60 01 1F
| Register | Value | Meaning |
|---|---|---|
| WR0 | 18h | Channel reset |
| WR2 | 10h | Interrupt vector |
| WR4 | 44h | 1 stop bit, no parity, x16 clock |
| WR3 | 60h | 7 bits/char, Auto Enables ON, RX disable |
| WR5 | 60h | 8 bits/char, DTR=0, RTS=0, TX disable (initial) |
| WR1 | 1Fh | Same as Ch.A + Status Affects Vector |
Channel B is output-only (RX disabled). Auto Enables is set but only the CTS→TX gating matters — the printer can pause output by de-asserting CTS. The List routine dynamically enables TX with DTR+RTS+XENABL per character, same pattern as Channel A.
The original RC BIOS (rcbios/src/INIPARMS.MAC) uses WR3=61h on Channel A — also with Auto Enables ON (bit 5=1). So the hardware handshake was always present in the SIO initialization. The key differences in this rewritten BIOS are:
- 8-N-1 (WR4=44h) instead of 7-E-1 (WR4=47h)
- 8-bit characters (WR3=E1h) instead of 7-bit (WR3=61h)
- 256-byte ring buffer (QUEUE ADT) instead of single-byte CHARA variable
- 32-byte keyboard buffer (
kbdsize equ 32) instead of flag-only KEYFLG
