The PSION Organiser II Homepage
 
Home
Technical Reference
Introduction
System
Versions
Operating
System
Memory Usage
Filing System
System Timing
System Board
Power Supply Board
Display
Keyboard
Interface Slots
Packs
General
Flashpacks
Low Level
Access
External
Interfacing
Comms Link
Psion Link
Protocol
Utility System
Services
Built-in
Applications
LZ Passwords
Programming
Language
General
Q-Code
Table
Interpreter
System Services
 

Technical Reference Manual

COMMS LINK

INTRODUCTION

ALTERED SYSTEM SERVICES

MACHINE CODE INTERFACE

RS232 CONTROL SIGNALS

PROGRAMMING

FUNCTION REFERENCE

 

INTRODUCTION

COMMS LINK driver code is interrupt driven and handles XON/XOFF and hardware handshaking at the lowest level. It also parity checks all incoming data if parity is enabled.

As all serial I/O is interrupt driven, interrupts CANNOT be disabled (as with the keyboard). All calls to the operating system via the SWI instruction are intercepted by the driver code once the port has been opened, to make data pack access transparent (and possible!) while the port is open. It also ensures that the port is active and not affected by various power saving techniques in the operating system while it is open.

ALTERED SYSTEM SERVICES

The function of the following operating system services are altered when the port is opened; PK$SETP, PK$PKOF, BZ$TONE, BZ$ALRM and BZ$BELL. As all SWI's and interrupts are intercepted directly, and the old handlers are not chained to, any other application that re-vectors the same services will not function correctly while the port is open. The old handlers are saved only when the comms pack is booted during the install code but are restored every time the port is closed. Any application booted in after the comms pack, which re-vectors any service used by the comms pack, will not function correctly even when the port has been closed as the original handler will be restored.

  • PK$SETP - This function will first wait for the correct time to elapse from the last character being sent and then switch off the port. From this point the port will no longer be able to receive characters. The operating system function will then select the pack in the normal way, and the next call made to a COMMS LINK service will switch the port on again.
  • PK$PKOF - This function will do nothing while the port is open.
  • BZ$TONE, BZ$ALRM, BZ$BELL - These three functions will all just do a beep regardless of any parameters passed while the port is open because interrupts cannot be disabled.

MACHINE CODE INTERFACE

The interface to the COMMS LINK driver code is via a block of fixed address memory of 40 bytes long starting at dvt_spar ($214F). This memory is divided into two areas: a table of variables which set various I/O parameters and an entry point for calls to the driver code. All these variables and a macro for calling the driver code via this entry point are defined below.

VARIABLES

The following variables can be set set to control the function of the COMMS LINK driver code. However, these variables are also set by the SETUP option in the COMMS menu and by the LSET OPL function, so generally their values must be preserved.

After any of these variables have been altered a call to rs$setvars must be made to set up various derived variables.

None of these variables should be altered while the port is open.

SINGLE BYTE VARIABLES

Address Name Range (default values bold)  
$2150 rsb_baud 0-9 50,75,110,150,300,600,
1200,2400,4800,9600
Baud rate
(transfer speed)
$2151 rsb_parity 0-4 NONE, ODD, EVEN,
MARK, SPACE
Data, Parity, Stop Bit settings:
transfer frame setup
$2152 rsb_bits 0-1 0 - 7 BIT DATA
1 - 8 BIT DATA
$2153 rsb_stop 0-1 0 - 1 STOP BIT
1 - 2 STOP BITS
$2154 rsb_hand 0-7 NONE,XON,RTS,XON+RTS,
DTR,DTR+XON,DTR+RTS,ALL
Handshake mode
$2155 rsb_proto 0-2 NONE, XMODEM, PSION File transfer protocol
(off by default)
$2156 rsb_echo 0-1 LOCAL, HOST
Echo
(Terminal emulation only)
$2157 rsb_width 0-250 NONE,
1-250
buffer width
(forced line length)
$2158 rsb_timout 0-255 NONE,
1-255 seconds
LPRINT timeout
3 BYTE VARIABLES:

All contain a length byte (0-2) and two bytes of data

Address Name default  
$2159 rst_reol 13,10
<CR><LF>
Receive End Of Line character(s)
$215C rst_reof 26
<SUB>
Receive End Of File character(s)
$215F rst_rtrn empty Receive Translate character(s):
1 - remove, 2 - replace first by second
$2162 rst_teol 13,10
<CR><LF>
Transmit End Of Line character(s)
$2165 rst_teof 26
<SUB>
Transmit End Of Files character(s)
$2168 rst_ttrn empty Transmit Translate characters:
1 - remove, 2 - replace first by second
SYSTEM VARIABLES

