![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Technical Reference ManualCOMMS LINK
INTRODUCTIONCOMMS 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 SERVICESThe 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.
MACHINE CODE INTERFACEThe 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. VARIABLESThe 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
3 BYTE VARIABLES:All contain a length byte (0-2) and two bytes of data
SYSTEM VARIABLESIt is strongly suggested to leave these unchanged.
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 DRIVERAll 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 FUNCTIONSThe following functions are available:
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 SIGNALSThe 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.
Note that DTR (normally an output) is merely linked to DSR and can not be driven by a program. PROGRAMMINGCONSIDERATIONSIn 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:
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:
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 EXAMPLESChecking that COMMS LINK is installedFirst 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 portBefore 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 REFERENCEAll all function calls are made via the macro "RS", see above. RS$open
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:
RS$close
Closes the RS232 port. Carry is set if failed to close due to host busy Errors: none RS$putchar
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:
RS$getchar
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:
RS$flush
Flushes the receive buffer. Errors: none RS$setvars
Sets the derived COMMS LINK variables after a change to the setable COMMS LINK variables. Errors: none RS$lprint
Opens the RS232 port for output only, then writes the passed string to the port applying all the translates, timeouts etc. specified. Errors:
RS$linput
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:
RS$licon
Attempts to establish a logical link with the correspondent link entity. Wait for a suitable acknowledgment. Errors:
RS$lidis
Disconnect the logical link with the correspondent link layer. Harmless if the link is already disconnected. Errors:
RS$liput
Send data in buffer to the correspondent. The data length must be >=0 and <=MAXILEN. Waits for a suitable acknowledgment. (MAXILEN currently 260) Errors:
RS$liget
Wait for a frame to arrive from the physical layer. Returns number of bytes placed in buffer if all OK Errors:
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||