1.9	Block CRC library
Library: crc.lib
The block CRC library provides two functions for calculating cyclic redundancy check values from byte strings. Such values can be of use in, for example, the generation of the frame check sequence (FCS) in data communications.
A cyclic redundancy check value is the remainder from modulo 2 polynomial division. Consider bit sequences as representing the coefficients of polynomials; for example, the bit sequence 10100100 (where the leading bit is the most significant bit (msb)) corresponds to P(x) = x7 + x5 + x2. The routines in the library calculate the remainder of the modulo 2 polynomial division:
(xk+n H(x) + xn F(x))/G(x)
where:	F(x) corresponds to InputString
G(x) corresponds to PolynomialGenerator
H(x) corresponds to OldCRC
k is the number of bits in InputString         
n is the word size in bits of the processor used (i.e. n is 16 or 32).     
(OldCRC can be viewed as the value that would be preloaded into the cyclic shift register that is part of hardware implementations of CRC generators.).
When representing G(x) in the word PolynomialGenerator, note that there is an understood bit before the msb of PolynomialGenerator. For example, on a 16bit processor, with G(x) =x16 + x12 + x5 + 1, which is #11021, then PolynomialGenerator must be assigned #1021, because the bit corresponding to x16 is understood. Thus, a value of #9603 for PolynomialGenerator, corresponds to G(x) = x16 + x15 + x12 +x10 + x9 + x + 1, for a 16bit processor. 
A similar situation holds on a 32bit processor, so that:  
G(x) = x32 + x26 + x23 +x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 +x4 + x2 + x + 1 
is encoded in PolynomialGenerator as #04C11DB7.
It is possible, however, to calculate a 16bit CRC on a 32bit processor. For example, if G(x) = x16 + x12 + x5 + 1, then PolynomialGenerator is #10210000. This is because the most significant 16 bits of the 32bit integer form a 16bit generator; the least significant 16 bits of OldCRC form the initial CRC value; and the calculated CRC is the most significant 16 bits of the result from CRCFROMMSB and the least significant 16 bits of the result from CRCFROMLSB.
1.9.1	Example of use
Suppose it is required to transmit information between two 32bit transputers, and the message that is to be transmitted is the byte array [data FROM 4 FOR size.message], where there are size.message bytes in the message. Both the transmitter and receiver use the same 32bit generating polynomial and OldCRC value. There are two methods for the receiver to check messages:
First CRCFROMMSB is given the message as an input string, the result is placed into the first four bytes of data and the message is sent. The receiver can either: 
Give the received data (which is (size.message + 4) bytes long) to CRCFROMMSB and expect a result of zero, 
or:
Give the received [data FROM 4 FOR (size.message)] to CRCFROMMSB and check that the result is equal to the INT contained in the received [data FROM 0 FOR 4].        
These methods of checking are equivalent. If the check fails then the transmitted data was corrupted and retransmission can be requested; if the check passes then it is most probable that the data was transmitted without corruption  just how probable depends on many factors, associated with the transmission media.
Note: The occam predefines CRCBYTE and CRCWORD can be chained together to help calculate a CRC from a byte string, and this is indeed the use to which they are put in CRCFROMMSB and CRCFROMLSB. However, because these latter routines shift the polynomial F(x) corresponding to InputString by xn, these routines should not be chained together over segments of a byte string to find its CRC; the whole string must be used in a single call to CRCFROMMSB or CRCFROMLSB.
1.9.2	Function definitions
CRCFROMMSB
INT FUNCTION CRCFROMMSB (VAL []BYTE InputString,
                         VAL INT PolynomialGenerator,
                         VAL INT OldCRC)
This routine is intended for strings in normal transputer format (littleendian). The most significant bit of the given string is taken to be bit16 or bit32, depending, that is, on the word size of the processor, of 
InputString[(SIZE InputString)  1]. 
PolynomialGenerator, OldCRC and the result are all also in normal transputer format (littleendian).         
CRCFROMLSB
INT FUNCTION CRCFROMLSB (VAL []BYTE InputString,
                         VAL INT PolynomialGenerator,
                         VAL INT OldCRC)