It is strongly suggested to leave these unchanged.

Address Name Range  
$216B rsb_off_del 1-255
default=3
Time to off delay in characters
$216C rsb_xoff_del 1-255
default=7
Time to off delay with XON/XOFF
$216D rsb_tcon_val 0-255 Time constant value for timer 2 baud rate generation
$216E rsb_off_ticks 0-255 No. of ticks for baud rate dependent Tx off delay
$216F rsw_off_tcon 0-$FFFF Time constant for single tick TX off delay (word)
$2171 rsb_sec_timer 0-255 General purpose decrement to zero second timer (decremented once every second until zero)
$2172 RESERVED WORD
$2174 rst_entry_point   Entry point for assembler interface, contains a jump instruction to the driver (3 bytes).

The general purpose timer rsb_sec_timer is used by the higher level functions such as LPRINT to implement time outs so be warned!

CALLS TO THE DRIVER

All calls to the COMMS LINK driver code are made via the macro "RS" which is defined below:

    ;
    ; RS - Macro for assembler interface to COMMS LINK drivers
    ;
.macro    RS  function
          jsr rst_entry_point
.byte     function
.endm

Before using this macro a check must be made that the COMMS LINK code has been booted as follows:

          ldx  #opl_name           ; choose an OPL function unique to COMMS-LINK
          os   dv$lkup             ; ask O/S if it's booted
          bcs  not_booted          ;ok to call RS$ routines now

opl_name: .ascic"XFEOF"

DRIVER FUNCTIONS

The following functions are available:

  0 RS$open Open the COMMS LINK channel
  1 RS$close Close the COMMS LINK channel
  2 RS$putchar Put a character to the RS232 port
  3 RS$getchar Get a character from the RS232 port
  4 RS$flush Flush the receive buffer
  5 RS$setvars Set the COMMS LINK variables up after a change
  6 RS$lprint Print a string
  7 RS$linput Input a string
  8 RS$licon Link layer connect call
  9 RS$lidis Link layer disconnect call
  10 RS$liput Link layer put a frame call
  11 RS$liget Link layer get a frame call

Example to open the RS232 port for reading and writing:

        clrb                 ; Open for reading and writing
        RS   RS$open
        bcs  error           ; Deal with error
        ...                  ; Rest of code

In general all functions indicate an error condition by returning with the carry flag set and the appropriate error code in the B register.

RS232 CONTROL SIGNALS

The COMMSLINK hardware provides the following RS232 control signals on the port POB_PORT2 (address $03).

All bits are readable, writing to input bits is to be avoided.

Name Top slot pin Direction PORT2 bit no Set if:
RTS 5 input 2 correspondent busy
CTS 6 output 0 organiser busy
DSR 4 input 1 correspondent busy
DTR - linked to DSR - DSR set

Note that DTR (normally an output) is merely linked to DSR and can not be driven by a program.

PROGRAMMING

CONSIDERATIONS

In between a call to RS$OPEN and a call to RS$CLOSE, programmers should look out for the following operating system routines:

Routines which access packs:

  • all FL$ routines
  • all PK$ routines except for PK$PKOF
  • DV$BOOT, DV$LOAD
  • any other routines which indirectly access packs, such as calls to OPL, DV$VECT, TL$XXMD etc.

These turn off the RS232 port, until the next call to COMMS LINK. This is normally no problem, unless a program tries to access POB_PORT2 after a call to one of the above routines but before another COMMS LINK call. The RS232 port should then be turned on by calling RS$OPEN again, as follows:

Example: no problem here

        os FL$OPEN
        ...                     ; RS232 now off
        jsr rst_entry_point
        Byte RS$getchar        ; or similar COMMS LINK function
        ...
        tim #cts,POB_PORT2      ; test the CTS line

Example: this is a BUG

        Os PK$SETP
        ...                     ; RS232 now off
        Tim #CTS,POB_PORT2      ; test the CTS line

Example: corrected version of above

        Os PK$SETP              ; Re-open the RS232 port, to switch it on
        ldab #opened_with       ; use value originally supplied to RS$OPEN
        andb #^XFE              ; but with bit 0 clear to indicate that
        jsr rst_entry_point     ; the handshaking state is not to be reset
        Byte RS$open
        ...
        Tim #CTS,POB_PORT2      ; now OK to access port

