Emulating the 8250 UART in software

By | June 11, 2022

Starting with build A775, the PC emulation software contains a fairly complete implementation of a virtual 8250 UART chip for RS-232 communication. It supports both the INT 14h interface and direct access to 0x3F8-0x3FF ports, which are translated, via the inter-processor call mechanism, to appropriate Commodore KERNAL calls and 6551 ACIA chip accesses.

The implementation was tested with the TERM90 software packaged with Norton Commander, and allows to transfer the files over the serial line using XMODEM, YMODEM and KERMIT protocols (ZMODEM does not work yet – see below).

The implementation

The bulk of the implementation is contained in the virtual/serial.asm file, which handles I/O port accesses. They are translated to IPC calls $19 (read from RS-232), $1A (write to RS-232), $1B (set RS-232 parameters) and $1C (read RS-232 status). These same calls are used in the INT 14h implementation.

On the 6509 side, most of the RS-232 communications is handled by the KERNAL code. However, additional logic was added to control the hardware flow. Normally the KERNAL allocates a 256-byte buffer for incoming RS-232 data; if the buffer overflows, the data is lost. The code deasserts the RTS line when the buffer is about to become full, so that the other side stops sending more characters. This means that:

  • You should use hardware flow control on the PC connected to the serial line, otherwise you risk overflowing the input buffer in the CBM-II.
  • The 8088 has no control over the RTS line as it is managed directly by the 6509 code.

The trickiest part was, as usual, the interrupts. Software that uses the UART directly relies on IRQ4 to handle both incoming and outgoing RS-232 traffic. But there is no simple way to generate these interrupts from the 6509 to 8088, and even if there were, the overhead involved in processor context switch between the two CPUs on every character sent and received would be too big to make it practical.

Instead, the 60Hz interrupt handler checks each time if there are any characters in the RS-232 input buffer. If there are, it calls the IRQ4 routine repeatedly until the input buffer is exhausted (on the assumption that the terminal software uses the IRQ to read an incoming character1). Similarly, it issues an interrupt whenever a character is sent (on the assumption that the terminal software uses it to send the next character).

Because the complete UART is emulated in software, it adds a lot of overhead to the system. Therefore, even though the CBM-II’s ACIA is capable of transfer speeds beyond 9600 baud, the real speed is around 350 characters per second using the YMODEM protocol.

FreeDOS and terminal software

FreeDOS uses the INT 14h interface to access the serial port, so using the AUX / COM1 device from FreeDOS is straightforward. You can issue commands such as:

COPY file.txt COM1

and the file will be transferred to the other side via the serial line (transfer in he other direction will work too).

By default, FreeDOS sets the serial port to 2400 baud. The ACIA chip in the CBM-II is capable of much higher speeds, so you can use the MODE command to change it, such as:

MODE COM1 9600,N,8

You need to download the MODE command to your SD card to do so.

Terminal software usually bypasses the INT 14h interface and uses the I/O ports of the UART directly. Therefore some terminal programs may work well and others not at all. Personally I am using the TERM90 program, and it works flawlessly with XMODEM, YMODEM and KERMIT file transfer protocols (I recommend YMODEM as it is significantly faster than KERMIT). ZMODEM does not work – it either hangs or timeouts; a cursory analysis shows that the HyperTerminal software (which I am using on my Windows PC) keeps pumping out ZMODEM packets even if the RTS line is deasserted, constantly overwriting the Commodore’s input buffer. This issue needs further investigation.

  1. Of course, the loop is terminated if the interrupt handler does not read the incoming character.

Leave a Reply

Your email address will not be published. Required fields are marked *