Saturday, March 24, 2012

The 6551 ACIA


There is one more piece of hardware on the Replica 1 Multi I/O board that we haven't examined, the 6551 Asynchronous Communication Interface Adapter.  It provides a single serial port with programmable baud rate and the usual settings for serial ports: baud rate, parity, stop bits, etc.

The 6551 on my Multi I/O Board

Between the introduction to it in the Multi I/O board manual, and the data sheet (which is only 8 pages) it's a pretty simple chip to understand.

For it's time it was quite a good ACIA, providing an on-chip baud rate generator. It uses TTL (5V) levels so you need a level shifter to convert to and from the RS-232 levels. On the Multi I/O board this is done with a MAX 232 chip.The frequency of the ACIA is based on the 1.8432 MHz crystal connected to it, so it is not dependent on the CPU frequency or PH2 clock.

It is lacking a few features. Some ACIAs support two serial ports. The maximum baud rate is 19,200 bps which was good for its time but many systems later went up 115,200. Some ACIAs also supported a larger buffer than one character.

You can set the baud rate using an external clock signal. You could potentially drive this from the VIA, for example, but to support 115200bps the frequency would need be 1.8432 MHz, too high for the VIA to generate.

On the Multi I/O board the RTS and CTS handshaking lines do not go to the serial port so it can't support hardware handshaking (this would be an easy modification though). You can run it in an interrupt driven mode.

Basically it has four registers. A Control Register sets the serial mode including baud rate, word length and stop bits. A Command Register sets some transmit and receive functions such as parity, DTR, RTS, and CTS settings. A Status Register reports on the status of characters sent and received. The Transmit Data Register is used to send characters and the Receive Registers returns received characters.

Let's look at a simple example program. I created an include file, 6551.inc, to define the chip registers and their addresss on the Multi I/O board. Here is the file:

; 6551 Chip registers
        TXDATA = $C300
        RXDATA = $C300
        STATUSREG = $C301
        CMDREG = $C302
        CTLREG = $C303

Our example program will write a short message ("OK" followed by a carriage return) to the serial port. Then we will read characters from the port and echo them back. If the user presses 'Q' we will return (e.g. to the Woz monitor if that was where we were run from). Here is the listing:

       .include "6551.inc"
       CR = $0A ; carriage return
; Set 1 stop bit, 8 bit data, internal clock, 19200bps
       LDA #011111
       STA CTLREG
; Set no parity, no echo, no TX interrupts, RTS low, no RX interrupts, DTR low  
      LDA #001011
      STA CMDREG
; Display OK\n
      LDA #'O'
      JSR ECHO
      LDA #'K'
      JSR ECHO
      LDA #CR
      JSR ECHO
; Now get a character and echo it back
; Quit if it is 'Q'
LOOP: JSR GETCHAR
      CMP #'Q'
      BEQ DONE
      JSR ECHO
      JMP LOOP
DONE: RTS
; Send character in A out serial port
ECHO:   PHA
        LDA #$10
TXFULL: BIT STATUSREG ; wait for TDRE bit = 1
        BEQ TXFULL
        PLA
        STA TXDATA
        RTS
; Read character from serial port and return in A
GETCHAR: LDA #$08
RXFULL: BIT STATUSREG
        BEQ RXFULL
        LDA RXDATA
        RTS

To test it, load it into the Woz monitor (probably using the serial port on the Replica 1). Then connect the serial port of your computer to the Multi I/O board serial port. Set your communication program to 19200bps, 8N1, and no hardware handshaking. You should see the "OK" message and any characters you type will be echoed back. Pressing Q will return to the Woz monitor.

The ECHO and GETCHAR routines above can be used to do serial I/O in your programs rather than the normal Replica 1 keyboard. As an experiment I modified my JMON machine language monitor program to do serial I/O.

1 comment:

Tanvir said...

I would like to know about MC6850p ACIA chip. Could you please tell me for what purpose it is used? Basically I would like to develop a network of number of microcontrollers where they can communicate with each other directly or via another MCU. Someone suggested me to use an ACIA chip to establish connectivity between number of MCUs. But I don't understand why I need to use this as the baud rate, bit settings all are there in a MCU.


Thanks.