This routine accommodates strings in bigendian format. The most significant bit of InputString is taken to be bit 0 of InputString[0]. The generated CRC is given in bigendian format. PolynomialGenerator and OldCRC are taken to be in littleendian format.
1.10	Extraordinary link handling library
Library: xlink.lib
The extraordinary link handling library contains routines for handling communication failures on a link. Four procedures are provided to allow failures on input and output channels to be handled by timeout or by signalling the failure on another channel. A fifth procedure allows the channel to be reset. Use of these routines is described in section 11.5 of the User Guide.

Procedure	Parameter Specifiers	
InputOrFail.t	CHAN OF ANY c, []BYTE mess,
TIMER t, VAL INT time, BOOL aborted	
OutputOrFail.t	CHAN OF ANY c, VAL []BYTE mess,
TIMER t, VAL INT time, BOOL aborted	
InputOrFail.c	CHAN OF ANY c, []BYTE mess
CHAN OF INT kill, BOOL aborted	
OutputOrFail.c	CHAN OF ANY c, VAL []BYTE mess,
CHAN OF INT kill, BOOL aborted	
Reinitialise	CHAN OF ANY c	

CAUTION:
Use of the routines in xlink.lib during interactive debugging will lead to undefined results. In addition these routines may only be used for channel communication on a link; they must not be used for communications between processes on the same processor. 
1.10.1	Procedure definitions
The first four of these procedures take as parameters a link channel c (on which the communication is to take place), a byte vector mess (the object of the communication), and the boolean variable aborted. The choice of a byte vector for the message allows an object of any type to be passed along the channel providing it is retyped first. aborted is set to TRUE if the communication times out or is aborted; otherwise it is set to FALSE. 
Note: In rare circumstances aborted may be set to TRUE even though the communication is successful. This happens if the communication terminates successfully in the interval between the timeout/abort and channel renitialization. The likelihood of this event is very small.
InputOrFail.t 
PROC InputOrFail.t (CHAN OF ANY c, []BYTE mess, 
                    TIMER t, VAL INT time, 
                    BOOL aborted)
This procedure is used for communication where failure is determined by a timeout. It takes a timer parameter t, and an absolute time time. The procedure treats the communication as having failed when the time as measured by the timer t is AFTER the specified time time. If the timeout occurs then the channel c is reset and this procedure terminates.
OutputOrFail.t 
PROC OutputOrFail.t (CHAN OF ANY c, 
                     VAL []BYTE mess, 
                     TIMER t, VAL INT time, 
                     BOOL aborted)
This procedure is used for communication where failure is determined by a timeout. It takes a timer parameter t, and an absolute time time. The procedure treats the communication as having failed when the time as measured by the timer t is AFTER the specified time time. If the timeout occurs then the channel c is reset and this procedure terminates.
InputOrFail.c 
PROC InputOrFail.c (CHAN OF ANY c, []BYTE mess,
                    CHAN OF INT kill, 
                    BOOL aborted)
This procedure provides, through an abort control channel, for communication failure on a channel expecting an input. This is useful if failure cannot be detected by a simple timeout. Any integer on the channel kill will cause the channel c to be reset and this procedure to terminate. 
OutputOrFail.c 
PROC OutputOrFail.c (CHAN OF ANY c, 
                     VAL []BYTE mess,
                     CHAN OF INT kill, 
                     BOOL aborted)
This procedure provides, through an abort control channel, for communication failure on a channel attempting to output. This is useful if failure cannot be detected by a simple timeout. Any integer on the channel kill will cause the channel c to be reset and this procedure to terminate. 
Reinitialise
PROC Reinitialise (CHAN OF ANY c)
This procedure may be used to reinitialize the link channel c after it is known that all activity on the link has ceased.
Reinitialise must only be used to reinitialize a link channel after communication has finished. If the procedure is applied to a link channel which is being used for communication the transputer's error flag will be set and subsequent behavior is undefined. 
1.11	Debugging support library
Library: debug.lib
The debugging support library provides four procedures. Two procedures are provided to stop a process, one on a specified condition. The third procedure is used to insert debugging messages and the fourth procedure is a timer process for analyzing deadlocks. 

