forge Documentation

r-handler

R: Handler

R: device handler reference for RS-232 serial ports (Atari 850, R:Verter, BOB-Verter).

Overview

The R: device is typically a handler for an RS-232 serial port. This serial port can be on an Atari 850, an MIO, Black Box or P:R:Connection from ICD. Most handlers are the same with subtle differences.

What is an R: Device?

The R: device is a handler for an RS-232 serial port. This serial port can be on:

  • Atari 850 - Interface module with 4 RS-232 ports
  • MIO - Multi I/O interface
  • Black Box - Enhanced I/O interface
  • P:R:Connection - ICD interface
  • R:Verter - Modern serial interface
  • BOB-Verter - Modern serial interface

Atari 850

The Atari 850 is a computer peripheral for the Atari 8-bit line of computers that was released in 1980. It was called an "Interface module" that connected to the SIO port.

It provided:

  • 4 RS-232 serial ports:
    • R1: - Fully functional
    • R2:-R4: - Did not provide all RS-232 signals
  • 1 parallel port: P1:

Opening an R: Device

OPEN #channel, aux1, aux2, "R_n_:"

Aux1 specifies the direction of the port:

7 6 5 4 3 2 1 0
----------------
| | | | | | | | |
----------------
  • Aux1[7:4] = NOT USED
  • Aux1[3] = Specifies Output when high
  • Aux1[2] = Specifies Input when high
  • Aux1[1] = NOT USED
  • Aux1[0] = Specifies Concurrent I/O mode

Common values:

  • 4 = Input only
  • 8 = Output only
  • 12 = Input and Output (read/write)
  • 13 = Input and Output with Concurrent I/O mode

Aux2 is not used.

Example:

OPEN #1, 12, 0, "R1:"  ' Open R1: for read/write

XIO Commands

XIO 34 - DTR/RTS Control

XIO 34, #channel, aux1, aux2, "R_n_:"

Aux1 bits do the following:

  • Aux1[7] = DTR control enable (active high)
  • Aux1[6] = Force DTR value
  • Aux1[5] = RTS control enable (active high)
  • Aux1[4] = Force RTS value
  • Aux1[3:0] = not used

To force DTR off: Aux1 = 128
To force DTR on: Aux1 = 192

Aux2 is unused.

Example:

XIO 34, #1, 192, 0, "R1:"  ' Force DTR on
XIO 34, #1, 128, 0, "R1:"  ' Force DTR off

XIO 36 - Set Baud Rate and Parameters

XIO 36, #channel, aux1, aux2, "R_n_:"

Aux1 selects the Baud rate, Word size and stop bits. Add the values listed below to obtain the BASIC number.

Aux1[3:0] = Baud rate:

ValueBaud Rate
0300 bps
157600 bps (was 45.5 bps in 850 spec)
250 bps
3115200 bps (was 56.875 bps in 850 spec)
475 bps
5110 bps
6134.5 bps
7150 bps
8300 bps
9600 bps
101200 bps
111800 bps
122400 bps
134800 bps
149600 bps
1519200 bps

Aux1[5:4] = Word size:

ValueWord Size
08 bits
17 bits
26 bits
35 bits

Aux1[6] = Select 230400 bps (feature added to Atari800)

Aux1[7] = Stop bits:

  • 0 = 1 stop bit
  • 1 = 2 stop bits

Aux2 specifies whether or not the Interface Module should check Data Set Ready (DSR), Clear to Send (CTS) and/or Carrier Detect (CD). This function is currently not supported.

Example:

' 1200 baud, 8 bits, 1 stop bit
' 10 (1200 baud) + 0 (8 bits) + 0 (1 stop) = 10
XIO 36, #1, 10, 0, "R1:"

' 9600 baud, 8 bits, 1 stop bit
' 14 (9600 baud) + 0 (8 bits) + 0 (1 stop) = 14
XIO 36, #1, 14, 0, "R1:"

XIO 38 - Set Translation Mode

XIO 38, #channel, aux1, aux2, "R_n_:"

Aux1 specifies the translation mode, input/output parity modes and the append Line Feed option.

Aux1[1:0] = Output Parity (* Not Implemented)

  • 0 = Do not change parity bit
  • 1 = Set output parity odd
  • 2 = Set output parity even
  • 3 = Set output parity bit to 1

Aux1[3:2] = Input Parity

  • 0 = Ignore and do not change Parity bit (NO PARITY)
  • 1 = Set Parity to ODD
  • 2 = Set Parity to EVEN
  • 3 = Do not use Parity (NO PARITY)

Aux1[4] = Heavy Translation * Not Implemented

  • 0 = Light Translation
  • 1 = Heavy Translation

Aux1[5] = Translation

  • 0 = Translation ON
  • 1 = Translation off

Aux1[6] = Line Feeds

  • 0 = Do not append LF
  • 1 = Append LF after Carriage Return

