

                               ABSLINK
                               _______
                     The TRIPOS absolute linker
                     __________________________
          The TRIPOS absolute linker is used to build an
       absolute object file representing the contents of the
       store of a TRIPOS memory space, which can then be
       loaded and started by the bootstrap loader, or run as
       a mapped task.  It is invoked as the command
            ABSLINK   "FROM/A,TO/A,MAP/K,OPT/K"
       The FROM argument should be the name of a file of
       directives for the linker describing the object file
       to be built, and the TO argument should be the name of
       the required object file.
       The MAP keyword may be used to obtain a map of the
       system, in which case it should be followed by a
       suitable filename for the mapping output.
       The OPT keyword may be used to supply options;
              Wn  sets the workspace size
              F   specifies full map output
              O   map values to be octal machine addresses
              X   map values to be hex hacnine addresses
          The basic action of the linker is to mimic the
       operation of LOADSEG in allocating store, loading code,
       and performing relocation, to load all the required
       segments, then to build the rootnode and other data
       structures required.  Store is allocated in blocks
       starting from the top of available memory, each block
       being constructed to look exactly like one obtained by
       a call of GETVEC.  The block list is then completed by
       a single free block extending from the bottom of memory
       containing the remaining free store, and the absolute
       store then written out.  Any segments used for system
       initialisation and then thrown away may be placed at
       the bottom of the allocated area, so that when they are
       freed the user will have a single contiguous lump of
       free store.  Absolute store - typically the rootnode
       and any machine dependent data areas, such as page
       zero, is overlaid; any non zero words will overwrite
       previously loaded words, but zeros will not overwrite,
       so that overlapping absolute hunks may be assembled
       correctly.

                                  1


          The linker operates in two phases: firstly it reads
       the directive file, checking for syntax errors and
       building a tree structure representing the directives;
       then it reads the required code segment files and
       writes out the object file.
          The directive file consists of a number of
       directives, each terminated by a semicolon.  Layout
       characters - space, tab, and newline - are ignored
       except within strings, after '$', or where they
       terminate words or numbers.  The character '|'
       indicates a comment, causing the rest of the line to
       be ignored.  Numbers are a string of digits, possibly
       with a leading '-', or '#', or '#X', to denote a
       negative, octal, or hexadecimal number.  Words are a
       string of letters, digits, '#', '-', '$', or any other
       characters without special meanings, not beginning with
       a digit or '#', '-', or '$'.  Strings are a string of
       characters not including newline delimited by '"'s; the
       usual escape combinations '*E', '*N', '*"' are allowed.
        <value>     ::= <number>
                    ::= <name>
                    ::= <string>
                    ::= ( <value> [ , <value> ]* )
                    ::= <structref>
       When a string is encountered a GETVECed vector is
       created for it and its value is the BCPL address of the
       vector.  Similarly a bracketed list is used to
       construct a vector containing the specified values, and
       its value is the address of the vector.
        <directive> ::= MCADDRINC <number>
       This defines the ratio of machine addresses to BCPL
       addresses;  defaults to that of the host machine.
        <directive> ::= ABSMIN <number>
                    ::= ABSMAX <number>
       These define the limits of the absolute store; defaults
       to 0 - 255.
        <directive> ::= RELMIN <number>
                    ::= RELMAX <number>
       These define the limits or the relocatable store, i.e.
       the store chain for GETVEC. One should be even, the
       other odd;  defaults to 256 - 64K-1.
                                  2


        <directive> ::= ROOT <number> <value> [ , <value> ]*
       This defines a root node at address <number> containing
       the specified values.
        <directive> ::= SEG <name> <file> [ , <file> ]*
                    ::= INITSEG <name> <file> [ , <file> ]*
        <name>      ::= <word>
        <file>      ::= <word>
                    ::= <string>
       These define a code segment to be loaded and declare
       <name> to have as value the BCPL address of the first
       relocatable hunk.
        <directive> ::= NAME <name> = <value>
       This declares <name> to have as value <value>.  The
       form <name> = <name> is illegal.
        <directive> ::= STRUCT <name>( <structmem>
                           [ , <structmem> ]* )
        <structmem> ::= <value>
                    ::= <structtag> [ <value> ]
        <structtag> ::= $<word>
        <structref> := <name>( <structtag> <value>
                           [ , <structtag> ,value> ]* )
       The STRUCT directive declares a structure template,
       that will be used, each time it is referenced, to
       create a vector containing the values specified in its
       definition merged with those specified when it is
       referenced.  The tags must be given in the correct
       sequence, and any that are omitted must have been given
       a default value in its definition.
          As an example the directives used to link an
       unmapped TRIPOS system for a PDP11/45 with an RK05 disc
       is given.
       | Unmapped TRIPOS system for PDP11/45
       mcaddrinc    2;
       absmin       0;
       absmax     159;
       relmin     160;
       relmax   28671;
       seg lib1    sys.obj.klib,sys.obj.mlib;
       seg lib2    sys.obj.blib,sys.obj.iolib;
       seg cli     sys.obj.cli;
                                  3


       seg abort   sys.obj.abort;
       seg cohand  sys.obj.cohand;
       seg fihand  sys.obj.fihand;
       initseg cli-init     sys.obj.cli-init;
       initseg cohand-init  sys.obj.cohand-init;
       initseg fihand-init  sys.obj.fihand-init;
       struct tcb($link, $id, $pri 100, 0, 12, 0,
                  $stack 100, $seglist, 0, 0, 0, 0,
                  0, 0, 0, 0, 0, 0, 0, 0);
       name task1 = tcb($link     0, $id 1, $pri 1000,
                        $stack 165, $seglist (4, lib1, lib2,
                                        cli-init, cli));
       name task2 = tcb($link task1, $id 2, $pri 2000,
                        $stack  10, $seglist (3, lib1, lib2,
                                        abort));
       name task4 = tcb($link task2, $id 4, $pri 4000,
                        $stack  50, $seglist (4, lib1, lib2,
                                        fihand, fihand-init));
       name task3 = tcb($link task4, $id 3, $pri 5000,
                        $stack 265, $seglist (4, lib1, lib2,
                                        cohand, cohand-init));
       name tasktab = (20, task1, task2, task3, task4,
                       0, 0, 0, 0, 0, 0, 0, 0,
                       0, 0, 0, 0, 0, 0, 0, 0);
       seg dev-1 sys.obj.clock-driver;
       seg dev-2 sys.obj.dk-driver;
       seg dev-3 sys.obj.console-driver;
       name devtab = (10, dev-1, dev-2, dev-3,
                      0, 0, 0, 0, 0, 0, 0);
       name info = ( "PDP11",
                      0,
                      3,
                      (5, cohand, fihand, 0, 0, 0),
                      (5, 1, 1, 0, 0, 0),
                      (10, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0)
                   );
       root 148 tasktab, devtab, task3, task1,
                160, task2, 0, 0, 0, 0, 28, info, 0;

                                  4






                 TRIPOS BCPL ( BLIB ) LIBRARY
                 ____________________________
                         AUGUST 1980
                         ___________


                     COMPUTER LABORATORY
                     ___________________
                   UNIVERSITY OF CAMBRIDGE
                   _______________________









 Documentation               -1-                 BLIB Library



                          CAPITALCH

       To convert a character to upper case.

       ch2 := capitalch ( ch )

       If the character 'ch' is any of a, b,...., z then  the
 result is the upper case version of that character ( ie., A,
 B,...., Z respectively ). Otherwise the result is  just  the
 character.










 BLIB Library                -2-                Documentation



                            COMPCH

       To compare two characters irrespective of case.

       res := compch ( ch1, ch2 )

       The two characters are upper case  if  required  (  by
 calls  of capitalch ( q.v. ) ), and then lexically compared.
 If ch1 occurs before ch2 in the ordering used on the machine
 then  the  result is negative; if they are the same then the
 result is zero; if ch1 occurs after ch2 then the  result  is
 positive.









 Documentation               -3-                 BLIB Library



                          COMPSTRING

       To lexically compare two strings.

       res := compstring ( s1, s2 )

       The  two  strings  are  lexically  compared  with  the
 characters  upper  cased.   If s1 occurs lexically before s2
 then the result will be negative; if they are the same  then
 the  result  will  be  zero;  if s1 occurs after s2 then the
 result will be positive.










 BLIB Library                -4-                Documentation



                            DELAY

       To cause a task to be delayed for a given time.

       res := delay ( ticks )

       A packet is sent  to  the  timer  with  the  specified
 number of ticks.
       The result is the value of the pkt.res1 field  of  the
 packet  when  it  returns  from  the  timer, and the result2
 global will be set to the pkt.res2 value.










 Documentation               -5-                 BLIB Library



                           ENDREAD

       The currently selected input stream is closed.

       endread ()

       The currently selected input stream is closed.  If  no
 stream is selected then endread has no effect.












 BLIB Library                -6-                Documentation



                          ENDSTREAM

       A specified input or output stream is closed.

       endstream ( stream )

       The specified stream, which should be the result os  a
 call of findinput ( q.v. ) or findoutput ( q.v. ) is closed.
 If the stream is zero then endstream has no effect.











 Documentation               -7-                 BLIB Library



                           ENDTASK

       To cause a task to end.

       endtask ( seg )

       If the specified segment is non-zero then it  will  be
 unloaded.  The deletetask kernel primitive is then called to
 delete the task.  If this should return  then  endtask  will
 abort  with  code  180;   continuing  the abort will cause a
 return from endtask.










 BLIB Library                -8-                Documentation



                           ENDWRITE

       The currently selected output stream is closed.

       endwrite ()

       The currently selected output  stream  is  closed.  If
 there is no selected stream then endwrite has no effect.












 Documentation               -9-                 BLIB Library



                            FAULT

       To convert an error code to an explanatory message.

       fault ( code )

       The object code "sys:c.fault" is called using  callseg
 (  q.v.  ).  The  explanatory message will be written to the
 currently selected output stream.











 BLIB Library                -10-               Documentation



                           FINDARG

       To search for an item in a string.

       res := findarg ( keys, string )

       The string is compared with the items  in  the  string
 'keys' to see if there is a match. If there is then a number
 corresponding to the item in 'keys' is returned as a  result
 (  first  item  being  numbered  zero  ),  otherwise  -1  is
 returned.
       The    'keys'    string    should    have   the   form
 "item1,item2,...,itemn".

       Examples :

       findarg ( "DP0:,DP1:,SYS:", "DP1:" )
       res <- 1
       findarg ( "DP0:,DP1:,SYS:", "FS4" )
       res <- -1



 Documentation               -11-                BLIB Library



                          FINDINPUT

       To find and open an input stream.

       s := findinput ( name )

       A unique identifier is returned which  refers  to  the
 stream  of  the  given  name.   The name should be a string,
 while the result is a non-zero value.
       If  the  stream  cannot  be  found  or opened then the
 result will be zero, and the  result2  global  will  usually
 contain an error code indicating a reason for this failure.
       The result may subsequently  be  used  in  a  call  of
 selectinput ( q.v. ) to select the stream.








 BLIB Library                -12-               Documentation



                          FINDOUTPUT

       To find and open an output stream.

       s := findoutput ( name )

       A unique identifier is returned which  refers  to  the
 stream.  The  name should be a string, and the result a non-
 zero value.
       If the stream cannot be opened then the result will be
 zero, and the result2 global will usually contain a code in-
 dicating a specific reason for the failure.
       The result may be subsequently be  used  in  calls  of
 selectoutput ( q.v. ) to select the stream for output.








 Documentation               -13-                BLIB Library



                            INITIO

       To initialise input-output globals.

       initio ()

       The current input and output stream globals are set to
 zero.  The  current directory global is set to zero, and the
 consoletask global is set to  the  default  console  handler
 task ( manifest task.consolehandler ).










 BLIB Library                -14-               Documentation



                            INPUT

       To determine the currently selected input stream.

       stream := input ()

       The input routine yields the identifier  of  the  cur-
 rently  selected input stream ( originally yielded by a call
 of findinput ( q.v. ) and selected by selectinput (  q.v.  )
 ). If there is no current stream then the result is zero.










 Documentation               -15-                BLIB Library



                           LOADSEG

       To load a load module into memory.

       res := loadseg ( file )

       The file should be  a  load  module  consisting  of  a
 series  of  interspersed 'relocatable hunk' and 'relocation'
 blocks ( manifest types t.hunk and t.reloc )  terminated  by
 an end ( t.end ) block. These are scatter loaded into memory
 in a series of getvec'ed blocks, chained together  on  their
 first words. The end of the chain is indicated by a zero.
       In the event of an error ( ubnrecongnised block  type,
 relocation  offsets outside hunk limits, no end block ) then
 any blocks loaded will be unloaded, the result2  global  set
 to 121, and a false ( zero ) result will be reutrned. In the
 envent of the file not being found the result is zero.
       If the module is correctly loaded then the result will
 be a pointer at the beginning of the list of  blocks,  which
 may be used at the argument to the 'globin' routine.




 BLIB Library                -16-               Documentation



                           NEWLINE

       To write a newline to the current output stream.

       newline ()

       A  newline  character  is  written  to  the  currently
 selected output stream. The routine is simply a call of wrch
 ( '*N' ).











 Documentation               -17-                BLIB Library



                            OUTPUT

       To identify the currently selected output stream.

       stream := output ()

       The output routine yields the identifier of  the  cur-
 rently selected output stream ( originally yielded by a call
 of findoutput ( q.v. ) and selected by selectoutput ( q.v. )
 ). If there is no current output stream then the result will
 be zero.










 BLIB Library                -18-               Documentation



                             PACK

       To pack the characters in a vector into a string.

       size := pack ( vector, string )

       The zero element of  the  vector  should  contain  the
 number of characters to be packed; this is anded with a mask
 of 255 ( =#XFF ) to prevent the string being longer than 255
 characters.
       The specified numbers of characters  are  then  packed
 into the string such that
       vector ! i -> string % i
 etc.  The  length  is  inserted, and any unused bytes in the
 last word of the string are set to zero. The string and vec-
 tor  may  be coincident ( ie., @vector = @string ), but they
 may not otherwise overlap.
       The result is the number of words used in the string.





 Documentation               -19-                BLIB Library



                           PKTWAIT

       To wait for a packet to be sent to the task.

       pkt := pktwait ()

       The pktwait routine calls taskwait  to  wait  for  the
 next  packet to be sent to the task, and returns this packet
 as its result.
       The  purpose  of  having  this  routine  is  to  allow
 redefinition of the exact funtion of taskwait without having
 to  lose  the  taskwait  primitive.  All  BLIB routines call
 pktwait rather then taskwait.








 BLIB Library                -20-               Documentation



                             RDCH

       To read the next character from the currently selected
 input stream.

       ch := rdch ()

       A call of rdch yields the next sequential character of
 the currently selected input stream, unless that  stream  is
 exhausted,  in which case the end-of-stream character ( end-
 streamch ) is returned.










 Documentation               -21-                BLIB Library



                            RDITEM

       To read an item from the input stream.

       res := rditem ( vec, size )

       An item is read from the input stream (  normally  the
 command  line  ) and placed in the vector 'vec' as a string.
 Unused bytes in the vector are set to zeroes.
       The  result is -2 if an equal symbol is encountered, 0
 for the '*N', '*E', and endstreamch characters, 1 if an  un-
 quoted  string  is found, 2 if a quoted string occurs, or -1
 in the event of an error ( the item is too big for the  vec-
 tor; 'size' should be the size of 'vec' in words ).
       All strings, quoted  or  unquoted,  are  teminated  by
 '*N', '*E', and endstreamch characters. Unquoted strings are
 also terminated by ';', '=', and space.

       Examples :
       DP0: INIT :L.FH-INIT-X
       vec <- "DP0:"
       "BSP:PRINT/ TEST " ; SET

 BLIB Library                -22-               Documentation


       vec <- "BSP:PRINT/ TEST "

















 Documentation               -23-                BLIB Library



                            READN

       To read a number from the current input stream.

       n := readn ()

       Characters are read from the currently selected  input
 stream until one is found that is not a space, a newline, or
 a tab character.  Unless it is a digit or a plus  or  minius
 sign  the  result  is  zero and the result2 global is set to
 minus one and the character is unread ( unrdch ).
       A  number  is  then read comprising a following conti-
 gious string of digits.  There is no chack for numeric over-
 flow.  The  number  is terminated by the first non-digit en-
 countered, and this character  unread.  The  result  is  the
 number, and the result2 global is set to zero.
       Note that a plus or minus sign which is  not  followed
 by a digit will be read as zero.





 BLIB Library                -24-               Documentation



                          RETURNPKT

       To return a packet to its sender.
       res := returnpkt ( pkt, res1, res2 )

       The res1 and res2 values are set into the pkt.res1 and
 pkt.res2 fields of the packet, and the  packet  then  trans-
 mitted using the qpkt primitive.  The result of returnpkt is
 the result of the call of qpkt.











 Documentation               -25-                BLIB Library



                         SELECTINPUT

   To select a stream for input.

       res := selectinput ( stream )

       The stream, which should be the result of  a  call  of
 findinput  (  q.v.  ) is selected and made the current input
 stream. A true result is returned.
       If the stream is not valid then the routine will abort
 with code 186.  Continuing the abort will cause  the  stream
 to  be  selected  anyway;  however this is likely to lead to
 fatal consequences later.








 BLIB Library                -26-               Documentation



                         SELECTOUTPUT

       A stream is selected for output.

       res := selectoutput ( stream )

       The specified stream, which should be the result of  a
 call  of  findoutput ( q.v. ), is selected and made the cur-
 rent output stream. A true result is returned.
       If the stream is not valid then the routine will abort
 with code 187. If this abort is continued  then  the  stream
 will  be  selected anyway; however this is likely to lead to
 fatal consequences later.








 Documentation               -27-                BLIB Library



                           SENDPKT

       A packet is transmitted, and its return awaited.

       res := sendpkt ( link, id, type, r1, r2, a1,..., a6 )

       The packet which makes up the argument is  sent  using
 qpkt, and pktwait called to await its return.
       If the call of qpkt fails  then  sendpkt  aborts  with
 code  181; continuing the abort causes a return from sendpkt
 with an undefined result.
       Unless the call of pktwait yields the same packet that
 was transmitted, sendpkt aborts with  code  182;  continuing
 this abort causes it to await the next packet.
       If the packet is transmitted and  received  correctly,
 then  the  result  is the value of the pkt.res1 field of the
 packet, and the result2 global is set to the pkt.res2 value.






 BLIB Library                -28-               Documentation



                            SPLIT

       To split a string on the first  occurance  of  a  par-
 ticular character.

       pos := split ( prefix, ch, string, ptr )

       The  string  'string'  is split on the character 'ch',
 except that all characters before that  indicated  by  'ptr'
 are  ignored.  The  substring  up  to  but not including the
 character 'ch ' is  put  into  'prefix'.  The  result  is  a
 pointer  at  the first character after 'ch', or zero if 'ch'
 is not found. If the prefix part of  the  string  is  longer
 than thirty characters then those after the first thirty are
 ignored.
       Examples :
       split ( pfx, ':', "sys:c.echo", 0 )
       pfx <- "sys"
       res <- 5
       split ( pfx, ':', "bsp:print/sys:boggle", 5 )
       pfx <- "print/sys"
       res <- 15

 Documentation               -29-                BLIB Library



                         UNPACKSTRING

       To unpack the length count and characters in a  string
 into a vector, one to a word.

       unpackstring ( string, vector )

       The  length  and characters in the string are unpacked
 one to a word into the vector, such that
           string % 0 -> vector ! 0
 etc. The string and vector may be coincident ( ie.,  @string
 = @vector ) but they may not otherwise overlap.









 BLIB Library                -30-               Documentation



                            UNRDCH

       To push a character back into the  currently  selected
 input   stream  so  that  the  next  rdch  will  yield  that
 character.

       res := unrdch ()

       The last character read is pushed back into  the  cur-
 rently  selected  input steam ( ie., the steam is backspaced
 by one character ). The routine returns a true result unless
 an  attempt is made to move past the buffer origin, in which
 case the result is false and unrdch has no effect  (  unless
 the stream is exhausted, in which case it is true anyway ).
       The implementation of unrdch and rdch is such that  it
 is always possible to perform at least one unrdch.






 Documentation               -31-                BLIB Library



                             WRCH

       To write a character to the currently selected  output
 steam.

       wrch ( ch )

       The  character  is  written  to the currently selected
 output stream.
       If  the  output  steam is interactive then writing the
 characters '*N' ( newline ), '*P' ( newpage ), '*C'  (  car-
 riage return ), or '*E' ( empty buffer ) will cause the out-
 put buffer to be flushed and output.








 BLIB Library                -32-               Documentation



                            WRITED

       To write a number to the current output  stream  is  a
 given field width.

       writed ( n, w )

       The  number  'n'  is written in a field of 'w' spaces,
 except that if the field is not wide enough then it will  be
 expanded  to  the necessary size.  The number will be right-
 justified in the field, and the field will  be  padded  with
 blanks.









 Documentation               -33-                BLIB Library



                            WRITEF

       To write out formated data.

       writef ( format, a, b,..., k )

       The  'format'  is  a  string.  This  is  written   out
 character  by  character  as for writes ( q.v. ) except that
 when a percent ( % ) character is encountered, the next item
 from  'a',  'b', etc., is taken, and written out in a format
 dependant on the character or characters directly  following
 the %.
       The options are as follows :
      %S  Write argument as a string.
      %Tn   Write arguement as  a  string  in  a  field  of n
 places.
          n should be 0,...., 9, A,......
      %C  Write argument as a character.
      %On   Write argument in octal in a field of n places.
          n should be 0,...., 9, A,......
      %Xn  Write as for %O but in hexadecimal.
      %In  Write as for %O but in decimal.
      %N  Write in decimal.
      %Un  Write as for %O but in unsigned decimal.

 BLIB Library                -34-               Documentation


       For the cases of writing in a given field  width,  the
 truncation  and padding schemes are as for the corresponding
 direct routines ( ie., writet ( q.v. ), writeoct (  q.v.  ),
 etc. ).
       If the character following the % is  not  one  of  the
 above  then that character is written out. Hence to output a
 % the string 'format' should contain %%.
       Note  that strings that are written out ( %S and %Tn )
 are not processed for percent symbols.












 Documentation               -35-                BLIB Library



                           WRITEHEX

       To write out a number in hexadecimal format.

       writehex ( n, w )

       The number 'n' is written to  the  currently  selected
 output  stream  in  hexadecimal  format  in  a  field of 'w'
 spaces. If the field is not wide enough then only the lowest
 order 'w' digits are written. Otherwise the number is right-
 justified in the field and padded with zeroes.










 BLIB Library                -36-               Documentation



                            WRITEN

       To write out a number.

       writen ( n )

       The number 'n' is written to  the  currently  selected
 output  stream  in  a  field  that  is just wide enough. The
 routine is simply a call of writed ( n, 0 ) ( q.v. ).











 Documentation               -37-                BLIB Library



                           WRITEOCT

       To write out a number in octal format.

       writeoct ( n, w )

       The speccation of this  routine  is  exactly  that  of
 writehex ( q.v. ), except that octal format is used.












 BLIB Library                -38-               Documentation



                            WRITES

       To write a string.

       writes ( string )

       The string is written to the currently selected output
 stream,  character  by  character,  using the wrch routine (
 q.v. ). If the stream is interactive then newline,  newpage,
 carriage return, or buffer flushing ( '*E' ) characters will
 cause the output buffer to be flushed.










 Documentation               -39-                BLIB Library



                            WRITET

       To write a string in a field of given width.

       writet ( string, w )

       The string is written to the currently selected output
 stream  in  a  field  of  'w' spaces. If the field is insuf-
 ficiently wide then it is expanded as  necessary,  otherwise
 the  string  is left-justified in the field and the field is
 padded with blanks.










 BLIB Library                -40-               Documentation



                            WRITEU

       To write out a number in unsigned decimal format.

       writeu ( n, w )

       The number 'n' is written to  the  currently  selected
 output  stream  in unsigned decimal format in a field of 'w'
 spaces. If the field is not wide enough then it will be  ex-
 panded,  otherwise the number will be right-justified in the
 field and the field will be padded with blanks.










 Documentation               -41-                BLIB Library








                       TRIPOS Data Structures
                       ______________________
                            Brian Knight
                           September 1979






              (C) Copyright 1979 TRIPOS Research Group
             University of Cambridge Computer Laboratory
                        Corn Exchange Street
                              Cambridge
                               CB2 3QG




                              Contents
                              ________
                 1  Introduction
                 2  The Root Node
                 3  The Task Table
                 4  Task Control Blocks
                 5  The TCB List; Task Scheduling
                 6  The Device Table
                 7  Device Drivers
                 8  Packets
                 9  Work Queues
                 10 Store Allocation
                 11 Stream Control Blocks









       TRIPOS                    -1-           Data Structures


                           1  Introduction
                           _______________
           The data structures described below are those which
       are machine independent.  Except where otherwise
       stated, all pointers are BCPL pointers; the value zero
       is usually used as a null pointer (e.g. to mark the end
       of chains).  In the box diagrams, each cell represents
       one machine word.















       TRIPOS                    -2-           Data Structures


                          2  The Root Node
                          ________________
            +-----------+
            |  TASKTAB -+--> Pointer to the task table
            |           |
            |-----------|
            |  DEVTAB  -+--> Pointer to the device table
            |           |
            |-----------|
            |  TCBLIST -+--> Pointer to the TCB of the
            |           |    highest priority task
            |-----------|
            |  CRNTASK -+--> Pointer to the TCB of the
            |           |    task currently running
            |-----------|
            |  BLKLIST -+--> Pointer to the block list
            |           |    for storage allocation
            |-----------|
            |  DEBTASK -+--> M/c address of TCB of DEBUG task.
            |           |    Used by kernel on traps, etc.
            |-----------|
            |   DAYS    |    since start of 1978
            |           |
            |-----------|
            |   MINS    |    since midnight
            |           |
            |-----------|
            |   TICKS   |    clock ticks in current minute
            |           |
            |-----------|
            |   CLKWQ  -+--> Pointer to the first packet on
            |           |    the clock work queue
            |-----------|
            |  MEMSIZE  |    memory size in units of 1K words
            |           |
            |-----------|
            |   INFO   -+--> Pointer to vector of extra
            |           |    (implementation dependent) info
            |-----------|
            |  KSTART  -+--> M/c address of kernel entry
            |           |    point (used by bootstrap)
            |-----------|
            | entry     |
            | points of |    Implementation dependent
            | kernel    |
            | m/c code  |
            | routines  |
            | used by   |
            | device    |
            | drivers   |
            +-----------+
       TRIPOS                    -3-           Data Structures


           The root node is the central point from which all
       the system structures in store can be found.  It is a
       vector containing pointers to the main chains and
       tables.  The position in store of the root node is
       fixed on any given machine.  Unfortunately, it is not
       practical to use the same address on all machines;
       instead, it is given as the manifest constant ROOTNODE
       in the standard BCPL library header for each machine.
           The first part has a machine independent format.
       It is followed by some addresses of kernel entry points
       for such operations as saving and restoring registers
       on interrupts, and entering the task selector.  These
       are needed by device drivers which may be dynamically
       loaded, so must be in fixed store locations.

       BLKLIST
       _______
           This points to the start of the area from which
       store is allocated by GETVEC.  For details of the
       format of store blocks, see section 10.

       DAYS, MINS and TICKS
       ____________________
           The clock interrupt routine maintains the date and
       time in these three words.  DAYS is the number of days
       since the start of 1978 (i.e. 1st Jan 1798 is day 0).
       MINS is the number of minutes since midnight.  TICKS
       is the number of clock ticks since the last minute
       boundary.  The time is updated at an implementation
       dependent frequency given by the manifest constant
       TICKSPERSECOND.

       INFO
       ____
           The INFO field is provided so that extra
       information may be made available from the root node
       without making any change to root node format.  For
       example, it may point to a vector containing details
       of machine type, the machine name as a string, and/or
       the identities of particular non-resident tasks.

       TRIPOS                    -4-           Data Structures


       KSTART
       ______
           This value is assembled into the rootnode, and is
       the means by which the bootstrap finds the kernel entry
       point after loading the system into store.
















       TRIPOS                    -5-           Data Structures


                          3  The Task Table
                          _________________
       TASKTAB ->+------------+
                 | UPPERBOUND |    Maximum valid table offset
                 |------------|
                 |           -+--> Pointer to TCB of task 1
                 |------------|
                 |           -+--> Pointer to TCB of task 2
                 |------------|
                 |            |
                 /            /
                 /            /
                 |            |
                 |------------|
                 |           -+--> Pointer to the TCB of
                 +------------+    task UPPERBOUND
           This table enables a task control block to be found
       from its corresponding task id.  Unused elements
       contain zero.










       TRIPOS                    -6-           Data Structures


                       4  Task Control Blocks
                       ______________________
         -->+--------------+
            |     LINK    -+--> Points to the TCB of next
            |              |    highest priority
            |--------------|
            |    TASKID    |    The task's identity
            |              |    (a positive integer)
            |--------------|
            |   PRIORITY   |    (a positive integer)
            |              |
            |--------------|
            |    WORKQ    -+--> Points to the first packet
            |              |    on the task's work queue
            |--------------|
            |    STATE     |    The task state (see below)
            |              |
            |--------------|
            |    FLAGS     |    The break flags
            |              |
            |--------------|
            |  STACKSIZE   |    Upperbound of the store block
            |              |    for BCPL stack & global vector
            |--------------|
            |   SEGLIST   -+--> Points to the code segments
            |              |    for the task
            |--------------|
            |  GLOBALBASE -+--> Points to global zero
            |              |
            |--------------|
            |  STACKBASE  -+--> Pointer to base of root stack
            |              |
            |--------------|
            |              |
            /              /
                                Save area
            /              /
            |              |
            |--------------|
           Each task in the system has a task control block
       (TCB) which contains information relating to the task.
       There are two parts to a TCB.  The first part is
       machine independent, and contains information used by
       the operating system for controlling the task.  The
       second part contains the save area used to hold the
       machine registers, program counter, and processor
       status, when a task suspends itself or is interrupted.
       Its format is necessarily machine dependent.

       TRIPOS                    -7-           Data Structures


       The Task State
       ______________
           This is held in the least significant 4 bits of the
       state field.  All the remaining bits are zero.  The
       significance of each bit is as follows:-
         0001: Packet bit.
                   If this bit is set, the task has at least
               one packet on its work queue.  If clear, then
               the work queue is empty.
         0010: Held bit.
                   This bit is set when the task is in held
               state.  It means that the task will not be
               selected for running, even though it might
               otherwise be eligible.  Its primary purpose is
               as a debugging aid.
         0100: Wait bit.
                   This is set when the task has called
               TASKWAIT, and is waiting for a packet to
               arrive.  The task will not run while its work
               queue is empty.
         1000: Interrupted bit.
                   When this bit is set, the task has been
               interrupted.  The task will run again when the
               interrupt service routine is complete, and any
               higher priority tasks it may have activated are
               once again held up.
         1100: Dead state.
                   Note that this bit pattern would otherwise
               be invalid, as a waiting task could not be
               interrupted, and an interrupted task could not
               call TASKWAIT.  It indicates that the task is
               dead or dormant, with no BCPL stack or global
               vector.  The only other TCB fields which are
               valid are the LINK, PRIORITY, STACKSIZE, and
               SEGLIST.
           All of the 16 possible bit patterns are valid.
       This means that the the task selector can rapidly
       decide how to deal with a task, by using the state to
       index a table of routine addresses.


       TRIPOS                    -8-           Data Structures


       FLAGS
       _____
           These also indicate states of the task, but do not
       affect scheduling, and so live in a separate word.
       They are set and tested by using the kernel primitives
       SETFLAGS and TESTFLAGS.  They are useful as a cheap
       signal between tasks, and are used to implement break.
           The console handler responds to typed characters
       ctrl/B,C,D and E by setting flags #B0001 to #B1000
       respectively in the currently selected task.
       Conventionally, the #B0001 flag is recognised by
       commands and causes them to finish.  Flag #B0010 is
       inspected by the CLI between commands, and causes
       termination of command sequences.

       SEGLIST
       _______
           This pointer leads to all the program sections
       which comprise the code of the task.  The TCB pointer
       addresses a vector, each element of which either points
       to a chain of BCPL sections, or is zero.
       SEGLIST
             |
             
          +-----+
          | UPB |    Upperbound of vector
          |-----|
          |    -+-->
          |-----|
          |    -+-->+---------+   +---------+   +---------+
          |-----|   |        -+-->|        -+-->|    0    |
          |     |   |---------|   |---------|   |---------|
          /     /   |         |   |         |   |         |
                    |   One   |   |         |   |         |
          /     /   |   BCPL  |   |         |   |         |
          |     |   | section |   |         |   |         |
          |-----|   |         |   |         |   |         |
          |  0  |   +---------+   +---------+   +---------+
          |-----|
          |  0  |  (i.e. unused)
          |-----|
          |    -+-->
          |-----|
           Conventionally, the first two pointers are used for
       the machine code and BCPL resident libraries.
       TRIPOS                    -9-           Data Structures


       TRIPOS BCPL Section Format
       __________________________
            +-----------------+
            |     LENGTH      | in words
            |-----------------|
            |     SECWORD     | (For MAPSTORE - optional)
            |-----------------|
            |  SECTION  NAME  | as a BCPL string (optional)
            |                 |
            /                 /
                 Compiled
                   code
            /                 /
            |                 |
            |-----------------|
            |        0        |
            |-----------------|
            |  GLOBAL NUMBER  |
            |-----------------|
            |     OFFSET      |
            |-----------------|
            |                 |
            /                 /
            /                 /
            |                 |
            |-----------------|
            |  GLOBAL NUMBER  |
            |-----------------|
            |     OFFSET      |
            |-----------------|
            |  GLOBAL NUMBER  |
            |-----------------|
            |     OFFSET      |
            |-----------------|
            |     H.R.G.      | Highest Referenced Global
            |-----------------|
           The diagram shows the standard layout of a BCPL
       section for use under TRIPOS.  The length field gives
       the total number of words in the section (including
       itself).  The name follows immediately - its length
       need not be fixed, since it is a BCPL string.  The end
       of the section contains the information needed to set
       up the global vector.  The last word is the highest
       global number referenced in the section.  This is
       preceded by a list of word pairs, giving the numbers
       of globals defined, and the word offsets in the section
       of the corresponding routines.  The list is terminated
       by a word containing zero.
       TRIPOS                   -10-           Data Structures


                           5  The TCB list
                           _______________
           As well as being addressed by the task table, the
       TCBs are linked into a chain, for the benefit of the
       scheduler.  The TCBLIST field of the root node points
       to the TCB of highest priority, whose link field points
       to the TCB of next highest priority.  The chain links
       all the TCBs in order of decreasing priority, ending
       with that of the idle task, which has a priority of
       zero, and link of zero.  No two tasks may have the same
       priority, so the correct chain order is well defined.
           The scheduling rule is very simple: the highest
       priority task which is free to run is the one that
       should be running.  A task is free to run if it is not
       held, and, if it is waiting or dead, its work queue is
       not empty.  Whenever the task selector is entered, it
       is handed the TCB of the highest priority task which
       might be runnable.  If it cannot run this task, it just
       chains down the TCB list until it finds one that it can
       run.  The idle task is always free to run, so the task
       selector cannot fall off the end of the chain.










       TRIPOS                   -11-           Data Structures


                         6  The Device Table
                         ___________________
       DEVTAB->+------------+
               | UPPERBOUND |    Maximum valid table offset
               |------------|
               |            |    (unused)
               |------------|
               |           -+--> Pointer to DCB of device -2
               |------------|
               |           -+--> Pointer to DCB of device -3
               |------------|
               |            |
               /            /
               /            /
               |            |
               |------------|
               |           -+--> Pointer to DCB of
               |------------|    device -UPPERBOUND
           This table is used to find the device control block
       from the corresponding device id.  Unused locations
       contain zero.  Device ids are negative integers; the
       value -1 is used for the clock.









       TRIPOS                   -12-           Data Structures


                          7  Device Drivers
                          _________________
              DCB                   Driver
       -->+-----------+         +-----------+
          |   LINK   -+-------->|     0     |
          |-----------|         |-----------|
          | DEVICE ID |         |   INIT   -+--+
          |-----------|         |-----------|  |
          |  WORK Q   |         |  UNINIT  -+--+--+
          |-----------|         |-----------|  |  |
          |   START  -+-----+   |           |<-+  |
          |-----------|     |   |           |     |
          |   STOP   -+--+  |   |           |<----+
          |-----------|  |  +-->|   code    |
          |           |  |      |    of     |
          |  machine  |  +----->|  driver   |
          | dependent |         |           |
          |           |         |           |
          | includes  |         |           |
          | pointer to|         |           |
          | interrupt |         |           |
          | routine  -+-------->|           |
          | in driver |         |           |
          |           |         |           |
          +-----------+         |           |
                                |           |
                                |           |
                                |           |
                                +-----------+
           A device consists of a device control block (DCB)
       which points to a device driver.  In practice, the
       assembled code of devices is often stored as two
       concatenated object modules, so that this link is
       automatically established when they are loaded by
       LOADSEG.  However, as there are no backward pointers,
       a driver may be shared by several DCBs.
           As the way in which peripherals are controlled
       varies considerably between machines and types of
       device, only the first few words of DCBs and drivers
       have a machine independent format.  Also, as most of
       the fields are accessed only from the machine code
       written drivers and kernel primitives, all pointers
       except the link and work queue are machine addresses.


       TRIPOS                   -13-           Data Structures


           A driver contains five machine code subroutines
       called from outside:
       INIT:  Called by CREATEDEV when the device is created.
              It sets up the pointers to the START, STOP and
              INT(errupt) routines in the DCB, and performs
              any action necessary to initialise the device
              (such as setting up the interrupt vector).
       UNINIT: Called by DELETEDEV.  Performs any action
              necessary to uninitialise the device (often
              nothing).
       START: Called by QPKT when putting a packet on a
              previously empty work queue.  Should initiate
              the action requested in the packet.
       STOP:  Called by DQPKT when removing the head packet
              from the work queue.  Should cancel the action
              currently in progress.
       INT:   The interrupt routine.  It is called in a way
              which makes the address of the corresponding DCB
              available.  Usually, the interrupt indicates
              that the last action is complete or has failed,
              so the INT routine puts a return code in the
              head packet, sends it back, and initiates the
              action requested by the next packet (if any).








       TRIPOS                   -14-           Data Structures


                             8  Packets
                             __________
           Under TRIPOS, all communication between tasks,
       device drivers, and the timer, is performed by sending
       packets.  A packet is a vector of at least two words.
       The first two words are used by the system; any further
       words are available for data.  The conventional format
       is as follows:-

         -->+-----------+
            |   LINK   -+--> To next packet on work queue
            |-----------|
            | DEVTASKID |    Identifies destination or sender
            |-----------|
            |   TYPE    |    Packet type or action
            |-----------|
            |   RES1    |    First result
            |-----------|
            |   RES2    |    Second result
            |-----------|
            |   ARG1    |    First argument
            |-----------|
            |   ARG2    |    Second argument
            |-----------|
            |   ARG3    |    Third argument
            |   etc.    |
            |           |

           The LINK field is used when the packet is on a work
       queue.  It points to the first packet to arrive after
       the current one, or contains zero if this one is on the
       end of the queue.  Whenever a packet is not queued, the
       link should contain the value of the manifest constant
       NOTINUSE.
           Before QPKT is called to send a packet, the
       DEVTASKID field should be set to indicate the
       destination.  Values less than or equal to -2 indicate
       devices, -1 means the clock, and values greater than
       zero refer to tasks.  The value zero is invalid.  As
       QPKT sends the packet, it overwrites this field with
       the identity of the sender.  In practice, packets are
       nearly always returned to their senders, so it is
       useful to have this field altered automatically.
           By convention, the third word is used to specify
       the type or requested action of the packet.  The two
       result fields are in general not looked at by the
       TRIPOS                   -15-           Data Structures


       receiver of the packet, but are used to return results
       or error codes.  The number and format of the arguments
       are entirely up to the users of the packet.  The
       arguments and type field should not be overwritten by
       the receiver, so that the packet can reused without
       modification by the sender.















       TRIPOS                   -16-           Data Structures


       Packets to Device Drivers
       _________________________
       Single Character Devices
       ________________________
           The single character devices have only one function
       each, so there is no need for a function code in a
       packet sent to them.
       Input:
            +-----------+
            |   LINK   -+-->
            |-----------|
            | DEVTASKID |
            |-----------|
            |   TYPE    |
            |-----------|
            | I/P CHAR  |
            |-----------|
            |   RES2    |  (normally unused)
            +-----------+

       Output:
            +-----------+
            |   LINK   -+-->
            |-----------|
            | DEVTASKID |
            |-----------|
            |   TYPE    |
            |-----------|
            |   RES1    |
            |-----------|
            |   RES2    |
            |-----------|
            | O/P CHAR  |
            +-----------+




       TRIPOS                   -17-           Data Structures


       Disc packets
       ____________
            +-----------+
            |   LINK   -+-->
            |-----------|
            | DEVTASKID |
            |-----------|
       TYPE |  ACTION   |    Requested device action
            |-----------|
       RES1 |  STATUS   |    Return code from driver
            |-----------|
       RES2 |  ERRCODE  |    More info on error
            |-----------|
       ARG1 |  BUFFER  -+--> Points to buffer in store
            |-----------|
       ARG2 | WORDCOUNT |    Size of transfer
            |-----------|
       ARG3 |   DRIVE   |    Disc drive number
            |-----------|
       ARG4 | CYLINDER  |    Cylinder address
            |-----------|
       ARG5 |  SURFACE  |    Surface address
            |-----------|
       ARG6 |  SECTOR   |    Sector address
            +-----------+
           A packet sent to the disc driver must have values
       set in all the ARG fields.  The action codes are given
       as the manifest constants ACT.READ, ACT.WRITE and
       ACT.SEEK.
           When the requested action is a read, WORDCOUNT
       words are read from the specified disc address to the
       store buffer.  For a write, WORDCOUNT words are copied
       from the buffer to the disc block.  The STATUS field
       is used to indicate errors.  If the transfer is
       successful, it is set to 0; any other value means that
       an error occurred.




       TRIPOS                   -18-           Data Structures


       Timer Packets
       _____________
            +-----------+
            |   LINK   -+-->
            |-----------|
            |    -1     |    Timer ID
            |-----------|
            |   TYPE    |
            |-----------|
       RES1 |           |    (corrupted by clock)
            |-----------|
       RES2 |           |
            |-----------|
       ARG1 |   DELAY   |    Requested delay
            +-----------+
           In packets to the timer, the requested delay in
       clock ticks is placed in the ARG1 field.  After this
       number of ticks have occurred, the packet will come
       back.  Note that the requested delay is not
       overwritten, so the packet can immediately be returned
       to the timer for another delay of the same length.










       TRIPOS                   -19-           Data Structures


                           9  Work Queues
                           ______________
           Packets are not moved in store; when they are
       "sent", they are simply linked into a chain called a
       work queue.  Tasks and devices process packets in the
       order in which they arrive, so a new packet is linked
       on the end of the work queue.  Packets are removed from
       the head of the queue, which is addressed by a field
       in the TCB or DCB.
           The timer's work queue is different, in that the
       packets are chained in order of increasing time value.
       This is for efficiency reasons: on each clock
       interrupt, the service routine must check whether any
       packets have expired.  With the ordered queue, the head
       packet must expire first, so usually is the only one
       that has to be inspected.  If several packets contain
       the same time, then they will be adjacent in the queue.
       QPKT does the job of linking a new packet into the
       correct place.
           The head of the clock work queue is in the root
       node.










       TRIPOS                   -20-           Data Structures


                         10 Store Allocation
                         ___________________
           Blocks of store are allocated and freed by the
       kernel primitives GETVEC and FREEVEC.  Store is
       allocated from an area which starts at the address
       given by the BLKLIST field of the root node.  This area
       is divided into contiguous blocks, which each consist
       of an even number of words.  The first word of each
       block is used both to indicate the length of the block
       (and hence the start of the next), and to record
       whether or not the block is allocated.  As all block
       lengths are even, the least significant bit of the
       length is not needed, and so this is used to indicate
       allocation:
       Free block:
            +----------------+
            |      n       |1|
            |----------------|
            |                |
            |                |
            |   2n-1 words   |
            |                |
            |                |
            +----------------+
       Allocated block:
            +----------------+
            |      n       |0|
            |----------------|
            |                |
            |                |
            |   2n-1 words   |
            |                |
            |                |
            +----------------+
           The end of the block list is marked by a word
       containing zero.



       TRIPOS                   -21-           Data Structures


                      11 Stream Control Blocks
                      ________________________
           Stream control blocks (SCBs) are created and
       returned by the BLIB functions FINDINPUT and
       FINDOUTPUT, and may be used as arguments to SELECTINPUT
       and SELECTOUTPUT.
           Their format is as follows:
            +-----------+
            |   LINK    |    (unused)
            |-----------|
            |    ID     |    direction of stream
            |-----------|
            |   TYPE    |    handler id / whether interactive
            |-----------|
            |    BUF   -+--> Pointer to buffer
            |-----------|
            |    POS    |    current char pos in buffer
            |-----------|
            |    END    |    size of buffer in chars
            |-----------|
            |   FUNC1   |    function called by REPLENISH
            |-----------|
            |   FUNC2   |    function called by DEPLETE
            |-----------|
            |   FUNC3   |    called by ENDREAD/ENDWRITE
            |-----------|
            |   ARG1    |
            |-----------|    use of these arguments depends
            |   ARG2    |    on type of stream
            +-----------+
           ID can take one of two values: ID.INSCB for an
       input stream, or ID.OUTSCB for an output stream.
           TYPE is negative for an interactive stream, or
       positive for a non-interactive stream.  ABS TYPE is the
       task id of the handler for the stream.
           FUNC1 is the routine which fetches a new input
       buffer.
           FUNC2 is the routine which sends off an output
       buffer.
           FUNC3 closes the stream.

       TRIPOS                   -22-           Data Structures



                                DEBUG
                                _____
          The DEBUG task in TRIPOS provides a means for the
       user to monitor and modify the code or data of any
       other task in the system, or of the kernel or device
       drivers.  It has facilities for debugging user
       programs, and also for handling aborts, whether they
       occurr in a task which is regarded as a user program,
       or one of the standard system tasks.  Some parts are
       necessarily machine dependent, as DEBUG can operate at
       the level of the machine instructions, but the list of
       available commands should be almost identical in all
       implementations.
          DEBUG can run in either of two modes: as a TRIPOS
       task communicating with the user via the console
       handler in the normal way, or in standalone mode with
       machine interrupts turned off driving the console
       keyboard and output device directly.  Standalone mode
       is entered while handling an abort or breakpoint, so
       that the normal operation of TRIPOS is suspended.
       DEBUG is also entered after CTRL/A is keyed on the
       console; the console handler calls ABORT to enter DEBUG
       in standalone mode, passing the taskid of the broken
       task to DEBUG as an argument.  It is also possible to
       enter DEBUG in standalone mode by restarting the
       machine at the kernel standalone restart address - this
       is for debugging after a system crash.
       Location Names and the Current Expression
       _________________________________________
          Store locations are referenced through names, a name
       being a single letter followed by an argument, e.g.
       'G100' means global variable 100 of the selected task,
       'A1200' means absolute store location 1200, 'L1' means
       local variable 1 - the second argument on the BCPL
       stack frame which must have previously been set up by
       one of the 'E' commands (qv.).  The registers may be
       referenced by 'R' - but only after an abort or
       breakpoint - and TCB locations by 'W'.  'Y' refers to
       absolute store, suppressing address checking; normally
       all storage references are checked to ensure that they
       are within the limits of the memory and are not
       breakpoints; this feature allows access to memory
       mapped status registers etc.. Ten variables V0 - V9 are
       available for workspace or to hold temporary results.
          DEBUG maintains a current expression, which consists
       of the last expression typed that was not a command
       argument.  It is reset whenever an unexpected operand
                                  1


       is typed and modified whenever a dyadic operator is
       typed followed by an operand.  The command '=' types
       the value of the current expression, so, for example,
       the sequence '3+4=-1' types 7 then 6.  Certain commands
       reference the current location; these are only valid
       when the current expression is in the form of a name.
       Examining and Updating Named Locations
       ______________________________________
          The command '/' will cause the current location to
       be opened, and the value it contains to be typed.  The
       command 'N' will select the next consecutive location
       and open it.  'T' will type the contents of successive
       locations starting with the current location; it should
       be followed by an argument to indicate the number of
       locations to be typed.  'I' and 'J' perform BCPL and
       machine address indirection through the current value
       and open the resulting location.
          The style in which values are typed may be set by
       the '$' command:  '$C' prints two ASCII characters,
       '$F' attempts to print a function name, otherwise it
       prints in decimal, '$D' prints in decimal, '$X' prints
       in hexadecimal, '$O' in octal, and '$U' in unsigned
       decimal; the initial style is '$F'.  If the style is
       set immediately after a '=' command or while a location
       is open then it is only set temporarily, the value is
       typed and the style reverts to the old style when the
       location is closed.
          The command 'U' can be used to update the current
       location, if it has been opened; it should be followed
       by an expression representing the required new value.
       A newline or any command other than '$', '=', 'U' will
       cause the location to be closed; any other command that
       does not open a new location will cause the style to
       revert.  Alternatively, a location may be updated with
       the current value by the 'P' command followed by the
       name of the location to be updated.
       Task Selection Aborts and Breakpoints
       _____________________________________
          The task which is to be debugged may be selected by
       the 'S' command, which should be followed by an
       argument representing the appropiate taskid.  Initially
       the foreground task is selected, but after an abort or
       breakpoint the appropiate task is selected
       automatically.  DEBUG locates the TCB of the required
       task and thus obtains the global vector base, and the
       stack pointer (unless it is available in the saved
                                  2


       registers after an abort or breakpoint) for the 'E'
       command.  If an abort or breakpoint occurrs while
       inside a kernel routine, device driver, or the idle
       task then the current task is considered to have been
       task 0 and no task selection takes place.
          The commands 'C' and 'H' may be used while TRIPOS
       is running to release or hold the currently selected
       task, but they have a different interpretation whilst
       in standalone mode: 'C' means leave standalone mode and
       continue - after a breakpoint it expects an argument
       specifying the number of times the broken instruction
       is to be executed before trapping again, with 0 or 1
       meaning once;  'H' means leave standalone mode and hold
       the task that aborted, executed a breakpoint, or was
       broken.
          Breakpoints may be set by the 'B' command, which
       should be followed by an argument in the range 1-9
       indicating the number of the breakpoint to be set.  If
       the current expression is a named location then it is
       assumed to be a function, and thus contain the machine
       address of the location where the breakpoint is to be
       set; DEBUG will check that this is a valid BCPL entry
       point.  If the current expression is not a name then
       it is assumed to be the BCPL address of the breakpoint
       - some implementations will only allow breakpoints to
       be set on function entries.  'B0' lists all the
       breakpoints and '0B<i>' deletes breakpoint <i>.
       Breakpoints are ignored while the DEBUG task is
       running, and are unset temporarily when DEBUG is
       entered in standalone mode, so it is quite safe to
       breakpoint library routines used by DEBUG itself.
       Environment Tracing
       ___________________
          The environment, or stack level, in which local
       variables are referred to may be set up by the 'E'
       command.  After 'E' the following sub-commands are
       accepted:
        'B' do a non-interactive backtrace
        'L' set the stack pointer to the current value
        'S' set the stack base to the current value
        'N' go to next coroutine stack
        'T' go to the top of the outermost active coroutine
       stack;  the stack base is obtained from the global
       vector and the stack pointer from the registers if
       available, otherwise from the value saved in the TCB
       at the last interrupt or kernel call
        'U' go up to the top of the current stack
        'D' go down one level on the current stack, or to the
                                  3


       top of the next coroutine stack;  this generates the
       next line of the backtrace.
        'V' verify the current stack level
        Escape is ignored; control reverts to the normal
       command interpreter at the next newline, or at the end
       of a non-interactive backtrace.  When a new stack
       pointer or stack base is selected it is verified by
       typing the appropiate line of backtrace output.
       Miscellaneous Commands
       ______________________
          The 'X' command executes a BCPL callable function,
       using DEBUG's global vector and stack.  The current
       expression should be the function to be called, as for
       the 'B' command.  It may be followed by up to 4
       arguments, separated by spaces.  The current expression
       is set to the result.
          The 'Z' command enters the bootstrap loader to
       reload the system; it is only available on machines
       with a suitable program callable bootstrap.
       Loading Overlays
       ________________
          In some systems DEBUG will be permanently resident,
       and all the facilities described will be permanently
       available.  in systems where store is more limited, the
       full DEBUG can be loaded when required, as follows:
          The root DEBUG task prompts, each time the user
       types newline, with ": ". If the user types any other
       character the file ":L.DEBUG-x" is called, where x is
       the character the user typed.  The standard overlays
       available are - DEBUG-D, the full DEBUG, which remains
       loaded until 'Q' is typed, and prompts with "* ",
       DEBUG-E, for environment tracing only, which accepts
       commands 'B', 'D', 'N', 'T', 'U' and operates similarly
       to the same letters following 'E' in the full DEBUG,
       and DEBUG-M, a minimal version, which remains loaded
       until the next newline and recognises only 'A', 'G',
       'C', 'H', 'N', 'P', 'S', 'T', 'U', '=', '/', monadic
       '-', and digits.
          In standalone mode overlays cannot be loaded or
       unloaded.  Commands 'C', 'H', 'Z' (if available on the
       machine) are always available, and any others in the
       overlay loaded, with the exception of DEBUG-E which
       does not operate in standalone mode.

                                  4


       Expression Syntax
       _________________
       <e>          ::= <e><dyadicop><i>
                    ::= <i>
       <i>          ::= <monadicop><i>
                    ::= (<e>)
                    ::= @<name> | '<char>
                    ::= <name> | <number>
       <dyadicop>   ::= + | - | * | % | ? | < | > | & | | | !
       <monadicop>  ::= + | - | !
       <name>       ::= <nameletter><i>
       <nameletter> ::= A | G | L | R | V | W
       <char>       ::= any character
       <number>     ::= <digit>* | #<digit>* | #X<hexdigit>*
       <digit>      ::= any digit
       <hexdigit>   ::= <digit> | A | B | C | D | E | F
          Spaces are ignored and lower case letters treated
       as upper case, except after ' or spaces after '@' and
       within numbers.  Null <i>s have value zero.
       Operators
       _________
       +       addition, positive
       -       subtraction, negative
       *       multiplication
       %       division
       ?       remainder
       <       shift left
       >       shift right
       &       logical AND
       |       logical OR
       !       subscription, indirection
       @<name> yields address of <name>
       '<char> yields value of char
          All dyadic operators are also commands; they have
       the effect of modifying the current value.
       Names
       _____
       A<i>    Absolute store location <i>
       G<i>    Global variable <i>
       L<i>    Local variable <i>
       R<i>    Register <i>
       V<i>    Variable <i>
       W<i>    TCB location <i>
       Y<i>    store location <i> (suppress checking)
                                  5


       Commands
       ________
       B<i>    set/delete Breakpoint or list all
       C       Continue/release task
       C<i>    Continue after breakpoint
       E       trace Environment
         B     non-interactive Backtrace
         D     Down one level
         L     set stack level to current value
         N     Next coroutine
         S     set Stack base to current value
         T     Top of stack
         U     Up to top of current coroutine
         V     Verify current level
       H       Hold task
       I       BCPL Indirection
       J       machine address indirection
       N       Next location
       P<name> Put current value into <name>
       Q       Quit
       S<i>    Select task
       T<i>    Type contents of <i> locations
       U<e>    Update current location with <e>
       X...    eXecute function (up to 4 <i>s as args)
       Z       enter bootstrap (if available)
       $       set style
         C     characters
         D     decimal
         F     function
         O     octal
         U     unsigned decimal
         X     hexadecimal
       /       open current location
       =       type current value
          Except in standalone mode, commands are not
       transmitted by the console handler until escape (or
       altmode) or newline is keyed.  In standalone mode
       rubout will cause a partially typed command to be
       ignored.




                                  6



                                EDIT
                                ____
                          The TRIPOS editor
                          _________________
          EDIT is a sequential editor that moves through a
       document and edits it line by line.  It invoked by the
       command
            EDIT      "FROM/A,TO,WITH/K,VER/K,OPT/K"
       The FROM file must be specified; the TO file is
       optional.  EDIT commands are read from the file WITH,
       which defaults to the command input stream, and
       verification and error messages are sent to the file
       VER, which defaults to the command output stream.  EDIT
       operates in one of two modes:
           EDIT A TO B
       reads the file A copying its contents with any edits
       made directly to the file B.
           EDIT A
       edits the file A to a temporary file, which is then
       renamed to the original file when editing is finished.
          The editor bufers a limited number of lines within
       store.  It is not possible to move further back,
       however it is possible to rewind - the rest of the
       input is copied to the output, and the output then
       reopened for input.  In the EDIT A case, this means
       that after a rewind the editor is working from a
       temporary file to a temporary file; on successive
       rewinds the files T:EDIT-Tnn-WORK1 and -WORK2 are used
       as input and output alternately.  When the editor is
       wound up, the original input is renamed as
       T:EDIT-BACKUP, and the appropiate work file renamed to
       the input file; the other work file is deleted.  In the
       EDIT A TO B case, after a rewind this becomes EDIT B.
       Note that it is possible to edit A to B regardless of
       which devices the files A and B are on, but EDIT A will
       only succeed if A is on the same device as the
       temporary directory, otherwise the rename will fail and
       the output will be left in a temporary file with the
       original file untouched.
          The OPT keyword allows options to be specified:
                Pn  specifies the maximum number of previous
       lines
                    to be buffered in store - default 20
                Wn  specifies maximum line width - default 120

                                  1


       Commands.  Edit commands are single letters, double
       _________
       letters, or single characters.  More than one command
       may be given on a single command line, and commands
       need not be separated by spaces or other delimiters.
       Some commands accept numeric arguments, which may be
       either an integer or the characters '.' or '*', which
       denote the current line or the end of the document
       respectively.  Other commands accept character strings
       as arguments; the next character after the command
       letter(s) is read as a delimiter, then all characters
       up to the next occurrence of the delimiter as the first
       argment, then a second argument if required by the
       command.  Delimiters occurring at the end of the line
       may be omitted.  Some commands take file names as
       arguments, which should be preceeded by space(s) and
       terminated by spaces or end of line.  Any command,
       except one that changes the command input or is
       followed by in-line insertion material, or rewind, may
       be preceeded by a repeat count indicating that it is
       to be obeyed that number of times in succession.  A
       group of commands, which must be all on the same line,
       may be enclosed in brackets and preceeded by a repeat
       count.  A count of zero indicates indefinite
       repetition, or until the end of document is reached.
       Verification and Error Handling.  Automatic
       ________________________________
       verification of edits is provided.  Each line of input
       that is modified is verified before it is output, and
       at the end of a line of commands the current line is
       verified if it has been changed since it was last
       verified.  The editor is initially in verify mode if
       the original edit command stream was interactive,
       otherwise verification is turned off.  Verification
       consists of typing the line number, followed by '.' or
       '*' to indicate the current line or the end of the
       document respectively, and on the next line the
       contents of the current line, with tabs expanded and
       non-printing characters converted to '?'s.  A command
       is provided to verify the case of letters, for use with
       upper case only printers, and the position of tabs and
       non-printing characters etc..  At the end of a line of
       commands, if the current command input is interactive
       and the current line is unchanged, then a blank line
       is output to prompt the user for the next command line.
       If in-line insertion material is expected then
       automatic verification is suppressed to avoid
       interfering with the typing of input.
          If an error is detected the current line of commands
       is abandoned.  Unless the command stream is interactive
       the command line is verified with a marker indicating
                                  2


       where the error was detected.  An error message is
       output and successive command streams are closed until
       an interactive stream is reached, otherwise editing is
       abandoned without further copying and the output file
       is not renamed.  Break is treated in a similar manner,
       the message **BREAK is output and control returns to
       an interactive level if possible, otherwise editing is
       abandoned.  The case where the input is exhausted
       within a repeat count of zero is treated specially, so
       that repeated commands can be written to scan the
       entire file without error, in that it causes the
       current line of commands to be abandoned but is not
       otherwise treated as an error.
       Editing by Line Number.  Each line in the input may be
       _______________________
       referenced by its line number.  Commands are available
       to delete insert or replace single lines or blocks of
       lines.  Initially the editor is positioned at line zero
       of the document, and none of the text has been read;
       moving to the next line causes the first line of the
       document to be read in to become line 1, the new
       current line.  lines before the current line that are
       still in store may be referenced by number, but any
       that were created by insertions etc. and do not
       corespond to lines in the source do not have numbers
       and so cannot be thus referenced.  If the source is
       rewound then the editor is reinitialised to line zero,
       and if any lines were inserted or deleted in the
       previous pass then all subsequent lines are effectively
       renumbered; the '=' command may be used to reset the
       line numbering if required.
       Editing by Context.  The alternative way of indicating
       ___________________
       a particular line is to search for a given context.
       Searching starts from the current line to find the
       first line containing the required context.  A context
       is a character string which may be specified either to
       be at the start of the line or anywhere in the line.
       A number of commands are available to insert and delete
       strings within the current line.  By default all string
       matching is performed with letters forced to upper
       case; this feature may be switched off if desired.
       Global Exchanges.  A number of global exchanges may be
       _________________
       set up, which cause every occurrence of a given string
       in the input as it is read to be replaced by another
       string.  Global exchanges are performed on each input
       line in the order in which they were defined; when a
       new global is defined it cancells any previous global
                                  3


       for that string, and immediately performs the exchange
       on the current line and all lines ahead of it that have
       already bean read into store.  All globals are
       cancelled on a rewind.
       The Character Pointer indicates the current position
       _____________________
       within the current line.  All context searches operate
       to the right of the character pointer, which is reset
       to the beginning of the line when a new line is read
       in.  The position of the pointer is indicated when the
       line is verified, unless it is at the left hand margin.
       A number of commands are available to move or step on
       the character pointer and to delete or modify the first
       character to its right.
       Carriage Control Characters.  The characters *C, *E,
       ____________________________
       *N, *P are recognised as carriage control characters,
       in that they terminate a line of input.  The carriage
       control character is not regarded as part of the input
       line, but is stored with it and may be inspected or
       updated if desired.  It is possible for a line to have
       no carriage control character, this is so in the case
       of any characters right at the end of the document
       after the last control character; these characters are
       referred to as line *, which initially has no control
       character.  Normal files end with a control character
       so this line is empty and is not apparent.  In a
       similar way line zero is an empty line at the beginning
       of the file, with no control character, that preceeds
       the contents of the file.
       Line Truncation.  The editor will handle input lines
       ________________
       of up to the specified maximum width; if an input line
       is longer, or if it is expanded too far it is
       truncated;  a message is given but normal error
       handling does not take place.  By default, trailing
       spaces are removed from the end of both input and
       output lines; a switch is provided to cause trailing
       spaces to be preserved.
       File Selection.  The current source and output streams
       _______________
       may be switched by the S and O commands respectively.
       The editor maintains lists of files other than the
       primary input and output open for input and open for
       output, so that if a file already open is selected
       again for input or output then reading or writing
       continues from the same point in the file.  The CF
       command can be used to explicitly close a file if
                                  4


       required.  On a windup or rewind the rest of the
       current input is copied to the current output, then
       both are closed, but it is recomended that the primary
       input and output be reselected beforehand to avoid
       confusion.  The special filename "#" is interpreted to
       mean the primary input or output as appropiate, which
       is assumed if no argument is given.  File name
       comparison is done by comparing the text strings, so
       if directory or device names are included they should
       be quoted in each reference to the same file.  Source
       file selection causes the next line read into store to
       be read from the current position in the new source;
       all lines allready in store remain but lose their
       numbers.  Output file selection causes all lines in
       store before the current line to be output to the old
       output, then the new file is selected.  The command
       input may be switched by the C command; this causes the
       contents of the specified file to be obeyed before the
       rest of the line of commands in the original file.
       Nesting of C commands is allowed; C with no argument
       will cause the command stream to revert to the previous
       stream.  Exhaustion of all command streams will cause
       the editor to wind up.










                                  5


       List of Commands
       ________________
          A/s/t/     After string s insert string t
          B/s/t/     Before string s insert string t
          C file     obey Commands from file
          CC/N/      set Carriage Control to *N (or C,E,P)
          CC//       clear Carriage Control
          CC/?/      query Carriage Control
          CF file    Close File
          CL         Concatenate next Line to current
          Dn m       Delete line n (to m if m present)
          DF/s/      Delete Find. delete from current to
                     line before line beginning with s
          DL/s/      Delete Locate. delete from current to
                     line before line containing s
          DT/s/      Delete all characters in current line
                     up To but not including s
          DG/s/      Delete Global for s
          DG//       Delete all Globals
          E/s/t/     Exchange s replacing it by t
          F/s/       Find line beginning with s
          G/s/t/     Globally exchange s replacing by t
          Hn         Halt at line n - refuse to go beyond
                     n until reset. * = end of file
          In         Insert before line n the following
                     command lines terminated by a line
                     containing onl the letter Z
          In file    Insert before n the contents of file
          L/s/       Locate line containing s
          Mn         Move to line n
          N          Next line
          O file     select Output to file
          P          move to Previous line
          PA/s/      Point After. set character pointer to
                     after s
          PB/s/      Point Before
          Q          Quit immediately no copying or rename
          Rn m       Replace lines n (to m if m present)
                     by following lines terminated by Z
          Rn m file  Replace n (to m) by contents of file
          S file     select Source from file
          SA/s/      Split current line After s
          SB/s/      Split current line Before s
          Tn         Type n lines from current. * = to end
          TLn        Type with Line numbers
          TN         Type Next page - for VDUs
          TP         Type Previous page - for VDUs
          TR+/-      set/clear TRailing spaces preserved
          U+/-       set/clear Uppercase string matching
          V+/-       set/clear Verify mode
          W          Windup. copy rest (rename) and exit
                                  6


          Z/s/       change terminator for I,R from Z to s
          *          rewind
          +n         move on n lines through source
          -n         move on n lines deleting them
          =n         renumber current line as n
          ?          verify current line
          !          expanded verify. underline upper
                     case, mark tabs, non-printing
                     characters in hex
          '          repeat last explicit A,B,E,DL,DF,DT,
                     PA,PB command
          "          equivalent to N'
          &          repeat last explicit F,L,DF,DL
                     command
          |          ignore rest of command line
          >          step character pointer on one
          <          reset character pointer to left margin
          :          set character pointer to end of line
          #          delete next character
          $          force next character to lower case
                     and step pointer
          %          force upper case, step pointer
          _          force to space, step pointer










                                  7








                        TRIPOS File Structure
                        _____________________
                       The TRIPOS Disc Editor
                       ______________________
                            Brian Knight
                           September 1979






              (C) Copyright 1979 TRIPOS Research Group
             University of Cambridge Computer Laboratory
                        Corn Exchange Street
                              Cambridge
                               CB2 3QG



       Introduction
       ____________
           This document describes the format of TRIPOS disc
       files.  The second part is a guide to the disc editor
       program DISCED which can be used to inspect and patch
       disc blocks.















       TRIPOS                    -1-            File Structure


       File Structure
       ______________
           The TRIPOS file handler uses a disc which is
       formatted with blocks of equal size.  It provides an
       indefinitely deep hierarchy of directories, where each
       directory may contain other directories and/or files.
       The structure is a pure tree - i.e. loops are not
       allowed.
           The root of the tree is the Root Block, which is
       at a fixed place on the disc.  This is like any other
       directory, except that it has no parent, and its
       secondary type is different.  The name of the disc is
       stored in the name field of the root block.
           Each block which is part of the filing system
       contains a checksum.  This is set so that the sum
       (ignoring overflow) of all the words of the block is
       zero.











       TRIPOS                    -2-            File Structure


       Root Block
       __________
               +-----------+
             0 |  T.SHORT  |    type
               |-----------|
             1 |     0     |    header key
               |-----------|
             2 |     0     |    highest seq num
               |-----------|
             3 |  HT SIZE  |    = blocksize-56
               |-----------|
             4 |     0     |
               |-----------|
             5 | CHECKSUM  |
               |-----------|
             6 |           |
               |           |
               |           |
               |           |
               |   hash    |
               |   table   |
               |           |
               |           |
               |           |
       SIZE-51 |           |
               |-----------|
       SIZE-50 |           |
               |   info    |    (unused)
       SIZE-24 |           |
               |-----------|
       SIZE-23 |   DAYS    |    Creation date and time
               |-----------|
       SIZE-22 |   MINS    |
               |-----------|
       SIZE-21 |   TICKS   |
               |-----------|
       SIZE-20 |           |
               |           |
               |   DISC    |    as a BCPL string
               |   NAME    |    of <= 30 characters
               |           |
               |           |
               |-----------|
       SIZE-4  |     0     |    hash chain
               |-----------|
       SIZE-3  |     0     |    parent directory
               |-----------|
       SIZE-2  | INFO BITS |    (unused)
               |-----------|
       SIZE-1  |  ST.ROOT  |    secondary type
               +-----------+
       TRIPOS                    -3-            File Structure


       User directory blocks
       _____________________
               +-----------+
             0 |  T.SHORT  |    type
               |-----------|
             1 |  OWN KEY  |    header key
               |-----------|
             2 |     0     |    highest seq num
               |-----------|
             3 |     0     |
               |-----------|
             4 |     0     |
               |-----------|
             5 | CHECKSUM  |
               |-----------|
             6 |           |
               |           |
               |           |
               |           |
               |   hash    |
               |   table   |
               |           |
               |           |
               |           |
       SIZE-51 |           |
               |-----------|
       SIZE-50 |           |
               |   info    |    (unused)
       SIZE-24 |           |
               |-----------|
       SIZE-23 |   DAYS    |    Creation date and time
               |-----------|
       SIZE-22 |   MINS    |
               |-----------|
       SIZE-21 |   TICKS   |
               |-----------|
       SIZE-20 |           |
               |           |
               | DIRECTORY |    as a BCPL string
               |   NAME    |    of <= 30 characters
               |           |
               |           |
               |-----------|
       SIZE-4  | HASHCHAIN |    next with same hash value
               |-----------|
       SIZE-3  |   PARENT  |    parent directory
               |-----------|
       SIZE-2  | INFO BITS |    (unused)
               |-----------|
       SIZE-1  |ST.USERDIR |    secondary type
               +-----------+
       TRIPOS                    -4-            File Structure


           User directory blocks are identified by having type
       T.SHORT and secondary type ST.USERDIRECTORY.  The six
       information words at the start of the block also
       indicate the block's own key (i.e. block number) as a
       consistency check, and the size of the hash table.  The
       50 information words at the end of the block contain
       the date and time of creation, the name of the
       directory, a pointer to the next file or directory on
       the hash chain, and a pointer to the directory above.
           A file or sub-directory is found as follows:
       firstly, a hash function is applied to its name.  This
       yields an offset in the hash table, which is the key
       of the first block on a chain linking those with the
       same hash value (or zero if there are none).  The block
       with this key is read, and its name compared with the
       required name.  If it does not match, then the next
       block on the chain is read, and so on.











       TRIPOS                    -5-            File Structure


       File Header Block
       _________________
               +-----------+
             0 |  T.SHORT  |    type
               |-----------|
             1 |  OWN KEY  |    header key
               |-----------|
             2 |HIGHEST SEQ|    = number of data blocks
               |-----------|
             3 | DATA SIZE |
               |-----------|
             4 | FIRST DATA|    First data block
               |-----------|
             5 | CHECKSUM  |
               |-----------|
             6 |           |
               |   last    |    last data of file can be
               |   data    |    stored here if there is room
               |           |
               |-----------|
               |-----------|
               |           |
               | DATA BLK 3|
               | DATA BLK 2|    list of data block keys
       SIZE-51 | DATA BLK 1|
               |-----------|
       SIZE-50 |           |
               |   info    |    (unused)
       SIZE-24 |           |
               |-----------|
       SIZE-23 |   DAYS    |    Creation date and time
               |-----------|
       SIZE-22 |   MINS    |
               |-----------|
       SIZE-21 |   TICKS   |
               |-----------|
       SIZE-20 |           |
               |           |
               |   FILE    |    as a BCPL string
               |   NAME    |    of <= 30 characters
               |           |
               |           |
               |-----------|
       SIZE-4  | HASHCHAIN |    next with same hash value
               |-----------|
       SIZE-3  |  PARENT   |    parent directory
               |-----------|
       SIZE-2  | INFO BITS |    (unused)
               |-----------|
       SIZE-1  |  ST.FILE  |    secondary type
               +-----------+
       TRIPOS                    -6-            File Structure


           Each terminal file starts with a file header block,
       which has type T.SHORT, and secondary type ST.FILE.
       The start and end of the block contain name, time and
       redundancy information similar to that in a directory
       block.  The body of the file consists of Data blocks
       with sequence numbers from 1 upwards.  The addresses
       of these blocks are stored in consecutive words
       downwards from offset size-51 in the block.  In
       general, the space for this list will not all be used,
       and the last data block will not be full.  In this
       case, it may be possible to use the header as the last
       data block as well.  If this is done, then the data is
       stored from offset 6 upwards and its size is given in
       offset 3.













       TRIPOS                    -7-            File Structure


       Data Block
       __________
               +-----------+
             0 |  T.DATA   |    type
               |-----------|
             1 |  HEADER   |    header key
               |-----------|
             2 |  SEQ NUM  |    sequence number
               |-----------|
             3 | DATA SIZE |
               |-----------|
             4 | NEXT DATA |    next data block
               |-----------|
             5 | CHECKSUM  |
               |-----------|
             6 |           |
               |           |
               |           |
               |           |
               |           |
               |   DATA    |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
               |           |
       SIZE-1  +-----------+
       TRIPOS                    -8-            File Structure


           Data blocks contain only six words of filing system
       information.  This is the type (T.DATA), a pointer to
       the file header block, the sequence number of the data
       block, the number of words of data, a pointer to the
       next data block, and the checksum.  Normally, all data
       blocks except the last will be full (i.e. have size =
       blocksize-6).  The last data block has a forward
       pointer of zero.















       TRIPOS                    -9-            File Structure


                   DISCED - The TRIPOS disc editor
                   _______________________________
           The disc editor is invoked by the command DISCED.
       It allows blocks to be read from disc, inspected and
       patched in core, and written back.  It has some
       knowledge of the filing system structure, so can print
       information about blocks in words, calculate hash
       values from filenames, and set checksums.  It uses the
       same block numbering scheme as the filing system.
           As the disc editor is frequently used just for
       inspecting blocks, it is by default in a mode in which
       it will refuse to write to the disc.
           The file handler includes sufficient redundant
       information in blocks that is usually not difficult to
       repair a broken disc - e.g. left in an odd state as the
       result of a system crash.  For example, headers and
       directories contain their own disc addresses, and data
       block chains are recorded both in the links and as a
       list in the header.  The header blocks of deleted files
       have a 'deleted' bit set in the type field, but all the
       information is preserved.
           DISCED commands are all single characters,
       sometimes with arguments.  The next page contains a
       complete list.








       TRIPOS                   -10-               Disc Editor


       TRIPOS Disc Editor
       __________________
       Commands available:
       B n         Set logical block number base to n
       C n         Print n characters from current offset
       D n         Select disc drive n
       G [n]       Get block n from disc (default: current
                   block number)
       H name      Calculate hash value of name
       I           Print block information
       K           Check block checksum (& correct if wrong)
       L [lwb upb] Locate words which match Value under Mask
                   (lwb & upb restrict the search)
       M n         Set Mask (for L & N commands) to n
       N [lwb upb] Locate words which do not match Value
                   under Mask
       P n         Put block in store to block n on disc
                   (default: current block number)
       R           Print block number of Root Block
       Q           Quit (do not write to disc)
       S char      Set printing Style:
                   char = C -> characters
                          S -> string
                          O -> octal
                          X -> hex
                          D -> decimal
       T lwb upb   Type range of offsets in block
       V n         Set Value for L & N commands
       W           Windup (=PQ)
       X           Invert write protect state
       Y n         Set cYlinder base to n
       Z           Zero all words of buffer
       number      Set current word offset in block
       =           Print values set in program
       / [n]       Print word at current offset
                   [or update value to n]
       'chars'     Put chars at current offset
       "chars"     Put string at current offset
           Numbers can start with # or #X to indicate octal
       or hex.  Strings can include BCPL string escapes (*N
       etc.).
           The current block is that from the last G or P
       command.  It is the offset from the logical block
       number base.


       TRIPOS                   -11-               Disc Editor


               TRIPOS Kernel Primitives Specification
                       TRIPOS Research Project
                   University Computer Laboratory
                        Corn Exchange Street
                              Cambridge
                               England
                               CB2 3QG




                     TRIPOS Kernel Specification
                     ___________________________
          This  document  presents the specification of Kernel
       primitives  in  release  1  of  TRIPOS.   All  standard
       implementations   guarantee   that  routines  described
       herein will be available and  that  they  fulfil  these
       specifications.
                                                Paul Bond
                                                May 1978







                                 -1-

               TRIPOS Kernel Primitives Specification
                              Contents
                              ________
          Routines are described in alphabetical  order.   The
       complete list of Kernel primitives is:

       rtn              ABORT(CODE, ARG)
       fn   RESULT   := CHANGEPRI(TASKID, NEWPRIORITY)
       fn   DEVID    := CREATEDEV(DCB)
       fn   TASKID   := CREATETASK(SEGMENTLIST,
                             STACKSIZE, PRIORITY)
       fn   DCB      := DELETEDEV(DEVID)
       fn   RESULT   := DELETETASK(TASKID)
       fn   RESULTID := DQPKT(ID, PACKET)
       rtn              FREEVEC(VECTOR)
       fn   VECTOR   := GETVEC(UPPERBOUND)
       fn   RESULT   := HOLD(TASKID)
       fn   RESULT   := QPKT(PACKET)
       fn   RESULT   := RELEASE(TASKID)
       fn   RESULT   := SETFLAGS(TASKID, MASK)
       fn   PACKET   := TASKWAIT()
       fn   RESULT   := TESTFLAGS(MASK)

          Appendices A & B contain a summary  of  error  codes
       and abort codes used by the Kernel.



                                 -2-

               TRIPOS Kernel Primitives Specification
       Introduction
       ____________
          An  error return is normally indicated by a function
       returning the  value  0.   There  are  few  exceptions.
       Those  that  exist  are  due  to the need to return the
       value 0 as a meaningful result.
          Functions which  return  in  error  set  RESULT2  to
       indicate  further  the  type  of error detected.  These
       codes are global to all routines.
          Error codes allocated for use  by  the  Kernel,  M/C
       library and BLIB lie in the range 100-199.
          Error  codes used by the Kernel and their associated
       texts may be found in appendix A.
          The effects listed under 'Side effects' do not occur
       in  the  event  of  an  error  return (unless otherwise
       specified).
          Various manifest constants and offsets are mentioned
       in this document.
          NOTINUSE (=-1)  is  a  packet  link  value  used  to
       indicate  that  the  packet  is not present on any work
       queue.
          PKT.LINK (=0) is the  packet  offset  used  to  link
       packets of a given work queue together.
          PKT.ID  (=1)  is  the  packet  offset indicating the
       destination/sender's task or device id.
          PKT.TYPE (=2) is the packet offset used to  indicate
       the purpose for which the given packet has been sent.
          PKT.RES1  (=3)  and PKT.RES2 (=4) are packet offsets
       which hold, by convention, result values.
          PKT.ARG1 (=5), PKT.ARG2 (=6) etc. are packet offsets
       commonly used to pass arguments to the destination task
       or device.


                                 -3-

               TRIPOS Kernel Primitives Specification
       ABORT(CODE, ARG)
          Abort the issuing task.
       Arguments:
       __________
       CODE
          An indication of the reason for the abort.
       ARG
          May be used to pass additional information.
       Notes:
       ______
          See the documentation on DEBUG for further details.











                                 -4-

               TRIPOS Kernel Primitives Specification
       RESULT := CHANGEPRI(TASKID, NEWPRIORITY)
          Change the priority of a task.
       Arguments:
       __________
       TASKID
          The task id. of  the  task  which  is  to  have  its
       priority changed.
       NEWPRIORITY
          The priority that the specified task is to adopt.
          Must  be  strictly  positive  and  distinct from any
       existing task priority other than that of the specified
       task.
       Normal return:
       ______________
       RESULT\=0
          The task's priority has been changed.
       Error return:
       _____________
       RESULT=0, possible errors are:
          RESULT2=101, Invalid id.
          RESULT2=102, Invalid priority.
       Side effects:
       _____________
          May cause a change of current task.
       Related routines:
       _________________
          CREATETASK
          DELETETASK



                                 -5-

               TRIPOS Kernel Primitives Specification
       DEVID := CREATEDEV(DCB)
          Create a device.
       Arguments:
       __________
       DCB
          A skeleton device control block  for  the  specified
       type of device.
          DCB!0  must  point  to  the  device  driver  section
       containing initialisation code.
       Normal return:
       ______________
       DEVID\=0
          The id. of the created device.
       Error return:
       _____________
       RESULT=0, possible errors are:
          RESULT2=104, Device table full.
          RESULT2=106, Failure to initialise device.
       Side effects:
       _____________
          An  entry  for  the specified device is put into the
       device table.
          The device is initialised.
       Related routines:
       _________________
          DELETEDEV




                                 -6-

               TRIPOS Kernel Primitives Specification
       TASKID := CREATETASK(SEGMENTLIST, STACKSIZE, PRIORITY)
          Create a task.
       Arguments:
       __________
       SEGMENTLIST
          A list of segments headed by an entry count.
          Entries  in  the  list  may  be 0 indicating that no
       segment exists for that entry.
          SEGMENTLIST may be 0 if no segment list is provided.
       STACKSIZE
          The size of the root stack upon activation.
       PRIORITY
          The priority of the new task.
          Must be strictly  positive  and  distinct  from  any
       existing task priority.
       Normal return:
       ______________
       TASKID\=0
          The id. of the newly created task.
       Error return:
       _____________
       TASKID=0, possible errors are:
          RESULT2=102, Invalid priority.
          RESULT2=103, Insufficient free store.
          RESULT2=105, Task table full.
       Related routines:
       _________________
          CHANGEPRI
          DELETETASK
       Notes:
       ______
          If a segment list is present it  is  copied  into  a
       GETVEC'ed vector.
          The TCB is allocated from the free store area.
          The  segment  list  (at  task activation) is used to
       initialise  global  slots.   A  segment   list   should
       therefore  exist at task activation and segments should
                                 -7-

               TRIPOS Kernel Primitives Specification
       consist of a chained list of BCPL-format sections.
          Note that the creation of a task  is  distinct  from
                        ________
       its  activation,  which occurs when a task receives its
            ___________
       first packet and which might occur some time after  the
       task  was  created.   Sufficient  free  store  must  be
       available at  the  time  of  task  activation  for  the
       allocation  of  a  global  vector  and  a  root  stack.
       Otherwise, the task will abort.














                                 -8-

               TRIPOS Kernel Primitives Specification
       DCB := DELETEDEV(DEVID)
          Delete a device.
       Arguments:
       __________
       DEVID
          The id. of the device to be deleted.
       Normal return:
       ______________
       DCB\=0
          The specified device has been successfully deleted.
       Error return:
       _____________
       RESULT=0, possible errors are:
          RESULT2=101, Invalid id.
          RESULT2=107, Work queue not empty.
       Side effects:
       _____________
          The device entry will be  removed  from  the  device
       table.
       Related routines:
       _________________
          CREATEDEV
       Notes:
       ______
          The device work queue must be empty.
          The DCB is not FREEVEC'ed.




                                 -9-

               TRIPOS Kernel Primitives Specification
       RESULT := DELETETASK(TASKID)
          Delete a task.
       Arguments:
       __________
       TASKID
          The id. of the task to be deleted.
       Normal return:
       ______________
       RESULT\=0
          The given task has been deleted.
       Error return:
       _____________
       RESULT=0, possible errors are:
          RESULT2=101, Invalid id.
          RESULT2=108, Task not deletable.
       Side effects:
       _____________
          The task's entry in the task table is removed.
          The task's entry in the TCB chain is removed.
          The task's segment list is FREEVEC'ed (if any).
          The task's TCB is FREEVEC'ed.
       Related routines:
       _________________
          CHANGEPRI
          CREATETASK
       Notes:
       ______
          The  task  must  be  dead,  not  held  and   without
       packet(s).
          However, the issuing task may delete  itself  if  it
       has an empty work queue.


                                -10-

               TRIPOS Kernel Primitives Specification
       RESULTID := DQPKT(ID, PACKET)
          Remove a packet from  a  given  work  queue  or  the
       issuing task's work queue.
       Arguments:
       __________
       ID
          The id. of a task or device whose work queue will be
       searched first for the packet.
       PACKET
          The sought packet.
       Normal return:
       ______________
       RESULTID\=0
          The  id.  of the task or device whose work queue was
       found to contain the sought packet.
       Error return:
       _____________
       RESULTID=0, possible errors are:
          RESULT2=101, Invalid id.
          RESULT2=109, Packet not found.
       Side effects:
       _____________
          The packet will have been dequeued.
          PACKET!0 will be set to NOTINUSE.
          PACKET!1 will be set to ID if the packet  was  found
       on  a  work  queue other than that of the issuing task.
       Otherwise, it will be left unaltered.
       Related routines:
       _________________
          QPKT
          TASKWAIT
       Notes:
       ______
          Packets may always be dequeued from devices.
          Dequeueing a device packet may involve  an  implicit
       device reset.
                                -11-

               TRIPOS Kernel Primitives Specification
       FREEVEC(VECTOR)
          Return a vector (if  supplied)  to  the  free  store
       area.
       Arguments:
       __________
       VECTOR
          A pointer to a vector allocated by GETVEC.
       Abort condition:
       ________________
          An attempt to free a vector which does not appear to
       have  been  allocated by GETVEC results in the aborting
       of the issuing task.
       Related routines:
       _________________
          GETVEC
       Notes:
       ______
          A call of  FREEVEC(0)  is  permissible  and  has  no
       effect.







                                -12-

               TRIPOS Kernel Primitives Specification
       VECTOR := GETVEC(UPPERBOUND)
          Allocate a vector of the  indicated  size  from  the
       free store area.
       Arguments:
       __________
       UPPERBOUND
          The upperbound (unsigned) of the required vector.
       Normal return:
       ______________
       VECTOR\=0
          The vector has been allocated successfully.
       Error return:
       _____________
       VECTOR=0, error is:
          RESULT2=103, Insufficient free store.
       Related routines:
       _________________
          FREEVEC
       Notes:
       ______
          It is permissable to allocate vectors of 32k or more
       on a 16-bit machine, although this is  not  recommended
       as a matter of programming style.
          It is possible that corruption  of  the  free  store
       area  might be detected by the call. If this is so then
       a system abort will occur.




                                -13-

               TRIPOS Kernel Primitives Specification
       RESULT := HOLD(TASKID)
          Place a task into a held state.
       Arguments:
       __________
       TASKID
          The id. of the task to be placed into a held state.
       Normal return:
       ______________
       RESULT/=0
          The specified task  has  been  placed  into  a  held
       state, having been formerly not held.
       RESULT=0, with:
          RESULT2=110, Task already held.
       Error return:
       _____________
       RESULT=0, error is:
          RESULT2=101, Invalid id.
       Side effects:
       _____________
          May cause a change of current task.
       Related routines:
       _________________
          RELEASE
       Notes:
       ______
          A task may hold itself.



                                -14-

               TRIPOS Kernel Primitives Specification
       RESULT := QPKT(PACKET)
          Append a packet to the work queue of  the  specified
       task  or  device,  or  inserts  it into the appropriate
       place on the timer work queue.
       Arguments:
       __________
       PACKET
          A TRIPOS packet.
          PACKET!0 must be NOTINUSE.
          PACKET!1 indicates the destination  id.,  >0  for  a
       task, =-1 for the timer, <-1 for a device.
          Contents of other offsets have application dependent
       information (see below for the timer).
       Normal return:
       ______________
       RESULT\=0
          The packet was queued successfully.
       Error return:
       _____________
       RESULT=0, error is:
          RESULT2=101, Invalid id.
       Abort condition:
       ________________
          PACKET!0 not NOTINUSE.
       Side effects:
       _____________
          PACKET!0 will be set to a value \=NOTINUSE.
          PACKET!1 will be set to the issuing task's id.
          May cause a change of current task.
       Related routines:
       _________________
          DQPKT
          TASKWAIT

                                               contd. overleaf
                                -15-

               TRIPOS Kernel Primitives Specification
       Notes:
       ______
       Packets sent to the timer:
       __________________________
          Offset PKT.ARG1 represents the requested  delay  (in
       clock timer units, unsigned).
          A delay of X ticks means that  the  packet  will  be
       returned to the issuing task's work queue after a delay
       of between X-1 and X clock timer units.














                                -16-

               TRIPOS Kernel Primitives Specification
       RESULT := RELEASE(TASKID)
          Place a task into a non-held state.
       Arguments:
       __________
       TASKID
          The id. of the task to be  placed  into  a  non-held
       state.
       Normal return:
       ______________
       RESULT\=0
          The  specified  task  has  been placed in a non-held
       state.
       Error return:
       _____________
       RESULT=0, error is:
          RESULT2=101, Invalid id.
       Side effects:
       _____________
          May cause a change of current task.
       Related routines:
       _________________
          HOLD






                                -17-

               TRIPOS Kernel Primitives Specification
       RESULT := SETFLAGS(TASKID, MASK)
          Set selected task flags of a given task.
       Arguments:
       __________
       TASKID
          The id. of the task whose flags are to be set.
       MASK
          A  mask  indicating  which flags are to be set.  A 1
       indicates selection, 0 otherwise.
       Normal return:
       ______________
       RESULT\=0
          The specified flags have been set.
       Error return:
       _____________
       RESULT=0, error is:
          RESULT2=101, Invalid id.
       Related routines:
       _________________
          TESTFLAGS







                                -18-

               TRIPOS Kernel Primitives Specification
       PACKET := TASKWAIT()
          Return the earliest packet sent to the task, or  the
       next  packet  to  be sent to the task (if the task work
       queue is empty).
       Arguments:
       __________
          None.
       Normal return:
       ______________
          PACKET points to a TRIPOS packet.
          PACKET!0 will be NOTINUSE.
          PACKET!1 will be set to the sender's id.
       Side effects:
       _____________
          May cause a change of current task.
       Related routines:
       _________________
          DQPKT
          QPKT







                                -19-

               TRIPOS Kernel Primitives Specification
       RESULT := TESTFLAGS(MASK)
          Discover the state of a  selection  of  the  issuing
       task's task flags.
       Arguments:
       __________
       MASK
          The  selection of flags to be tested.  A 1 indicates
       selection, 0 otherwise.
       Normal return:
       ______________
       RESULT=TRUE
          At least one of the selected flags was set.  RESULT2
       holds the result of ANDing the contents of the flagword
       (prior to testing), with MASK.
       RESULT=FALSE
          None of the selected flags was set.
       Side effects:
       _____________
          All selected flags will be cleared.
          Note the setting of RESULT2 as data.
       Related routines:
       _________________
          SETFLAGS






                                -20-

               TRIPOS Kernel Primitives Specification
                             Appendix A
                             __________
       Kernel RESULT2 error code summary:
       __________________________________
            RESULT2     Error text & explanation.
              101       INVALID ID.
                         The   task  [or  device]  id.
                         presented     as     argument
                         referred  to  a  non-existent
                         task [or device].
              102       INVALID PRIORITY.
                         The   priority  presented  as
                         argument   was   either   not
                         strictly  positive or already
                         existed.
              103       INSUFFICIENT FREE STORE.
                         An  explicit or implicit call
                         of GETVEC requested a  vector
                         whose  size  was greater than
                         that  of  the  largest  block
                         available  in  the free store
                         area.
              104       DEVICE TABLE FULL.
                         The    maximum    permissible
                         number  of  devices   already
                         exists.   (Solution: increase
                         the  size   of   the   device
                         table).
              105       TASK TABLE FULL.
                         The    maximum    permissible
                         number   of   tasks   already
                         exists.  (Solution:  increase
                         the size of the task table).
              106       FAILURE TO INITIALISE DEVICE.
                         The skeleton  device  control
                         block    specified   a   non-
                         existent   device   OR    the
                         (valid)  device  could not be
                         initialised.
                                -21-

               TRIPOS Kernel Primitives Specification
              107       WORK QUEUE NOT EMPTY.
                         The quoted device  still  had
                         packets on its work queue.
              108       TASK NOT DELETABLE.
                         The  current  task   can   be
                         deleted   only  if  its  work
                         queue is empty.  Other  tasks
                         must  be  dead,  not held and
                         without packet(s) in order to
                         be deleted.
              109       PACKET NOT FOUND.
                         The specified packet was  not
                         found  on  the  work queue(s)
                         explicitly   or    implicitly
                         searched by the routine.
              110       TASK ALREADY HELD.
                         An attempt was made to hold a
                         task  that  was  already in a
                         held state.










                                -22-

               TRIPOS Kernel Primitives Specification
                             Appendix B
                             __________
       Kernel abort code summary:
       __________________________
              Code      Abort text & explanation.
              199       INVALID QPKT.
                         An attempt was made to QPKT a
                         packet  whose packet link was
                         not NOTINUSE. (Common  cause:
                         failure   to  initialise  the
                         packet  or  overwriting   the
                         immediately         preceding
                         location(s)).
              198       INVALID FREEVEC.
                         An attempt was made to free a
                         vector that did not appear to
                         have  been GETVEC'ed. (Common
                         cause:  overwriting past  the
                         end    of   the   immediately
                         preceding free store block).
              197       FREE STORE AREA CORRUPT.
                         Corruption  of the free store
                         area  is   usually   detected
                         within a call of GETVEC. More
                         specifically the  free  store
                         chain  has  been  found to be
                         inconsistent. This results in
                         a system abort rather than an
                         abort of  the  issuing  task.
                         (Common  cause:   overwriting
                         outside  the  bounds   of   a
                         GETVEC'ed  vector,  often due
                         to stack overflow).
              196       INSUFFICIENT  FREE  STORE  FOR
                         TASK ACTIVATION.
                         There  is  insufficient  free
                         store  to  allocate  a global
                         vector  and  stack  for   the
                         specified task.


                                -23-






                      THE MOUNT COMMAND
                      _________________

                       MIKE RICHARDSON
                       _______________
                        SEPTEMBER 1980
                        ______________


             Copyright (C) Tripos Research Group
         University of Cambridge Computer Laboratory








 Specification               -1-                        Mount



       This document describes the new implementation of  the
 mount  command  for  loading new devices and handlers into a
 TRIPOS system. The program and method used are based on that
 by Adrian Aylward.
       The mount command uses a file ( "sys:info.mount" )  to
 provide  the  necessary  information  about a new device and
 handler, and two vectors attached  to  the  info  vector  to
 record loaded devices and handlers, their locations, and use
 counts. By means of the  latter,  sharing  of  code  is  im-
 plemented.

                     Information vectors
                     ___________________
       The  command  makes use of two information vectors for
 devices and handlers, which are attached to theinfo vector.
       The  devices  and  handlers are assigned numbers which
 represent offsets into the vectors. The entry is then either
 zero,  if  the device or handler is not loaded, or otherwise
 points at a three word vector.
       The first word is the TRIPOS device number for devices
 ( unused for handlers ), the second a pointer  at  the  code
 segments ( unused for devices ), and the third a use count.

                         Driving File
                         ____________
 Mount                       -2-                Specification


       The driving file consists of a  series  of  specifica-
 tions in the form
       <device> <specification> ;
       where device is a string of characters followed  by  a
 colon,  in  the normal manner, for example "DF1:" or "MT2:".
 The  specification  then  describes  first  the  device   or
 devices, and then the handler.
                           Devices
                           _______
       Devices are either resident or  non-resident.  In  the
 former  case, the device part of the specification takes the
 form
       driver res devs <device list>
       where   the  device  list  is  a  series  of  numbers,
 separated by spaces. The first of these  is  the  number  of
 devices  (  currently one or two ) and the other numbers are
 the offsets into the info device vector of the device entry.
 The  device numbers will be passed to the handler when it is
 started.
       Where the devices are non-resident, then the form is
       driver nonres devs <device list> file <file list>
       The device list is as before. If the device or devices
 are  loaded already then they will be shared. Note that this

 Specification               -3-                        Mount


 is not just code-sharing, but actual sharing of the  device.
 If not then they are dynamically loaded and created, and en-
 tries inserted into the device information vector,  the  ob-
 ject modules being taken from the specified file or files.
                           Handlers
                           ________
       The second  half  of  the  specification  is  for  the
 handler, and has the form
       handler res <description>
       in the case of resident handlers, or
       handler nonres file <file> <description>
       for non-resident handlers.
       The number is the offset into the handler  information
 vector for code sharing. File is the object module file that
 holds the handler, while the description  contains  informa-
 tion needed to start the handler.
       This has the form
       hand <number>
       init <init file>
       pri  <priority> stack <stack size>
       unit <unit number> env   <environment vector>
       mode <mode list>
       The   init   file  is  the  file  which  contains  the

 Mount                       -4-                Specification


 initialisation code, or "$"  if  there  is  none.  When  the
 handler  segment  list  is constructed, segments one and two
 are MLIB/KLIB and BLIB, segment three is  the  handler  code
 itself, and segment four is the initialisation code, if any.
       The handler number is the offset into the handler  in-
 formation  vector of the entry for the handler. The priority
 is the approximate priority at which the handler should run,
 and  the  stack  size  is  that of the root stack.  The unit
 number is supplied to the  handler  when  it  is  activated,
 whicle  the  environment  vector  is  a  series  of numbers,
 separated by commas, that are also passed to the handler.
       The  mode  list is a list of words. If a value is sup-
 plied as the mode to the command ( eg., mount  df1:  read  )
 then  it  is matched against the list, and the mode value in
 the startup packet to the handler set to the number  of  the
 word in the list. If no mode is given then the mode defaults
 to one.
                           Example
                           _______
       The following is a full example.
 df1: dev  nonres devs 2 2 3
                  file sys:d.dfreader sys:d.dfwriter
      hand nonres file sys:l.df-mu-handler
                  hand 6
                  init sys:l.df-mu-init
                  pri  500  stack 140
 Specification               -5-                        Mount


                  unit 1
                  env  10,1,1,4,56,256,8,3
                  mode update read validate
      ;

                           Startup
                           _______
       The  handler is activated with a startup packet, which
 contains the following information.
 (..i)  arg1  -  a  pointer  at  the device vector, in which,
 starting  at  offset  zero  are  placed  the  TRIPOS  device
 numbers.
 (.ii) arg2 - the unit number on the device.
 (iii) arg3 - a pointer at the environment vector, in  which,
 starting  at  offset  zero  are  placed the entries from the
 'env' item in the driving file.
 (.iv) arg4 - the startup mode

                           Dismount
                           ________

       The  associated  'dismount'  command  uses  the   same
 driving  file,  and unloads devices and handlers if they are
 non-resident, and are no longer in use.

 Mount                       -6-                Specification








                     TRIPOS Ring Software
                     ____________________
                         Brian Knight
                        December 1980






           (C) Copyright 1980 TRIPOS Research Group
         University of Cambridge Computer Laboratory
                     Corn Exchange Street
                          Cambridge
                           CB2 3QG







                           Contents
                           ________

       1 Introduction
       2 Ring System Components
       3 Ring Device Drivers
       4 Ring Handler Task
       5 Ring Services Task
       6 Byte Stream Protocol Handler Task
       7 Single Shot Protocol
       8 Use of the Name Lookup Server
       9 File Transfer
       10 Some useful commands






 TRIPOS                      -1-                Ring Software


                       1   Introduction
                       ________________
     This document describes the interfaces to the Cambridge
 Data Ring provided under TRIPOS for the various protocols
 in general use.
     Programs which use the ring should GET the BCPL header
 file "RINGHDR", which contains manifests for offsets in ring
 basic blocks and TRIPOS packets, plus various masks and code
 values.  Manifest constants referred to below are to be
 found in this header.














 TRIPOS                      -2-                Ring Software


                  2   Ring System Components
                  __________________________
     The software components fall into five main groups:
   (1) Ring device drivers (written in assembler)
   (2) Ring system tasks:-  Ring Handler
                            BSP Handler
                            Ring Services
   (3) Source libraries:- commonly used routines which
         can be included in ring programs.
   (4) Ring services:- programs loaded by the ring
         services task to provide particular services.
   (5) Commands:- to start and stop the system tasks,
         provide information on the ring,
         transfer files, and access ring services.

                   3   Ring Device Drivers
                   _______________________
     All communication with the ring is done using two device
 drivers - an independent transmitter and receiver.  These
 accept packets requesting transfer of a vector of 16-bit
 words to/from a given station.  As the only routing
 information is that provided by the hardware station
 addresses, these drivers must only be used directly by one
 task within a machine at once.  In general, user programs
 and system programs (other than the ring handler) never send
 packets to these devices.






 TRIPOS                      -3-                Ring Software


                    4   Ring Handler Task
                    _____________________
     The ring handler task provides a 'basic block' interface
 to the data ring.  It acts as a multiplexor, allowing
 several tasks to use the ring independently.  It is normally
 the only task in the system to send packets to the ring
 device drivers.  It also provides timeouts on both reception
 and transmission of blocks, and retry on transmission
 errors.
     The format of a basic block (Systems Research Group
 Project Note RDHW 27.10.78) is as follows:-

              4 bits 2 bits    10 bits
             +------+------+-----------+
             | 1001 | type |  count    |  Header packet
             |-------------------------|
             |flags |   port number    |  Route packet
             |-------------------------|
             |                         |
             |                         |
             |                         |
             |      (count + 1)        |
             |      data packets       |
             |                         |
             |                         |
             |                         |
             |                         |
             |                         |
             |-------------------------|
             |        checksum         |
             +-------------------------+
     The header packet contains a fixed pattern, a 2-bit type
 code, and the length of the block.  Possible block types are
 00, meaning a block with checksum, and 01, meaning a block
 with zero checksum.  The handler accepts either type, but
 always sends type 00.  The second packet contains a 12-bit
 port number, which is used to direct the block to the right
 task within the machine.  The flag bits are not used at
 present.  The checksum is an end around carry sum of all the
 other packets in the block (or zero for blocks of type 01).



 TRIPOS                      -4-                Ring Software


 Starting and Stopping the Handler
 _________________________________
     The ring handler is started by the command LOADRINGHAND.
 This command loads and creates the transmitter and receiver
 devices, and creates the ring handler task, unless it was
 already running.
     The command RHINFO KILL is used to make the handler
 delete itself, abandoning any outstanding requests.  Thus
 any program which uses the handler should be killed first.
     In TRIPOS systems using the Data Ring File Server for
 their filing system, the ring handler is a resident part of
 the system, so does not need to be loaded, and does not
 respond to RHINFO KILL.

 Locating the Handler
 ____________________
 The task number of the ring handler is stored in a ring
 information vector which hangs from the root node 'info'
 vector, at the offset given by the manifest constant
 RTNINFO.RING.  The task number of the ring handler is found
 as follows:
    rh.task := rootnode ! rtn.info ! rtninfo.ring !
               ri.rhtaskid
     If the value is zero, then the handler is not running.








 TRIPOS                      -5-                Ring Software


 Transmission and Reception
 __________________________
     Calls to the ring handler requesting transmission or
 reception of basic blocks use the following packet format:
   Field  RINGHDR Manifest
                           +----------+
   Link                    |   LINK   |
                           |----------|
   ID                      |    ID    |
                           |----------|
   Type                    |  ACTION  |
                           |----------|
   Res1                    |   RES1   |
                           |----------|
   Res2                    |   RES2   |
                           |----------|
   Arg1   rhpkt.buff       |  BUFFER -+-> User's buffer
                           |----------|
   Arg2   rhpkt.size       |   SIZE   | of buffer
                           |----------|
   Arg3   rhpkt.station    |  STATION |
                           |----------|
   Arg4   rhpkt.port       |   PORT   |
                           |----------|
   Arg5   rhpkt.lifetime   | LIFETIME | in ticks
                           +----------+ (reception)
                                        (  only   )








 TRIPOS                      -6-                Ring Software


 Transmission
 ____________
     To transmit data in basic block(s), a packet is sent to
 the handler giving the address of a buffer containing the
 data, the number of data words, and the station and route
 code to which it should be sent.  The data is transmitted
 in a single basic block, or a series of blocks if there is
 too much for one.
     The packet is returned with a result indicating whether
 the transmission succeeded, and if not, how it failed.  The
 buffer is available for re-use when the packet returns.
     The transmission is abandoned if the destination goes
 'unselected' during a basic block, ignores any packet, or
 is 'busy' for more than a timeout period.  If the station
 is 'unselected' at the start of the block, then the
 transmission request is put to the back of the queue, and
 retried several times.












 TRIPOS                      -7-                Ring Software


 Transmission Packet Format
 __________________________
     The action requesting transmission is ACT.TX, which
 causes the supplied data to be sent to the given station on
 the given port in one or more basic blocks.
   pkt.type:      ACT.TX
   rhpkt.buff:    Buffer containing data
   rhpkt.size:    Number of words of data (>= 1)
   rhpkt.station: Destination station
   rhpkt.port:    Destination port
     On return there is a status code in pkt.res1.  Possible
 codes are as follows:-
   txst.accepted:     Whole block accepted
   txst.busy:         Timeout while busy
   txst.unsel.in.blk: Went unselected during block
   txst.unsel.hdr:    Unselected for 1st packet
   txst.ignored:      Packet ignored
   txst.ring.error:   Ring error
   txst.bad.dest:     Invalid destination address










 TRIPOS                      -8-                Ring Software


 Reception
 _________
     Two modes of reception are provided, to receive a single
 basic block, or to receive a specified quantity of data in
 one or more basic blocks.  The requests are given a lifetime
 by the user: if the data has not arrived within that time,
 then the request is cancelled, and the packet sent back.
     The handler's normal state is waiting for a valid block
 header packet to arrive from any station.  When one appears,
 it receives the rest of the block, listening to only the
 source station of the header.  If the rest does not arrive
 within a timeout period, if the checksum is invalid, there
 is no request which it satisfies, or it is too big for a
 request which it otherwise satisfies, then the block is
 discarded.  Otherwise, a user request packet is returned
 with the data from the block in its buffer.
     Outstanding requests may be cancelled, in which case the
 packets are 'dropped', so that the user task does not have
 to use repeated TASKWAITs to get them back.  The link and
 ID field of each packet is set so that QPKT will send it
 back to the ring handler.










 TRIPOS                      -9-                Ring Software


 Reception Packet Formats
 ________________________
 ACT.RX.BB
     Receive a single basic block from the specified ring
 station on the given port, and put the data in the supplied
 buffer.  The station may be 255, meaning 'anywhere'.  Blocks
 which are too big for the supplied buffer will be thrown
 away.
   pkt.type:        ACT.RX.BB
   rhpkt.buffer:    User's buffer for data
   rhpkt.size:      Size of buffer in words
   rhpkt.station:   Source ring station
   rhpkt.port:      Port number
   rhpkt.lifetime:  Lifetime of request (ticks)
     On return, both result fields are set:
   pkt.res1:        Number of data words received
                    (Zero if timeout occurred)
   pkt.res2:        Actual source station
                    (Only useful if specified
                    station was 255)

 ACT.RX.CHAIN:
     As ACT.RX.BB, except that the data may arrive in more
 than one basic block.  The request is satisfied only when
 exactly the specified amount of data has arrived.

 ACT.CANCEL.RX:
     Cancel all outstanding reception requests for the given
 port number and ring source.  The corresponding TRIPOS
 packets held by the handler are simply dequeued, but not
 returned.
   pkt.type:      ACT.CANCEL.RX
   rhpkt.station: Source ring station
   rhpkt.port:    Port number
     No results.


 TRIPOS                      -10-               Ring Software


 Port Allocation
 _______________
     When requesting a response from a remote machine, there
 is a need to be able to quote an unused port number for it
 to use.  The ring handler provides a centralised mechanism
 for dynamic allocation and freeing of ports, and for
 reserving fixed ports.  Port numbers are allocated
 cyclically, to maximise the time before each is reused.
 Packet Formats
 ______________

 ACT.FINDFREEPORT - Find an unused port number for reception,
                and reserve it.
     No arguments.
     pkt.Res1:  Port number

 ACT.RESERVEPORT - Reserve the specified port number for
                reception, and indicate whether it was
                already reserved.
     pkt.Arg1:  Port number
     pkt.Res1:  TRUE if not previously reserved,
                FALSE otherwise.

 ACT.RELEASEPORT - Release the given reception port number.
                Any reception requests outstanding on this
                port are cancelled.
     pkt.Arg1:  Port number
     No results




 TRIPOS                      -11-               Ring Software


                    5   Ring Services Task
                    ______________________
     The ring services task is used to load and start
 programs which are activated by basic blocks containing SSP
 or BSP OPEN requests received from the ring.  It should be
 started by the command
      LOADRINGSERV
     The task issues a reception request to the ring handler
 to receive a basic block on a fixed port number from any
 station.  When a basic block arrives on this port, it is
 inspected to see if it looks like an SSP (Single Shot
 Protocol) or BSP OPEN request (by examining the first data
 word).  If it doesn't, then the block is ignored.
 Otherwise, the function code (third data word) is read, and
 the driving file scanned to find the corresponding filename.
 This file is loaded, a task made from it, and an initial
 packet sent to start it.  The initial packet contains the
 following arguments:-
     pkt.Arg1: The data part of the received basic
               block (which the activated task
               should FREEVEC after use).
     pkt.Arg2: The number of data words in the
               received block.
     pkt.Arg3: The station from which it came
     pkt.Arg4: The port word of the block.
     pkt.Arg5: The task number of the ring handler
     This initial packet should be returned as soon as
 possible.  The new task should inspect the contents of the
 basic block, and proceed with whatever service it provides.
     The driving file is "sys:info.ring-services".  Each line
 consists of a function code number followed by the
 corresponding filename, the nameserver name of the service,
 and flags indicating the type of service.



 TRIPOS                      -12-               Ring Software


     If the basic block received is an SSP or OPEN block, but
 the corresponding task cannot be provided (e.g. because
 there is no entry for it in the driving file, or task
 creation fails), then an SSP reply (=OPENACK) block is with
 a standard ring return code is transmitted back.  If the
 task is successfully created, then it is its job to reply.
     The task may be killed by using crtl/D break, but will
 go away automatically if the ring handler is killed.















 TRIPOS                      -13-               Ring Software


            6   Byte Stream Protocol Handler Task
            _____________________________________
     The BSP Handler task implements the Byte Stream Protocol
 defined in the document by M.A.Johnson (June 1979).  It
 enables an input/output pair of byte streams to be opened
 via the ring, which provide an error-free channel with flow
 control.  The task will set up and manage an arbitrary
 number of byte stream pairs.

 Initiating a Byte Stream Connection
 ___________________________________
     In order to initiate a connection, you must know the
 name of a ring service to which you wish to connect.  In
 TRIPOS, a BSP open is performed using the normal BCPL
 routines FINDINPUT or FINDOUTPUT with the pseudo-device
 "BSP:".  The BSP handler task will be dynamically loaded if
 it was not already running.  The input or output stream (as
 appropriate to the call) is returned, and the other stream
 of the pair is placed in RESULT2:
 Thus, use either:
       instr  := findinput("BSP:<service name>")
       outstr := result2
 or:
       outstr := findoutput("BSP:<service name>")
       instr  := result2
     If the stream cannot be opened, then the result is zero,
 and a fault code is in result2.
     It is possible to include a string in the user parameter
 area of the BSP OPEN block sent, by including it after the
 service name, separated from it by a slash.  This facility
 is used by the read and write services, and by the printer
 service (where the string is the document title).  For
 example, this can be used in a command such as:
   EX :C TO BSP:PRINT/Commands

 Providing a BSP service
 _______________________
     In order to provide a BSP service, a program should be
 written which can be activated by the Ring Services Task.
 Normally, it will find itself running when a BSP OPEN
 request arrives via the ring.  It should check that the
 request is indeed an OPEN, respond with an OPENACK block,
 and set up the local end of the byte stream pair.
     A routine for doing this is provided in the library
 TRIPOS                      -14-               Ring Software


 BSPLIB (see "Extra Stream Control Routines" below).  It is
 used as follows:
     RES := BSP.OPENACK(OPEN.BLOCK, SIZE, SOURCE,
                        @INSTR, @OUTSTR)
     OPEN.BLOCK is the data part of the ring basic block
 which activated the service.  It is FREEVECed by the
 routine.
     SIZE is the number of words in OPEN.BLOCK.
     SOURCE is the station number of the sender of OPEN.BLOCK
     INSTR and OUTSTR are the variables which are to hold the
 input and output stream pointers respectively.
     If RES is TRUE, then OPEN.BLOCK was a BSP OPEN, the
 OPENACK block has been successfully transmitted, the BSP
 handler loaded if necessary, the local end of the stream
 created, and INSTR and OUTSTR updated.
     If RES is FALSE, the connection could not be completed;
 RESULT2 contains the fault code.  If possible, an OPENACK
 block has been sent with a non-zero return code.  (The fault
 may be, for instance, that transmission of the OPENACK
 itself failed).

 Stream Interface
 ________________
     The input and output streams created by either of the
 means described above may then be used as arguments to
 SELECTINPUT/SELECTOUTPUT, and used as normal BCPL byte
 streams, via RDCH and WRCH.
     If the BSP connection is closed down from the other end,
 then the local streams become as if connected to the pseudo-
 device "NIL:" - i.e. the output stream is an infinite sink,
 and the input stream is an infinite source of ENDSTREAMCH.




 TRIPOS                      -15-               Ring Software


 Closing the streams
 ___________________
     To close BSP streams, the routines ENDREAD and ENDWRITE
 are used as normal.  Only one of these should be called, as
 either will break the BSP connection, and so end the other
 stream of the pair.
     ENDREAD causes a BSP CLOSE command to be transmitted,
 which will forcibly close down the streams.  ENDWRITE causes
 the last buffer to be sent (even if empty), with the 'close
 request' and 'force transmission' flags set.  This will
 result in the byte streams dying only when the other end has
 processed all the data sent.

 Unloading the Handler
 _____________________
     The BSP handler may be killed by using the command
 BSINFO KILL.  This causes the handler to go away when it
 next has no streams open.











 TRIPOS                      -16-               Ring Software


 Extra stream control routines
 _____________________________
     When using byte streams to a remote machine, some extra
 actions are required which are not normally necessary for
 a stream to a local file or device.  A library is provided
 containing routines to perform these operations.  It is most
 easily used as a BCPL header file, by including the
 following directives at the head of a program:
     GET "libhdr"
     GET "ringhdr"
     GET "iohdr"
     GET "sys:ring.bcpl.bsplib"
     Routines defined in BSPLIB are as follows:
 BSP.FORCEOUT()
     This forces the current buffer to be transmitted with
 the 'force transmission' flag set.
 BSP.TEST.INPUT()
     This returns TRUE if a call of RDCH would return
 immediately (with a character or ENDSTREAMCH), or FALSE if
 it would have to wait for input to arrive.  This enables a
 sequential task to respond to asynchronous input while
 writing to the output stream.
 BSP.TEST.RESET(SCB)
     This returns TRUE if there has been a reset on the byte
 stream pair of which SCB is one half, and FALSE otherwise.
 If there has been a reset, then the buffers used by RDCH and
 WRCH are cleared so that all data in transit before the
 reset was noticed is lost.  Note that a byte stream reset
 can cause a dummy character to appear on the input stream,
 to force a return from RDCH.  If this function is used to
 test the input stream, it should be called just after RDCH,
 and if there has been a reset, that result from RDCH should
 be ignored.

 BSP.RESET(SCB)
     This resets the byte stream pair of which SCB is one
 half.

 TRIPOS                      -17-               Ring Software


 Tracing
 _______
     The current BSP handler has a tracing facility, which
 displays the commands in every basic block sent or received.
 The trace option is initially disabled, and is enabled or
 disabled by successive calls of the command BSINFO TRACE.

 Inspecting the state of streams
 _______________________________
     The command BSINFO may be used to inspect the state of
 byte streams.  It prints the task number of the BSP handler,
 and information on the states and sequence numbers of each
 open stream pair.













 TRIPOS                      -18-               Ring Software


                   7   Single Shot Protocol
                   ________________________
     Many ring services are called using the Single Shot
 Protocol (Systems Research Group Project Note by N.J.Ody
 19.4.79).  In this protocol, one basic block is sent to
 request a service, and one is received in reply.  The first
 three data words of the blocks are treated specially.
 SSP request
 ___________
   word  +-----------+
      0  |  #X6C00   | fixed value (CODE.SSPREQ)
         |-----------|
      1  |REPLY PORT | reply expected on this port
         |-----------|
      2  | FUNC CODE | part of service's ring address
         |-----------|
      3+ |           |
         |  service  |
         | dependent |
         | arguments |
         |           |
         +-----------+

 SSP reply
 _________
   word  +-----------+
      0  |  #X6500   | fixed value (CODE.SSPREPLY)
         |-----------|
      1  | PORT or 0 | port for rest of conversation
         |-----------|                     (if any)
      2  |RETURN CODE| zero iff successful
         |-----------|
      3+ |           |
         |   reply   |
         |   data    |
         |           |
         +-----------+
     A function for performing SSP calls is provided in the
 BCPL source library SSPLIB, which is designed to be used as
 a header file.  For example:
     GET "libhdr"
     GET "ringhdr"
     GET "sys:ring.bcpl.ssplib"


 TRIPOS                      -19-               Ring Software


     An SSP call to a service whose name is in the nameserver
 can be done as follows:
     RES := SSP(SERVICE.NAME, TXBUFF, TXWORDS,
                RXBUFF, RXWORDS, NSVEC, FUNC)
     The result is TRUE if the call succeeds; otherwise it
 is FALSE and RESULT2 contains an error code.
     SERVICE.NAME is a string giving the text name of the
 required service.
     TXBUFF is a buffer which will form the data part of the
 transmitted basic block, and is TXWORDS long.  The arguments
 for the service call should start at offset BB.SSP.ARGS (=
 3), leaving room for the three SSP words to be filled in at
 the beginning.
     RXBUFF is a buffer for the data part of the reply basic
 block, and is RXWORDS long.  After the call, it will contain
 the whole reply, including the three SSP words at the
 beginning.
     NSVEC is a vector with upperbound of at least 3.  The
 results of the nameserver lookup are returned in it, in the
 usual format (see section 8 below).
     FUNC is used only if the nameserver lookup yields a ring
 address with the 'no function code' flag set, and is written
 to the function field of the SSP request block.  Otherwise
 it is ignored.
     The same function can be used to call a service whose
 ring address is already known, avoiding the nameserver
 lookup.  [In particular, the name lookup service is called
 in this way].  The form is as follows:
     RES := SSP(0, TXBUFF, TXWORDS, RXBUFF, RXWORDS,
                ?, FUNC, STATION, PORT)
     STATION, PORT and FUNC are the station number, port
 number and function code for the service.




 TRIPOS                      -20-               Ring Software


              8   Use of the Name Lookup Server
              _________________________________
 Looking up service names
 ________________________
     One machine on the ring implements a name lookup
 service, converting the text name of a service or machine
 into a ring station address, port number, function code, and
 some flags indicating the protocol to be used.  (Systems
 Research Group Project Note N.J.Ody 20.4.1979).
     To look up a name in the name server, include the
 library SSPLIB in your program, and then use:-
     RES := LOOKUP.NAME(NAME.STRING, NSVEC)
     RES = TRUE indicates that the lookup was successful, and
 that NSVEC (which should have upperbound >= 3) contains the
 following information:-
     NSVEC ! NSV.MACHINE.ID: ring station address
     NSVEC ! NSV.FLAGS:      flags
     NSVEC ! NSV.PORT:       port number
     NSVEC ! NSV.FUNC:       function code
     RINGHDR contains manifests for the protocol codes and
 flag bits which can be found in the flag word:
     NSV.FLAGS.PMASK    mask for protocol code
     NSV.FLAGS.BSP      BSP open service
     NSV.FLAGS.SSP      SSP service
     NSV.FLAGS.NOFUNC   No function code given
     NSV.FLAGS.SLOW     Service may be slow to reply
                        (i.e. > about 5 seconds)

 Reverse Lookup
 ______________
     A facility is provided for writing the text name of a
 machine given its ring address, by using the reverse lookup
 facility of the name server.  This is useful when the remote
 machine has called the local one and an operator message is
 wanted.  Include SSPLIB and use:
     WRITE.MACHINE.NAME(STATION.NUMBER)
     The name is written to the current output stream with
 no delimiting spaces.  If the machine name is not known, or
 lookup fails, then "Station <number>" is written.  Station
 number 255 is called "anywhere".

 TRIPOS                      -21-               Ring Software


 Adding names
 ____________
     Names may be added to the nameserver by using:
   res := callseg("sys:l.nameserver-addname",
                  name, flags, port, function)
     Res = TRUE indicates that the name was successfully
 added.  If res = FALSE then result2 will contain a fault
 code indicating why the addition failed (e.g. name already
 exists, illegal character).
     The name will be set up referring to the machine which
 installed it.

 Deleting Names
 ______________
     To delete a name from the nameserver, use:
   res := callseg("sys:l.nameserver-delname", name)
     Res is TRUE if deletion worked.  Note that deletion of
 machine names, and names of services on other machines is
 not allowed.









 TRIPOS                      -22-               Ring Software


 Nameserver Commands
 ___________________
 ADDNAME       "NAME/A,FLAGS/A,PORT/A,FUNC"
     Adds the given name to the nameserver, with the supplied
 flags, port, and function code.  If the function code is
 omitted, then the 'no function code' flag is set.
     Possible values for the FLAGS argument are:
     ssp
     slow-ssp
     bsp
     slow-bsp

 DELNAME       "NAME/A"
     Deletes the given name from the nameserver.

 SETNAMES      "FROM"
     This takes a file in the format accepted by RINGSERV,
 and puts the names of all the services in the nameserver,
 deleting the old version of each name first.  The default
 FROM is "sys:info.ring-services".

 LISTNAMES     "TO"
     This lists the entire nameserver table.
 LOOKUP        "NAME/A"
     Prints the ring address of NAME.





 TRIPOS                      -23-               Ring Software


                      9   File Transfer
                      _________________
     Files can be transferred to other machines on the ring
 using a protocol superimposed on a byte stream connection.
 Files may be treated as characters or as a sequence of
 uninterpreted bytes.  Characters files are sent as a
 sequence of records in a machine-independent format,
 allowing transfer between machines that store text files in
 different ways or different codes.
 The command to transmit a file is:
     GIVEFILE  "FROM/A,TO=MACHINE/A,AS/A,BINARY/S"
     FROM is the local name of the file.  TO is the name of
 the destination machine.  AS is the filename to be used on
 the remote machine.  BINARY is a switch indicating that the
 file should be sent as a sequence of bytes, rather than
 being treated as a text file.
     The command to fetch a file is:
     TAKEFILE  "FILE/A,FROM=MACHINE/A,AS/A,SERVICE/K"
     FILE is the name of the file on the FROM machine.  AS
 is the local filename to be used.  The service to which the
 byte streams are connected is that with name
 "<SERVICE>-<MACHINE>".  The default value of SERVICE is
 "GIVEFILE".
     Where the remote machine is one with typed files, the
 format in which the file is sent depends on whether or not
 it is considered to be a text file.  Machines with untyped
 files may provide binary transfer as a different service
 name - hence the provision of a SERVICE keyword.

 Streams to remote files
 _______________________
     TRIPOS provides ring services which allow remote files
 to be read and written in a similar way to local files,
 using the "BSP:" pseudo-device.  The data is transmitted as
 a series of uninterpreted bytes, so this system can only be
 used between machines with the same character code and the
 same view of streams.


 TRIPOS                      -24-               Ring Software


     The filename is sent in the BSP OPEN block, and so is
 included after a slash in the "BSP:" name.  E.g.:-
     TYPE BSP:READ-LSI4/:G.RINGHDR
     EX :C TO BSP:WRITE-NOVA/T:COMMANDS
















 TRIPOS                      -25-               Ring Software


                   10  Some Useful Commands
                   ________________________
 RPROD     "MC/A,PORT,CLOSE,BOOT"
     Sends a basic block containing one data packet to the
 specified machine, and reports on whether it was accepted.
 By default, the value of the data is #X1234 (to stop the
 checksum looking like a header).  CLOSE causes it to be set
 to a BSP CLOSE command, so it can be used to encourage
 errant byte streams to go away.  BOOT sets the data to the
 value which will cause a crashed PDP11 TRIPOS system to
 reboot.

 RSTATUS
     Sends a basic block (on port 1) to each ring address in
 turn, and reports on all those for which the block is not
 'ignored'.  This is an easy way of discovering which
 machines are 'alive'.

 RHINFO    "KILL/S"
     Prints information about outstanding reception requests,
 reserved ports, and bad or unwanted blocks received.  KILL
 causes the ring handler task to finish.








 TRIPOS                      -26-               Ring Software



                               SYSLINK
                               _______
                      The TRIPOS system linker
                      ________________________
          The TRIPOS system linker program is used to build
       an absolute object file representing the contents of
       the store of a TRIPOS system, which can then be loaded
       and started by the bootstrap loader.  It is invoked as
       the command
            SYSLINK   "FROM/A,TO/A,MAP/K,OPT/K"
       The FROM argument should be the name of a file of
       commands for the linker describing the system to be
       built, and the TO argument should be the name of the
       required object file.  The MAP keyword may be used to
       obtain a map of the system, in which case it should be
       followed by a suitable filename for the mapping output.
       The OPT keyword may be used to supply options; the
       letter 'W' followed by an integer specifies the
       workspace size, and 'F' specifies full map output,
       rather than the abbreviated form given by default.
          The basic action of the linker is to mimic the
       operation of LOADSEG in allocating store, loading code,
       and performing relocation, to load all the required
       segments, then to build and link together the segment
       lists, TCBs and task table.  A similar action is then
       performed for the device table, DCBs, and device
       drivers.  Store is allocated in blocks starting from
       the top of available memory, each block being
       constructed to look exactly like one obtained by a call
       of GETVEC.  The block list is then completed by a
       single free block extending from the bottom of memory
       containing the remaining free store, and the rootnode
       then written out.  Any segments used for system
       initialisation and then thrown away may be placed at
       the bottom of the allocated area, so that when they are
       freed the user will have a single contiguous lump of
       free store.  Absolute store - the rootnode and any
       machine dependent data areas, such as page zero, is
       overlaid; any non zero words will overwrite previously
       loaded words, but zeros will not overwrite, so that
       overlapping absolute hunks may be assembled correctly.
          The linker operates in three phases: firstly it
       reads the command file, checking for syntax errors and
       building a tree structure representing the
                                  1


       declarations; secondly it scans the tree checking the
       validity and consistency of the declarations; thirdly
       it reads the required code segment files etc. and
       writes out the object file.
          The syntax for the command file is as follows:
       <commandfile>
           ::= <declaration>; [<declaration>;]*
       <declaration>
           ::= <star><declaration>
           ::= <segment-declaration>
           ::= TASKTAB <number>
           ::= <task-declaration>
           ::= <driver-declaration>
           ::= <DCB-declaation>
           ::= DEVTAB <number>
           ::= <device-declaration>
           ::= ABSMIN <number>
           ::= ABSMAX <number>
           ::= TCBSIZE <number>
           ::= STOREMIN <number>
           ::= STOREMAX <number>
           ::= MCADDRINC <number>
       <segment-declaration>
           ::= SEGMENT <name> <name-list>
       <task-declaration>
           ::= TASK <number>
                   [PRIORITY <number> | STACK <number>]*
                   SEGMENTS <name-list>
       <driver-declaration>
           ::= DRIVER <name> <name-list>
       <DCB-declaration>
           ::= DCB <name> <name-list>
       <device-declaration>
           ::= DEVICE <number>
                   [DCB <name>]*
                   DRIVER <name>
       <name-list>
           ::= [<name>[, <name>]*]
       Layout characters - space, tab, and newline are
       ignored, except that they terminate names and numbers.
       <star> is the character '*'.  <number> is a string of
                                  2


       one or more digits, which may be preceeded by '#' or
       '#X' to denote an octal or hexadecimal number.  <name>
       is a string of one or more characters, except layout
       characters, ';', ',', and not starting with a digit.
       SEG is allowed as an abbreviation for SEGMENT, SEGS for
       SEGMENTS, PRI for PRIORITY, and DEV for DEVICE.
          A segment declaration declares a segment name and
       causes the following name list to be interpreted as a
       list of names of files, the contents of which are
       loaded and linked together to form the segment, which
       will be included in the segment list of all tasks the
       declarations of which reference the segment name.  A
       '*' preceeding the declaration indicates that the
       segment is an initialisation segment.  A TASKTAB
       declaration sets the size of the task table; otherwise
       a default of 10 is assumed.  A TASK declaration causes
       a TCB and segment list to be built and inserted into
       the task table and linked into the appropiate position
       on the priority chain; tasks of equal priority are
       linked in the order in which they are declared.  The
       number following TASK is the taskid; PRIORITY and STACK
       set the priority and stack size, with defaults of 1000
       and 100.  The list following SEGMENTS is a list of the
       names of the segments to be included in its segment
       list - these must be declared in segment declarations.
       Note that null entries may be obtained by declarng a
       null segment.  A '*' before a task declaration
       indicates the initial task, which will be sent a dummy
       packet by the kernel initialisation code to start the
       system.  A driver declaration declares a device driver
       name and causes the appropiate files to be loaded.  A
       DCB declaration declares a DCB name and associates it
       with the following name list, but a new copy of the DCB
       will be loaded for each device declaration that
       references it, since DCBs cannot be shared between
       devices, unlike device drivers.  A DEVTAB declaration
       sets the size of the device table, default 10.  A
       device declaration causes the DCB to be loaded, entered
       in the device table, and linked to its driver; the
       number following DEVICE is the devid (without the -
       sign).  The DCB should consist of exactly one object
       hunk, and the driver of at least one hunk, so that
       device initialisation can be performed when the kernel
       is started.  The declarations ABSMIN and ABSMAX define
       the limits of absolute store, which is to be overlaid;
       these default to ROOTNODE and ROOTNODE+RTN.UPB as
       declared in LIBHDR.  STOREMIN and STOREMAX define the
       limits of available memory, TCBSIZE the upper bound of
       a TCB, and MCADDRINC the factor by which BCPL addresses
       must be multiplied to obtain machine addresses; the
                                  3


       defaults for these are the values declared in LIBHDR.
          A straightforward example of linking for the
       standard system follows
       SET TRIPOS
       SYSLINK SYS-DECLS TO SYS-ABS MAP SYS-MAP
       where the file TRIPOS.SYS-DECLS contains
        SEG    LIB1    KLIB,MLIB;
        SEG    LIB2    BLIB;
        SEG    CLI     CLI;
        SEG    DEBUG   DEBUG;
        SEG    COHAND  COHAND;
        SEG    FIHAND  FIHAND;
       *SEG    CLINIT  CLI-INIT;
       *SEG    FHINIT  FIHAND-INIT;
       TASKTAB 20;
       *TASK 1 PRI 1000 STACK 160 SEGS LIB1,LIB2,CLI,CLINIT;
        TASK 2 PRI 2000 STACK 130 SEGS LIB1,LIB2,DEBUG;
        TASK 3 PRI 3000 STACK 200 SEGS LIB1,LIB2,COHAND;
        TASK 4 PRI 4000 STACK 120 SEGS LIB1,LIB2,FIHAND,FHINIT;
        DRIVER RDRIV  RDRIV;
        DRIVER PDRIV  PDRIV;
        DRIVER DKDRIV DKDRIV;
        DCB DISK     DKDCB;
        DCB KEYBOARD CKDCB;
        DCB PRINTER  CPDCB;
       DEVTAB 20;
        DEV 2 DCB DISK     DRIVER DKDRIV;
        DEV 3 DCB KEYBOARD DRIVER RDRIV;
        DEV 4 DCB PRINTER  DRIVER PDRIV;
       In this example the entire system is loaded by the
       system linker;  it is quite possible to link a version
       of the system containing only the filing system task
       and disc device which loads the rest of the system
       dynamically - this is more flexible when updating
       components of the system or reconfiguring it, but has
       the disadvantage of requiring more time to bootstrap
       and of making the storage allocation less neat,
       possibly causing fragmentation problems.
                                  4