Procedure	Parameter Specifiers	
DEBUG.STOP	()	
DEBUG.ASSERT	VAL BOOL assertion	
DEBUG.MESSAGE	VAL []BYTE message	
DEBUG.TIMER	CHAN OF INT stop	

1.11.1	Procedure definitions
DEBUG.ASSERT 
PROC DEBUG.ASSERT (VAL BOOL assertion)
If a condition fails this procedure stops a process and notifies the debugger. 
If assertion evaluates FALSE, DEBUG.ASSERT stops the process and sends process data to the debugger. If assertion evaluates TRUE no action is taken. 
If the program is not being run within the breakpoint debugger and the assertion fails, then the procedure behaves like DEBUG.STOP. 
DEBUG.MESSAGE 
PROC DEBUG.MESSAGE (VAL []BYTE message)
This procedure sends a message to the debugger which is displayed along with normal program output. Note: that only the first 83 characters of the message are displayed.
If the program is not being run within the breakpoint debugger the procedure has no effect. 
DEBUG.STOP 
PROC DEBUG.STOP ()
This procedure stops the process and sends process data to the debugger. 
If the program is not being run within the breakpoint debugger then the procedure stops the process or processor, depending on the error mode that the processor is in. 
DEBUG.TIMER 
PROC DEBUG.TIMER (CHAN OF INT stop)
A timer process for use when analyzing deadlocks in occam programs. The procedure remains on the timer queue until receipt of any integer value on the channel stop, whereupon it will terminate. For an example of this form of usage see section 7.14.6 in the User Guide.
1.12	DOS specific hostio library 
Library: msdos.lib
The MSDOS host file server library allows programs to use some facilities specific to the IBM PC. A set of constants for the library are provided in the include file msdos.inc.
Caution: Programs that use this DOS specific library will not be portable to versions of the toolset on other hosts.

Procedure	Parameter Specifiers	
dos.receive.block	CHAN OF SP fs, ts,
VAL INT32 location,
INT bytes.read, []BYTE block,
BYTE result	
dos.send.block	CHAN OF SP fs, ts,
VAL INT32 location,
VAL []BYTE block,
INT len, BYTE result	
dos.call.interrupt	CHAN OF SP fs, ts,
VAL INT16 interrupt,
VAL[dos.interrupt.regs.size]BYTE
register.block.in,
BYTE carry.flag,
[dos.interrupt.regs.size]BYTE
register.block.out,
BYTE result	
dos.read.regs	CHAN OF SP fs, ts,
[dos.read.regs.size] BYTE registers,
BYTE result	
dos.port.read	CHAN OF SP fs, ts,
VAL INT16 port.location,
BYTE value, result	
dos.port.write	CHAN OF SP fs, ts,
VAL INT16 port.location,
VAL BYTE value, BYTE result	

1.12.1	Procedure definitions 
dos.receive.block
PROC dos.receive.block (CHAN OF SP fs, ts,
                        VAL INT32 location,
                        INT bytes.read, 
                        []BYTE block,
                        BYTE result)
Reads a block of data, starting at location, from host memory.
location is arranged as the segment in the top two bytes and the offset in the lower two bytes, both unsigned. The number bytes requested is SIZE[block]; the number of bytes read is returned in bytes.read. The result returned can take any of the following values: 

spr.ok	The read operation was successful.	
spr.bad.packet.size	Too many bytes were requested to be read: (SIZE[block]) > 
dos.max.receive.block.buffer.size.	
.spr.operation.failed	The read failed, so bytes.read = 0. If
result . spr.operation.failed then this denotes a server returned failure. (See section C.2 in the Toolset Reference Manual.)	

dos.send.block
PROC dos.send.block (CHAN OF SP fs, ts,
                     VAL INT32 location,
                     VAL []BYTE block,
                     INT len, BYTE result)