Other routines whose behavior is altered while the RS232 port open:

  • PK$PKOF - has no effect
  • BZ$ routines - these all give a strange beep
  • KB$ routines do not switch the packs off to save power

Do not call BT$SWOF without first closing the RS232 port with RS$CLOSE

The keyboard interrupt service routine is altered so that interrupts remain enabled while the keyboard is being scanned. This gives RS232 interrupts a higher priority than keyboard interrupts.

PROGRAMMING EXAMPLES

Checking that COMMS LINK is installed

First check that the COMMS LINK software has been loaded - i.e. COMMS is in the top-level menu. If COMMS LINK is not installed, any program which calls the machine code interface routines provided by COMMS LINK will crash.

This check can be performed in OPL as follows:

        commsin%:
        rem return true if COMMS LINK installed
        onerr iserr::
        xfeof:          :rem try a harmless COMMS LINK function
        iserr::
        return err<>203 : rem not installed if "missing proc" error

or in machine code:

                bsr check_present
                bcs not_present
                bra is_present

check_present:  bsr 1$          ; PC relative LDX #XFEOF
                .ascic "XFEOF"  ; leading count byte string
           1$:  pulx            ; PC = address of "XFEOF"
                Os dv$lkup      ; if XFEOF not there, no COMMS LINK
                rts
Opening and closing the RS232 port

Before accessing the RS232 port, the program must first call the COMMS LINK machine code interface routine RS$OPEN. This indicates that the RS232 port is now in use.

Example:

                clrb            ; Open for reading and writing
                jsr rst_entry_point
                Byte RS$open
                bcs error       ; Deal with error
                ...             ; Now free to access the port

RS$CLOSE should be called when the RS232 port is no longer needed.

        ; bit masks for RS$close
        turn_off_immed= 1       ; switch off immediately after close
                                ; else leave port on
        fail_busy= 2            ; fail with carry set if paused by XOFF
                                ; else ignore XOFF state, and close immediately

        ; Example where port not closed while XOFF handshake

        close_type = fail_busy  ; dont close if busy handshaking,
                                ; leave port switched on

        wait_busy:      ldab #close_type
                        jsr  rst_entry_point
                        Byte RS$close
                        bcs wait_busy   ; wait until XON

        ; Straight close

        close_type = 0  ; ignore XOFF state,
                        ; leave port switched on

                        ldab #close_type
                        jsr rst_entry_point
                        Byte RS$close
Using handshaking lines
        ; Bit masks
                CTS= 1
                dsr= 2
                rts= 4
        ;Set CTS to indicate ORGANISER II busy

                oim #CTS,POB_PORT2


        ;Clear CTS to indicate ORGANISER II ready for input

                aim #CTS,POB_PORT2      ; not (1) = $FE


        ;Wait on both RTS and DSR

        wait:   Tim #rts!dsr,POB_PORT2
                bne wait

Example: OPL/Machine code for controlling the RTS line directly:

        global rtshigh%(2),rtslow%(2),a%
        rtshigh%(1)=$71fe
        rtshigh%(2)=$0339
        rtslow%(1)=$7201
        rtslow%(2)=$0339

        rem to assert (raise) the rts line
        a%=usr%(addr(rtshigh%()),0)

        rem to de-assert (lower) the rts line
        a%=usr%(addr(rtslow%()),0)

FUNCTION REFERENCE

All all function calls are made via the macro "RS", see above.


RS$open
Function Number: 0
Input parameters: B register: Mode to open.
  • Bit 0 - Set if port in TX only mode.
  • Bit 1 - Set to enable break key error inhibiting.
  • Bit 2 - Set if the TX paused state is to be cleared.
Output values: Carry set if error, error number in B
Registers corrupted: All

Opens the RS232 channel and initialises the hardware, also sets various modes of operation for the port depending on the value passed in B.

If a pack access is made while RS232 is open this access will be delayed until any stray characters have been delt with. Any subsequent calls to RS_putchar or RS_getchar will switch the port on again. If a call to RS$open is made while the port is already open the call is ignored.

Errors:

  • ER_DV_NP - Device not present
  • ER_GN_BL - Battery too low

RS$close
Function Number: 1
Input parameters: B register: Mode to close.
  • Bit 0 CLEAR port closed and is turned off later by pack access or key scan
  • Bit 0 SET port closed and turned off
  • Bit 1 CLEAR host paused state is ignored
  • Bit 1 SET port fails to close if the host is busy (paused by an XOFF)
