PETTERM is a terminal emulator program for the Commodore PET/CBM series computers. It provides a 40x25 terminal with limited ANSI support over a bit-banged serial interface. It is capable of running on all versions of BASIC, including BASIC 1 released on the earliest of PET 2001's. As well it only requires 4kB of RAM.
PETTERM was initially developed over the course of less than a week to it's first working public release – 0.2.2. It is written entirely in 6502 assembly, save for a one line stub BASIC loader incorporated into the assembly source. This loader simply consists of a SYS statement that jumps from BASIC into the machine code.
The only external connections the software requires is for TTL level (0-5v) serial:
- Rx(to the PET) to be connected to pin C of the user port
- Tx(from the PET) to be connected to pin M of the user port
- Ground at either pin 1, 12, A, or N of the user port.
This set of connections appear to be the most common set-up for bit-banged RS-232 interfaces for Commodore computers. Though on others you may find a connection between B and C, this will also work just fine as my software ignores B.
The software does not use hardware flow control, and software flow control is not supported at the moment. Thus the above connections are all that are required &mdash making this a very quick to set-up and test terminal program compared to others that may require external inverters or gates.
The main component of the software is it's bit-banged RS-232 serial routines. I developed a transmit and recieve routine that are sampled at three times the desired baud rate. The reasoning for this three times sampling is so that no matter where we detect the start bit, then we can start sampling subsequent bits in the middle ⅓rd of the bit. This improves tollerence of recieve speed fluctuations. This methodology was learned from a 1995 website by Eric Smith – Notes on bit-banging async serial.
As I do not have access to a Commodore PET series computer, the serial bit-bang routines were generously tested by Paul Rickards over Twitter. Thanks to his help I was able to find some timing issues and eventually find the problem that I had initially assumed that the STOP bit in RS-232 was a zero instead of a one.
Both the Rx and Tx routines are implemented as simple state machines to determine what type of bit they are looking for. As well they use counters to determine the next sampling period that the routines should be reentered.
|PETTERM Menu on a real PET-2001 — Image courtesy of Chris Osborn|
To provide a useful terminal from the serial routines, a subset of the ANSI escape codes were implemented to provide cursor movement, and screen clearing functionality. The implemented codes are from the Control Sequence Introducer set of ESC [. They are:
- Cursor Up - CUU - ESC[nA
- Cursor Down - CUD - ESC[nB
- Cursor Forward - CUF - ESC[nC
- Cursor Back - CUB - ESC[nD
- Cursor Position - CUP - ESC[n;mH
- Erase in Display - ED - ESC[nJ
All other ANSI escape codes should be parsed and ignore.
On top of the ANSI codes, simple ASCII codes such as backspace, new line, carage return, and tab are handled. As well, scrolling is handled.
To maintain compatability with all versions of the KERNAL ROM, and to get the non-blocking behaviour I wanted, I had to poll the keyboard matrix myself. This unfortuantly means that the program in it's current form is only compatable with the graphics keyboard versions of the PET, and not those with the buisness keyboard at the moment. Though support can be added by adding an additional matrix table, a way to determine the keyboard type without user input needs to be found.
This project turned out to be a nice refresher in programming on the Commodore series of computers, and built nicely on the work I did in CPSC 599.82 - Retrogames, and helped to show that architecturally the PET and VIC-20 computers are very much alike. For example I was able to use the exact same BASIC stub loader that I developed for the VIC-20, with the only change being to the load address of the program.
In addition the project helped to de-mystify implementing bit-banged protocols in software. I learned more about how the RS-232 protocol worked, and how to go about sampling and generating it in software using an interrupt routine.