Writes a block of data to host memory, starting at location. The location is arranged as the segment in the top two bytes and the offset in the lower two bytes, both unsigned. 
The number of bytes requested to be written is SIZE[block]; the number of bytes written is returned in len. The result returned can take any of the following values:

spr.ok	The write operation was successful.	
spr.bad.packet.size	Too many bytes were requested to be written: (SIZE[block]) > 
dos.max.send.block.buffer.size.	
.spr.operation.failed 	The write failed. If result takes a value . spr.operation.failed then this denotes a server returned failure. (See section C.2 in the Toolset Reference Manual.)	

dos.call.interrupt
PROC dos.call.interrupt 
    (CHAN OF SP fs, ts,
     VAL INT16 interrupt,
     VAL [dos.interrupt.regs.size] BYTE register.block.in,
     BYTE carry.flag,
     [dos.interrupt.regs.size] BYTE register.block.out,
     BYTE result)

Invokes an interrupt call on the host PC, with the processor's registers initialized to requested values. On return from the interrupt the values stored in the processor's registers are returned in register.block.out, along with the value of the carry flag on the PC, which is stored in carry.flag. 
The interrupt number is specified by interrupt. The registers are represented by a block of bytes called register.block.in. This block stores the values to be written to the registers. Each register value occupies 4 bytes of a block. On the IBM PC the 2 most significant bytes are ignored as this machine has only 2 byte registers (16 bit registers). The layout of registers in the block is as follows:  

Register	Start position in block (least significant byte)	End position in block (most significant byte)	
ax	0	3	
bx	4	7	
cx	8	11	
dx	12	15	
di	16	19	
si	20	23	
cs	24	27	
ds	28	31	
es	32	35	
ss	36	39	

Note, however, that the cs and ss registers cannot be set.
The result returned can take any of the following values:

spr.ok	The interrupt was successful.	
.spr.operation.failed 	The interrupt failed. If result takes a value . spr.operation.failed then this denotes a server returned failure. (See section C.2 in the Toolset Reference Manual.)	

dos.read.regs
PROC dos.read.regs 
              (CHAN OF SP fs, ts,
              [dos.read.regs.size] BYTE registers,
              BYTE result)
Reads the current values of some registers of the PC. The values of the registers are returned as a block of bytes, each register occupying 4 bytes of the block:

Register	Start position in block (least significant byte)	End position in block (most significant byte)	
ax	0	3	
bx	4	7	
cx	8	11	
dx	12	15	

On the IBM PC the 2 most significant bytes are ignored as this machine has only 2 byte registers (16 bit registers).
The result returned can take any of the following values:

spr.ok	The read was successful.	
.spr.operation.failed	The read failed. If result takes a value . spr.operation.failed then this denotes a server returned failure. (See section C.2 in the Toolset Reference Manual.)	

dos.port.read 
PROC dos.port.read (CHAN OF SP fs, ts,
                    VAL INT16 port.location,
                    BYTE value, result)
Reads the value at the port, specified by the port address port.location. The port address being in the input/output space of the PC is an unsigned number between 0 and 64K.  
No check is made to ensure that the value received from the port (if any) is valid. The value returned in value is that of the given address at the moment the port is read by the host file server. 
The result returned can take any of the following values:

spr.ok	The read was successful.	
.spr.operation.failed	The read failed. If result takes a value . spr.operation.failed then this denotes a server returned failure. (See section C.2 in the Toolset Reference Manual.)	

dos.port.write
PROC dos.port.write (CHAN OF SP fs, ts,
                     VAL INT16 port.location,
                     VAL BYTE value, BYTE result)
Writes value to the port specified by the port address port.location. The port address being in the input/output space of the PC is an unsigned number between 0 and 64K.
No check is made to ensure that the value written to the port has been correctly read by the device connected to the port (if any). 
The result returned can take any of the following values:

spr.ok	The write was successful.	
.spr.operation.failed	The write failed. If result takes a value . spr.operation.failed then this denotes a server returned failure. (See section C.2 in the Toolset Reference Manual.)