Output values: Carry set if can not close port because host is busy
Registers corrupted: All

Closes the RS232 port. Carry is set if failed to close due to host busy

Errors: none


RS$putchar
Function Number: 2
Input parameters: A register: Character to be put to buffer
Output values: Carry set if error or busy
B clear or error number
Registers corrupted: B, CCR

Transmits the passed character. Returns with the carry set if an error or the port was busy, else the carry is clear. B is clear if no error.

Errors:

  • ER_DV_CA - Invalid device call - Port not open
  • ER_RT_BK - Break Key
  • ER_GN_BL - Battery too low

RS$getchar
Function Number: 3
Input parameters: None
Output values: A register - Next character from receive buffer
B clear or error number
Carry set if error or busy
Registers corrupted: A, B, CCR

Gets the next character from the receive buffer. Returns with carry set if error or no characters in the buffer, else the next character from the buffer in the A register B is clear.

Errors:

  • ER_DV_CA - Invalid device call - Port not open
  • ER_GN_RF - Device read fail - Parity or overrun
  • ER_RT_BK - Break Key
  • ER_GN_BL - Battery too low

RS$flush
Function Number: 4
Input parameters: None
Output values: None
Registers corrupted: CCR

Flushes the receive buffer.

Errors: none


RS$setvars
Function Number: 5
Input parameters: None
Output values: None
Registers corrupted: All

Sets the derived COMMS LINK variables after a change to the setable COMMS LINK variables.

Errors: none


RS$lprint
Function Number: 6
Input parameters: X register - Pointer to text to print
B register - Length of string to print
Output values: B register - Error code if any
Registers corrupted: All

Opens the RS232 port for output only, then writes the passed string to the port applying all the translates, timeouts etc. specified.

Errors:

  • ER_GN_BL - Battery too low
  • ER_GN_WF - Device write fail (Timeout)
  • ER_RT_BK - Break Key
  • ER_DV_NP - Device not present

RS$linput
Function Number: 7
Input parameters: A register - Timeout in seconds (0=no timeout)
B register - Number of characters to receive
X register - Address of buffer to place characters
Output values: B register - Error code if any
A register - Number of characters received
Registers corrupted: All

Opens the RS232 port for output and input and then reads the passed number of bytes into the passed buffer applying all the translates, timeouts etc. specified.

Errors:

  • ER_GN_BL - Battery too low
  • ER_GN_RF - Device read fail (Timeout)
  • ER_RT_BK - Break Key
  • ER_DV_NP - Device not present

RS$licon
Function Number: 8
Input parameters: None
Output values: B register - Error code if any
Registers corrupted: All

Attempts to establish a logical link with the correspondent link entity. Wait for a suitable acknowledgment.

Errors:

  • ER_RT_F0 - a link already exists (local error)
  • ER_GN_RF - timeout trying to get a connection
  • ER_DV_NP - Device not present
  • ER_GN_BL - Battery too low

RS$lidis
Function Number: 9
Input parameters: None
Output values: B register - Error code if any
Registers corrupted: All

Disconnect the logical link with the correspondent link layer. Harmless if the link is already disconnected.

Errors:

  • ER_RT_FC - no link in existence
  • ER_GN_BL - Battery too low

RS$liput
Function Number: 10
Input parameters: D register - Length of buffer to send
X register - Address of buffer to send
Output values: B register - Error code if any
Registers corrupted: All

Send data in buffer to the correspondent. The data length must be >=0 and <=MAXILEN. Waits for a suitable acknowledgment. (MAXILEN currently 260)

Errors:

  • ER_RT_FC - a link does not exist (local error)
  • ER_GN_RF - a re-transmission threshold expired
  • ER_LX_ST - len exceeds MAXILEN (no data transferred)
  • A server disconnection reason code, e.g. "no disk space"
  • ER_GN_BL - Battery too low

RS$liget
Function Number: 11
Input parameters: D register - Number of bytes to get
X register - Address of buffer to put bytes
Output values: B register - Error code if any
D register - Number of bytes placed in buffer if OK
Registers corrupted: All

Wait for a frame to arrive from the physical layer. Returns number of bytes placed in buffer if all OK

Errors:

  • ER_RT_FC - a link does not exist (local error)
  • ER_GN_RF - a timer expired
  • ER_LX_ST - data length exceeds Len (1st Len bytes in buffer)
  • A file server disconnection reason code, e.g. drive door open.
  • ER_GN_BL - Battery too low
 
first previous   next top