Aux1[7] = Not Used

Aux2 is the numeric representation of the "won't translate" character for heavy translation. (Not currently supported.)

Example:

' Full ATASCII translation, append LF
' 0 (no parity) + 0 (light) + 0 (translation on) + 64 (append LF) = 64
XIO 38, #1, 64, 0, "R1:"

XIO 40 - Start Concurrent I/O Mode

XIO 40, #channel, aux1, aux2, "R_n_:"

XIO 40 starts concurrent I/O Mode.

Both Aux1 and Aux2 are used to specify an output buffer, but using the specified input buffer is not currently supported. The default 256 byte internal buffer is used when both Aux1 and Aux2 = 0.

Example:

XIO 40, #1, 0, 0, "R1:"  ' Start concurrent I/O

STATUS Command

STATUS #channel, statusVar

The STATUS command will update the memory locations 746-749 (DVSTAT buffer).

DVSTAT Buffer:

AddressHexDescription
746$02EAError bits (bitfield)
747$02EBSense byte or buffer count low byte
748$02ECBuffer count high byte (usually 0)
749$02EDOutput buffer count

Error Bits (746 / $02EA)

Not Implemented in all handlers

  • Bit 7 = Received Data Framing Error
  • Bit 6 = Received Data Byte Overrun Error
  • Bit 5 = Received Data Parity Error
  • Bit 4 = Received Data Buffer Overflow error
  • Bit 3 = Illegal Option Combination Attempted
  • Bit 2 = External Device Not Fully Ready Flag
  • Bit 1 = Error On Block Data Transfer Out
  • Bit 0 = Error On Command To Interface Module

Sense Byte (747 / $02EB)

Concurrent I/O Mode:

  • Number of Characters in Input buffer (Low Byte)

Non-Concurrent I/O Mode: (* Not Implemented)

  • Bit 7 = Data Set Ready (DSR) status during current STATUS command
  • Bit 6 = DSR status during last STATUS command
  • Bit 5 = Clear to Send (CTS) status during current STATUS command
  • Bit 4 = CTS status during last STATUS command
  • Bit 3 = CARRIER DETECT (CD) status during current STATUS command
  • Bit 2 = CD status during last STATUS command
  • Bit 1 = NOT USED
  • Bit 0 = Data Receive (RCV) current status

Checking carrier:

STATUS #1, ST
IF ST = 1 AND (PEEK(747) AND 8) <> 0 THEN
  ? "Connection active"
ELSE
  ? "No carrier"
ENDIF

Buffer Counts

Concurrent I/O Mode:

  • 747 + 256 * 748 = Input buffer count
  • 749 = Output buffer count

Example:

STATUS #1, ST
IF ST = 1 THEN
  INPUT_BYTES = PEEK(747) + 256 * PEEK(748)
  OUTPUT_BYTES = PEEK(749)
  ? "Input buffer: "; INPUT_BYTES; " bytes"
  ? "Output buffer: "; OUTPUT_BYTES; " bytes"
ENDIF

Basic I/O Operations

GET, INPUT, PUT, PRINT

Use as normal:

GET #1, BYTE_VAL
INPUT #1, LINE$
PUT #1, BYTE_VAL
PRINT #1, "Hello"

CLOSE

Closes the Serial port or the network connection.

CLOSE #1

Example: Terminal Program

' Open R: device
OPEN #1, 12, 0, "R1:"

' Set baud rate (1200 baud, 8 bits, 1 stop)
XIO 36, #1, 10, 0, "R1:"

' Set translation (append LF)
XIO 38, #1, 64, 0, "R1:"

' Start concurrent I/O
XIO 40, #1, 0, 0, "R1:"

' Terminal loop
REPEAT
  ' Check for incoming data
  STATUS #1, ST
  IF ST = 1 THEN
    BYTES = PEEK(747) + 256 * PEEK(748)
    IF BYTES > 0 THEN
      GET #1, C
      PUT C  ' Echo to screen
    ENDIF
  ENDIF
  
  ' Check for keyboard input
  IF KEY() THEN
    GET K
    PUT #1, K  ' Send to serial port
  ENDIF
UNTIL K = 27  ' ESC to exit

CLOSE #1

Limitations

Not all features of the 850 are currently supported by all emulators/handlers:

  1. Cannot set RTS or XMT in XIO 34
  2. Cannot select 45.5 bps or 56.875 bps in XIO 36
  3. Cannot monitor DSR, CTS or CD in XIO 36
  4. Heavy ASCII/ATASCII translation
  5. Early force of short I/O block (XIO 32)
  6. Cannot set output parity with XIO 38
  7. Using a different input buffer as specified by XIO 40 is not supported
  8. Error bits at location 746 are not always implemented
  9. Cannot have more than one R: device open at a time in some implementations

Related Topics