Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-06 - 43,50362/iolib5.man
There are no other files named iolib5.man in the archive.












                          IOLIB Reference Manual
                          ----- --------- ------





                                 Rob Cook
                    LaTrobe University Computer Centre
                                 10-Aug-74

















                                      NOTE

         This manual describes the subroutine  library,  IOLIB  version
         5(205),  and  the  parameter  program  IO version 5(153).  The
         information in this document  is  subject  to  change  without
         notice  and  should  not  be  construed as a commitment to the
         author or to LaTrobe University.

         Actual distribution of the software described in this document
         will be subject to terms and conditions that will be announced
         by the author.
IOLIB Reference Manual















                                    Abstract

         IOLIB is a system of subroutines, macros  and  parameters  for
         use in MACRO-10 programs.  The system is intended to provide a
         prewritten set of commonly used subroutines  and  macros  that
         rely  on  a  standardised method of IO, and that make assembly
         language programming simple, and programs readable.  IOLIB may
         be   used   by   wizards  for  the  most  complicated  systems
         programming, but it is  also  an  extremely  useful  tool  for
         teaching assembly language programming.
IOLIB Reference Manual
Table of Contents


                             Table of Contents

     Chapter 1 - IOLIB Explained                                       

     1.1   What is IOLIB?                                             1-1
     1.2   Some Features of IOLIB                                     1-2
     1.3   Who can usefully use IOLIB?                                1-2
     1.4   How to use this manual                                     1-3
     1.5   Software Support                                           1-4
     1.6   Credits                                                    1-4


     Chapter 2 - Concepts                                              

     2.1   Components of IOLIB                                        2-1
     2.2   Files and FDBs                                             2-2
     2.3   The IOLIB Data Base                                        2-4
     2.4   Routines and Macros                                        2-4
     2.5   Error Messages                                             2-5
     2.6   Replaceable Routines                                       2-5
     2.7   Formatted IO                                               2-6
     2.8   User Program Structure                                     2-6


     Chapter 3 - Programming Techniques                                

     3.1   General Description                                        3-1
     3.2   Compiling and Loading Programs with IOLIB                  3-1
     3.3   Program Structure                                          3-2
     3.4   Symbol Naming Conventions                                  3-3
     3.5   Accumulator Conventions                                    3-3
     3.6   Subroutine Calls                                           3-5
     3.7   Assembly Switches                                          3-6
     3.8   Push Down Stack                                            3-7
     3.9   BEGIN$ - Program Initialisation                            3-7
     3.10  Global Parameters                                          3-8
     3.11  Segmentation                                               3-9
     3.12  FDESC$ - Build an FDB and Set Values                       3-9
     3.13  MAKFD$ - Produce Code to Build an FDB                      3-10
     3.14  Version Number Macros                                      3-11
     3.15  Debugging Aids                                             3-11


     Chapter 4 - IOLIB Tables                                          

     4.1   General Description                                        4-1
     4.2   $TBWAD - Table of Write Routine Addresses                  4-1
     4.3   Switch Tables                                              4-2
     4.4   Switch Table Building Macros                               4-2


     Chapter 5 - Memory Management                                     

     5.1   General Description                                        5-1
     5.2   Dynamic Memory Management                                  5-2
IOLIB Reference Manual
Table of Contents


     5.3   Static Memory Management                                   5-2


     Chapter 6 - Basic IO Routines                                     

     6.1   General Description                                        6-1
     6.2   $INPUT - Read a Physical Record from a File                6-2
     6.3   $OUTPU - Write a Physical record to a File                 6-3
     6.4   $LUKUP - LOOKUP a File                                     6-4
     6.5   $ENTER - ENTER a File                                      6-5
     6.6   $OPEN - OPEN an IO Channel                                 6-5
     6.7   $CLOSE - Disconnect a File from a Channel                  6-7
     6.8   $RLEAS - Release an IO Channel                             6-7
     6.9   $RENAM - Change RIB Details for a File                     6-8
     6.10  $DELET - Delete a File                                     6-9
     6.11  $USETI/O - Set the Disk Record Number                      6-9
     6.12  $GETST - Read the IO Channel Status                        6-9
     6.13  $SETST - Set the IO Channel Status                         6-9
     6.14  $XTUUO - Execute an IO UUO                                 6-9
     6.15  $XTCAL - Execute an IO Oriented CALLI UUO                  6-10
     6.16  $XTDCL - Execute a Device Oriented CALLI UUO               6-10
     6.17  $MKBUF - Make a Ring of Buffers                            6-11
     6.18  $DLBUF - Delete a Ring of Buffers                          6-11
     6.19  $UPDAT - Open a File for Updating                          6-11
     6.20  $UPDWT - Open for Updating, Wait if Being Modified         6-11
     6.21  $APEND - Open a File for Appending                         6-11
     6.22  $APDWT - Open a File for Appending and Wait                6-12
     6.23  $MTxxx - Execute an MTAPE UUO for a File                   6-12


     Chapter 7 - Formatted Reading and Writing                         

     7.1   General Description                                        7-1
     7.2   $WRITE - Write one Byte to the Current File                7-2
     7.3   $$WBYT - Write one Byte to the Current File                7-2
     7.4   $$WCHR - Write a Character to the Current File             7-2
     7.5   $READ - Read one Byte from the Currrent File               7-3
     7.6   $$RBYT - Read one Byte from the Current File               7-3
     7.7   $$RCH0 - Read a Character from the Current File            7-4
     7.8   $$RCHR - Read a Character from the Current Command File    7-4
     7.9   $REDCH - Read a Character and do Basic Editing             7-5
     7.10  $RCCHR - Read a Character and Edit as a Command Character  7-5
     7.11  $RFILE - Read a File Specification from the Current File   7-6
     7.12  Read Path and PPN Specifications                           7-7
     7.13  $RSWIT - Read a Switch Name and Value                      7-7


     Chapter 8 - Tempcore Routines                                     

     8.1   General Description                                        8-1
     8.2   $TMPFD - Build a Tempcore FDB                              8-1
     8.3   $TMPIN - Read a File from Tempcore                         8-2
     8.4   $TMPDL - Delete a File from Tempcore                       8-2
     8.5   $TMPOU - Close a Tempcore Output File                      8-2
IOLIB Reference Manual
Table of Contents


     Chapter 9 - Error Reporting                                       

     9.1   General Description                                        9-1
     9.2   Message Format                                             9-1
     9.3   Error Severity                                             9-3
     9.4   $ERROR - The Error Reporter                                9-3
     9.5   $FATAL and $WARN                                           9-5
     9.6   The FATAL$ and WARN$ macros                                9-5
     9.7   IO Error Reporting                                         9-6
     9.8   Syntax Error Reporting                                     9-6
     9.9   $$FERR - the Fatal Error Trap Routine                      9-7


     Chapter 10 - Utility Routines                                     

     10.1  General Description                                        10-1
     10.2  $MATCH - Match a Name in a Table of Names                  10-1


     Chapter 11 - Examples                                             

     11.1  Formatted IO                                               11-1
     11.2  Copy a File to LPT                                         11-2
     11.3  Subroutine to Read a Filename                              11-2


     Appendix A - List of all IOLIB Routines                           

     A.1   Basic IO Routines                                          A-1
     A.2   Formatted Read Routines                                    A-5
     A.3   Formatted Write Routines                                   A-11
     A.4   Core Management Routines                                   A-14
     A.5   Data Block Manipulation Routines                           A-15
     A.6   Tempcore Routines                                          A-16
     A.7   Error Routines                                             A-17
     A.8   Utility Routines                                           A-18


     Appendix B - List of all IOLIB macros                             

     B.1   Programming Macros                                         B-1
     B.2   Basic IO Macros                                            B-3
     B.3   Read Macros                                                B-5
     B.4   Write Macros                                               B-7
     B.5   Core Management Macros                                     B-9
     B.6   Data Block Manipulation Macros                             B-9
     B.7   Tempcore Macros                                            B-9
     B.8   Error Macros                                               B-10
     B.9   Utility Routine Macros                                     B-11


     Appendix C - Contents of the FDB                                  

     C.1   Details of Words in the FDB                                C-1
     C.2   Bit Definitions for $FDCHN                                 C-4
IOLIB Reference Manual
Table of Contents


     C.3   Bit Definitions for $FDMOD and $FDMOM                      C-4


     Appendix D - Contents of the IDB                                  


     Appendix E - IO Error Codes                                       

     E.1   UUO IO Error Codes                                         E-1
     E.2   IO Error Codes                                             E-2


     Appendix F - IOLIB Standard Error IDs                             











                                CHAPTER 1

                              IOLIB EXPLAINED



     1.1  WHAT IS IOLIB?

          IOLIB  is  a  MACRO-10  assembly  language   programming   system
     comprising  subroutines  and  definitions  of macros and symbols.  The
     subroutines are a collection of routines commonly  used  and  commonly
     written  by  assembly language programmers.  IOLIB contains definitive
     versions of these routines  written  to  be  correct,  consistent  and
     versatile  so  that  they  may  be  used  in almost any situation that
     requires them, and they  can  be  relied  upon.   The  programming  is
     modular,  all  the  routines having well-defined consistent interfaces
     with each other, and with the caller and  most  of  the  routines  are
     separate  units  that  can  be  loaded individually, together with any
     other routines that they call.  The base of the  system  is  a  module
     that  will  execute  the IO UUOs on files described by a standard data
     block.   The  various   routines   in   the   module   are   organised
     hierarchically, so that the programmer needs only to call the function
     he requires and all prerequisites are organised for him.  The basic IO
     module  is  general  enough  to  be  used  for  the  most  complicated
     algorithms.

          The rest of the package is built on the basic IO  module.   There
     are  routines  for  reading  and  writing  data  in a number of common
     formats, for memory management,  for  error  reporting,  for  tempcore
     handling  and  many  others.   The  routines that read data in various
     formats make up a useful command scanner with a power similar to  that
     of the DEC SCAN module.

          The macros  and  symbols  come  in  a  parameter  file  which  is
     assembled   with   the  user  programs.   Each  IOLIB  routine  has  a
     corresponding macro, which may be used to  call  it,  making  programs
     very  readable  and the calls shorter.  Other macros are used to write
     program initialisation code, to define  version  numbers  and  control
     assembly.   IOLIB  forms  a  useful  programming  standard  that makes
     assembly language programs easier to write  and  read,  and  therefore
     more maintainable.

          It is so easy to write simple programs in IOLIB that  the  system
     can be used to teach MACRO-10 assembly language programming.  Students
     can use IOLIB macros for program initialisation and for  all  IO,  and
     can  concentrate  on  learning  the instruction set and the use of the
     assembler and hardware.
IOLIB EXPLAINED                                                    Page 1-2
SOME FEATURES OF IOLIB


     1.2  SOME FEATURES OF IOLIB


     *  basic IO module for executing IO UUOs on any file.

     *  files described by standard data block.  A large number of defaults
        are supplied.

     *  buffer sizes are variable because IOLIB creates buffer rings itself

     *  any IO call for a file ensures  that  all  prerequisites  for  that
        function are fulfilled first.

     *  routines for writing data in a wide variety of  formats;   decimal,
        date/time, filename, cash ...  IOLIB has them all

     *  routines for reading data in all the same  formats.   This  feature
        gives  a  command  scanner of similar power to the DEC SCAN module,
        but smaller.

     *  dynamic memory management using the ALGOL heap algorithm

     *  comprehensive routines for reporting errors  in  the  DEC  standard
        format.  Verbosity level can be set by program or user.

     *  critical routines replaceable by user programmer, so  that  IOLIB's
        simple  approach  can be replaced by something more complicated for
        e.g.  fatal error traps.

     *  a macro to call each IOLIB routine, making code  shorter  and  more
        readable.

     *  a macro to write program initialisation code

     *  macros to define file data blocks

     *  all the SAVEn and POPJ/POPJ1 utility routines

     *  all symbols are parametised.  All contain the character '$' so that
        they  are easily recognisable.  IOLIB uses C.MAC, so that all the C
        symbols are available to the programmer.

     *  DEC compatibility

     *  will run on 5.06 and later monitors only.



     1.3  WHO CAN USEFULLY USE IOLIB?

     IOLIB is aimed at 3 main classes of programmer:

     1.  the professional systems programmer, who spends much of  his  time
         coding in assembly langauge.  For him IOLIB is a complete assembly
         language programming system of  standard  modules  that  he  would
IOLIB EXPLAINED                                                    Page 1-3
WHO CAN USEFULLY USE IOLIB?


         otherwise  write for himself for each program, as well as offering
         features that he might not consider using if  the  code  were  not
         prewritten.   The  basic IO routines handle all IO on all channels
         in  one  module.   They  are  extremely  flexible,  allowing   the
         programmer  to  manipulate  his  file  transactions  in  the  most
         complicated ways.  Most routines are written independently of  the
         other  routines  and  are loaded separately so that the programmer
         can use as much or as little of the system as he  wants,  and  his
         final  program  is  not burdened with unused routines.  Advertised
         routines are easily replaceable by the programmer's  own  routines
         and  the clever programmer can make good use of rewriting specific
         critical  routines.   Use  of  IOLIB  ensures  that  programs  are
         reasonably  standardised,  and in particular text output and error
         messages are in a standard form.

              As well as standard  routines,  IOLIB  defines  a  wealth  of
         standard  symbols  and  macros  and  includes all those defined in
         C.MAC.  Together, IOLIB and C form  a  programming  standard  that
         could  usefully  be  adopted  by  installations  to  make programs
         readable and maintainable.

     2.  the programmer who  writes  simple  one-off  programs.   The  main
         reason  such  a  user wants to write assembly language programs is
         because the higher level languages cannot  provide  some  feature.
         IOLIB  can  be  used to construct one-off programs easily, because
         the command decoder, message writer and basic IO are laid on.   At
         the  same time it offers access to all the machine characteristics
         that straight assembly language code does.  IOLIB is easy  to  use
         reliably without detailed study of the system.

     3.  for teaching MACRO-10.  IOLIB allows students to call  macros  for
         initialising  their  programs  and  for  all  IO, so that they can
         concentrate on the basics of assembly language.  The IOLIB  system
         is  so  simple  that  students  can  be taught enough to construct
         simple programs in a few minutes.  This basic subset includes  the
         use of the SEARCH pseudo-op, the BEGIN$ macro to start programs, a
         few formatted read and write macros,  accumulator  names  and  the
         MONRT$  macro.   Later they can be introduced to files through the
         FDB system, using all the same macros together with MAKFD$.  Using
         IOLIB,  students can write full assembly langage programs from the
         first class;  there is no need to bother  with  starting  them  on
         writing FORTRAN subroutines with all the addressing technique that
         that involves.




     1.4  HOW TO USE THIS MANUAL

          The manual is a reference manual rather than a teaching text, and
     it  is  laid out so that the programmer can easily locate details of a
     routine or macro  to  perform  a  specific  task.   The  concepts  and
     conventions used in IOLIB are explained in chapters 2 and 3.  Chapters
     5 to 10 contain details of critical or complicated routines, including
     full  algorithms  and  even  code  in some places.  Chapter 4 contains
IOLIB EXPLAINED                                                    Page 1-4
HOW TO USE THIS MANUAL


     details of IOLIB tables that the  user  may  need  to  use,  build  or
     modify.  The main reference parts of the manual lie in the appendices.
     Appendix A is a full list of  all  the  routines,  and  entry  points,
     available in IOLIB.  It contains a specification, including details of
     return addresses, input arguments and output results.   Also  included
     are details of the acs altered by the routine, the size of the routine
     in words, the macros that call  the  routine  and  a  reference  to  a
     section  in the main part of the manual that contains further details,
     if necessary.  Appendix B is a full list of all  macros  available  in
     the  IOLIB  system.   It  contains  full details of the macro call and
     specification of the  effect,  as  well  as  a  reference  to  further
     details.   Appendices  C  and D list the words in the FDB and the IDB,
     and explain them fully.  Appendices E and F deal with error  messages.
     Appendix  E  gives  the  codes  returned  by  the  basic  IO  routines
     indicating errors, and appendix F gives a  list  of  the  3  character
     error ids produced by IOLIB and explains them in full.

          The files constituting this manual are distributed in sections so
     that  the  appendices  may  be  printed separately and used alone as a
     quick reference document.

          To use the manual, digest  the  contents  of  chapters  2  and  3
     thoroughly  and  understand  the  simple examples given in chapter 11.
     After a basic understanding is gained,  the  programmer  can  look  up
     routines that he requires in the appendices A and B.



     1.5  SOFTWARE SUPPORT

          The IOLIB system is  maintained  at  Latrobe  University  by  the
     author.   Software Performance Reports submitted to the author will be
     answered promptly and problems solved as quickly as possible.  Further
     versions of IOLIB are under development.

          Suggestions for routines to be included in future versions or for
     changes and improvements to current routines are welcomed.



     1.6  CREDITS

          The original work and the development of the first 3 versions  of
     IOLIB  was  done  at  the  University  of  Queensland computer centre.
     Versions 4 and 5 were written at Latrobe University  computer  centre.
     The  author  gratefully  acknowledges the help and advice given by all
     members of the staffs of the two computer centres.

          When IOLIB was converted from the University of  Queensland  4s72
     (highly  modified)  monitor  to  DEC  standard 5-series monitors, much
     effort went into achieving DEC compatibility.  Ideas and code from the
     DEC  SCAN  and WILD modules were a great help and influence in meeting
     this goal.











                                CHAPTER 2

                                 CONCEPTS



     2.1  COMPONENTS OF IOLIB

          IOLIB is a set of subroutines contained in the subroutine library
     file  IOLIB.REL  and  a  set of macro and parameter symbol definitions
     contained in the UNIVERSAL parameter file IO.UNV, and  in  the  source
     file IO.MAC.  Programs using IOLIB must be assembled with the IO and C
     symbol tables, and they must  be  loaded  with  a  library  search  of
     IOLIB.REL.   Full  assembly  and  loading  instructions  are  given in
     section 3.2.  All programs written to use IOLIB may  use  any  of  the
     symbols  defined  in  IO.MAC  and the DEC parameter file C.MAC without
     prior definition.

          IOLIB subroutines fall into several broad  categories,  with  the
     main  emphasis  on  making  DECsystem-10  IO  readily available to the
     MACRO-10 programmer, and on giving  him  a  broad  range  of  standard
     routines to perform common tasks:

     1.  routines to execute  the  basic  IO  UUOs  for  any  file.   These
         routines  smooth  out the differences between devices, are channel
         independant and are organised in a hierarchic fashion, so  that  a
         call to one routine will ensure calls to other routines to execute
         prerequisite UUOs and routines.  For  example,  $LUKUP  will  call
         $OPEN.

     2.  routines to read/write one byte with a  file  using  buffered  IO,
         TTCALL UUOs or byte instructions, for a packing and unpacking like
         function.  These routines also ensure that prerequisite  UUOs  are
         executed by calling the basic IO routines.

     3.  routines to  read  and  write  character  strings  with  files  as
         described  above,  in  a  wide  variety of formats.  The formatted
         input  routines  read  characters  through  a   command   scanning
         coroutine similar to that in the DEC SCAN module.

     4.  error message printers that will print fatal or  warning  messages
         in  DEC  standard  format.   IO  and  command syntax errors can be
         reported easily by these routines since all  necessary  codes  are
         set up on error return from the IO and command scanning routines.
CONCEPTS                                                           Page 2-2
COMPONENTS OF IOLIB


     5.  routines to handle tempcore files (input, output and delete).

     6.  a variety of utility routines that are commonly used  by  assembly
         language  programmers,  such as accumulator save/restore routines,
         POPJ routines, table scanning, and many others.

     7.  the IOLIB data base


          The IO.MAC parameter file contains definitions of the IOLIB  data
     base symbols and of macros and OPDEFs that are useful (and some almost
     essential) for writing programs that use IOLIB.

     1.  useful symbol definitions for all accumulators

     2.  a macro to call each IOLIB routine

     3.  a macro to initialise a program that includes setting up  a  stack
         and  the  IOLIB  data  base, handling CCL calls and concealed mode
         entry.

     4.  symbolic definition of all  independant  words  and  bits  in  the
         various data blocks

     5.  macros to build file data blocks

     6.  macros to create calls to the error messages writers

     7.  macros to control version numbering

     8.  macros to aid assembly by  setting  assembly  into  high  and  low
         segments etc




     2.2  FILES AND FDBS

          IOLIB is mostly concerned with reading and writing  data  to  and
     from  files.   Files  are  described  to  IOLIB basic IO routines by a
     standard data block known as the File Descriptor Block, or FDB.   This
     block  contains  all the known information about a file and includes a
     RIB area, an OPEN UUO block, two buffer headers, the  channel  number,
     record number, buffering details and room for wildcard masks and other
     file attributes associated with command scanning.  Every file that  is
     to be accessed by IOLIB must be described by an FDB.

          The programmer is  responsible  for  building  the  FDB  and  for
     filling  in  all  his  non-default values.  The basic IO routines will
     supply defaults for all unfilled words.  IOLIB contains  routines  for
     obtaining  space  for an FDB from the memory manager, for initialising
     an FDB and for deallocating the space  used  by  an  FDB  ($CLRFD  and
     $LOSFD).  There are macros for building FDBs and for filling them with
     basic data.  The MAKFD$ macro produces inline code to obtain space (if
     necessary)  and  fill  in  details.  The FDESC$ macro builds an FDB at
CONCEPTS                                                           Page 2-3
FILES AND FDBS


     assembly time, and fills it.  The defaults are:

                         device         DSK
                         name           null
                         extension      null
                         PPN            null
                         IO mode        .IOASC
                         buffers        2; standard size for device
                         sequential IO starting at block 1

          The last item in an FDB is the RIB area for LOOKUP-class UUOs.  A
     standard length FDB contains the words of an extended RIB from  .RBCNT
     to .RBVER.  If the programmer needs longer extended RIBs, all  he  has
     to  do  is  build  a  longer  FDB.  The routines that create FDBs will
     accept a length as an argument, using the standard length by  default.
     If  all  FDBs  are  to  be  longer  than  normal, the programmer could
     redefine the symbol, $LNFDB, which gives the length of a standard FDB,
     e.g.

             $LNFDB==$FDRIB+.RBALC+1 ;all FDBs continue until .RBALC

          The  basic  IO  routines  perform  their  function  on  the  file
     described  by the FDB pointed at by an accumulator named D.  Therefore
     ac(D) must be loaded with a pointer to the required FDB before calling
     any  basic  IO  routine, and therefore any routine that uses the basic
     routines, such as the formatted IO routines.   The  FDB  used  by  the
     basic  IO  routines  is  known as the 'current FDB'.  So, to execute a
     LOOKUP on a file described by an FDB at location INPFDB:

             ...
             MOVEI   D,INPFDB        ;load current FDB
             LUKUP$                  ;execute LOOKUP (including OPEN)
               JRST  ERROR           ;
             ...

          The routines which read and write one  byte  ($READ  and  $WRITE)
     extend  the current FDB concept so that it includes TTCALL UUO for the
     job's terminal and byte pointers for reading and writing into  memory.
     If  ac(D)  contains  zero,  the routines use TTCALL.  If bits 0-11 are
     non-zero, ac(D) contains a byte pointer.  Otherwise, the right half of
     ac(D)  is  a  point  to  the  current FDB.  The file described by this
     extended pointer is known as the 'current file', and all formatted  IO
     routines perform their IO with the current file.  IO.MAC defines ac(D)
     to be ac15, and this ac is reserved for use as  the  current  file  by
     IOLIB.

     To write a message to the job's terminal:

             ...
             SETZ    D,              ;set TTCALL IO
             WTEXT$  <End of execution>
             ...

     To read a character from an incore buffer called TMPBUF:
CONCEPTS                                                           Page 2-4
FILES AND FDBS


             ...
             MOVE    D,[POINT 7,TMPBUF]  ;set up pointer
             RCHAR$                  ;read a character into ac(T1)
             ...

          The BEGIN$ macro which initialises the IOLIB system at the  start
     of  execution, sets up ac(D) to point to the command input file, which
     is either the terminal or a CCL file.  Pointers to the  command  input
     and  message  output  FDBs are kept in the IOLIB data base, and may be
     loaded into ac(D) using the CMDFD$  and  MSGFD$  macros.   The  TRMFD$
     macro sets ac(D) to zero for terminal IO.

          The contents of an FDB are explained in detail in Appendix C, and
     the  descriptions  of the basic routines in Chapter 7 explain how each
     routine uses and changes the FDB.  $RFILE, the filename input routine,
     also sets (and can create) FDBs.



     2.3  THE IOLIB DATA BASE

          IOLIB needs to keep a certain amount of data about the  state  of
     the program and of the IOLIB system.  It must be in the low segment so
     that it is modifiable, and  must  be  positioned  independent  of  any
     particular  program so that high segments can call each other and pass
     the address of the IOLIB data base between them.  IOLIB keeps its data
     in  one  block,  the  IOLIB  data  block,  or  IDB.  An accumulator is
     reserved to point to the IDB, and this pointer may be  passed  between
     segments.  The accumulator is given the name I, and is defined as ac16
     by IO.MAC.  This definition clashes with the standard use of  ac16  as
     ac(L),  the link register, and this clash must be resolved by the user
     programmer.  The IDB contains data used internally by IOLIB  routines,
     such  as the anchor for the linked list of free memory, and parameters
     which may be set by the programmer such as the maximum core which  may
     be  used  by  the  program.   The  parameters  which may be set by the
     programmer are discussed in section 3.10, and each word of the IDB  is
     explained in full in appendix D.



     2.4  ROUTINES AND MACROS

          Each IOLIB routine has a corresponding macro associated with  it.
     This  macro  may  be  used  to call the routine, and in some cases the
     arguments to the routine may be specified in the macro call;  e.g.

             OPEN$                   ;calls $OPEN to execute an OPEN UUO

             WDECL$  10              ;calls $WDECL to write decimal 10

          Using the macros makes the program more readable (expansions  are
     SALLed by default) and helps to cut down programming errors.
CONCEPTS                                                           Page 2-5
ROUTINES AND MACROS


          The complete list of IOLIB routines, their arguments and  results
     and  calling macros is given in Appendix A.  A complete list of macros
     is given in Appendix B.



     2.5  ERROR MESSAGES

          IOLIB  includes  routines  for  writing  error  messages  in  DEC
     standard format.  The messages may include text and a value, which may
     be written in one of several formats.  The routines are called by  the
     FATAL$,  WARN$  and  ADVIS$  macros,  which  take  a list of arguments
     specifying the message in full.  The macros create only  one  location
     of inline code, so that they may be used in an error return location.

          The basic IO routines return an error code in ac(T1),  when  they
     detect  an  IO  error,  and  a  call to the error routines through the
     FATAL$ and WARN$ macros with  no  arguments  produces  an  informative
     error message.

             ...
             LUKUP$                  ;LOOKUP a file
               FATAL$                ;errors are fatal
             ...

     might produce:

             ?RENAEF RENAME(4), Already exists: IOLIB.BAK

          Some of the command decoding routines detect  syntax  errors  and
     these  too  have an error return with an error code in ac(T1).  A call
     to FATAL$ or WARN$ again produces a detailed diagnostic.

             ...
             RFILE$                  ;read a filename
               FATAL$ ,SY            ;write a syntax error message
             ...

     might produce:

             ?DELILC Illegal character: <BEL>



     2.6  REPLACEABLE ROUTINES

          Since IOLIB.REL is searched as a  subroutine  library,  the  user
     programmer  may replace any of the routines by one of his own with the
     same name.  However some routines  are  specifically  designed  to  be
     rewritten by the user.  These routines are called at critical parts of
     the IO process where the user may want to gain control to perform some
     extra  functions.   Examples  of  these routines are $$FERR, the fatal
     error trap  routine,  and  $$RCHR,  the  routine  called  by  all  the
     formatted  input  routines to read one character.  The standard $$FERR
     merely returns to monitor mode, but the user programmer might want  to
CONCEPTS                                                           Page 2-6
REPLACEABLE ROUTINES


     clean  up  his  program  first,  or  restart the program at some point
     instead.  The standard $$RCHR uses the SCAN type command scanning code
     to  edit  the  characters it reads, but the user might want to do less
     thorough editing or to treat different files in different ways.

          The main replaceable routines in the  current  version  of  IOLIB
     are:

             $$ALLC    allocate a chunk of free memory
             $$DALC    deallocate a chunk of memory
             $$FERR    fatal error trap routine
             $$RBYT    read a byte from the current file
             $$RCHR    read a command character (all formatted input)
             $$RCH0    read a character (all command scanner input)
             $$WBYT    write a byte to the current file
             $$WCHR    write a character (all formatted output)



     2.7  FORMATTED IO

          Formatted IO is the transfer of data formatted  in  various  ways
     between the program and files, so that the formatted data in the files
     becomes binary data in the correct format in the program.  An  example
     is  the  reading  of a string of decimal digits and producing a binary
     number.  The formatted IO routines are explained fully in  Appendix  A
     with more detail about some of the important routines in Chapter 6.

          The formatted input routines read  characters  from  the  current
     file  and  interpret  them according to the format of the data that is
     being read.  The general philosophy of the routines is to read until a
     character is read which is outside the range of characters expected at
     that stage, e.g.  an endline, or  an  erroneous  character.   At  that
     stage,  the  simple  routines  return  the  value  read so far and the
     terminal character, and it is the caller's responsibility to work  out
     whether  the character is correct.  The more complicated routines must
     detect some syntax errors within their own code,  and  these  routines
     have error returns.

          In the terminology used  throughout  this  manual,  a  number  of
     consecutive  characters  read  or  written  through  the  formatted IO
     routines is called a 'string' of characters, and a terminal  character
     is called a 'delimiter'.



     2.8  USER PROGRAM STRUCTURE

          IOLIB places few restrictions on the way a programmer writes  his
     code,  but  those  that  do exist are important.  Firstly, the program
     must contain a SEARCH pseudo-op to instruct the  assembler  to  search
     the C and IO symbol tables for missing symbols.  Secondly, the program
     must start execution with a BEGIN$ macro which initialises IOLIB.
CONCEPTS                                                           Page 2-7
USER PROGRAM STRUCTURE


          IOLIB contains other features  which  assist  the  programmer  to
     structure his program such as the version number macros and the HISEG$
     and LOSEG$ macros which organise programs into two segments.











                                 CHAPTER 3

                          PROGRAMMING TECHNIQUES



     3.1  GENERAL DESCRIPTION

          This chapter covers a range of instructions and  techniques  that
     have  a  bearing  on  writing  programs using IOLIB.  It includes some
     tables  of  symbols  defined  in  IO.MAC  including  the   accumulator
     definitions,  and  explains  some  of  the  important macros.  The DEC
     parameter  program,  C.MAC,  is  an  essential  part  of  IOLIB  since
     definitions  in  IO.MAC  depend  on C.MAC.  C.MAC contains a number of
     extremely useful  macro  definitions  and  a  large  range  of  symbol
     definitions  for  all  the  various  parameters  available through the
     monitor.  Unfortunately the only documentation for C is in the code of
     the  program  itself,  and  a long explanation is outside the scope of
     this manual.  However study and use of the symbols and macros in C.MAC
     does make programs clearer and gives a better chance of correctness.



     3.2  COMPILING AND LOADING PROGRAMS WITH IOLIB

          The following instructions assume that the installation is  using
     MACRO-10  version 50 or later.  They do not apply to MACRO version 47,
     which does not support .UNV files.  The files C.UNV and IO.UNV must be
     on the ersatz device UNV:, and the library file IOLIB.REL should be on
     the ersatz device MAC:, although your installation may prefer to  keep
     it on REL:.

          To compile a user program, ensure that  the  program  contains  a
     SEARCH  pseudo-op  for C and IO and then give a normal COMPIL command,
     e.g.:

                               .COMPIL/CREF MYPROG

          To LOAD, DEBUG or EXECUTE a user program,  include  the  indirect
     command  file  IOLO  or  IOHI  in the command string.  IOLO forces all
     IOLIB routines into the low segment, whereas IOHI allows the  code  to
     fall into the default segment which is the high segment.

                               .EXECUT MYPROG,@MAC:IOHI

                               .DEBUG MYPROG,@MAC:IOLO
PROGRAMMING TECHNIQUES                                             Page 3-2
PROGRAM STRUCTURE


     3.3  PROGRAM STRUCTURE

          A suggested layout for the  user  program  is  as  follows.   The
     reasons for the various parts are explained in the comments:

             TITLE   MYPROG - EXAMPLE OF PROGRAM LAYOUT
             SUBTTL  ROB COOK        
      
             SEARCH  C,IO             ;search UNIVERSAL files
      
     ;define version numbering
      
             VERSN$  1,101,3         ;see section 3.14
             PATCH$                  ;ditto
             JBVER$                  ;set version number into .JBVER
      
     COMMENT ;
             ...
             comments including description of
             program and revision history
             ...
     ;
      
             ;assembly switch definitions
      
             ;symbol definitions
      
             ;OPDEF and macro definitions
      
             ;global symbol definitions
      
             HISEG$                  ;only if two segment program
      
     MYPROG: ;start of program code
             BEGIN$                  ;initialisation macro
             ...
             program code
             ...
             data area definitions
             ...
             END     MYPROG

          The ordering of most items is not important and  most  items  are
     optional, but are included in the majority of programs.

          Logical execution of a program may be terminated by  calling  the
     $MONRT routine which returns the program to monitor mode with an 'EXIT
     1,' UUO.  The routine returns to caller if the user  types  'CONTINUE'
     to the monitor.

             ...
             WTEXT$  <All done>      ;end of program
             MONRT$                  ;back to monitor
             JRST    START           ;restart on 'CONTINUE'
             END     START           ;
PROGRAMMING TECHNIQUES                                             Page 3-3
SYMBOL NAMING CONVENTIONS


     3.4  SYMBOL NAMING CONVENTIONS

          By published DEC standard, symbol names containing the  character
     '$'  are free for use by customers, and IOLIB uses exclusively symbols
     containing '$' in an  effort  to  keep  the  names  of  IOLIB  symbols
     distinct  from names that DEC or the user might choose.  IOLIB follows
     DEC conventions for special symbol names as far as possible,  using  a
     '$'  where  the  equivalent  DEC  symbol  would  use a '.' or '%'.  In
     particular IOLIB uses the following templates for different  types  of
     symbol:

     Template      Use
     --------      ---

             $ggsss  number of general category 'gg', specific use 'sss'
             gg$sss  byte of general category 'gg', specific use 'sss'
             mmmmm$  opcode definition, whether by macro or OPDEF
             ggeee$  error code of category 'gg', specific error 'eee'

          All symbols for entry points to IOLIB routines are  of  the  form
     '$xxxxx'.   The  routines  advertised  as replaceable, as well as some
     concealed routines and debug points, have entry  points  of  the  form
     '$$xxxx'.   The  first characters of the entry point name indicate the
     broad type of the routine:

             $Rxxxx  formatted read routines
             $Wxxxx  formatted write routines
             $TMPxx  tempcore routines
             $FTLxx  fatal error routines
             $WRNxx  warning error routines
             $ERRxx  collective error routines
             $CNVxx  conversion routines
             $INIxx  initialisation routines

          Secondary entry points are  normally  identical  to  the  primary
     entry point except that the last character is replaced by a digit:

             $RFILE  read a file specification
             $RFIL0  as above, but with different arguments

          The symbols for macro names are all of the  form  xxxxx$,  except
     for  a few special purpose macros which are xxxx$$.  The macro usually
     takes its name from the routine it calls.   The  replaceable  routines
     are called by macros that have ordinary names;  e.g.  $$WCHR is called
     by the WCHAR$ macro.



     3.5  ACCUMULATOR CONVENTIONS

          IOLIB breaks the accumulators down into 3 types of ac, temporary,
     preserved  and  global.   The differences lie in the conventions about
     the way they are treated in subroutine calls.  Temporary acs are  just
     that.   They should be used for temporary workspace, and in particular
     no caller routine should expect  any  temporary  ac  to  be  preserved
PROGRAMMING TECHNIQUES                                             Page 3-4
ACCUMULATOR CONVENTIONS


     across  a  subroutine call.  It is the caller's responsibility to save
     temporary acs if this is necessary.

          Preserved acs can be used by  a  routine  as  workspace  that  is
     permanent  for the life of that routine.  Any subroutine must save any
     preserved ac that it uses before  use,  and  must  restore  it  before
     returning  to  the  caller.   Any  routine must be able to rely on all
     subroutines obeying this convention.

          Global acs are free for the program to use as  it  wishes.   They
     are  normally used for quantities that are set in defined routines and
     otherwise passed around from routine to routine.

          IOLIB uses these conventions.  However, not  all  IOLIB  routines
     destroy  temporary acs, and in particular, frequently called routines,
     such as the basic  IO  routines,  are  very  careful  not  to  destroy
     temporaries.  Appendix A details the temporaries that are destroyed by
     each routine.  IOLIB only changes T1-T4 and always preserves preserved
     acs.  IOLIB reserves 3 globals for itself.  They are acs 15 16 and 17,
     and they are used for the current file point, the IDB  point  and  the
     push down stack point respectively.  They are named D, I and P.  IOLIB
     never touches any other global.  Acs 0 and 11-14 are always  free  for
     the caller.

          IOLIB defines symbols  for  the  various  acs  as  given  in  the
     following table:

                  Ac     Name        Use
                  --     ----        ---

                  0       T0      temporary (never by IOLIB)
                  1       T1          "     (used by IOLIB)
                  2       T2          "            "
                  3       T3          "            "
                  4       T4          "            "


                  5       P1      preserved
                  6       P2          "
                  7       P3          "
                  10      P4          "

                  11      G1      global
                  12      G2         "
                  13      G3         "
                  14      G4         "
                  15      G5         "  (reserved to IOLIB)
                  16      G6         "  (reserved to IOLIB)
                  17      G7         "  (reserved to IOLIB)

                  0       F       flag register (since non-index)
                  15      D       current file point
                  16      I       IDB point
                  16      L       link ac (DEC standard)
                  17      P       push down stack point
PROGRAMMING TECHNIQUES                                             Page 3-5
ACCUMULATOR CONVENTIONS


          IOLIB contains routines ($SAVEn) to save from 1  to  4  preserved
     acs  and  to ensure that they are restored correctly on return.  These
     routines should be called by PUSHJ on entry to a routine.   They  save
     preserved  acs, starting at P1, on the stack and then call the rest of
     the caller routine as a subroutine.  When the caller routine exits  by
     POPJ,  control  returns to the $SAVEn routine which restores the saved
     acs and jumps back to the original caller.  $SAVE1 preserves  P1,  and
     $SAVE3 preserves P1-P3 etc.

     SUBROU:
             SAVE2$                  ;saves P1 & P2
             ...
             body of subroutine
             may use P1 & P2
             ...
             POPJ    P,              ;returns to $SAVE2 to restore P1 & P2
                                     ; before returning out of SUBROU

          There are routines, $SAVET and $RESTT, that save and restore  the
     4  temporary accumulators, T1-T4.  These would normally be used by the
     caller of a subroutine to ensure that acs are preserved.

          The user programmer does not have to adhere to  IOLIB's  division
     of acs into temporaries, preserved and globals.  He need only be aware
     that IOLIB reserves G5-G7, and that T1-T4 may be  destroyed  by  IOLIB
     calls.  He may decide that he only needs two preserved acs, P1 and P2,
     and that P3 and P4 will be used as globals  or  as  temporaries.   The
     user programmer may define new symbols for the acs as he pleases.

          IOLIB defines ac0 as F, a flag register,  because  many  programs
     use  ac0  as  a  vector of 1 bit program flags.  Ac0 is convenient for
     this purpose since it is not an index register.   IOLIB  itself  never
     uses ac0.



     3.6  SUBROUTINE CALLS

          All calls to IOLIB subroutines are by 'PUSHJ P,' instruction  and
     returns are by a corresponding 'POPJ P,'.  Arguments are passed in acs
     and values are returned in acs also.  The IOLIB argument convention is
     that  arguments  are passed in acs T1-T4 except in special cases.  Acs
     are allocated to arguments in ascending order,  so  that  T1  is  used
     first.   The  special  cases  are  acs D and I.  These acs must almost
     always be set up  to  point  to  the  current  file  and  to  the  IDB
     respectively.   Appendix  A shows which routines need acs D and I, and
     which do not.

          A common convention in MACRO-10 is that a subroutine (or UUO) may
     have  normal  and abnormal returns.  In these cases, the convention is
     that abnormal returns are to the 'return address' and  normal  returns
     are to the 'return address +1'.

             PUSHJ   P,SUBROU        ;call subroutine
               error return          ;abnormal
PROGRAMMING TECHNIQUES                                             Page 3-6
SUBROUTINE CALLS


             o.k. return             ;normal

     IOLIB routines that have error returns adhere to this convention.  The
     only  exceptions  are  the  $READ  and  $INPUT  routines  which have 3
     returns, for error, endfile and normal.

          The routines $POPJ and $POPJ1 can be called to  give  returns  to
     the return address and the return address +1;  e.g.

             PJUMPE  T1,$POPJ##      ;return if zero

             PJRST   $POPJ1##        ;skip return now

          It is often useful to be able to pop ac(T1) from  the  stack  and
     then return either nonskip or skip.  IOLIB contains routines $TOPJ and
     $TOPJ1 which are the same as $POPJ and $POPJ1 except  that  ac(T1)  is
     popped before return.

          There are also routines to pop the stack (but not destroy ac(T1))
     and then return.  They are $XOPJ and $XOPJ1.

          Lastly, there are routines $POPJ2 and $TOPJ2 which give a  double
     skip  return  as with the normal return from $INPUT.  The user must be
     careful with these routines as they will  not  work  with  the  $SAVEn
     routines.



     3.7  ASSEMBLY SWITCHES

     IO.MAC defines a number of assembly switches, with symbols FT$xxx  for
     feature  tests,  that  are used to control optional features which are
     included for this program.  The  programmer  may  alter  the  standard
     settings  of  these  switches  by including a symbol definition in his
     program.

             FT$DBG==-1              ;debug feature required

          The assembly  switches  defined  in  IO.MAC  and  their  standard
     settings and effects are:

     Switch    Value   Effect
     ------    -----   ------

     Switches which the programmer may set:

     FT$ALC    -1      nonzero for dynamic memory management; zero for
                       static memory management
     FT$CCL    0       nonzero for CCL entry points to be included in
                       the BEGIN$ macro; zero for no CCL entry points
     FT$DBG    0       nonzero for debug features (such as caller address
                       printed in error messages); zero for no debug
                       features

     Switches which the installation may change:
PROGRAMMING TECHNIQUES                                             Page 3-7
ASSEMBLY SWITCHES


     FT$SFD    6       level of SFDs supported by IOLIB.
                       Note that the level of SFDs supported by the monitor
                       will take
                       precedence.



     3.8  PUSH DOWN STACK

          IOLIB contains a push down stack and a pointer to the top of  the
     empty  stack.   The  stack  is replaceable, so that the programmer can
     define his own stack if he needs a longer or shorter stack.  The IOLIB
     stack  is  called $STACK and is 100 (octal) locations long.  The stack
     pointer is called $PTSTK and is merely 'IOWD 100,$STACK'.  To define a
     replacement stack, write:

     $PTSTK::
             IOWD    STLEN,$STACK    ;stack pointer
     $STACK::
             BLOCK   STLEN           ;stack block



     3.9  BEGIN$ - PROGRAM INITIALISATION

          The  BEGIN$  macro  performs  all  the  initialisation  functions
     required at the start of execution of a program.  It must be the first
     statement following the start address because it notices whether entry
     was a 'start', or 'start+1' for the special CCL entry point.  The code
     produced by BEGIN$ runs to about 15BEGIN$ produces 5 words of code and
     calls  the  $BEGIN (or $BEGCC) routines.  BEGIN$ labels the first word
     of  the  user's  program  with  the  internal  symbol  $$BEG,  to  aid
     debugging.

     1.  unless  FT$DBG  is  on,  SALL,  to  suppress  listings  of   macro
         expansions.   If  debugging, load the patch area and special debug
         code, otherwise load nondebug code.

     2.  if FT$ALC is zero, set the replaceable entry  points,  $$ALLC  and
         $$DALC, to the memory manager to use static management.

     3.  

              produce PORTAL instructions for normal and CCL  entry  points
         to implement concealed mode.

     4.  set T1=0 for normal entry and T1=-1 for CCL entry.

     5.  RESET UUO

     6.  load ac(P) from $PTSTK to set up the push down stack pointer.

     7.  call $INIID to initialise the  IDB  by  clearing  it  and  setting
         default values.
PROGRAMMING TECHNIQUES                                             Page 3-8
BEGIN$ - PROGRAM INITIALISATION


     8.  set the program name, extension, device and PPN  provided  in  the
         acs by the monitor into the IDB.

     9.  if FT$CCL is on, test ac(T1), and if entry was at  the  CCL  entry
         point build a tempcore FDB, and read the tempcore file.

    10.  set the current file, ac(D), from the command file  point  in  the
         IDB.




     3.10  GLOBAL PARAMETERS

          The IDB contains program parameters  which  may  be  set  by  the
     programmer  or  by a user through standard switches.  These parameters
     are:

     1.  memory limit.  A maximum on the  amount  of  memory  used  by  the
         program  can  be  imposed.   Normally  the  memory  managers  will
         continue expanding the program size on request, until the  monitor
         refuses  to  provide  any  more  memory.  But, the memory managers
         check $IDTOP(I) first and will not exceed the size set there.   To
         limit  the  amount  of  memory  to  16K, say, set $IDTOP(I) to the
         memory limit can also be set by  the  user  through  the  standard
         /MAXCOR switch.  The system default is 256K.  16K words +1, e.g.

                    MOVEI   T0,^D16*^D1024
                    MOVEM   T0,$IDTOP(I)

     2.  program id for error messages (see chapter  10).   A  3  character
         SIXBIT  code  can  be  set  into  the left half of $IDECD(I).  The
         default is none.

                       MOVSI   T0,'IOL'
                       HLLM    T0,$IDECD(I)

     3.  error message verbosity.  May be  set  to  0,1  or  2  for  'low',
         'standard'  and  'high', by moving the code into the right half of
         $IDECD(I).  Also set by the /VERBOSITY  switch.   The  default  is
         standard verbosity.

     4.  standard switch table.  A pointer to the standard switch table can
         be  set  into  the  right  half of $IDSWT(I).  See section 4.3 for
         details.

     5.  help file name.  The SIXBIT name of the file containing help  text
         may  be  set into $IDHNM(I).  If no help name is set, and the user
         gives a /HELP switch, IOLIB uses the program's name  to  look  for
         the help file.

     6.  the default FDB for filename decoding.  A point to a  default  FDB
         may be set into the right half of $IDDFD(I).
PROGRAMMING TECHNIQUES                                             Page 3-9
GLOBAL PARAMETERS


     7.  the command input file.  A  point  to  an  FDB  may  be  set  into
         $IDIFD(I),  and that point will be loaded into ac(D) by the CMDFD$
         macro.  The command input file is initialised by BEGIN$.

     8.  the message output file.  A point  to  an  FDB  may  be  set  into
         $IDOFD(I), and that point will be loaded by the MSGFD$ macro.  The
         message output file is initialised by the BEGIN$ macro.

     9.  the error messge file.   A  point  to  an  FDB  may  be  set  into
         $IDEFD(I),  and that point will be loaded by the ERRFD$ macro, and
         will be used to write all error messages (unless it is for  an  IO
         error in the message file).

    10.  the next character to be  read  by  the  command  character  input
         routine,  $RCCHR.   An  ASCII character or endline code may be set
         into $IDNXC(I).  The character should be right-justified.

    11.  the default path for the job should be changed by setting the path
         into $IDJPT and then using the PATH.  UUO.




     3.11  SEGMENTATION

          The programmer may set the segment that code  will  be  assembled
     into  through  two  macros, HISEG$ and LOSEG$.  The macros first check
     that  a  change  of  segment  is  needed  and  then  ensure  that  all
     outstanding  literals  are  assembled  into the current segment before
     issuing a RELOC to change segments.  In a two segment program, a  call
     to  HISEG$  should appear at the start of a program so that HISEG$ can
     set up the TWOSEG pseudo-op to define this program as  a  two  segment
     program.

             TITLE   2SEGEX - two segment example
      
             HISEG$                  ;set high segment
      
     SEGEX:
             BEGIN$
             ...
             high segment code
             ...
             LOSEG$                  ;change to low segment
             ...
             low segment code
             ...
             HISEG$                  ;back to high segment
             END     SEGEX
PROGRAMMING TECHNIQUES                                            Page 3-10
FDESC$ - BUILD AN FDB AND SET VALUES


     3.12  FDESC$ - BUILD AN FDB AND SET VALUES

          The FDESC$ macro assembles an FDB in inline  code  and  fills  it
     with any arguments supplied to the macro.  The call is

                  FDESC$   dev,nam,ext,<path>,mode,length

     where:

      dev      is the name of a device
      nam      is the file name
      ext      is the file extension
      path     is a path specification (without []).  If no SFD  names  are
               given,  the  PPN  is  set  into $FDPPN;  otherwise the macro
               builds  a  path  block,   sets   the   components   of   the
               specification into the block and sets a pointer to the block
               into $FDPPN.
      mode     is the IO mode.  In fact a complete IO status  halfword  may
               be given.
      length   is the length of the FDB to be created.  The  default  is  a
               standard length FDB.

     For example:

             FDESC$  DSK,ACCT,SYS,<,,ACCOUN>,.IOBIN

     makes an FDB for the file  'DSK:ACCT.SYS[,,ACCOUN]'  and  sets  binary
     mode.



     3.13  MAKFD$ - PRODUCE CODE TO BUILD AN FDB

          MAKFD$ writes inline code to create an FDB if none is  given,  to
     initialise  the FDB using $CLRFD, and to set values given as arguments
     into the FDB.  At the end of execution of the macro code, a  point  to
     the FDB is left in ac(D).  as arguments into the FDB.  The call is:

              MAKFD$   dev,nam,ext,<path>,mode,length,address

     where:

      dev      is the name of a device
      nam      is the file name
      ext      is the file extension
      path     is a path specification (without []).  If no SFD  names  are
               given,  the  PPN  is  set  into $FDPPN;  otherwise the macro
               writes code to build a path block, set the components of the
               specification  into the block and set a pointer to the block
               into $FDPPN.
      mode     is the IO mode.  In fact a complete IO status  halfword  may
               be given.
      length   is the length of the FDB to be created.  The  default  is  a
               standard length FDB.
      address  is the address of an existing FDB.  If no address  is  given
PROGRAMMING TECHNIQUES                                            Page 3-11
MAKFD$ - PRODUCE CODE TO BUILD AN FDB


               the  macro  creates  a  new  FDB  in space obtained from the
               memory manager.

             MAKFD$   DSK,INPFIL,DAT,<104,427>,,,INPFDB

     creates the code to call $CLRFD for the FDB, and then set the  details
     for 'DSK:INPFIL.DAT[104,427]' into the FDB.



     3.14  VERSION NUMBER MACROS

          IOLIB contains 4 macros to help  the  programmer  to  define  and
     update  version numbers of programs.  The VERSN$ macro creates symbols
     for the 4 fields of the version number and assigns  values  (given  as
     arguments)  to  them.  The PATCH$ macro increments the edit-number for
     each patch and defines a patch symbol that can be used in  conditional
     assembly  of code added or deleted by the change.  Each call to PATCH$
     increments the minor  version  number.   The  JBVER$  macro  sets  the
     version  number  into .JBVER in the job data area, and VTEXT$ produces
     an ASCIZ string of the version number.

               VERSN$   major-version,edit-number,who-edited

     the minor version number is set to zero, and  is  incremented  by  the
     PATCH$  macro.   VERSN$  types  out  the  version numbers of C.MAC and
     IO.MAC used during assembly, while being assembled.

                         PATCH$   <patch numbers>

     each patch is assigned a patch number and the numbers are given as the
     argument.   PATCH$  creates  a  symbol  '$n'  for each number and this
     symbol can be used in IFDEF  and  IFNDEF  conditionals.   PATCH$  also
     increments  the  edit  number for each patch, and increments the minor
     version number once per PATCH$ macro.

                                  JBVER$

     The JBVER$ macro takes no arguments, and sets the version number  into
     .JBVER.

                                  VTEXT$


     The VTEXT$ macro uses the values for  the  symbols  generated  by  the
     VERSN$  and  PATCH$  macros  to  make  an  ASCIZ string of the version
     number.

     e.g.
             VERSN$  5,7,3           ;version 5(7)-3
             PATCH$  <10,11,13,14>   ;version 5A(14)-3
             PATCH$  <15,16>         ;version 5B(16)-3
             JBVER$                  ;137/  BYTE (3)3(9)5(6)2(18)16
      
             VTEXT$                  ;makes the string '5B(16)-3'
PROGRAMMING TECHNIQUES                                            Page 3-12
DEBUGGING AIDS


     3.15  DEBUGGING AIDS

          Programmers writing programs using IOLIB often have trouble  with
     debugging  when  they  see  control  disappearing  into  the  basic IO
     routines and then coming out with the wrong answer or with an  illegal
     memory reference.  IOLIB code is written to be efficient, and does not
     go to great lengths to defend itself against misuse, and this can make
     life more difficult when debugging.

          One useful technique is to watch  the  IO  UUOs  that  are  being
     executed to find out at what point the trouble starts.  IOLIB provides
     two special symbols, $$XUUO and $$XCAL, which label  the  instructions
     that  execute  IO  UUOs  and  CALLI  UUOs concerned with devices.  The
     debugger can place DDT breakpoints on these symbols and examine ac(T1)
     to find the UUO.  The point to the current FDB is always in ac(D).

          Another internal symbol of use is $$BEG, which the  BEGIN$  macro
     uses  to label the first word of the user program following the BEGIN$
     macro code.

          There is an assembly  switch,  FT$DBG,  which  invokes  debugging
     features  if  set  to -1 by the programmer.  In the present version of
     IOLIB, FT$DBG suppresses the SALL, so  that  macros  are  expanded  in
     listings,  and  also  ensures  that the caller's address is printed in
     octal in error messages.

          If FT$DBG is on, a 200 word patch  area  is  loaded  from  IOLIB,
     which the debugger can use to insert extra words of code.  The name of
     the patch area is $PATCH, and there is a second  symbol,  $PAT,  which
     may  be  moved  after  inserting each patch to point to the first free
     word in the patch area.  Note that LINK-10 and  LOADER  load  a  patch
     area, caled PAT.., if DDT is loaded.











                                CHAPTER 4

                               IOLIB TABLES



     4.1  GENERAL DESCRIPTION

          IOLIB contains a number of tables that the programmer may need to
     know  about  so  that he can replace them with his own versions or use
     the contents.  The table $TBWAD contains addresses of formatted  write
     routines  that  will  be  used  to  print value in error texts.  It is
     indexed by the error value  code  supplied  to  the  FATAL$  or  WARN$
     macros.

          The programmer who is using IOLIB  to  read  commands  will  very
     likely want to include switch specifictions in his command string.  He
     can define his own switches in a switch table using macros defined  in
     IO.MAC.



     4.2  $TBEVL - TABLE OF ERROR VALUES

          $TBWAD contains the address of the routine which prints the value
     supplied  by  the  user  for each possible code in the EC$TYP field in
     ac(T1) on a call to $ERROR.  The  standard  IOLIB  $TBWAD  contains  6
     possible  types,  but  the  user is free to define his own table if he
     needs others.  Each word in the table  contains  the  address  of  the
     formatted  write  routine in the right half.  The table must be called
     $TBWAD and the length symbol $LNEVL must  be  defined  INTERNal  also.
     The contents of the standard table are:

          Index     Symbol    Write Routine
          -----     ------    ----- -------

          0         $ECTNO    none
          1         $ECTCH    $WFCHA, write a 'funny' character
          2         $ECTDE    $WDECL, write a number in decimal
          3         $ECTFI    $WFILE, write a filename
          4         $ECTOC    $WOCTL, write a number in octal
          5         $ECTTE    $WTEXT, write an ASCIZ string
          6         $ECTWO    $WWORD, write a SIXBIT word
          7         $LNWAD    length symbol
IOLIB TABLES                                                       Page 4-2
SWITCH TABLES


     4.3  SWITCH TABLES

          Switch tables are lists of switch names, and  details  about  the
     values that those switches can take.  Switch names and values are read
     by the IOLIB subroutines $RSWIT and $RFILE (which calls $RSWIT).   The
     routines  may  be  given the address of a switch table as an argument.
     When $RSWIT reads a switch name, it searches the list of names in  the
     switch  table  for  an unambiguous match.  If it finds a match it uses
     the details in the associated lists to read a value (if one is  given)
     check legality of the value, and set the value wherever the programmer
     directs.  In fact, $RSWIT can search two tables, the table provided by
     the  programmer  as  an  argument,  and  a  table of standard switches
     pointed at by $IDSWT(I).  Standard switches are  ones  such  as  those
     provided  in  $TBSSW  in  IOLIB,  which contains switches for changing
     parameters in the IDB, and file switches.  The point to the  table  of
     standard switches must be set into $IDSWT(I) by the programmer.

          A switch table is actually 5 tables, that can all be built by the
     one  macro,  SWTAB$.   There  is  a table of 4 pointers to the other 4
     tables.  These tables are a table of switch names in SIXBIT,  a  table
     that  tells  $RSWIT  where  to put the value of the switch that $RSWIT
     reads, a table giving either the address of a list of keyword  values,
     or  a  maximum value, and a table of default values for if no value is
     given.  All these tables can be built by the one  macro  SWTAB$.   The
     switches in $TBSSW are:

                   Value/
     Name         Keywords           Default Deposit
     ----         --------           ------- -------

     BLOCKSIZE    decimal            4000    buffer size in FDB
     DENSITY      INSTAL/200/556/800 INSTAL  FM$DEN in $FDMOD/MOM
     HELP         TEXT/SWITCHES      TEXT    call $WHELP to write text
     MAXCOR       kword              28K     $IDTOP(I)
     PARITY       ODD/EVEN           ODD     FM$PAR in $FDMOD/MOM
     PHYSICAL                                FM$PHY in $FDMOD/MOM
     PROTECTION   octal              157     FM$PRO in $FDMOD/MOM
     RUN          filename                   rh($IDRUN(I))
     RUNOFFSET    octal              1       lh($IDRUN(I))
     VERBOSITY    LOW/STANDARD/HIGH  STD     rh($IDECD(I))



     4.4  SWITCH TABLE BUILDING MACROS

          There are several macros involved in the complicated procedure of
     building  switch tables.  SWTAB$ is the macro called by the user to do
     the building, but the programmer must have already  defined  a  SWIT$$
     macro  of his own to tell SWTAB$ the switch details.  The programmer's
     SWIT$$ macro definition contains calls to the SL$, SP$ and SS$ macros,
     which  define each individual switch.  The switches which take keyword
     values require a table of keywords which can be built  by  the  KEYWD$
     macro,  and the switches which take numeric values need default values
     and maximum values, which can be defined by the DM$ macro.
IOLIB TABLES                                                       Page 4-3
SWITCH TABLE BUILDING MACROS


          SL$,  SP$  and  SS$  take  several  arguments  which  define  the
     attributes  of the switch, and differ between the 3 macros.  The first
     argument is the switch name.  If the first character is an  '*',  then
     the  first  character of the switch is a sufficient abbreviation;  i.e
     if the name was given as '*HELP', then the user can always  type  '/H'
     to  get  help, no matter what other switches begin with letter H.  The
     second argument is always a pointer, which  is  used  to  deposit  the
     value of the switch.  The pointer may be a byte pointer, or a halfword
     point to a full word, or a word with -1  in  the  left  half  and  the
     address  of  a  user routine in the right half.  The user routine does
     the depositing itself.  The other  arguments  are  different  for  the
     different macros.

     e.g.
             ;the DM$ macro defines the symbols MX$MXC and PD$MXC
             ; for the /MAXCOR switch
      
             DM$     MXC,256,28,28   ;defaults
      
             ;the SWIT$$ macro contains definitions for 3 switches
             ;  HELP   : takes keywords 'TEXT' and 'SWITCHES'
             ;             (e.g. /HELP:TEXT)
             ;           the default is TEXT (4th argument)
             ;           the keyword table is HELP$T
             ;           a user routine called 'SWHELP' is called to
             ;             deposit the value.
             ;  MAXCOR : takes values in pages or Kwords
             ;           the maximum is MX$MXC and the default is PD$MXC
             ;           the value will be set into $IDTOP(I)
             ;  PHYSIC : takes no value
             ;           if given, '1' will be set into $FDMOD in an FDB
             ;            at FM$PHY
      
     DEFINE SWIT$$,<
             SL$     <*HELP>,<-1,,SWHELP>,HELP,HELPTEXT
             SP$     <MAXCOR>,<$IDTOP(I)>,$SWKWD,MXC
             SS$     <PHYSICAL>,<POINT 1,$FDMOD(T1),3>,1
     >
      
     HMPTAB:                         ;address of table
             SWTAB$  HMP             ;define tables
      
             KEYWD$  HELP,<SWITCHES,TEXT> ;define HELP keywords

     SWTAB$
     ------

          A call to SWTAB$ produces the 5 switch tables.  The  macro  takes
     one  argument,  which  is a 3 character name that is concatenated with
     '$$x' to give names for the individual tables.  A call  to  the  macro
     requires  that  the  user  has  defined a macro, SWIT$$, that contains
     calls to macros  which  define  the  individual  switch  details  (see
     below).
IOLIB TABLES                                                       Page 4-4
SWITCH TABLE BUILDING MACROS


          SWTAB$     UTB             ;define switch tables

     The name table is called UTB$$N, the pointer table UTB$$P, the maximum
     table UTB$$M, and the default table UTB$$D.

     SWIT$$
     ------

          The SWIT$$ macro must be defined by the  programmer  calling  the
     SWTAB$ macro.  It contains calls to the macros, SS$, SL$ and SP$ which
     are defined below.

     SS$
     ---

          SS$ defines a switch which has no value.  If this switch is given
     by  the  user,  $RSWIT deposits a value given in the 3rd argument (and
     usually a 1 bit flag), into  the  position  specified  by  the  second
     argument.   For  an  example, see the definition of SWIT$$ above.  The
     call is

                       SS$  name,deposit-point,value

     SP$
     ---

          SP$ defines switches which have values other than  keywords,  for
     example  decimal  numbers or kword values.  The 3rd argument is a code
     for the name of the routine that will read the value.  Available codes
     are:   DECL,  FILE,  KWRD, OCTL.  The name of the code is concatenated
     with '$SW' to form the name of the value reader.

          The fourth argument is a 3 letter  abbreviation  for  the  switch
     name, which is concatenated with the characters 'MX$' to give a symbol
     for the maximum value, and with 'PD$' to  give  one  for  the  default
     value.   The  MX$xxx  and PD$xxx symbols are defined by the DM$ macro.
     If no maximum or default is wanted, this argument may be ommitted.

              SP$  name,deposit-point,value-code,abbreviation

     SL$
     ---

          Defines a switch which takes keyword values.  The keywords can be
     defined  by a separate KEYWD$ macro.  The third argument is a code for
     the name of the table defined by the keyword macro.  It  is  the  same
     name as the first argument of the appropriate KEYWD$ macro.

          The fourth argument is a symbol for  the  default  index  in  the
     table.   It  is  a concatenation of the 4 characters of the table name
     and the first two characters of the default keyword name.

            SL$  name,deposit-point,keyword-table,default-index

     DM$
     ---
IOLIB TABLES                                                       Page 4-5
SWITCH TABLE BUILDING MACROS


          Defines three symbols, the maximum  value  of  a  parameter,  the
     default  value  if  the  switch is given but no value, and the default
     value if the switch is not given.  The symbols  defined  are,  MX$xxx,
     PD$xxx and AD$xxx respectively.  Call:

               DM$   abbreviation,MX-value,AD-value,PD-value

     KEYWD$
     ------

          Defines a table of keywords for  switches  and  symbols  for  the
     index  of  each  keyword in the table.  The name argument of the macro
     should be 4 characters long, and it is concatenated with the  first  2
     characters  of  the  keyword name to make the index symbol.  The index
     symbol for the default value should be used in the default argument of
     the SL$ macro.  Call:

                         KEYWD$   name,<keywords>

     e.g.    KEYWD$  DEN,<200,556,800,INSTALLATION>

     The symbols for the indices of each keyword are DENS20, DENS55, DENS80
     and DENSIN.











                                CHAPTER 5

                             MEMORY MANAGEMENT



     5.1  GENERAL DESCRIPTION

          Programs use free memory space for various purposes during  their
     execution,  for arrays of data, for buffers, for linked lists and many
     others.  Sometimes it is convenient to build  all  the  memory  chunks
     that  a  program  needs  into  the  program while it is being written.
     Often however, it is easy and useful to be able to ask for and receive
     a chunk of free memory during program execution.  On the DECsystem-10,
     the program is effectively broken into high and low segments, the high
     segment  being  used  for  reentrant  code,  and  the  low segment for
     non-reentrant code and data.  Memory is allocated to  the  program  in
     chunks  of 1P on a KI10 and 1K on a KA10 processor.  The last location
     used by the program is generally not the top of the allocated  memory,
     and  the  space  between  the  last  location and the top of allocated
     memory is free for use by the user  program.   In  addition,  if  this
     space  is  insufficient, the user program can request more memory from
     the monitor.

          The IOLIB memory management routines allocate this free space  to
     any  routine  that  requests  it,  and  deallocate  the space when the
     routine announces that it has finished with it.  The memory management
     routines  first  allocate  all  the  sace  that was available when the
     program was loaded, and then ask the monitor  for  more  as  required.
     All the programmer has to do is to call the memory managers to ask for
     a chunk, or to donate chunks back to the pool.

          It is not always a good thing to allow programs to grab  as  much
     memory as they ask for, since some programs are almost insatiable, but
     will move onto  secondary  storage  when  memory  is  exhausted  (e.g.
     LINK-10).   IOLIB  allows the programmer or user to limit the absolute
     size of his program.  The location $IDTOP(I) in the IDB specifies  the
     maximum  number  of  words that the memory managers may obtain for the
     program.  The BEGIN$ macro initialises $IDTOP(I) to 256K, the  maximum
     physically  possible  (without virtual memory).  The program may alter
     $IDTOP(I) to any required value, and the user  can  use  the  standard
     /MAXCOR switch to do the same.

          IOLIB  contains  two  forms  of  memory  management,  static  and
     dynamic.   They  may  be  used  in  the  same  program,  but  this  is
     unsatisfactory  and  an  excessive  code  overhead.    Static   memory
     management  satisfies  each request by finding extra space starting at
MEMORY MANAGEMENT                                                  Page 5-2
GENERAL DESCRIPTION


     the first unused location (pointed at by

          .JBFF in  the  job  data  area).   Chunks  of  memory  cannot  be
     deallocated   using  static  management.   Dynamic  memory  management
     maintains a chain of free chunks, and allocates and deallocates chunks
     from  the chain.  It is much more versatile than static management but
     the program overhead is higher and it uses one overhead word for  each
     chunk.  IOLIB automatically selects dynamic management unless the user
     opts for static management through the FT$ALC  assembly  feature  test
     switch.   If  FT$ALC is defined as FT$ALC=0, then static management is
     used.

          Both memory allocators zero chunks of memory before handing  them
     to the caller.



     5.2  DYNAMIC MEMORY MANAGEMENT

          The dynamic memory manager is basically the  ALGOL  heap  routine
     which  was  originally written for ALGOL-10 by R.M.  DeMorgan, and was
     adapted later for FOROTS.  The manager routines keep a linked list  of
     free  chunks  of memory anchored to $IDDYC(I) in the IDB.  The list is
     linked through the first word (the overhead word) of each  chunk,  and
     the last chunk has a link of 0.  The left half of the overhead word is
     a count of the words in the chunk including  the  overhead  word,  and
     this  count  must never be altered by the programmer.  The linked list
     of chunks is ordered by size with the smallest chunk first.

          When the manager is asked for a chunk, it scans the list for  the
     first  chunk  of  the required size or larger.  If there is a chunk of
     the correct size, it is handed back as a pointer to the  second  word,
     which  is the first word available to the program.  If not, the larger
     chunk is split and the excess returned to the list.  If  there  is  no
     chunk   large   enough,   the   manager  garbage  collects  the  list,
     concatenating adjacent chunks and tries again.  If  the  search  fails
     again,  the manager resorts to asking the monitor for more memory, and
     so on until either $IDTOP(I) is reached, or  the  monitor  refuses  to
     supply  any  more memory.  On failure, the manager returns code ERNEC%
     in ac(T1).

          When a user deallocates a chunk, the manager merely  inserts  the
     chunk  into the linked list at the correct point.  The user may return
     a linked list of chunks, linked through the overhead word.  The chunks
     need  not  be  in order of size.  When the program returns a chunk, he
     must supply a point to  the  second  word  of  the  chunk;   the  word
     following the overhead word.
MEMORY MANAGEMENT                                                  Page 5-3
STATIC MEMORY ALLOCATION


     5.3  STATIC MEMORY ALLOCATION

          The static allocator is very simple.  It merely  looks  at  .JBFF
     for  the first free location, increases it by the amount requested and
     returns a point to the caller.  If the new first free location pointer
     exceeds  the highest available the allocator requests more memory from
     the monitor until either $IDTOP(I) is reached or the  monitor  refuses
     to  supply  more  memory.  If the allocator fails it returns the error
     code ERNEC% in ac(T1).

          The static deallocator gives an immediate return.  The  space  is
     not made available for reallocation.











                                CHAPTER 6

                             BASIC IO ROUTINES



     6.1  GENERAL DESCRIPTION

          The basic IO routines execute UUOs, manipulate  the  contents  of
     FDBs  to  set  default  values  and keep track of progress through the
     labyrinth of monitor calls.  The basic IO routines are called  by  all
     formatted  read  and  write routines, and by other IOLIB routines that
     need to do IO.

          It is quite possible to do IO operations  without  realising  the
     existence  of the basic routines by setting up file details in the FDB
     and using read and write calls.  However, the individual UUOs  may  be
     executed  by  descending  to  basic  IO  calls.  The basic IO routines
     reflect the structure of the monitor IO  UUOs;   there  is  an  $INPUT
     routine  to  execute  an  INPUT UUO and a $CLOSE routine for the CLOSE
     UUO.  Most of the routines do much more than execute the UUO that they
     are  named  after.   Firstly, the routines check that all prerequisite
     UUOs have been executed, and if  not,  the  appropriate  routines  are
     called.   So  if  the  user calls $INPUT as his first IOLIB call for a
     file, $INPUT will call $LUKUP to check whether  the  LOOKUP  has  been
     done, and $LUKUP in turn will call $OPEN.  After the OPEN UUO is done,
     control returns to $LUKUP for the LOOKUP UUO, and  finally  to  $INPUT
     for  the  INPUT  UUO.   Secondly,  some  basic  routines perform other
     functions that would otherwise have  to  be  done  separately  by  the
     calling program.  $INPUT will create a buffer ring, if none is set up,
     with the number and size of  the  buffers  a  parameter  in  the  FDB.
     $INPUT also calls $USETI, to find the required record, taking the next
     record number from the FDB.  The programmer can control  all  IO  from
     the  highest  level by making changes to the parameters in his FDB and
     calling any read or write  routine.   IOLIB  arranges  to  call  other
     necessary routines lower in the hierachy.

          Calls  to  the  basic  routines  are  channel  independent.   The
     programmer  need  not  try to assign channels to individual files, but
     should let IOLIB do it for him.  $OPEN assigns the next  free  channel
     to  the user, starting with channel 1.  Channel 0 is never used unless
     the programmer explicitly directs $OPEN to use it.  The caller  cannot
     specify  an  exact channel number for a file, but he can suggest where
     the search for a free channel should begin.
BASIC IO ROUTINES                                                  Page 6-2
GENERAL DESCRIPTION


          All the basic IO routines expect the pointer to the  current  FDB
     to be set up in ac(D), to describe the file for which the IO operation
     is to be performed.  All non-default values must be set in the FDB.

          Because the basic routines are called  so  frequently,  they  are
     careful  to  save all acs, including temporaries, except those used to
     transmit arguments.  An exception is the  error  return,  when  ac(T1)
     contains an error code with a UUO code in the left half and a specific
     error code in the right half.

          Most of the basic routines are assembled into one module,  IOMOD,
     which  is always loaded with every program that uses IOLIB.  The calls
     for the basic routines are explained in Appendices A & B.   Algorithms
     for critical routines are given in the sections below.



     6.2  $INPUT - READ A PHYSICAL RECORD FROM A FILE

          To read a physical record from a  file.   There  are  3  returns;
     non-skip  on an error, skip on endfile and double skip on a successful
     return.  An error code is  returned  in  ac(T1)  for  both  error  and
     endfile returns.  The full algorithm is:

     1.  check the tempcore input flag (FC$TCI in $FDCHN(D)).  If on,  give
         an immediate endfile return.

     2.  call $LUKUP to execute OPEN and LOOKUP UUOs if  not  already  done
         for this file.

     3.  if dump mode (check $FDSTS(D)), goto step  4.   Otherwise,  if  no
         input  buffer ring is established, call $MKBUF to build one taking
         the size and number of buffers from $FDBUF(D).

     4.  load the next block number from $FDNBK(D) and call $USETI to  find
         the required physical record.

     5.  set [this block number,,next block number] into $FDNBK(D).

     6.  execute the input by an 'INPUT ch,@$FDIOW(D)' instruction so  that
         for dump mode, $FDIOW(D) should point to a chain of IOWDs, and for
         buffered modes $FDIOW should normally be zero, but  may  point  to
         the next buffer.

     7.  if ok, return double-skip now.  Otherwise, call $GETST to read the
         IO  channel  status,  then  call $SETST to clear error and endfile
         bits.

     8.  calculate the error code from the error and endfile bits in the IO
         channel status.

     9.  skip return if endfile.  Otherwise normal return.


     FDB words altered:
     --- ----- --------
BASIC IO ROUTINES                                                  Page 6-3
$INPUT - READ A PHYSICAL RECORD FROM A FILE


     $FDNBK set  to  [this-record-number,,next-record-number].   The   next
            record is just this record+1 for sequential reads.
     $FDSTS on error and endfile, right half set to IO channel status word.

     FDB words used:
     --- ----- -----
     $FDBUF to build buffer ring.  $OPEN sets defaults from the monitor  if
            the  user  does  not  provide his own values.  Either number or
            size of buffers or both may be given.

     $FDNBK the right half is used to determine which record to  read  next
            (disk only).  The programmer may set the next record number for
            random input, otherwise $INPUT will read sequentially  starting
            from the beginning.

     $FDIOW addressed by the INPUT UUO instruction.  The user must  set  up
            this word for dump mode IO.



     6.3  $OUTPU - WRITE A PHYSICAL RECORD TO A FILE

          To write a physical record to  a  file.   There  are  2  returns;
     non-skip  on an error, and skip on a successful return.  An error code
     is returned in ac(T1) for error return.  The full algorithm is:

     1.  call $ENTER to execute OPEN and ENTER UUOs if not already done for
         this file.

     2.  if dump mode (check $FDSTS(D)), goto step 4.  If an output  buffer
         ring  is  established,  goto  step  4  to  avoid  a  dummy output.
         Otherwise call $MKBUF to build one taking the size and  number  of
         buffers from $FDBUF(D).

     3.  clear $FDNBK(D) because this is a dummy  output.   Before  return,
         $FDNBK(D)  will  be incremented for the first output.  Goto step 5
         to avoid USETO.

     4.  load the next block number from $FDNBK(D) and call $USETO to  find
         the required physical record.

     5.  set this block number,,next block number into $FDNBK(D).

     6.  execute the output by an  'OUTPUT  ch,@$FDIOW(D)'  instruction  so
         that  for  dump  mode, $FDIOW(D) should point to a chain of IOWDs,
         and for buffered modes $FDIOW should normally  be  zero,  but  may
         point to the next buffer.

     7.  if ok, return skip now.  Otherwise, call $GETST  to  read  the  IO
         channel status, then call $SETST to clear error bits.

     8.  calculate the error code from the error bits  in  the  IO  channel
         status.
BASIC IO ROUTINES                                                  Page 6-4
$OUTPU - WRITE A PHYSICAL RECORD TO A FILE


     9.  non-skip return to show error.


     FDB words altered:
     --- ----- --------
     $FDNBK set  to  [this-record-number,,next-record-number].   The   next
            record is just this record+1 for sequential writes.

     $FDSTS on error, right half set to IO channel status word.

     FDB words used:
     --- ----- -----
     $FDBUF to build buffer ring.  $OPEN sets defaults from the monitor  if
            the  user  does  not  provide his own values.  Either number or
            size of buffers or both may be given.

     $FDNBK the right half is used to determine which record to write  next
            (disk only).  The programmer may set the next record number for
            random  output,  otherwise  $OUTPU  will   write   sequentially
            starting from the beginning.

     $FDIOW addressed by the OUTPUT UUO instruction.  The user must set  up
            this word for dump mode IO.



     6.4  $LUKUP - LOOKUP A FILE

          Check if the file has already been LOOKUPed.  If so, give a  good
     return.   Otherwise,  execute  a LOOKUP UUO for the file.  The routine
     executes an extended LOOKUP for disk files, and a short LOOKUP for all
     other  devices.   The  length  of  the  extended  LOOKUP is taken from
     $FDCNT(D) which is initialised by $CLRFD.  The full algorithm is:

     1.  call $OPEN to execute an OPEN UUO if necessary.

     2.  check whether $LUKUP has already been called for this file (FC$LUK
         in $FDCHN on).  If so, give an immediate skip return.

     3.  execute a LOOKUP UUO.  If  error,  set  error  code  and  non-skip
         return.

     4.  otherwise, set FC$LUK in $FDCHN(D) and skip return.


     FDB words altered:
     --- ----- --------
     $FDCHN FC$LUK is set on a skip return so that $LUKUP  will  know  next
            time it is called.

     $FDRIB see Monitor Calls Handbook for words  affected  by  the  LOOKUP
            UUO.

     FDB words used:
     --- ----- -----
BASIC IO ROUTINES                                                  Page 6-5
$LUKUP - LOOKUP A FILE


     $FDRIB used by LOOKUP UUO



     6.5  $ENTER - ENTER A FILE

          Check if the file has already been ENTERed.  If so, give  a  good
     return.   Otherwise,  execute  a  ENTER UUO for the file.  The routine
     executes an extended ENTER for disk files, and a short ENTER  for  all
     other  devices.   The  length  of  the  extended  ENTER  is taken from
     $FDCNT(D) which is initialised by $CLRFD.  If FM$PRO is set to ones in
     $FDMOM(D),  then  the  contents  of  FM$PRO  in  $FDMOD(D) is set into
     $FDPRV(D).

          $ENTER has two entry points, $ENTER and $ENTE0.   $ENTER  assumes
     that  the caller does not want to set the protection, the mode, or the
     create time and date  from  $FDRIB(D),  so  it  clears  $FDPRV(D)  and
     rh($FDEXT(D)).   $ENTE0 does not alter $FDRIB(D) in any way other than
     that described below.  Note that all  IOLIB  routines  higher  in  the
     hierachy enter this routine at $ENTER.  The full algorithm is:

     1.  ENTER entry:  zero $FDPRV(D) and rh($FDEXT(D)).

     2.  ENTE0 entry:  call $OPEN to execute an OPEN UUO if necessary.

     3.  check whether $ENTER has already been called for this file (FC$ENT
         in $FDCHN on).  If so, give an immediate skip return.

     4.  execute a ENTER UUO.   If  error,  set  error  code  and  non-skip
         return.

     5.  otherwise, set FC$ENT in $FDCHN(D) and skip return.


     FDB words altered:
     --- ----- --------
     $FDCHN FC$ENT is set on a skip return so that $ENTER  will  know  next
            time it is called.

     $FDPRV contents of protection field  in  $FDMOD  added  if  masked  by
            $FDMOM.

     $FDRIB see Monitor Calls Handbook for words affected by the ENTER UUO.

     FDB words used:
     --- ----- -----
     $FDMOD protection field used if masked by $FDMOM

     $FDMOM FM$PRO mask used.

     $FDRIB used by ENTER UUO
BASIC IO ROUTINES                                                  Page 6-6
$OPEN - OPEN AN IO CHANNEL


     6.6  $OPEN - OPEN AN IO CHANNEL

          A software IO channel must be OPENed  to  initiate  IO  with  any
     file.  $OPEN takes the file described by the current FDB, finds a free
     channel, inserts defaults for all values not given by the  caller  and
     then  executes  an  OPEN UUO.  $OPEN does not attempt to reopen a file
     that has already been OPENed.  The full algorithm is:

     1.  check whether the channel is already open  ($FDOPN  in  $FDCHN(D))
         and skip return if so.

     2.  call $FRCHN to find the  first  free  channel  starting  with  the
         channel  number supplied by the user if $FDCHN(D) is non-zero, and
         with channel 1 otherwise.  Set the channel number into  FC$CHN  in
         $FDCHN(D).  If no free channels are found, set ERNFC$ and non-skip
         return.

     3.  check $FDDEV(D), and set 'DSK' if zero.

     4.  do a DEVTYP UUO.  If the result  is  zero  set  ERNSD%  and  error
         return.  Otherwise, set the result into $FDTYP(D).

     5.  check the DEVTYP word to see whether the device is available.   If
         not, set ERDNA% and error return.

     6.  check whether the device is not spooled and is restricted.  If so,
         check  that we have the device assigned and if not give ERRSD$ and
         error return.

     7.  execute a DEVSIZ UUO.  if dump mode, goto  step  9.   If  improper
         mode set, set ERIMP$ and error return.

     8.  use the user settings or the defaults returned by the  DEVSIZ  UUO
         to set $FDBUF(D) with the buffer number and size.  Set pointers to
         the buffer headers, $FDIBH(D) and $FDOBH(D) into $FDBHD(D).

     9.  check if the device is a magtape.  If not, goto step 11

    10.  check whether the magtape parity and density were set in $FDMOD(D)
         were they masked in $FDMOM(D)), and if so transfer the settings to
         $FDSTS(D).

    11.  check whether 'physical-only' set in $FDMOD(D) (FM$PHY  masked  in
         $FDMOM(D)) and if so, set it in $FDSTS(D).

    12.  execute the OPEN UUO.  The only unchecked error  is  no  available
         DDBs, so if error, set ERNET% and error return.

    13.  if the next block number is zero, set it to 1

    14.  set FC$OPN in $FDCHN(D) and skip return.


     FDB words altered:
     --- ----- --------
BASIC IO ROUTINES                                                  Page 6-7
$OPEN - OPEN AN IO CHANNEL


     $FDCHN channel number into FC$CHN and FC$OPN on.

     $FDTYP filled with result of DEVTYP UUO.

     $FDDEV if zero, filled with 'DSK'.

     $FDBUF if buffered mode, and either half zero,  that  half  is  filled
            with  the  system  default  returned by the monitor on a DEVSIZ
            UUO.

     $FDBHD if buffered mode, filled with points to $FDIBH and $FDOBH.

     $FDSTS may have physical-only and magtape parity and  density  set  if
            those fields are masked by $FDMOM.

     FDB words used:
     --- ----- -----
     $FDCHN if non-zero, channel number is used as  a  starting  point  for
            free channel search.

     $FDOPN see Monitor Calls Handbook for usage by OPEN and DEVSIZ UUOs.

     $FDMOD holds magtape density  and  parity  and  physical-only  bit  if
            corresponding masks in $FDMOM are ones.

     $FDMOM masks for fields in $FDMOD.



     6.7  $CLOSE - DISCONNECT A FILE FROM AN IO CHANNEL

          $CLOSE severs the  connection  between  a  file  and  a  software
     channel, but does not RELEAS the channel.  There are two entry points.
     $CLOSE closes both sides of the channel, and does not allow the caller
     to set any CLOSE bits.  $CLOS0 takes CLOSE bits as an argument.  $OPEN
     must have already been called for this file.  The algorithm is:

     1.  CLOSE entry:  zero CLOSE bits

     2.  CLOS0 entry:  execute CLOSE UUO.

     3.  zero the block number in $FDNBK(D).

     4.  if CL.OUT was not set, clear FC$ENT in $FDCHN(D).

     5.  if CL.IN was not set, clear FC$LUK in $FDCHN(D), and return.


     FDB words altered:
     --- ----- --------
     $FDNBK zeroed

     $FDCHN bits FC$ENT and FC$LUK may be cleared.
BASIC IO ROUTINES                                                  Page 6-8
$RLEAS - RELEASE AN IO CHANNEL


     6.8  $RLEAS - RELEASE AN IO CHANNEL

          The IO channel used by the  current  FDB  is  released,  and  any
     buffer  rings  are  returned  to  the pool of free core chunks.  $OPEN
     should have been called for the current FDB before calling $RLEAS.

          $RLEAS has two entry points:  $RLEAS executes the UUO and deletes
     buffer rings but $RLEA0 saves the buffer rings.  The algorithm is:

     1.  call $DLBUF to return output buffer ring  to  pool  of  free  core
         chunks

     2.  call $DLBUF to return input buffer ring

     3.  $RLEA0:  execute the RELEAS UUO.

     4.  clear $FDCHN(D) to zero the flags and channel number


     FDB words altered:
     --- ----- --------
     $FDCHN zeroed

     FDB words used:
     --- ----- -----
     $FDBHD to find the buffer headers and rings.



     6.9  $RENAM - CHANGE RIB DETAILS FOR A FILE

          To execute a RENAME UUO for the current file.  A  RENAME  can  be
     used to delete a file from disk or DECtape, and to change the name and
     extension.  In addition, it can be used to change other  details  kept
     in  the  RIB  block,  such as protection and create date/time.  $RENAM
     does an extended RENAME for disk files using the length in  $FDCNT(D),
     and a short RENAME for other devices.

          The programmer should call $LUKUP for  the  file  to  obtain  the
     current file details, and then change the FDB and call $RENAM.  If the
     protection  field  in  $FDMOM(D)  is  on  (FM$PRO  is  777)  then  the
     protection code is taken from the FM$PRO field in $FDMOD(D).

     FDB words altered:
     --- ----- --------
     $FDPRV the protection field is changed if FM$PRO is on in $FDMOM.

     FDB words used:
     --- ----- -----
     $FDRIB used by RENAME UUO.

     $FDMOD used if FM$PRO is on in $FDMOM.

     $FDMOM for FM$PRO mask
BASIC IO ROUTINES                                                  Page 6-9
$DELET - DELETE A FILE


     6.10  $DELET - DELETE A FILE

          Delete a file from disk or DECtape by calling $LUKUP to find  the
     file,  and  then  $RENAM to delete the file.  There is no need for the
     file to have been referenced before a call to $DELET.



     6.11  $USETI/O - SET THE DISK FILE RECORD NUMBER

          These routines execute USETI or USETO UUOs  to  ensure  that  the
     next  block  read or written with the disk is the correct one.  A word
     containing the last record number in the left helf  and  the  required
     block number in the right half is an argument.  If the required record
     is the last record + 1, then no UUO is executed.   These  routines  do
     not  defend  against asynchronous IO, therefore they are only suitable
     for use with dump mode, or with synchronous buffered modes.

     FDB words altered:
     --- ----- --------
     $FDNBK returns with right half set to this record number, and the left
            half set to this record - 1.



     6.12  $GETST - READ THE IO CHANNEL STATUS

          Read the IO channel status from the monitor and store it  in  the
     right half of $FDSTS(D).  This routine requires that $OPEN has already
     been called.

     FDB words altered:
     --- ----- --------
     $FDSTS right half receives IO status word.



     6.13  $SETST - SET THE IO CHANNEL STATUS

          Set the given IO status word into the  monitor  for  the  current
     FDB.  This routine requires that $OPEN has already been called.



     6.14  $XTUUO - EXECUTE AN IO UUO

          Execute the given IO UUO for the current FDB.  The channel number
     is obtained from FC$CHN in $FDCHN(D) and or'ed into the A field of the
     UUO instruction.  The routine has skip and non-skip returns,  but  the
     skip return may be ignored for UUOs that have no skip return

          A useful feature for debugging programs is that every IO  UUO  is
     executed by an XCT instruction from the location labelled '$$XUUO', so
     that a breakpoint on $$XUUO will catch every IO UUO.  Examine  ac(T1),
     to find the UUO.
BASIC IO ROUTINES                                                 Page 6-10
$XTCAL - EXECUTE AN IO ORIENTED CALLI UUO


     6.15  $XTCAL - EXECUTE AN IO ORIENTED CALLI UUO

          For some CALLI UUOs it is important to know  whether  IO  on  the
     associated file is 'physical only' e.g.  a GETSEG UUO must be executed
     physical only if this is specified.  $XTCAL, checks the current FDB to
     see  whether  either  UU.PHS  is  set in $FDSTS(D) or UU.PHY is set in
     $FDMOM(D) and $FDMOD(D), and if so, makes the UUO physical only before
     executing  it.   As a side effect, if physical only was set in $FDMOM,
     then the setting in $FDMOD(D) is set into $FDSTS(D).

          A useful debugging  feature  is  that  all  CALLI  UUOs  executed
     through  a  $XTCAL (or $XTDCL) call are executed by an XCT instruction
     at '$$XCAL'.  Examine ac(T1) to find the UUO.  The full algorithm is:

     1.  check whether physical only is implemented.   If  not,  clear  the
         indicator.  Goto step 4.

     2.  check whether FM$PHY is set on in $FDMOM(D).  If not, goto step 5.

     3.  read the physical-only setting from FM$PHY in $FDMOD(D)  into  the
         indicator.

     4.  set the indicator into $FDSTS(D).

     5.  check the physical only flag  in  $FDSTS(D).   If  on,  complement
         bit19  of  the  UUO,  to  show physical only.  Execute the UUO and
         return.


     FDB words altered:
     --- ----- --------
     $FDSTS bit0 is set if FM$PHY is on in $FDMOM.  Bit0 is set  to  FM$PHY
            in $FDMOD.

     FDB words used:
     --- ----- -----
     $FDMOD FM$PHY field checked and used.

     $FDMOM FM$PHY mask used



     6.16  $XTDCL - EXECUTE A DEVICE ORIENTED CALLI UUO

          This routine is an  entry  point  to  the  $XTCAL  routine.   The
     distinction  is that this routine is for CALLI UUOs that take a device
     name as an argument.  $XTDCL takes the device name from $FDDEV(D), and
     uses 'DSK' as a default.  'DSK' is set into $FDDEV(D) if it was empty.

     FDB words altered:
     --- ----- --------
     $FDDEV if empty on entry, it is set to 'DSK'.
BASIC IO ROUTINES                                                 Page 6-11
$MKBUF - BUILD A RING OF BUFFERS


     6.17  $MKBUF - BUILD A RING OF BUFFERS

          Use the size and number of buffers stored in $FDBUF(D) to build a
     ring  of  buffers  of  the  requied size, and link them into the given
     buffer header.  Initialise the ring-use bit.

     FDB words used:
     --- ----- -----
     $FDBUF uses both number and size of buffers to create ring



     6.18  $DLBUF - DELETE A RINF OF BUFFERS

          Given the address of a buffer header, garbage collect the  buffer
     ring  and return all buffers to the pool of free chunks of core.  This
     routine is ineffective if static core allocation is being used.



     6.19  $UPDAT - OPEN A FILE FOR UPDATING

          Open the file with a LOOKUP and ENTER on the same channel.



     6.20  $UPDWT - OPEN A FILE FOR UPDATING AND WAIT

          Call $UPDAT to open the file for updating.  If the  error  return
     gives  'file  being  modified',  wait  for a given time and try again.
     Repeat for a given number of times, and finally give up.



     6.21  $APEND - OPEN A FILE FOR APPENDING

          Open the current file  for  updating,  by  executing  a  call  to
     $UPDAT, then setup the FDB so that the first block written will be the
     last block.  If IO is in a buffered mode, set the output buffer header
     to  point to the first free word of the last block.  Return a count of
     the number of free words in the last block.

          Note that $APEND assumes that the current file is an  append-only
     file, and this routine will fail if the protection is more liberal.

          The full algorithm is:

     1.  open the file for updating using $UPDAT

     2.  calculate the  number  of  blocks  in  the  file,  and  the  words
         remaining  in the last block from $FDSIZ.  Set $FDNBK to write the
         last block.
BASIC IO ROUTINES                                                 Page 6-12
$APEND - OPEN A FILE FOR APPENDING


     3.  check the channel IO mode.  If a dump mode, goto step 6.

     4.  do a dummy output for buffered modes

     5.  set the byte pointer in the output buffer header to point  to  the
         first free word, and alter the remaining byte count accordingly.

     6.  set ac(T1) to the count of free words and skip return.


     FDB words used
     --- ----- ----
     $FDSIZ gives the size of the file in words

     $FDSTS gives the channel IO mode

     FDB words altered
     --- ----- -------
     $FDNBK set to the last block of the file

     $FDOBH byte pointer set to the first free word and byte count  set  to
            reflect free bytes remaining



     6.22  $APDWT - OPEN A FILE FOR APPENDING AND WAIT

          Call $UPDWT to open the file for updating.  If the file is opened
     successfully, call $APEND to set up the block number and buffer header
     for appending to the file.



     6.23  $MTXXX - EXECUTE AN MTAPE UUO

          There are 12 $MTxxx routines, each of which executes a  different
     function of the MTAPE UUO for the current file.  The 'xxx' is the code
     for the various functions e.g.  $MTREW does a MTREW.   to  rewind  the
     tape.   A complete list of functions may be found in the Monitor Calls
     Handbook.

          The $MTxxx routines all wait for completion of the function  with
     an  MTWAT.   before returning control.  $MTBSF (backspace file), skips
     forward over the endfile unless at beginning of tape.











                                CHAPTER 7

                       FORMATTED READING AND WRITING



     7.1  GENERAL DESCRIPTION

          IOLIB contains routines for reading and  writing  data  as  ASCII
     strings  and converting them into an internal form according to a wide
     variety of formats.  For example, the $RDECL routine  reads  a  string
     from the current file and converts it as a signed decimal integer into
     a binary number.  The $WDECL routine takes a binary  number,  converts
     it  as  a  signed  decimal  integer into a string and writes it to the
     current file.

          All the formatted input and output routines work on  the  current
     file,  so  that they need the current file point set up in ac(D).  All
     the input routines use a single routine,  $$RCHR,  to  read  the  next
     character  from the file, and all the output routines use one routine,
     $$WCHR, to write the next character.  These routines do  not  have  an
     error return, but assume that all IO errors are fatal, and trap to the
     fatal error handler, $FTLIO.  The user programmer may  rewrite  $$WCHR
     and  $$RCHR  to  provide  his  own  error handling or to provide other
     features at a low level.  $$WCHR  merely  calls  $WRITE,  the  routine
     which  writes  one  byte to the current file, and traps error returns.
     $$RCHR interprets the input string as a DECsystem-10 standard  command
     string,  and  uses  the  DEC algorithm to edit the input string before
     passing the characters back to the calling routine.  $$RCHR compresses
     sequences of spaces, removes spaces at the beginning and end of lines,
     handles continuation lines and returns  standard  codes  for  endline,
     endfile and altmode.  The user programmer may redefine $$RCHR to use a
     lower level of editing or no editing at all, or even to  edit  or  not
     depending on the current file, if he wishes.

          The formatted  output  routines  are  straightforward,  and  full
     details  may be found in Appendix A.  Formatted input is a little more
     complicated.  The input routines read the  input  string  interpreting
     characters  until  they  find  one  that does not belong to the format
     being read.  Then they return the values read to the caller, including
     the  delimiting  character  in  ac(T1).  Therefore, the caller has the
     responsibility to check the delimiter to ensure that  it  is  correct.
     The  routines to read filenames and switches are special cases and are
     dealt with in some detail in this chapter.
FORMATTED READING AND WRITING                                      Page 7-2
$WRITE - WRITE ONE BYTE TO THE CURRENT FILE


     7.2  $WRITE - WRITE ONE BYTE TO THE CURRENT FILE

          This is the basic buffered-write routine.  It is called to  write
     one  byte,  of the size defined by the current file, to that file.  It
     ensures that all prerequisite UUOs have  been  performed  and  that  a
     buffer  ring  is  built and initialised, by calling $OUTPU for a dummy
     output.  It has error  and  skip  returns.   There  is  a  write  byte
     routine, $$WBYT, that performs the same function as $WRITE, but has no
     error return and instead calls $FTLIO.  The algoritm is:

     1.  if the current file point is zero (TTCALL IO), write the character
         using OUTCHR and skip return immediately.

     2.  if the current file point is a byte pointer (bits  0-11  nonzero),
         write the byte using IDPB and skip return immediately.

     3.  otherwise, check the byte count in the  buffer  header  $FDOBH(D);
         unless the buffer is full, goto step 5.

     4.  call $OUTPU to empty the buffer.  This also ensures a dummy OUTPUT
         on the first call.  If error, nonskip return.

     5.  decrement byte pointer in $FDOBH(D) and write the  byte  into  the
         buffer.  Skip return.


     FDB words altered:
     --- ----- --------
     $FDOBH the buffer header is altered by changing the byte  pointer  and
            byte counts



     7.3  $$WBYT - WRITE A BYTE TO THE CURRENT FILE

          $$WBYT is a replaceable routine.  The IOLIB version calls $WRITE,
     and  returns to caller if $WRITE gives a skip return, but calls $FTLIO
     if $WRITE gives an error return.  The user programmer may rewrite this
     routine to perform additional functions if he wishes.



     7.4  $$WCHR - WRITE A CHARACTER TO THE CURRENT FILE

          The IOLIB version of $$WCHR  is  identical  to  $$WBYT,  but  the
     routines  are  separately replaceable.  The distinction is that $$WCHR
     is called by all formatted output routines to write characters.

          As an example of a replacement $$WCHR, suppose that a log file is
     used  for  error messages and the point to the log file FDB is kept in
     $IDEFD(I).  We want to send messages that go to the log file,  to  the
     terminal as well, so write:

     $$WCHR::
             CAME    D,$IDEFD(I)     ;is this the log file?
FORMATTED READING AND WRITING                                      Page 7-3
$$WCHR - WRITE A CHARACTER TO THE CURRENT FILE


             JRST    WCH10           ;no
             PUSH    P,T1            ;yes, save character
             TRMFD$                  ;set FDB to terminal
             WRITE$                  ;send character to terminal
               FATAL$                ;
             POP     P,T1            ;recover character
             MOVE    D,$IDEFD(I)     ;recover log file FDB
     WCH10:
             WRITE$                  ;send character to file
               FATAL$                ;
             POPJ    P,              ;



     7.5  $READ - READ A BYTE FROM THE CURRENT FILE

          This is the basic buffered-read routine.  It is  called  to  read
     one  byte,  of  the size defined by the current file, from the current
     file.  It ensures that all prerequisite UUOs are executed and  that  a
     buffer  ring  is  built  and  initialised,  by  calling $INPUT to read
     records from the file.  It has three returns, nonskip for errors, skip
     for endfile and double-skip for normal return.  There is a replaceable
     read byte routine, $$RBYT, that performs the same function  as  $READ,
     but has no error return, and instead calls $FTLIO.  The algorithm is:

     1.  if the current file point is zero (TTCALL IO), read the  character
         using INCHWL and double-skip return immediately.

     2.  if the current file point is a byte pointer  (bits  0-11  nonzero)
         read  a  byte  using  ILDB.   If the byte is zero, give an endfile
         return with T1 0;  otherwise give a double skip return.

     3.  otherwise, check the byte count in the buffer  header,  $FDIBH(D),
         and unless the buffer is empty, go to step 5.

     4.  call $INPUT to read the next record.  If error  or  endfile,  give
         the appropriate returns.

     5.  read the next character from the buffer, and decrement the  buffer
         byte count.  Double skip return.


     FDB words altered:
     --- ----- --------
     $FDIBH the buffer header is altered by changing the byte  pointer  and
            byte count.



     7.6  $$RBYT - READ A BYTE FROM THE CURRENT FILE

          $$RBYT is a replaceable routine.  The IOLIB version calls  $READ,
     and  returns  to  caller  if  $READ  gives  endfile or normal returns;
     endfile is nonskip and normal  is  skip.   If  $READ  gives  an  error
     return,  $$RBYT  calls $FTLIO.  The user programmer may rewrite $$RBYT
FORMATTED READING AND WRITING                                      Page 7-4
$$RBYT - READ A BYTE FROM THE CURRENT FILE


     to perform additional functions if he wishes.



     7.7  $$RCH0 - READ A CHARACTER FRM THE CURRENT FILE

          The IOLIB version of $$RCH0  is  identical  to  $$RBYT,  but  the
     routines  are  separately replaceable.  The distinction is that $$RCH0
     is called by the command string character editor $REDCH, and  is  used
     for reading all command characters.

          The user programmer may  rewrite  $$RCH0  to  perform  additional
     functions.   For example, he might want to be able to trap endfile and
     move up one level of command file in  a  system  that  allowed  nested
     command files:

     $$RCH0::
             READ$                   ;get next character
               FATAL$                ;
               CAIA                  ;endfile, so check nesting depth
             PJRST   $POPJ1##        ;skip return
      
             MOVE    T1,CFSTKP       ;pick up point to command file stack
             CAMN    T1,CFSTK0       ;compare with empty stack
             POPJ    P,              ;empty - user typed control-Z
             RLEAS$                  ;lose current command file
             POP     T1,D            ;recover next command FDB
             POP     T1,CFSTKP       ;recover last character from this file
             EXCH    T1,CFSTKP       ;swap stack point and character
             PJUMPE  D,$POPJ1##      ;return if TTCALL
      
             ;back to previous command file.  Reopen it
      
             HLRS    $FDNBK(D)       ;reread last block
             PUSH    P,$FDIBH+1(D)   ;save buffer header pointer and count
             PUSH    P,$FDIBH+2(D)   ;
             INPUT$                  ;read block
               FATAL$                ;error
               FATAL$                ;endfile is error too
             POP     P,$FDIBH+2(D)   ;set up for next read
             POP     P,$FDIBH+1(D)   ;
             PJRST   $POPJ1##        ;good return



     7.8  $$RCHR - READ A CHARACTER FROM THE CURRENT COMMAND FILE

          $$RCHR is the replaceable routine called  by  all  the  formatted
     read  routines to read the next character.  It has no error or endfile
     returns.  The endfile condition should  be  converted  into  a  $CHEOF
     special character.  The IOLIB version of $$RCHR calls $RCALT, which is
     one of the entry points to the command  character  editing  coroutine,
     $RCCHR.   $RCALT  has the property that if the last character read was
     an altmode ($CHALT), then another altmode is returned  to  the  caller
     without  reading  anything from the input file.  Therefore if the user
FORMATTED READING AND WRITING                                      Page 7-5
$$RCHR - READ A CHARACTER FROM THE CURRENT COMMAND FILE


     ends a line with an altmode, and the altmode condition is not cleared,
     the  caller  routine  will  have  altmodes returned for all subsequent
     requests for characters.  This is just what is required for a  program
     asking  a  series  of questions, when an altmode means that all future
     questions take the default answer.  If this feature is  not  required,
     redefine $$RCHR as a jump to $RCCHR:

     $$RCHR::
             PJRST   $RCCHR##        ;no altmode defaulting

     If the command character interpreting is not required, but  the  basic
     editing  provided  in  $REDCH  is,  then  redefine $$RCHR as a jump to
     $REDCH:

     $$RCHR::
             PJRST   $REDCH##        ;just basic editing

     Of course, $$RCHR can be rewritten to perform additional functions  as
     well,  but  since  it  is called by all the formatted input routine it
     must at least return the codes:

                    0    $CHALT    altmode (ASCII 033)
                    -1   $CHEOL    endline (ASCII 012,013,014)
                    -2   $CHEOF    endfile (ASCII 003,032)



     7.9  $REDCH - READ A CHARACTER AND DO BASIC COMMAND EDITING

          Read a character from the current command file and  perform  some
     preliminary editing.  $$RCH0 is used to read the character.

     1.  make the endfile return look like a control-Z character.

     2.  ignore nul (ASCII 000), carriage return  (ASCII  015)  and  delete
         (ASCII 177).

     3.  make tab (ASCII 011) into space (ASCII 040)

     4.  if escape (ASCII 033) give terminal user a <cr><lf> and  set  code
         $CHALX (0).

     5.  make vertical tab (ASCII 013), form feed (ASCII 014) and line feed
         (ASCII 012) into $CHEOL (-1).

     6.  if control-C (ASCII 003) clear the command scanning coroutine pc

     7.  if either control-C or control-Z  (ASCII  032)  turn  into  $CHEOF
         (-2).
FORMATTED READING AND WRITING                                      Page 7-6
$RCCHR - READ A CHARACTER AND EDIT AS A COMMAND CHARACTER


     7.10  $RCCHR - READ A CHARACTER AND EDIT AS A COMMAND CHARACTER

          Return the next character in a command string.  This may  involve
     reading  a  character  from  the command file or rereading a character
     already processed.  The routine compresses multiple  spaces  into  one
     space, ignores leading and trailing spaces on a line, ignores comments
     (all characters following  a  ';')  and  ignores  endline  immediately
     preceded by a '-', so that continuation lines are possible.

          $RCCHR is a coroutine whose pc is kept in $IDCPC(I) in  the  IDB.
     The  coroutine  often has to look ahead one character to determine the
     meaning of the current character, and the lookahead character is  kept
     in  $IDLAC(I) in the IDB.  The last character read is always available
     in $IDLSC(I).

          If any character is set in $IDNXC(I) on entry to $RCCHR, then the
     routine  will  take  this  character as the next character to be read.
     The programmer can force a character to  be  read  by  placing  it  in
     $IDNXC(I).

          There is a second entry point to $RCCHR, $RCALT, which checks  if
     the  last  character  was  an  altmode,  and  if so returns an altmode
     immediately instead of reading another character.  This is the default
     entry point to $RCCHR.

     Note:  This routine may only be used for one file at a time.



     7.11  $RFILE - READ A FILENAME FROM THE CURRENT FILE

          $RFILE will read a complete file specification written in a  form
     compatible  with  that accepted by SCAN, the DEC command scanner.  The
     filename read by $RFILE can contain the components:  one  device,  one
     name,  one  extension, one path specification and a number of switches
     written in any order.  The name, extension and path specification  may
     contain  wild  cards.   No  individual  field  is  compulsory  and the
     specification is terminated by some character  not  belonging  to  the
     specification.

          The filename is decoded into an FDB, which may be supplied by the
     caller, but if not will be obtained by $RFILE from the memory manager.
     The FDB is intialised by calling $CLRFD.

          $RFILE maintains an extra FDB known as the default file FDB.  Any
     parts  of  the  file  specification that are typed before the name are
     assumed to be 'sticky' for any other file specifications typed on  the
     same  line,  and  these  sticky defaults are remembered in the default
     FDB.  The current defaults are applied to a filename after reading the
     specification and before returning to the caller.  The user programmer
     may supply the default  FDB  by  putting  a  point  to  the  FDB  into
     $IDDFD(I)  in  the  IDB.   Otherwise, $RFILE obtains space for the FDB
     from the memory manager.  The user programmer may preset defaults into
     the default FDB, if for instance he wishes the default extension to be
     '.REL'.
FORMATTED READING AND WRITING                                      Page 7-7
$RFILE - READ A FILENAME FROM THE CURRENT FILE


          Wildcard characters are set into the appropriate  fields  in  the
     FDB  and are masked by the corresponding field in the appropriate mask
     word.  Non-wild characters are masked by ones, and wild characters are
     masked  by  zeros.   The  programmer  must  call $LKWLD The caller can
     provide a table of switches that  may  be  encountered  in  this  file
     specification.   He  can  also  specify standard switches by placing a
     pointer to the standard switch table into $IDSWT(I) in the IDB.  IOLIB
     defines  a  set  of standard file switches in the table $TBSSW and the
     user programmer can use this as  the  standard  table.   Some  of  the
     standard  file  switches  set  fields in $FDMOD in the FDB and set the
     corresponding mask in $FDMOM.  These switches will also be set in  the
     default  FDB,  and  become  sticky  if  they are given before the name
     field.

          $RFILE returns the delimiting character and a point to  the  FDB.
     The  point  to  the  FDB  is  in  ac(T2), and the left half of that ac
     contains flags:

          1B0       FF$NUL    file specification was null  except  possibly
                              for switches.  No meaningful file name fields
                              were typed.

          1B1       FF$WLD    the   file   specification   contains    wild
                              characters



     7.12  READ PATH AND PPN SPECIFICATIONS

          There  are  three  routines  for  reading   parts   of   a   path
     specification.   $RPJPG reads a project-programmer number (without [])
     including wildcards, and checks to make  sure  that  the  numbers  are
     within  range.  $RPPN reads a full PPN specification including the [],
     and $RPATH can read SFD names as well.

          All the routines return a delimiter (in the  case  of  $RPPN  and
     $RPATH,  the character following ']'), a value, a mask and a flag word
     which has bit0 set if the PPN is the default ([-]) and bit1 set if any
     wildcards  were seen.  The value is the PPN if there were no SFDs, and
     the mask is the PPN mask.  If $RPATH did read SFD names, the the value
     is  a  point to a path block, and the mask is a point to a mask block.
     $RPATH obtains the path and mask blocks from the memory manager.



     7.13  $RSWIT - READ A SWITCH NAME AND VALUE

          $RSWIT reads a switch name and compares it with a table of switch
     names supplied by the caller.  If this does not succeed unambiguously,
     $RSWIT looks for a point to a table of standard switches in  $IDSWT(I)
     in  the  IDB.   If there is one, $RSWIT tries to match the switch with
     those in this second table.  Assuming that $RSWIT succeeds  somewhere,
     it  then uses data in the switch tables to determine whether to read a
     value and if so, what data format to read the value in.  $RSWIT  reads
     the  value,  and  uses  further  information  in  the switch tables to
FORMATTED READING AND WRITING                                      Page 7-8
$RSWIT - READ A SWITCH NAME AND VALUE


     determine where to deposit either the value, or default data if  there
     was  no  value.   $RSWIT  can  deposit data using a byte pointer.  The
     macros that build switch tables are discussed in sections 4.2 and 4.3.











                                 CHAPTER 8

                             TEMPCORE ROUTINES



     8.1  GENERAL DESCRIPTION

          Tempcore is a device whereby small files of data may be  kept  in
     core  storage  within  the  monitor  for  ultra  fast  access  by user
     programs.   It  is  mainly  intended  for  use  by  the  CCL   command
     interpreter which keeps small files of commands in tempcore for one of
     the invoked processors to read.

          The amount of space allocated to tempcore is small and if  enough
     users  generate  enough  tempcore  files at once it overflows.  So the
     programs that read and write tempcore are built to try tempcore first,
     and  if that is unsuccessful, to try a file on the disk with a certain
     name.  The tempcore read, write and delete routines  handle  the  file
     whether it is in tempcore or on the disk.

          A convention on the DECsystem-10 is that if a program is  entered
     at  its start address then everything is normal, but if the program is
     entered at the location following the start address ('start+1'),  then
     commands  are  to  be  taken  from a tempcore file.  IOLIB allows this
     feature as an assembly parameter.  If FT$CCL=-1, then the  feature  is
     included.   If  FT$CCL=0, it is not.  If it is included and entry is a
     start+1, IOLIB sets up the command input file to be a  tempcore  file.
     The  user  programmer  must ensure that he calls $TMPIN before reading
     that file, and deletes the file with $TMPDL at some stage.

          Tempcore files have 3 character filenames, and by  default  IOLIB
     chooses  the first 3 characters of th program name.  If the file is on
     disk, the name is 'jjjnnn.TMP', where jjj is the job number,  and  nnn
     is the name.  e.g.  023MAC.TMP



     8.2  $TMPFD - BUILD A TEMPCORE FDB

          $TMPFD obtains an FDB from the memory manager and initialises  it
     with  the extension 'TMP', and a name made from the job number and the
     3 character name supplied.  The point to the FDB is returned in ac(D).
TEMPCORE ROUTINES                                                  Page 8-2
$TMPIN - READ A FILE FROM TEMPCORE


     8.3  $TMPIN - READ A FILE FROM TEMPCORE

          Build a one buffer ring using $MKBUF, and then try  to  read  the
     file from tempcore.  On success, set up the buffer header, so that the
     first call to $READ will return the first character, and set FC$TCI in
     $FDCHN(D)  to ensure that the next call to $INPUT will give an endfile
     return.  If the tempcore read fails, read the  file  from  disk  using
     $INPUT.  

          The technique for reading tempcore files is to  define  FT$CCL=-1
     for  assembly,  which  ensures that the FDB is set up correctly.  Call
     $TMPIN and then read the file using normal  formatted  read  routines.
     Finally,  when  the  program  finishes,  delte  the tempcore file with
     $TMPDL.



     8.4  $TMPDL - DELETE A TEMPCORE FILE

          Tempcore files should be deleted after they  have  been  read  so
     that  they  don't  clutter up an overcrowded tempcore area and so that
     the disk directory doesn't fill up with .TMP  files.   $TMPDL  deletes
     the file from both tempcore and disk.



     8.5  $TMPOU - CLOSE A TEMPCORE OUTPUT FILE

          Tempcore files are normally short.  If  they  have  exceeded  one
     buffer  in  length  then the file may already have been entered on the
     disk, and $TMPOU merely  releases  the  file.   If  not,  then  $TMPOU
     attempts  to write the file into tempcore, and if that fails, then the
     file is written to disk and released.

          The technique for writing a tempcore file, is to set up  the  FDB
     using  $TMPFD  (one  buffer  is sufficient), then to write to the file
     normally using formatted output routines, and finally to  end  with  a
     call to $TMPOU instead of to $RLEAS.











                                CHAPTER 9

                              ERROR REPORTING



     9.1  GENERAL DESCRIPTION

          IOLIB contains macros and routines for writing error messages  to
     a  specified file with the minimum of programmer effort.  The messages
     are written in the standard  DECsystem-10  error  format  with  a  one
     character  severity  indicator,  then  two  optional 3 character codes
     identifying the program and the error, and lastly the error  text.   A
     value  can  be  included in the message, printed in one of a number of
     possible formats.  Fatal errors do not return to the caller, but  fall
     into  a  special  trap  routine,  $$FERR,  which may be written by the
     caller.  The standard $$FERR routine merely tidies up and  returns  to
     monitor mode.  Other errors always return to the caller.

          There are special routines to print error messages for syntax and
     IO  errors,  which  may  be called on an error return from the command
     scanners and IO routines.  These routines print standard messages  and
     give the caller the decision as to whether the error is fatal or not.

          Any character may be used as a severity indicator,  e.g.   $  for
     messages  to  the  operator  from batch programs, but three characters
     have special entry points to the error routines.  ?  is a fatal error,
     %  is  a  warning  error,  and a message enclosed in [] is an advisory
     message.

          All the error routines can be called by the error macros, FATAL$,
     WARN$  and  ADVIS$ which take arguments which allow the user to define
     the form of the message in the macro call.  Each macro call uses  only
     one  word  of  inline  code so that the calls may be used in the error
     return location from subroutines and UUOs.

          The error reporters are driven by several tables of messages  and
     output routines, any of which may be replaced by the caller.



     9.2  MESSAGE FORMAT

          The messages have a maximum of 8 fields, although only  two,  the
     severity  indicator and the message text are mandatory.  An example of
     a full message is:
ERROR REPORTING                                                    Page 9-2
MESSAGE FORMAT


               ?(400140)DELFNF LOOKUP(0), No file:  ACCT.SYS[1,2]
               ^    ^    ^  ^     ^   ^      ^           ^
               s aaaaaa pppeee uuuuuu c   mmmmmmm  vvvvvvvvvvvvv


     where:
          s    is the severity flag (e.g.  '?' '%' '[')

          a    is the caller's address in octal.  It  is  only  printed  if
               FT$DBG is -1, that is, if the user is debugging his program.

          p    is  the  3  character  program  identifier.    The   program
               identifier  is set by the caller program in the left half of
               $IDECD(I).  If these identifier is not set,  this  field  is
               not printed.

          e    is the 3 character error identifier.  The  error  identifier
               is  unique  for  each  message,  and  must  be supplied as a
               parameter to the $FATAL and  $WARN  routines.   All  IO  and
               syntax  errors  provided  by IOLIB have an error identifier.
               The identifiers and their meanings are detailed in  full  in
               Appendix F.

          u    is a 6 character UUO or type indicator.  This indicator must
               be  supplied  as  a  parameter when calling $FATAL or $WARN.
               IOLIB IO routines put the UUO name of the UUO that found the
               error  into  this  field,  and  syntax  errors  put the word
               'SYNTAX'.

          c    is an octal  code  that  is  traditionally  printed  for  IO
               errors.   It  is  printed  if a flag is set on the $FATAL or
               $WARN call.

          m    is the message text.

          v    is a value which may be written  in  one  of  a  variety  of
               formats.   The  format  is  given  by  a  format code in the
               routine call, and the value is supplied by the caller.

          All the characters in the example not masked in  the  line  below
     are  added  by  the IOLIB routine.  Some examples of the messages that
     can be generated are:

                    %DELILC SYNTAX, Illegal character: <BEL>

                    ?REACAS Cannot access system files: ACCT.SYS

                    [DOR Out of range: 677777]

                    %Name does not match: FORMET

                    ?I don't like you, go away
ERROR REPORTING                                                    Page 9-3
MESSAGE FORMAT


          Normally the whole of an error message is output, but this can be
     controlled  through  the  'message  verbosity'.   The user can set the
     verbosity so that some combination of the 'prefix', the  'first  line'
     and the 'continuation lines' are typed, by command to the monitor.  If
     the message level is set to (PREFIX,NOFIRST) then only the s, a, p and
     e  fields  of  the  message  are  typed.   If  the  message  level  is
     (NOPREFIX,FIRST), the u, c, m and v fields are typed.  The default  is
     (PREFIX,FIRST).   See  Appendix  F for explanations of all IOLIB error
     ids.

                    ?(400140)DELFNF



     9.3  ERROR SEVERITY

          IOLIB treats fatal errors  differently  from  warnings,  advisory
     messages  and all others.  Fatal errors are those that cause immediate
     termination of execution of the program, or a restart from some  point
     in  the  program.   Warning errors are normally local to some phase of
     execution of a program, and do not necessarily  cause  termination  of
     the  whole  program.  The program may proceed normally after issuing a
     warning, or it may  jump  to  some  other  phase  of  execution.   For
     example,  if  a  delete  program  couldn't find one file to delete, it
     would only need a warning and it could proceed to delete  other  files
     in the same command, but if all the files were missing it might prompt
     a fatal message.

          The $FATAL routine flags fatal errors with a '?', and $WARN flags
     warning errors with a '%'.  Calls to the $WARN routine write the error
     message and then return to the calling routine, but  calls  to  $FATAL
     trap to a special routine labelled $$FERR.  The standard IOLIB version
     of $$FERR merely cleans up and returns the program  to  monitor  mode,
     but  users  may write their own $$FERR routines to e.g.  restart their
     program at some point.

          Advisory messages are enclosed in square brackets,  [],  but  are
     treated  in  the  same  way  as warnings by the error routines.  Other
     severity indicators may be used by the appropriate call to $ERROR  and
     these calls return in the same way.



     9.4  $ERROR - THE ERROR REPORTER

          The routine, $ERROR, is used to handle all error messages whether
     fatal or warning.  The inputs to $ERROR are:


          Ac        Bits      Description
          --        ----      -----------

          T1        0-4       flags, see full description below
                    5-11      severity flag character  in  ASCII.   FATAL$,
                              WARN$  and  ADVIS$  set up this field.  Other
ERROR REPORTING                                                    Page 9-4
$ERROR - THE ERROR REPORTER


                              severity characters must be set by the caller
                              before entering $ERROR.
                    12-17     value type code, which is used as  the  index
                              to a table of addresses of write routines.
                    18-35     pointer to either ASCIZ message  text,  or  a
                              word containing:
                              lh: error code in SIXBIT
                              rh: pointer to ASCIZ message text
                              depending on EC$IND.

          T2                  value to be printed in a format specified  by
                              the error code type

          T3                  UUO name in SIXBIT, to be  printed  if  flag,
                              EC$UUO, is set

          P                   top of stack  contains  return  address  that
                              will be printed if FT$DBG=-1.

          The flag field in ac(T1) contains 1 bit  flags  indicating  which
     fields of the message are to be printed.  They are:

          Bit       Symbol    Description
          ---       ------    -----------

          0         EC$IND    right  half  of  ac(T1)  points  to  a   word
                              containing  the  error  id  in the left half.
                              text in the right half.  If not set, then the
                              right  half  of  ac(T1)  points  to the ASCIZ
                              message text.

          1         EC$UUO    the u field is to be  written,  so  that  the
                              contents of ac(T3) are to be interpreted as a
                              SIXBIT name.

          2-4                 unused, but reserved

          5-11      EC$FLG    severity flag character in ASCII

          12-17     EC$TYP    an index+1 to $TBWAD, the table of address of
                              write  routines  for printing the value.  The
                              indices to  the  standard  IOLIB  $TBWAD  are
                              given symbolic values (see below).

          $ERROR writes the error message to a file  described  by  an  FDB
     pointed  at  by  $IDEFD(I).   The  BEGIN$ macro sets this to the job's
     terminal, but the programmer may modify it to be a log file or even to
     be  some flag for the write routine, $$WCHR, to recognise and send the
     message to several files.

          The  message  verbosity  and  the  program  id  are  taken   from
     $IDECD(I).   The  program  id is 3 SIXBIT characters in the left half,
     and is ignored if blank.
ERROR REPORTING                                                    Page 9-5
$ERROR - THE ERROR REPORTER


          If the message is fatal, the $ERROR routine  prints  the  message
     and  then  traps  to  $$FERR.   Otherwise  the  routine returns to the
     caller.



     9.5  $FATAL, $WARN AND $ADVIS

          These routines set the appropriate severity character into EC$FLG
     and  call  $ERROR  to  do all the hard work.  They may be conveniently
     called through the FATAL$, WARN$ and ADVIS$ macros, which use only one
     instruction  of inline code and set up all the routine parameters from
     the macro arguments.



     9.6  THE FATAL$, WARN$ AND ADVIS$ MACROS

          These macros normally call the $FATAL, $WARN and $ADVIS routines,
     but  they  may  call  other routines, depending on the arguments.  The
     format of the macro call is

          FATAL$   <message-text>,value-format-code,error-id,UUO-name

          If the first two arguments are absent, the macro generates a call
     to  $FTLIO,  or  $WRNIO,  which  print  IO  error  messages.   If  the
     message-text argument is absent, the  macro  generates  a  call  to  a
     routine  $FTLxx or $WRNxx, where 'xx' is the first 2 characters of the
     value-format-code.  This means that the programmer can write  his  own
     routines,  and  call  them  using  FATAL$ and WARN$.  The syntax error
     writing routines, $FTLSY and $WRNSY, may also be called in  this  way.
     If  both the first two arguments are present, then the macro generates
     a call to a literal, which sets arguments into  acs  T1-T3  and  calls
     $FATAL  or $WARN.  ADVIS$ always calls $ADVIS.  The value-format-codes
     available in the standard IOLIB table of value formats are:

                    CHAR      ASCII character, right-justified
                    DECL      decimal number
                    FILE      filename,given by pointer to FDB
                    OCTL      octal number
                    TEXT      ASCIZ string
                    WORD      SIXBIT word

     Examples:

     i)
             ....
             LUKUP$                  ;lookup a file
               FATAL$                ;error - fatal, call $FTLIO.
             ....

     ii)
             ....
             RFILE$                  ;read a filename from command string
               FATAL$  ,SY           ;error - call $FTLSY to report
ERROR REPORTING                                                    Page 9-6
THE FATAL$, WARN$ AND ADVIS$ MACROS


             ....

     iii)
             ....
             MOVE    T2,NUMLIN       ;pick up number of lines
             WARN$   <End of data at line>,DECL,EOD
             ....

     iv)
             ....
             DAEMON  T0,             ;issue DAEMON UUO
               FATAL$ <Not implemented>,,NIM,DAEMON
             ....



     9.7  IO ERROR REPORTING

          The basic IO modules in IOLIB produce error codes in  a  standard
     form  when  they  detect errors.  An error return is given with ac(T1)
     containing an error code in the right half, and a UUO code in the left
     half.   An  endfile  return  from $INPUT, $READ, $$RBYT or $$RCH0 also
     have an error code in ac(T1) so that the caller may treat  endfile  as
     an  error  if  he wishes.  The UUO codes are given in Appendix E.  The
     error  code  range  is   an   extension   of   the   range   for   DEC
     LOOKUP/ENTER/RENAME  errors.  DEC error codes, ERxxx%, range from 0 to
     27.  The IOLIB codes, ERxxx$, range from -1 to -11,  and  include  the
     error  bits in the IO status word, endfile, restricted device, unknown
     error and others.  In addition, the IOLIB  $OPEN,  $INPUT  and  $OUTPU
     routines  can  generate  some of the ERxxx% codes, when the message is
     appropriate.  The ERxxx$ codes are discussed in Appendix E.

          The routines, $FTLIO and $WRNIO, are called with the  error  code
     in  ac(T1)  and the pointer to the offending FDB in ac(D).  They write
     the entire error message.  If the error file  was  the  one  with  the
     error,  then  the routines use the job's terminal instead of the error
     file.

          The $FTLIO and $WRNIO routines may be called through  the  FATAL$
     and WARN$ macros.  The call uses only one word of inline code.



     9.8  SYNTAX ERROR REPORTING

          Some of the IOLIB formatted read routines  detect  syntax  errors
     while  they  are  scanning  the  input string.  These routines have an
     error return, and return an error code in ac(T1) and the  error  value
     in  ac(T2).   The  routines $FTLSY and $WRNSY process these values and
     write error messages from them.

          The $FTLSY and $WRNSY routines may be called through  the  $FATAL
     and WARN$ macros.  The call uses only one word of inline code.
ERROR REPORTING                                                    Page 9-7
$$FERR - FATAL ERROR TRAP ROUTINE


     9.9  $$FERR - FATAL ERROR TRAP ROUTINE

          The error reporter, $ERROR, transfers control to a routine called
     $$FERR  after  writing  any fatal error message.  $$FERR may be a user
     written routine or it may be the standard  routine  from  IOLIB.   The
     standard  $$FERR  merely  tidies  up and returns to monitor mode;  the
     exact code is reproduced below.  A user written $$FERR might  do  more
     tidying  up  before  returning  to  monitor mode, or might be the same
     location as the program start  address  so  that  the  program  starts
     again,  or might execute some of the same code as the user's control-C
     intercept routine.  In any case, the user must have an INTERNal symbol
     called $$FERR if he writes his own code.

     The code of IOLIB's $$FERR reads:

     $$FERR::
             CLRBFI                  ;clear job's terminal input
             MONRT$                  ;return to monitor mode
             HRRZ    T1,.JBSA        ;load program start address
             JUMPN   T1,(T1)         ;restart program if possible
             EXIT                    ;curses! Thwarted











                                CHAPTER 10

                             UTILITY ROUTINES



     10.1  GENERAL DESCRIPTION

          'Utility Routines' is a convenient heading for all those routines
     that  do  not  fall  into  any  other  category,  and  do  not  form a
     sufficiently numerous or important class to merit a chapter  on  their
     own.



     10.2  $MATCH - MATCH A SIXBIT NAME WITH A TABLE

          $MATCH accepts a SIXBIT name as input and the IOWD address  of  a
     table  of  SIXBIT  names.   The  routine  searches  through  the table
     linearly.  If the first character of the table name is  '*',  and  the
     second  charater  matches  the argument name, then the match is found.
     Otherwise the whole name may match, or the  whole  argument  name  may
     match  the  first n characters of the table name or there is no match.
     If the whole name matches, the search  terminates.   If  there  is  no
     match,  the  search continues.  If there is a partial match, the index
     is remembered and the search continues.  If there  is  no  match,  the
     routine  gives  an  error  return with ac(T1)<0.  If there are several
     partial matches, error return with ac(T1)=0.  Otherwise normal return,
     with  the  index in ac(T1), and ac(T1)<0 for partial match, and =0 for
     exact match.











                                CHAPTER 11

                                 EXAMPLES



     11.1  FORMATTED IO


     To read two numbers and add them together:

             TITLE   ADDTWO - ADD TWO NUMBERS TOGETHER
             SUBTTL  ROB COOK
      
             SEARCH  C,IO            ;
      
     ADDTWO:
             BEGIN$                  ;initialise
      
             WTEXT$  <First number: >
             RDECL$                  ;read number
             JUMPG   T1,ERRCHR       ;error if not endline
             MOVE    G1,T2           ;save number
             WTEXT$  < and the second: >
             RDECL$                  ;read number
             JUMPG   T1,ERRCHR       ;again, error unless endline
             ADD     G1,T2           ;add two numbers
             WLINE$  <Now ADDTWO performs its amazing feat....>
             WTEXT$  <....and the answer is: >
             MOVE    T1,G1           ;load number
             WDECL$
             WCRLF$                  ;endline
             MONRT$                  ;exit
             JRST    ADDTWO          ;start again
      
     ERRCHR: ;here to report errors and start again
      
             MOVE    T2,T1           ;set up value for error message
             WARN$   <Illegal character>,CHAR,ILC
             WLINE$  <...now we have to start everything again.>
             JRST    ADDTWO
             END     ADDTWO
EXAMPLES                                                          Page 11-2
COPY A FILE TO THE LPT:


     11.2  COPY A FILE TO THE LPT:


             TITLE   COPLPT - COPY A FILE TO THE LPT
             SUBTTL  ROB COOK
      
             SEARCH  C,IO            ;
      
     COPLPT:
             BEGIN$                  ;as always
      
     COP10:  ;loop here to copy each character
      
             MOVEI   D,INPFDB        ;set input FDB
             RBYTE$                  ;read next character
               JRST  ENDFIL          ;end of file
             MOVEI   D,LPTFDB        ;set LPT FDB
             WBYTE$                  ;write character
             JRST    COP10           ;loop back
      
     ENDFIL: ;here at endfile
      
             RLEAS$                  ;release input file
             MOVEI   D,LPTFDB        ;LPT FDB
             WCHAR$  .CHFFD          ;send formfeed
             RLEAS$                  ;release LPT
             TRMFD$                  ;tell user good news
             WLINE$  <All done>
             MONRT$                  ;back to monitor
             JRST    COPLPT          ;start again
      
     INPFDB: ;input FDB (SYS:NOTICE.TXT e.g.)
      
             FDESC$  SYS,NOTICE,TXT
      
     LPTFDB: ;LPT FDB
      
             FDESC$  LPT
             END     COPLPT



     11.3  SUBROUTINE TO READ A FILENAME


     This subroutine takes an FDB point as input and reads a filename  into
     that  FDB.   If  the  filename  was null, the routine asks for another
     name.  If the name was wild, the routine prints an error  message  and
     asks again.  If the delimiter was not endline it does the same.

     READFN::
             PUSH    P,T1            ;save FDB point
      
     RFN10:  ;here to reread a filename after error
      
EXAMPLES                                                          Page 11-3
SUBROUTINE TO READ A FILENAME


             MSGFD$                  ;load message FDB point
             WTEXT$  <File: >
             CMDFD$                  ;load command FDB point
             SETZ    T1,             ;no switch table
             MOVE    T2,(P)          ;recover FDB point
             RFILE$  T1              ;read filename
               JRST  SYNERR          ;syntax error
             JUMPG   T1,ILCHAR       ;endline is ok
             TXNE    T2,FF$NUL       ;null specification?
             JRST    RFN10           ;yes, reask question
             TXNN    T2,FF$WLD       ;any wildcards?
             PJRST   $XOPJ##         ;return popping stack
      
             ;wild character in file spec.
      
             WARN$   <Wild characters illegal>,FILE,WCI,SYNTAX
             JRST    RFN10           ;try again
      
     ILCHAR: ;illegal character
      
             MOVE    T2,T1           ;setup character as value
             WARN$   <Illegal character>,CHAR,ILC,SYNTAX
             JRST    RFN10           ;try again
      
     SYNERR: ;syntax error
      
             WARN$   ,SY
             JRST    RFN10           ;try again












                                                            APPENDIX A

                                                    LIST OF ALL IOLIB ROUTINES



          This appendix lists all the IOLIB routines in several categories.  If a category contains some critical  routines,  these
     are  listed  before  the  rest  separated  from  them  by  a  line.   Otherwise, within a category, the routines are listed in
     alphabetical order.

          The columns in the table are mostly self-explanatory.  The 'DI' column indicates whether the routine requires that  ac(D)
     points to the current file and/or ac(I) points to the IDB.  If the 'size' column contains a name instead of a number of words,
     then the routine is an entry point to the named routine.  Many routines are in IOMOD, the basic IO module.  The  current  size
     of  IOMOD  is 360 words long.  Note that all sizes are given in decimal.  If the 'section' column is empty, then this appendix
     is the defining and only mention of that routine.


                                                                                                       Acs        Size
     Routine    Macro    DI                  Description                                            destroyed    (words)  Section
     =======    =====    ==                  ===========                                            =========    =======  =======


     A.1 Basic IO Routines
     --- ----- -- --------
     $APDWT    APDWT$    D    open the current file for appending. If the file is being modified    T1             5         6.21
                              wait for a given period before giving up.
                              Inputs:  T1 : sleep seconds,,number of sleeps
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : bytes free in block (o.k. only)
                                       T1 : IO error code (error only)

     $APEND    APEND$    D    open the current file for appending, including setting the buffer     T1             21        6.22
                              pointer for buffered modes. $APEND will not work correctly for files
                              with more liberal protections.
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : bytes free in block (o.k. only)
                                       T1 : IO error code (error only)

     $CLOSE    CLOSE$    D    execute a CLOSE UUO for the current file.  All CLOSE bits are zeroed. T1             IOMOD     6.7
                              Inputs:  taken from FDB

     $CLOS0    CLOSE$    D    as $CLOSE but allow caller to set CLOSE bits                          T1             IOMOD     6.7
                              Inputs:  T1 : CLOSE bits

     $DELET    DELET$    DI   delete the current file                                               none           IOMOD     6.10
LIST OF ALL IOLIB ROUTINES                                                                                                  Page A-2


                              Returns: error : non-skip (LOOKUP or RENAME failure)
                                       o.k.  : skip
                              Outputs: T1 : IO error code (error only)

     $DLBUF    DLBUF$    DI   return a buffer ring to the memory manager                            T1             IOMOD     6.18
                              Inputs:  T1 : point to buffer header

     $ENTER    ENTER$    DI   execute an ENTER UUO on the current file                              T1             IOMOD     6.5
                              Inputs:  taken from FDB
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : IO error code (error only)

     $ENTE0    ENTER$    DI   as $ENTER, but allow the caller to set the protection and create      T1             IOMOD     6.5
                              date/time.

     $FRCHN    FRCHN$         find the first free channel starting with a given channel             T1             IOMOD      
                              Inputs:  T1 : starting channel
                              Returns: none free : non-skip
                                       o.k.      : skip
                              Outputs: T1 : channel number

     $GETST    GETST$    D    get the IO status halfword for the current file                       T1             IOMOD     6.12
                              Outputs: T1 : status halfword (rh)

     $LUKUP    LUKUP$    DI   execute a LOOKUP on the current file                                  T1             IOMOD     6.4
                              Inputs:  taken from FDB
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : IO error code (error only)

     $INPUT    INPUT$    DI   read a physical record from the current file.                         T1             IOMOD     6.2
                              Inputs:  taken from FDB
                              Returns: error   : non-skip
                                       endfile : skip
                                       o.k.    : double-skip

     $MKBUF    MKBUF$    DI   create a ring of buffers for the current file.  The size and number   T1             IOMOD     6.17
                              of the buffers is taken from $FDBUF.
                              Inputs:  T1 : point to buffer header
                                       $FDBUF(D)
                              Returns: no core : non-skip
                                       o.k.    : skip
                              Outputs: T1 : 0,,ERNEC% (error only)

     $MTxxx    MTxxx$    D    execute an MTAPE UUO for the current file. 'xxx' can be any of the    T1             35        6.23
                              codes for MTAPE functions: e.g. MTREW$, MTBSF$. All functions wait
                              for completion using MTWAT$.  MTBSF$ skips over EOF unless at BOT.

     $OPEN     OPEN$     DI   execute an OPEN UUO for the current file.  If the caller does not     T1             IOMOD     6.6
                              specify a channel number, $OPEN chooses the 1st free channel.
                              Inputs:  taken from FDB
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : IO error code (error only)
LIST OF ALL IOLIB ROUTINES                                                                                                  Page A-3


     $OUTIN    OUTIN$    DI   write the last physical record read back to the current file.         T1             IOMOD     6.3
                              as $OUTPU, but subtracts 1 from the block number before writing.

     $OUTPU    OUTPU$    DI   write a physical record to the current file                           T1             IOMOD     6.3
                              Inputs:  taken from FDB
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : IO error code (error only)

     $RLEAS    RLEAS$    DI   execute a RELEAS UUO for the current file. Return all buffers to      T1             IOMOD     6.8
                              the heap.
                              Inputs:  taken from FDB

     $RLEA0    RLEAS$    DI   as $RLEAS, but don't return rings to memory manager                   T1             IOMOD     6.8

     $RENAM    RENAM$    DI   change the name and/or other details of the current file              T1             IOMOD     6.9
                              The file must have been opened.
                              Inputs:  taken from FDB
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: IO error code (error only)

     $SETST    SETST$    D    set the status halfword for the current file                          T1             IOMOD     6.13
                              Inputs:  T1 : 0,,status halfword

     $UPDAT    UPDAT$    DI   open the current file for updating                                    T1             7         6.19
                              Returns: error : non-skip (LOOKUP or ENTER failure)
                                       o.k.  : skip
                              Outputs: T1 : IO error code (error only)

     $UPDWT    UPDWT$    DI   open the current file in update mode. If the file is being modified   T1             17        6.20
                              wait for a given period before giving up.
                              Inputs:  T1 : sleep seconds,,number of sleeps
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : IO error code (error only)

     $USETI    USETI$    DI   position the current file to a given physical record for input        T1             IOMOD     6.11
                              This routine is only effective for disk.
                              Inputs:  T1 : last record number,,this record number

     $USETO    USETO$    D    position the current file to a given physical record for output       T1             IOMOD     6.11
                              This routine is only effective for disk.
                              Inputs:  T1 : last record number,,this record number

     $XTCAL    XTCAL$    D    execute a CALLI UUO for the current file, setting physical-only       T1             IOMOD     6.15
                              if required
                              Inputs:  T1 : UUO
                                       T2 : argument
                              Returns: non-skip : non-skip
                                       skip     : skip

     $XTDCL    XTDCL$    D    execute a device dependent CALLI UUO for the current file.            T1             IOMOD     6.16
                              As $XTCLI, but set DSK if no device given.

     $XTUUO    XTUUO$    D    execute a UUO for the current file                                    none           IOMOD     6.14
LIST OF ALL IOLIB ROUTINES                                                                                                  Page A-4


                              Inputs:  T1 : UUO (without channel number)
                              Returns: non-skip : non-skip
                                       skip     : skip
LIST OF ALL IOLIB ROUTINES                                                                                                  Page A-5


                                                                                                       Acs        Size
     Routine    Macro    DI                  Description                                            destroyed    (words)  Section
     =======    =====    ==                  ===========                                            =========    =======  =======


     A.2 Formatted Read Routines
     --- --------- ---- --------

     $READ     READ$     DI   read one byte from the current file                                   T1             16        7.5
                              Returns: error   : non-skip
                                       endfile : skip
                                       o.k.    : double-skip
                              Outputs: T1 : byte, right-justified (o.k. only)
                                          : IO-error-code (error and endfile only)

     $$RBYT    RBYTE$    DI   read one byte from the current file.  Fatal errors go to $FTLIO.      T1             4         7.6
                              Returns: endfile : non-skip
                                       o.k.    : skip
                              Outputs: T1 : byte, right-justified  (o.k. only)
                                          : IO-error-code (endfile only)

     $$RCH0              DI   read a character from the current file.  Fatal errors goto $FTLIO.    T1             1         7.7
                              Returns: endfile : non-skip
                                       o.k.    : skip
                              Outputs: T1 : character, right justified (o.k. only)
                                          : IO error code (endfile only)

     $$RCHR    RCHAR$    DI   read a character from the current file and interpret it as            T1             1         7.8
                              command character.
                              Outputs: T1 : character, right justified or endline indicator
                                            (0 : ALT, -1 : EOL, -2 : EOF)

     -------------------------------------------------------------------------------------------------------------------------

     $RANCH    RANCH$    DI   read one character from the current file and test whether it is       T1-T4          8          
                              alphanumeric.
                              Returns: not alphanumeric : non-skip
                                       alphanumeric     : skip
                              Outputs: T1 : character

     $RANC0    RANCH$    DI   as $RANCH, but the character has already been read                    T1             $RANCH     
                              Note: this routine can be used to check whether a character is
                              alphanumeric.
                              Inputs:  T1 : character

     $RCASH    RCASH$    DI   read a cash value in dollars and cents from the current file.         T1-T4          29         
                              The string may appear as '$dddd.cc' with or without the '$'.
                              If there is no '.' or '$', the number is assumed to be cents.
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : delimiting character (o.k. only)
                                          : syntax error code (error only)
                                       T2 : value in cents

     $RCAS0    RCASH$    DI   as $RCASH but leading character already read                          T1-T4          $RCASH     
                              Inputs:  T1 : character
LIST OF ALL IOLIB ROUTINES                                                                                                  Page A-6


     $RCALT              DI   as $RCCHR, but check first if last character was altmode, and if so,  T1             $RCCHR    7.10
                              return $CHALX without reading another character
                              Outputs: T1 : character

     $RCCHR              DI   read a character from the current file as a command character which   T1             70        7.10
                              means that a certain amount of editing is done, to wit:
                                  the editing done by $REDCH
                                  leading spaces on a line are deleted
                                  multiple spaces are compressed
                                  trailing spaces are deleted
                                  comments are ignored
                                  '-' followed by <lf> is ignored (continuation line)
                              Outputs: T1 : character

     $RDATE    RDATE$    DI   read the date from the current file in the format 'dd-mmm-yy'         T1-T4          37         
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : delimiting character (o.k. only)
                                          : syntax error code (error only)
                                       T2 : date in internal format

     $RDAT0    RDATE$    DI   as $RDATE but leading character already read                          T1-T4          $RDATE     
                              Inputs:  T1 : character

     $RDECL    RDECL$    DI   read a signed decimal number from the current file.  If the 1st       T1-T4          17         
                              character is '#' read the rest as an octal number. The '#' may also
                              follow the sign.
                              Outputs: T1 : delimiting character
                                       T2 : number

     $RDEC0    RDECL$    DI   as $RDECL but leading character already read                          T1-T4          $RDECL     
                              Inputs:  T1 : character

     $RDECM    RDECM$    DI   read a decimal number (+ possible multiplier) from the current        T1-T4          3          
                              file. The number is as $RDECL, but may have a multiplier, 'K' kilo,
                              'M' mega or 'G' giga. Note that 1K = 1000, not 1024.
                              Outputs: T1 : delimiting character
                                       T2 : number

     $RDCM0    RDECM$    DI   as $RDECM but leading character already read                          T1-T4          $RDECM     
                              Inputs:  T1 : character

     $RDVIC    RDVIC$    DI   read a device name from the current device.  $RDVIC insists on a      T1-T3          14         
                              terminating ':'. Null names are forbidden.
                              Returns: error : nonskip
                                       o.k.  : skip
                              Outputs: T1 : delimiting character (o.k. only)
                                          : syntax error code (error only)
                                       T2 : device name in SIXBIT

     $RDVI0    RDVIC$    DI   as for $RDVIC but enter with the leading character already read       T1-T4          $RDVIC     
                              Inputs:  T1 : ASCII character

     $REDCH    REDCH$    DI   read a character from the current file and perform some basic         T1             24        7.9
                              editing:
                                  endfile is converted to ^Z
LIST OF ALL IOLIB ROUTINES                                                                                                  Page A-7


                                  <CR>, <DEL>, & <NUL> are ignored
                                  <TAB> is converted to <SP>
                                  <VT> & <FF> are converted to <LF>
                                  <LF> is converted to -1
                                  <ESC> is converted to 0
                                  ^C and ^Z are converted to -2
                              Outputs: T1 : character

     $REDC0    REDCH$    DI   as $REDCH but the character has already been read                     T1             $REDCH    7.9
                              Inputs:  T1 : character

     $RFILE    RFILE$    DI   read a filename from the current file.  The filename may              T1-T4          170       7.11
                              contain wild characters, and may include standard switches and
                              switches defined by the caller.  $RFILE remembers and applies
                              sticky parts of filenames.
                              Returns: error : nonskip
                                       o.k.  : skip
                              Outputs: T1 : delimiting character (o.k. return)
                                          : syntax error code (error return)
                                       T2 : flags,,point to FDB containing file details

     $RFIL0    RFILE$    DI   as for $RFILE, but the FDB and the user switches may be given         T1-T4          $RFILE    7.11
                              Inputs:  T1 : point to switch tables
                                       T2 : length,,point to FDB

     $RKWRD    RKWRD$    DI   read a Kword value from the current file in the format 'nnnx', where  T1-T4          11         
                              x maybe 'K' or 'P' or blank. e.g. 20P, 13K, 128.
                              Default is K.
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : delimiting character (o.k. only)
                                          : syntax error code (error only)
                                       T2 : value in words

     $RKWR0    RKWRD$    DI   as $RKWRD but leading character already read                          T1-T4          $RKWRD     
                              Inputs:  T1 : character

     $RNAME    RNAME$    DI   read an alphanumeric word from the current file. Only the 1st         T1-T4          11         
                              6 characters are remembered.
                              Outputs: T1 : delimiting character
                                       T2 : word of SIXBIT characters

     $RNAM0    RNAME$    DI   as $RNAME but leading character already read                          T1-T4          $RNAME     
                              Inputs:  T1 : charatcer

     $ROCTL    ROCTL$    DI   read a signed octal number from the current file.  If the number      T1-T4          17         
                              terminates with a period, treat the number as if it had been decimal.
                              Outputs: T1 : delimiting character
                                       T2 : number

     $ROCT0    ROCTL$    DI   as $ROCTL but leading character already read                          T1-T4          $ROCTL     
                              Inputs:  T1 : character

     $ROCTM    ROCTM$    DI   read an octal number (+ possible multiplier) from the current         T1-T4          3          
                              file. The number is as $ROCTL, but may have a multiplier, 'K' kilo,
                              'M' mega or 'G' giga. Note that 1K = 1000 octal or 512 decimal.
LIST OF ALL IOLIB ROUTINES                                                                                                  Page A-8


                              Outputs: T1 : delimiting character
                                       T2 : number

     $ROCM0    ROCTM$    DI   as $ROCTM but leading character already read                          T1-T4          $ROCTM     
                              Inputs:  T1 : character

     $RPATH    RPATH$    DI   read a path specification from the current file.  The spec. may       T1-T4          49        7.12
                              contain wild numbers and SFDs.
                              Returns: error : nonskip
                                       o.k.  : skip
                              Outputs: T1 : delimiting character (o.k. only)
                                            syntax error code (error only)
                                       T2 : PPN or point to path spec. block
                                       T3 : PPN mask or point to path mask block
                                       T4 : flags

     $RPAT0    RPATH$    DI   as $RPATH but enter with leading '[' already read                     T1-T4          $RPATH    7.12
                              Inputs:  T1 : ASCII character

     $RPJPG    RPJPG$    DI   read a project-programmer pair from the current file (no []).         T1-T4          43        7.12
                              Both project and programmer may be wild.
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : delimiting character (o.k. only)
                                          : syntax error code (error only)
                                       T2 : PPN
                                       T3 : wildcard mask
                                       T4 : flags

     $RPJP0    RPJPG$    DI   as $RPJPG but leading character already read.                         T1-T4          $RPJPG    7.12
                              Inputs:  T1 : character

     $RPPN     RPPN$     DI   read a PPN in the form [PPN] from the current device.  The PPN        T1-T4          12        7.12
                              may be wild.
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : delimiting character (o.k. only)
                                            syntax error code (error only)
                                       T2 : PPN
                                       T3 : wildcard mask
                                       T4 : flags

     $RPPN0    RPPN$     DI   as $RPPN but leading '[' already read                                 T1-T4          $RPPN     7.12
                              Inputs:  T1 : character

     $RREAL    RREAL$    DI   read a signed floating point number from the current file.            T1-T4          39         
                              The number may have a signed exponent as Esnn.
                              Outputs: T1 : delimiting character
                                       T2 : number

     $RREA0    RREAL$    DI   as $RREAL but leading character already read                          T1-T4          $RREAL     
                              Inputs:  T1 : character

     $RSWIT    RSWIT$    DI   read a switch spec. from the current file in the form                 T1-T4          122       7.13
                              '/name:value', where the name is a switch name either defined by the
                              caller, or a standard name, and the value is optional and may be in
LIST OF ALL IOLIB ROUTINES                                                                                                  Page A-9


                              one of a number of predefined forms.
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : delimiting character (o.k. only)
                                          : syntax error code (error only)

     $RSWI0    RSWIT$    DI   as $RSWIT but leading '/' already read                                T1-T4          $RSWIT    7.13
                              Inputs:  character

     $RTDAY    RTDAY$    DI   read a date and time from the current file in the format              T1-T4          16         
                              'dd-mmm-yy hh:mm:ss'.  Either date or time may be omitted. 
                              Assumptions are today, and midnight.
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : delimiting character
                                          : syntax error code (error only)
                                       T2 : time in milliseconds
                                       T3 : date in internal format

     $RTDA0    RTDAY$    DI   as $RTDAY but leading character already read                          T1-T4          $RTDAY     
                              Inputs:  T1 : character

     $RTIME    RTIME$    DI   read the time from the current file in the format 'hh:mm:ss'          T1-T4          22         
                              Trailing fields may be omitted.
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : delimiting character (o.k. only)
                                          : syntax error code (error only)
                                       T2 : time in milliseconds

     $RTIM0    RTIME$    DI   as $RTIME but leading character already read                          T1-T4          $RTIME     
                              Inputs:  T1 : character

     $RUCCH    RUCCH$    DI   read a character from the current file and convert lower case         T1             6          
                              alphabetics to upper case.
                              Note: this routine may be called to convert a character to upper case.
                              Outputs: T1 : character

     $RUCC0    RUCCH$    DI   as $RUCCH but character already read                                  T1             $RUCCH     
                              Inputs:  T1 : character

     $RWNAM    RWNAM$    DI   read a name from the current file, where the name can include         T1-T4          65         
                              wildcards.  The name is treated as alphanumeric and converted to
                              SIXBIT unless the leading character is '#' when it is octal with a
                              possible multiplier, and is converted to binary.
                              Outputs: T1 : delimiting character
                                       T2 : word (SIXBIT or binary)
                                       T3 : wildcard mask
                                       T4 : flags

     $RWNA0    RWNAM$    DI   as $RWNAM but leading character already read                          T1-T4          $RWNAM     
                              Inputs:  T1 : character

     $RWNUM    RWNUM$    DI   as $RWNAM, but octal is assumed unless the 1st character is alpha.    T1-T4          $RWNAM     

     $RWNU0    RWNUM$    DI   as $RWNUM but leading character already read                          T1-T4          $RWNAM     
LIST OF ALL IOLIB ROUTINES                                                                                                 Page A-10


                              Inputs:  T1 : character

     $RWORD    RWORD$    DI   read a word of characters from the current file delimited by <SP> or  T1-T4          12         
                              any non-SIXBIT character. Only the 1st 6 characters are remembered
                              Outputs: T1 : delimiting character
                                       T2 : word of SIXBIT characters

     $RWOR0    RWORD$    DI   as $RWORD, but leading character already read                         T1-T3          $RWORD     
                              Inputs:  T1 : character
LIST OF ALL IOLIB ROUTINES                                                                                                 Page A-11


                                                                                                       Acs        Size
     Routine    Macro    DI                  Description                                            destroyed    (words)  Section
     =======    =====    ==                  ===========                                            =========    =======  =======


     A.3 Formatted Write Routines
     --- --------- ----- --------

     $WRITE    WRITE$    DI   write one byte to the current file.                                   T1             14        7.2
                              Inputs:  T1 : byte, right-justified
                              Returns: error : non-skip
                                       o.k   : skip
                              Outputs: T1 : IO-error-code (error return only)

     $$WBYT    WBYTE$    DI   write one byte to the current file.  Fatal errors go to $FATAL.       T1             1         7.3
                              Inputs:  T1 : byte, right justified

     $$WCHR    WCHAR$    DI   write one character to the current file.  Fatal errors go to $FATAL.  T1             $$WBYT    7.4
                              Inputs:  T1 : ASCII character, right justified

     -------------------------------------------------------------------------------------------------------------------------

     $WADDR    WADDR$    DI   write the contents of a halfword (e.g. an address) as 6 octal         T1-T3          7          
                              digits, zero filled
                              Inputs:  T1 : binary halfword (rh)

     $WBWRD    WBWRD$    DI   write a number as blocks (128 words) rounded up                       T1-T3          $WWWRD     
                              Inputs:  T1 : number of words

     $WCASH    WCASH$    DI   write a sum in dollars and cents in the format '$ddddd.cc'            T1-T3          15         
                              Inputs:  T1 : value in cents

     $WCRLF    WCRLF$    DI   write a <cr><lf>                                                      none           5          
                              Inputs:  none

     $WCWRD    WCWRD$    DI   write a number as a number of words of core choosing kwords or words  T1-T3          $WWWRD     
                              Inputs:  T1 : number of words

     $WDATE    WDATE$    DI   write a date in the format 'dd-mmm-yy'                                T1-T3          15         
                              Inputs:  T1 : date in internal form

     $WDECL    WDECL$    DI   write a number in decimal                                             T1-T3          $WRADX     
                              Inputs:  T1 : number

     $WDNOW    WDNOW$    DI   write the date today in the format 'dd-mmm-yy'                        T1-T3          $WDATE     
                              Inputs:  none

     $WDVIC    WDVIC$    DI   write a device name to the current file as 'nnn:'                     T1-T2          3          
                              Inputs:  T1 : device name in SIXBIT

     $WFCHA    WFCHA$    DI   write a character exactly, by flagging control characters with ^,     T1-T3          34         
                              lower case characters with ', and naming special control characters.
                              e.g. ^A, 'Z, <BEL>
                              Inputs:  T1 : ASCII character, right justified

     $WFILE    WFILE$    DI   write a filename to the current file                                  T1-T2          22         
LIST OF ALL IOLIB ROUTINES                                                                                                 Page A-12


                              Inputs:  T1 : pointer to FDB containing filename

     $WKWRD    WKWRD$    DI   write a number as Kwords rounded up                                   T1-T3          $WWWRD     
                              Inputs:  T1 : number of words

     $WNAME    WNAME$    DI   write a name which maybe in XWD format                                T1-T2          3          
                              Inputs:  T1 : name in SIXBIT

     $WOCTL    WOCTL$    DI   write a number in octal                                               T1-T3          $WRADX     
                              Inputs:  T1 : number

     $WPATH    WPATH$    DI   write a path specification in []s                                     T1-T3          18         
                              Inputs:  T1 : PPN or pointer to PATH. UUO block

     $WPWOR    WPWOR$    DI   write a character followed by a word of SIXBIT characters             T1-T2          $WWORD     
                              Inputs:  T1 : ASCII prefix character
                                       T2 : word of SIXBIT characters

     $WPWRD    WPWRD$    DI   write a core size in pages rounded up                                 T1-T3          $WWWRD     
                              Inputs:  T1 : size in words

     $WRADX    WRADX$    DI   write an integer in a given radix                                     T1-T3          18         
                              Inputs:  T1 : number
                                       T2 : radix

     $WREAL    WREAL$    DI   write a word as a floating point number (F format if                  T1-T4          54         
                              0.1 .le. n .ge. 1.0 and E format otherwise)
                              Inputs:  T1 : number

     $WTDAY    WTDAY$    DI   write a time and date in format 'hh:mm:ss dd-mmm-yy'                  T1-T3          6          
                              Inputs:  T1 : time in milliseconds
                                       T2 : date in internal format

     $WTDNW    WTDNW$    DI   write the time and date now (i.e. write a timestamp)                  T1-T3          4          
                              Inputs:  none

     $WTEXT    WTEXT$    DI   write a text string to the current file                               T1             9          
               WLINE$         Inputs:  T1 : pointer to ASCIZ text string

     $WTIME    WTIME$    DI   write a time in hours and minutes 'hh:mm'                             T1-T3          8          
                              Inputs:  T1 : time in milliseconds

     $WTIMS    WTIMS$    DI   write a time accurate to seconds 'hh:mm:ss'                           T1-T3          9          
                              Inputs:  T1 : time in milliseconds

     $WTMTS    WTMTS$    DI   write a time accurate to tenths of a second 'hh:mm:ss.t'              T1-T3          8          
                              Inputs:  T1 : time in milliseconds

     $WTNOW    WTNOW$    DI   write the time now as 'hh:mm:ss'                                      T1-T3          $WTIMS     
                              Inputs:  none

     $WVERS    WVERS$    DI   write out all fields of a version number in standard format           T1-T3          25         
                              Inputs:  T1 : version number

     $WWORD    WWORD$    DI   write out a word as 6 SIXBIT characters                               T1-T2          7          
                              Inputs:  T1 : word of SIXBIT characters
LIST OF ALL IOLIB ROUTINES                                                                                                 Page A-13


     $WWWRD    WWWRD$    DI   write a number as a number of words e.g. 123W                         T1-T3          18         
                              Inputs:  T1 : number of words

     $WXWD     WXWD$     DI   write a word as two halfwords, blank filled, separated by ,           T1-T3          8          
                              Inputs:  T1 : word

     $W2FIL    W2FIL$    DI   write a 2 digit number with a given fill character                    T1-T3          8          
                              Inputs:  T1 : number
                                       T2 : ASCII fill character

     $W2FLB    W2FLB$    DI   write a number in 2 digits filled with a space                        T1-T3          $W2FIL     
                              Inputs:  T1 : number

     $W2FL0    W2FL0$    DI   write a number in 2 digits filled with a zero                         T1-T3          $W2FIL     
                              Inputs:  T1 : number
LIST OF ALL IOLIB ROUTINES                                                                                                 Page A-14


                                                                                                       Acs        Size
     Routine    Macro    DI                  Description                                            destroyed    (words)  Section
     =======    =====    ==                  ===========                                            =========    =======  =======


     A.4 Core Management Routines
     --- ---- ---------- --------

     $$ALLC    ALLOC$    I    allocate a block of free core. This routine exists to decide between  T1             2         5.1
                              dynamic and static core allocation.
                              Inputs:  T1 : number of words required
                              Returns: no core : non-skip
                                       o.k.    : skip
                              Outputs: T1 : point to word 1 of allocated block (o.k. only)
                                          : 0,,ERNEC% (error only)

     $$DALC    DEALC$    I    deallocate a block of core by returning it to the pool of             T1             $$ALLC    5.1
                              free blocks
                              Inputs:  T1 : point to word 1 of core block

     --------------------------------------------------------------------------------------------------------------------------

     $CRGET              I    allocate a block of core from above .JBFF, by moving .JBFF and        T1             17        5.3
                              obtaining more core from the monitor if need be.
                              Inputs:  T1 : size of chunk required
                              Returns: no core : non-skip
                                       o.k.   : skip
                              Outputs: T1 : point to 1st word of chunk (o.k. only)
                                          : 0,,ERNEC% (error only)

     $CRREL              I    it is not possible to deallocate a chunk using static management.     none           $CRGET    5.3
                              This call is a noop.

     $HPGET              I    allocate a block of core from a linked list of free chunks of core.   T1             108       5.2
                              If there is insuffient space, first garbage collect the list and then
                              get more space from the monitor.
                              Inputs:  T1 : size of chunk required or 0 for largest available
                              Returns: no core : non-skip
                                       o.k.   : skip
                              Outputs: T1 : point to 1st word of chunk
                                          : 0,,ERNEC% (error only)

     $HPREL              I    deallocate a chunk (or chunks) of core by linking it back into        T1             $HPGET    5.2
                              the chain of free chunks.  Several chunks may be deallocated together
                              chaining them through their -1th word.
                              Inputs:  T1 : point to 1st word of chunk
LIST OF ALL IOLIB ROUTINES                                                                                                 Page A-15


                                                                                                       Acs        Size
     Routine    Macro    DI                  Description                                            destroyed    (words)  Section
     =======    =====    ==                  ===========                                            =========    =======  =======


     A.5 Data Block Manipulation Routines
     --- ---- ----- ------------ --------

     $CLRFD    CLRFD$    I    create a new standard length FDB, clear it, set the length in $FDCNT  T1             20         
               MAKFD$         and initialise $FDBFR and $FDSNC to -1.
                              Returns: no core : non-skip
                                       o.k.    : skip
                              Outputs: T1 : point to FDB (o.k. only)
                                          : 0,,ERNEC% (error only)

     $CLRF0    CLRFD$    I    as $CLRFD, but allow caller to specify address and/or length of FDB   T1             $CLRFD     
                              If the address is given, the old FDB is used.
                              Inputs:  T1 : length,,address of FDB

     $INIID              I    clear the IDB, set the verbosity to standard, set MAXCOR to all core  I              10+19      
                              and set the last command character to endline. This routine contains
                              the IDB.

     $LOSFD    LOSFD$    I    deallocate the space occupied by an FDB.  If $FDPPN points to a path  T1             7          
                              block, the path block is deallocated also. This routine only
                              succeeds if dynamic core management is used.
                              Inputs:  T1 : point to 1st word of FDB

     $PATCH                   patch area loaded if FT$DBG is on                                     none           0+200      

     $STACK                   pushdown stack and pointer thereto                                    none           1+100     3.8
LIST OF ALL IOLIB ROUTINES                                                                                                 Page A-16


                                                                                                       Acs        Size
     Routine    Macro    DI                  Description                                            destroyed    (words)  Section
     =======    =====    ==                  ==========                                             =========    ======   =======


     A.6 Tempcore Routines
     --- -------- --------

     $TMPDL    TMPDL$    DI   delete a tempcore file from core and/or disk                          T1-T3          13        8.4
                              It is not an error if the file does not exist.
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : IO error code (error only)

     $TMPFD    TMPFD$         create an FDB for a tempcore file given a 3 character name            T1-T4          17        8.2
                              The name of the file is nnnccc.TMP, where 'nnn' is the job number
                              and 'ccc' is the 3 character name.
                              Inputs:  T1 : 3 SIXBIT characters, right justified
                              Outputs: D  : point to FDB

     $TMPIN    TMPIN$    DI   read 1 block of a tempcore file from core or from disk. If core,      T1-T4          31        8.3
                              set flag FC$TCI to ensure that further calls to $INPUT give endfile
                              return.
                              Inputs:  taken from FDB
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : IO error code (error only)

     $TMPOU    TMPOU$    DI   close off a tempcore file. If the file is not yet ENTERed, try to     T1-T4          19        8.5
                              write the file to tempcore.  If so, or if tempcore fails, write to
                              disk and release channel.
                              Returns: error : non-skip
                                       o.k.  : skip
                              Outputs: T1 : IO error code (error only)
LIST OF ALL IOLIB ROUTINES                                                                                                 Page A-17


                                                                                                       Acs        Size
     Routine    Macro    DI                  Description                                            destroyed    (words)  Section
     =======    =====    ==                  ===========                                            =========    =======  =======


     A.7 Error Routines
     --- ----- --------

     $ADVIS    ADVIS$    I    write an advisory error message. Call as for $ERROR                   T1-T4          $ERROR    9.5
                              Inputs:  as for $ERROR
                              Returns: yes

     $ERROR              I    write an error message to the error file whose point is in $IDEFD(I)  T1-T4          57        9.4
                              Full documentation may be found in section 9.4
                              Inputs:  T1 : message point and flags
                                       T2 : value
                                       T3 : UUO or error type name (optional)
                              Returns: depends; yes if warning, no if fatal

     $FATAL    FATAL$    I    write a fatal error message. Call as for $ERROR.                      T1-T4          $ERROR    9.5
                              Inputs:  as for $ERROR
                              Returns: never; traps to $$FERR

     $FTLIO    FATAL$    DI   write a fatal error message for the current file based on an IO error T1-T4          21        9.7
                              code, returned by basic IO module routines
                              Inputs:  T1 : UUO-code,,error code

     $FTLSY    FATAL$    I    write a fatal error message based on an error code returned by        T1-T4          8         9.8
                              the command scanning subroutines.
                              Inputs:  T1 : syntax error code
                                       T2 : value

     $WARN     WARN$     I    write a warning error message. Call as for $ERROR                     T1-T4          $ERROR    9.5
                              Inputs:  as for $ERROR
                              Returns: yes

     $WRNIO    WARN$     DI   write a warning error message about the current file. A code is       T1-T4          $FTLIO    9.7
                              returned by the routines in the basic IO module.
                              Inputs:  T1 : UUO-code,,error-code

     $WRNSY    WARN$     I    write a warning error about bad syntax, given a code returned         T1-T4          $FTLSY    9.8
                              by the command scanners on error.
                              Inputs:  T1 : syntax error code
                                       T2 : value

     $$FERR                   exit to monitor mode after clearing input buffer. If CONTINUEd,       T1             5         9.9
                              try to start at start address, if fail, exit.
                              Returns:  only to program start address
LIST OF ALL IOLIB ROUTINES                                                                                                 Page A-18


                                                                                                       Acs        Size
     Routine    Macro    DI                  Description                                            destroyed    (words)  Section
     =======    =====    ==                  ===========                                            =========    =======  =======


     A.8 Utility Routines
     --- ------- --------

     $POPJ                    execute a POPJ P, instruction                                         none           IOMOD      

     $POPJ1                   increment the return address and POPJ, thus doing a skip return       none           IOMOD      

     $POPJ2                   double increment the return address and POPJ, thus doing a double     none           IOMOD      
                              skip return. Cannot be used with $SAVEn.

     $TOPJ                    POP the top of the stack into T1 and POPJ return                      T1             IOMOD      

     $TOPJ1                   POP the top of the stack into T1 and skip POPJ return                 T1             IOMOD      

     $TOPJ2                   POP the top of the stack into T1 and double skip POPJ return          T1             IOMOD      
                              Cannot be used with $SAVEn.

     $XOPJ                    POP the top off the stack (to nowhere) and POPJ return                none           IOMOD      

     $XOPJ1                   POP the top off the stack and skip POPJ return                        none           IOMOD      

     --------------------------------------------------------------------------------------------------------------------------

     $RESTT    RESTT$         restore T1-T4 from the stack                                          T1-T4          $SAVET     

     $SAVET    SAVET$         save T1-T4 on the stack                                               none           13         

     $SAVE1    SAVE1$         called on entry to a subroutine to save P1 and to restore P1 on exit  none           IOMOD      
                              The caller is called as a subroutine so that his eventual POPJ
                              returns to $SAVE1 to restore P1.  POPJ and POPJ1 are catered for

     $SAVE2    SAVE2$         as $SAVE1, but P1 and P2 are saved and restored                       none           IOMOD      

     $SAVE3    SAVE3$         as $SAVE1, but P1, P2 and P3 are saved and restored                   none           IOMOD      

     $SAVE4    SAVE4$         as $SAVE1, but P1, P2, P3 and P4 are saved and restored               none           IOMOD      

     --------------------------------------------------------------------------------------------------------------------------

     $BATCH    BATCH$         determine whether the job's terminal is a PTY                         none           6          
                              Returns: not PTY : non-skip
                                       PTY     : skip

     $BEGCC    BEGIn$    DI   initialise a program and set up CCL tempcore input file if entry      T1-T2          10        3.9
                              was at 'start+1'.

     $BEGIN    BEGIN$    DI   initialise a program                                                  T1-T2          5         3.9

     $CLBUF    CLBUF$    DI   clear command input by clearing the TTCALL TTY buffer or by reading   T1             18         
                              to endline.
LIST OF ALL IOLIB ROUTINES                                                                                                 Page A-19


     $CLLIN    CLLIN$    DI   clear the current command input line                                  none           5          

     $CNVNU    CNVNU$         return the universal date/time now                                    T1-T4          $CNVUI     
                              As $CNVIU but uses the date/time from the monitor

     $CNVUI    CNVUI$         convert a date/time in universal format to internal format            T1-T4          102        
                              Inputs:  T1 : universal date,,time
                              Outputs: T1 : time in milliseconds
                                       T2 : date in internal format

     $CNVIU    CNVIU$         convert internal date/time to universal format                        T1-T4          $CNVUI     
                              Inputs:  T1 : time in milliseconds
                                       T2 : date in internal format
                              Outputs: T1 : universal date,,time

     $FDTTY    FDTTY$    DI   check whether the current file is a terminal or not.                  none           6          
                              Returns: not TTY : normal
                                       TTY     : skip

     $MATCH    MATCH$         match a SIXBIT name against a table of names, selecting               T1-T3          36        10.1
                              either an exact match or an unambiguous abbreviation. A name in
                              the table may begin with '*' to say that the first letter is enough
                              to identify this name.
                              Inputs:  T1 : IOWD length,address of table
                                       T2 : SIXBIT name to match
                              Returns: error, no or several matches
                                       o.k.  :skip
                              Outputs: T1 : flag,,table index. lh=0 if exact, lt 0 if not (o.k. only)
                                          : lt 0 : no match; ge 0 :several (error only)

     $MONRT    MONRT$         return to monitor mode by EXIT 1, unless job not logged in. Then      T1             13         
                              use LOGOUT.  Return to caller on 'CONTINUE'.
                              Return:  only if CONTINUE is typed at monitor mode

     $SLEEP    SLEEP$         send the job to sleep for a specified period using HIBER or SLEEP     T1             9          
                              Inputs:  T1 : sleep time in seconds

     $ZERO     ZERO$          zero a chunk of core by BLT                                           none           10         
                              Inputs:  T1 : length,,address











                                                            APPENDIX B

                                                            IOLIB MACROS



          This appendix is a complete list of all IOLIB macros.  The macros are listed  under  several  headings  but  within  those
     headings  the  macros  are listed in alphabetical order.  The macros that are useful in writing the program, rather than macros
     which merely call routines, are listed first.  The macro name is given, along with the names of any routines  called,  a  brief
     description,  the  call,  the  number  of  lines  of  inline code generated, and a further reference.  The descriptions in this
     appendix are not as full as those of the routines in appendix A,  and  the  user  should  refer  to  appendix  A  if  he  needs
     clarification.


                                                                                                                      Inline
     Macro     Routine                  Description                                       Call                         code  Section
     =====     =======                  ===========                                       ====                        ====== =======


     B.1 Programming Macros
     --- ----------- ------

     BEGIN$    $BEGIN    perform all program initialisation including concealed      BEGIN$   tfn                     5         3.9
                         mode entry points, CCL entry points, RESET UUO, stack
                         setup, IDB initialisation and command FDB setup
                         'tfn'  3 character tempcore filename (otherwise program name)

     CMDFD$              set ac(D) to point to the current command file.             CMDFD$                           1          
                         Load ac(D) from $IDIFD(I).

     ERRFD$              set ac(D) to point to the current error file.               ERRFD$                           1          
                         Load ac(D) from $IDEFD(I).

     FDESC$              create an inline FDB and fill it with values                FDESC$   dv,nm,ex,pt,md,ln       $LNFDB+   3.12
                         'dv' device name
                         'nm' file name
                         'ex' extension name
                         'pt' path spec. in <>, e.g. <104,427>
                         'md' IO mode
                         'ln' length of FDB, if longer than standard

     HISEG$              if first call of program, create 'TWOSEG' and               HISEG$                           0         3.11
                         'RELOC 400000' pseudo-ops to start two-segmenting
                         otherwise, if assembling high segment code, do nothing;
                         otherwise, set outstanding literals into low segment
                         and switch segments
IOLIB MACROS                                                                                                                Page B-2


     JBREN$              load .JBREN (reenter address) with the given address        JBREN$   ac,adr                  2          
                         The user may choose the temporary ac.
                         'ac'  temporary ac to be used
                         'adr' reenter address

     JBVER$              set the version number defined by the $$V??? symbols        JBVER$                           0         3.14
                         into .JBVER in DEC format

     LDFD$               move an FDB point into ac(D)                                LDFD$   adr                      1          
                         'adr'  address of FDB point

     LDFDI$              move immediate an FDB point into ac(D)                      LDFDI$   adr                     1          
                         'adr'  FDB point

     LOSEG$              if assembling code into the low segment, do nothing         LOSEG$                           0         3.11
                         otherwise, set all outstanding literals into high
                         segment and switch segments

     MAKFD$              write code to create or initialise an FDB and               MAKFD$   dv,nm,ex,pt,md,ln,ad    5+        3.13
                         fill the FDB with values.
                         'dv'  device name
                         'nm'  file name
                         'ex'  extension name
                         'pt'  path spec. inside <>, e.g. <104,427,SF1>
                         'md'  IO mode
                         'ln'  length of FDB if non-standard
                         'ad'  address of FDB; if none make a new FDB
                               if an ac, use it as point to address

     MSGFD$              set ac(D) to point to the current message file.             MSGFD$                           1          
                         Load ac(D) from $IDOFD(I).

     PATCH$              increment $$VEDT for each patch; increment $$VMIN by one    PATCH$   <p1,p2,..pn>            0         3.14
                         and make a symbol '$n' for each pn to be used if adding
                         and subtracting code with IFDEF and IFNDEF
                         'p1,..pn'  patch numbers

     TRMFD$              set ac(D) to point to the job's terminal. Zero ac(D).       TRMFD$                           1          

     VERSN$              define values for the symbols, $$VMAJ, $$VMIN               VERSN$   vm,ve,vw                0         3.14
                         $$VEDT and $$VCOD. These symbols are used by the other
                         version number macros and are explained in section 3.14.
                         'vm' is the major version number
                         've' is the edit number (updated by PATCH$)
                         'vw' is the who last edited code
                         the minor version is set to zero (updated by PATCH$)
                         The versions of C and IO used are PRINTXed during assembly.

     VTEXT$              creates an ASCIZ string of the version number from          VTEXT$                           1+        3.14
                         the version number symbols e.g. '5B(107)-1'
IOLIB MACROS                                                                                                                Page B-3


                                                                                                                      Inline
     Macro     Routine                  Description                                       Call                         code  Section
     =====     =======                  ===========                                       ====                        ====== =======


     B.2 Basic IO Macros
     --- ----- -- ------

     APDWT$    $APDWT    as APEND$ but on 'file being modified' failure              APDWT$                           1         6.21
                         wait and try again a given number of times                    error return

     APEND$    $APEND    open a file for appending, setting buffer pointers          APEND$                           1         6.22
                         appropriately. Only works for append mode files.              error return

     CLOSE$    $CLOSE    execute a CLOSE UUO. If the call has an argument, two       CLOSE$   bits                    1!2       6.7
                         instructions are generated, and the arguments are used
                         as CLOSE UUO bits.
                         'bits'  CLOSE UUO bits

     DELET$    $DELET    delete the current file                                     DELET$                           1         6.10
                                                                                       error return

     DLBUF$    $DLBUF    deallocate a buffer ring                                    DLBUF$                           1         6.18

     ENTER$    $ENTER    Execute an ENTER UUO for the current file. If the           ENTER   x                        1         6.5
                         macro has an argument then the UUO may change the             error return
                         create date/time field
                         'x'  any argument (just a flag)

     FRCHN$    $FRCHN    locate the first free software IO channel starting          FRCHN$                           1          
                         with the contents of ac(T1)                                   error return

     GETST$    $GETST    get the IO status halfword from the monitor. The status     GETST$                           1         6.12
                         returned in ac(t1)

     LUKUP$    $LUKUP    execute a LOOKUP UUO for the current file.                  LUKUP$                           1         6.4
                                                                                       error return

     INPUT$    $INPUT    execute an INPUT UUO for the current file. Make a           INPUT$                           1         6.2
                         buffer ring and find the required record if needed            error return
                                                                                       endfile return

     MKBUF$    $MKBUF    build a buffer ring (see Appendix A)                        MKBUF$                           1         6.17
                                                                                       error return

     MTxxx$    $MTxxx    execute an MTAPE UUO for the current file.                  MTxxx$                           1         6.23
                         'xxx' may be any of the codes for the various MTAPE
                         functions, e.g. MTREW$ executes a rewind.
                         All functions are followed by an MTWAT$ to wait for completion.
                         MTBSF$ skips over the EOF unless at BOT.

     OPEN$     $OPEN     execute an OPEN UUO for the current file, setting           OPEN$                            1         6.6
                         defaults and finding a free channel                           error return

     OUTIN$    $OUTIN    output the last record input (to a disk device)             OUTIN$                           1         6.3
                                                                                       error return
IOLIB MACROS                                                                                                                Page B-4


     OUTPU$    $OUTPU    execute an OUTPUT UUO for the current file                  OUTPU$                           1         6.3
                         making a buffer ring and finding required record if           error return
                         necessary

     RLEAS$    $RLEAS    execute a RELEAS UUO for the current file and               RLEAS$   x                       1         6.8
                         deallocate buffers
                         'x'  flag.  If given, don't deallocate buffers.

     RENAM$    $RENAM    execute a RENAME UUO for the current file. The file         RENAM$                           1         6.9
                         have been LUKUP$ed first.                                     error return

     SETST$    $SETST    set the IO channel status from ac(T1) into the monitor      SETST$                           1         6.13

     UPDAT$    $UPDAT    open a file for updating                                    UPDAT$                           1         6.19
                                                                                       error return

     UPDWT$    $UPDWT    as UPDAT$, but on 'file being modified' failure             UPDWT$                           1         6.20
                         wait and try again a given number of times                    error return

     USETI$    $USETI    find the required record for disk files. On entry           USETI$                           1         6.11
                         ac(T1) contains  'last-record,,next record'

     USETO$    $USETO    find the required record for output for disk files          USETO$                           1         6.11
                         On entry ac(T1) contains 'last-record,,this-record'

     XTCAL$    $XTCAL    execute a CALLI UUOZ for the current file, setting          XTCAL$  uuo                      2         6.15
                         physical-only if required                                     error return
                         'uuo'  CALLI UUO to be executed (arg in ac(T2))

     XTDCL$    $XTDCL    execute a device dependent CALLI UUO for the current        XTDCL$   uuo                     2         6.16
                         file.                                                         error return
                         'uuo'  CALLI UUO to be executed

     XTUUO$    $XTUUO    execute an IO UUO for the current file                      XTUUO$   uuo                     2         6.14
                         'uuo'  UUO name                                               error return
IOLIB MACROS                                                                                                                Page B-5


                                                                                                                      Inline
     Macro     Routine                  Description                                       Call                         code  Section
     =====     =======                  ===========                                       ====                        ====== =======


     B.3 Read macros
     --- ---- ------

     RBYTE$    $$RBYT    read a byte, and trap to $FATAL on error                    RBYTE$                           1         7.6
                                                                                       endfile

     RCALT$    $RCALT    read a character with command editing, but if last          RCALT$                           1         7.10
                         character was altmode, return altmode instead.

     RCCHR$    $RCCHR    read a character with command editing                       RCCHR$                           1         7.10

     RCHAR$    $$RCHR    read a character with command editing                       RCHAR$                           1         7.8

     READ$     $READ     read a byte                                                 READ$                            1         7.5
                                                                                       error return
                                                                                       endfile

     -----------------------------------------------------------------------------------------------------------------------------

          The following macros will accept an argument.  If an argument is provided it is assumed to be the address of  the  leading
     character  of the string to be read.  If that address is ac(T1), the macro merely assembles a jump to the secondary entry point
     of the routine.  If the address is elsewhere, then the macro assembles an extra instruction to move the character into  ac(T1).
     If there is no argument, the macro assembles a PUSHJ to the routine as described in appendix A.

          All the macros given below return the delimiting character in ac(T1) and the value read in ac(T2).  Some routines return a
     wildcard  mask in ac(T3), and a few return extra data in ac(T4).  Refer to the description of the routines for specific details
     of parameters.

     RANCH$    $RANCH    read a character and check whether alphanumeric             RANCH$  ac                       1!2        
                         error return means not alphanumeric                           error return

     RCASH$    $RCASH    read a cash value in dollars and cents                      RCASH$ ac                        1!2        
                                                                                       error return

     RDATE$    $RDATE    read a date from the current file in the format             RDATE$  ac                       1!2        
                         dd-mmm-yy.                                                    error return

     RDECL$    $RDECL    read a decimal number                                       RDECL$  ac                       1!2        

     RDECM$    $RDECM    read a decimal number possibly with a K, M or G             RDECM$  ac                       1!2        
                         multiplier

     RDVIC$    $RDVIC    read a device name                                          RDVIC$  ac                       1!2        

     REDCH$    $REDCH    read a character and perform basic editing                  REDCH$  ac                       1!2       7.9

     RFILE$    $RFILE    read a file specification into an FDB. Note that this       RFILE$   ac                      1!2       7.11
                         macro is different. If there is no argument, there is         error return
                         no switch table, and $RFILE creates an FDB. If there
                         is an argument, it is an ac which holds a point to the
                         switch table (possibly zero).  If this is ac(T1), no
IOLIB MACROS                                                                                                                Page B-6


                         extra code is created.  A point to an FDB or zero must
                         be in ac(T2).

     RKWRD$    $RKWRD    read a core size as Kwords or pages                         RKWRD$  ac                       1!2        

     RNAME$    $RNAME    read an alphanumeric name and convert to a SIXBIT word      RNAME$  ac                       1!2        

     ROCTL$    $ROCTL    read an octal number                                        ROCTL$  ac                       1!2        

     ROCTM$    $ROCTM    read an octal number possibled postfixed by a K, M or G     ROCTM$  ac                       1!2        
                         multiplier.

     RPATH$    $RPATH    read a path specification                                   RPATH$  ac                       1!2       7.12
                                                                                       error return

     RPJPG$    $RPJPG    read a project,programmer pair (no [])                      RPJPG$  ac                       1!2       7.12
                                                                                       error return

     RPPN$     $RPPN     read a PPN                                                  RPPN$   ac                       1!2       7.12
                                                                                       error return

     RREAL$    $RREAL    read a floating point number expressed in FORTRAN E or F    RREAL$  ac                       1!2        
                         format.

     RSWIT$    $RSWIT    read a switch name and value                                RSWIT$  ac                       1!2       7.13
                                                                                       error return

     RTDAY$    $RTDAY    read a tme and date                                         RTDAY$  ac                       1!2        
                                                                                       error return

     RTIME$    $RTIME    read a time in the format hh:mm:ss                          RTIME$  ac                       1!2        
                                                                                       error return

     RUCCH$    $RUCCH    read a character and convert lower to upper case            RUCCH$  ac                       1!2        

     RWNAM$    $RWNAM    read a possibly wild name                                   RWNAM$  ac                       1!2        

     RWNUM$    $RWNUM    read a possibly wild number (or name if 1st character is    RWNUM$  ac                       1!2        
                         alphabetic).
IOLIB MACROS                                                                                                                Page B-7


                                                                                                                      Inline
     Macro     Routine                  Description                                       Call                         code  Section
     =====     =======                  ===========                                       ====                        ====== =======


     B.4 Write Macros
     --- ----- ------

     WADDR$    $WADDR    write an octal address in 6 digits filled by zeros          WADDR$                           1          

     WBWRD$    $WBWRD    write a number as a number of blocks (128 words)            WBWRD$                           1          

     WBYTE$    $$WBYT    write a byte but trap to $FATAL on error                    WBYTE$                           1         7.3

     WCASH$    $WCASH    write a number of cents as dollars and cents                WCASH$                           1          

     WCHAR$    $$WCHR    write character                                             WCHAR$   "c"                     1!2       7.4
                         'c'  an ASCII character

     WCRLF$    $WCRLF    write an endline <cr><lf>                                   WCRLF$                           1          

     WCWRD$    $WCWRD    write a number as a multiple of core size                   WCWRD$                           1          
                         which may be P, K or W.

     WDATE$    $WDATE    write a date as dd-mmm-yy                                   WDATE$                           1          

     WDECL$    $WDECL    write a decimal number                                      WDECL$   n                       1!2        
                         'n'  a positive decimal number

     WDNOW$    $WDNOW    write the date now                                          WDNOW$                           1          

     WDVIC$    $WDVIC    write a device name as 'dev:'                               WDVIC$                           1          

     WFCHA$    $WFCHA    write a funny character, making code explicit               WFCHA$                           1          
                         by flagging control and lower case characters

     WFILE$    $WFILE    write the filename from an FDB                              WFILE$                           1          

     WHELP$    $WHELP    write a help text                                           WHELP$                           1          

     WKWRD$    $WKWRD    write a core size in Kwords                                 WKWRD$                           1          

     WLINE$    $WTEXT    write a text string adding a <cr><lf>                       WLINE$   <text>                  1!2        
                         'text'  a string of ASCII characters

     WNAME$    $WNAME    write a name in SIXBIT or halfwords                         WNAME$                           1          

     WOCTL$    $WOCTL    write an octal number                                       WOCTL$   n                       1!2        
                         'n'  a positive octal number

     WPATH$    $WPATH    write a path specification (or just PPN)                    WPATH$                           1          

     WPWOR$    $WPWOR    write a word of SIXBIT characters preceded by an            WPWOR$   "c",word                1!2!3      
                         ASCII character. Either argument may be ommitted.
                         'c'  an ASCII character
                         'word'  up to 6 SIXBIT characters
IOLIB MACROS                                                                                                                Page B-8


     WPWRD$    $WPWRD    write a core size in pages                                  WPWRD$                           1          

     WRADX$    $WRADX    write a number in a given radix (given in ac(T2))           WRADX$                           1          

     WREAL$    $WREAL    write a floating point number                               WREAL$   n                       1!2        
                         'n'  a number in FORTRAN E-format

     WRITE$    $WRITE    write a byte                                                WRITE$                           1         7.2
                                                                                       error return

     WTDAY$    $WTDAY    write time and date as dd-mmm-yy hh:mm                      WTDAY$                           1          

     WTDNW$    $WTDNW    write time and date now                                     WTDNW$                           1          

     WTEXT$    $WTEXT    write a text string                                         WTEXT$   <text>                  1!2        
                         'text'  a string of ASCII characters

     WTIME$    $WTIME    write time as hh:mm                                         WTIME$                           1          

     WTIMS$    $WTIMS    write time as hh:mm:ss                                      WTIMS$                           1           

     WTMTS$    $WTMTS    write time as hh:mm:ss.t                                    WTMTS$                           1          

     WTNOW$    $WTNOW    write time now as hh:mm:ss                                  WTNOW$                           1          

     WWORD$    $WWORD    write a word of SIXBIT characters                           WWORD$   word                    1!2        
                         'word'  a string of up to 6 characters

     WWWRD$    $WWWRD    write a number as a number of words                         WWWRD$                           1          

     WXWD$     $WXWD     write a word as two halfwords                               WXWD$                            1          

     W2FIL$    $W2FIL    write 2 digits, filled on left                              W2FIL$                           1          

     W2FLB$    $W2FLB    write 2 digits, filled on left by space                     W2FLB$                           1          

     W2FL0$    $W2FL0    write 2 digits, filled on left by zero                      W2FL0$                           1          
IOLIB MACROS                                                                                                                Page B-9


                                                                                                                      Inline
     Macro     Routine                  Description                                       Call                         code  Section
     =====     =======                  ===========                                       ====                        ====== =======


     B.5 Core Management Macros
     --- ---- ---------- ------

     ALLOC$    $$ALLC    call the memory manager to allocate space                   ALLOC$                           1         5.1
                                                                                       error return

     DEALC$    $$DALC    call the memory manager to deallocate space                 DEALC$                           1         5.1


     B.6 Data Block Manipulation Macros
     --- ---- ----- ------------ ------

     CLRFD$    $CLRFD    maybe create, but certainly zero and initialise an          CLRFD$  adr                      1!2        
                         FDB. If the macro has an argument use this as the address     error return (no core)
                         of the FDB.
                         'adr'  address of FDB

     LOSFD$    $LOSFD    deallocate space occupied by FDB. Deallocates path          LOSFD$                           1          
                         block, if any, too


     B.7 Tempcore Macros
     --- -------- ------

     TMPDL$    $TMPDL    delete a tempcore file                                      TMPDL$                           1         8.4
                                                                                       error return

     TMPFD$    $TMPFD    create an FDB for a tempcore file                           TMPFD$                           1         8.2

     TMPIN$    $TMPIN    read a tempcore file                                        TMPIN$                           1         8.3
                                                                                       error return

     TMPOU$    $TMPOU    write and close a tempcore file                             TMPOU$                           1         8.5
                                                                                       error return
IOLIB MACROS                                                                                                               Page B-10


                                                                                                                      Inline
     Macro     Routine                  Description                                       Call                         code  Section
     =====     =======                  ===========                                       ====                        ====== =======




     B.8 Error Macros
     --- ----- ------

     ADVIS$    $ADVIS    write an advisory message to the error file                 ADVIS$ <text>,arg,ec,uc          1         9.6
                         'text' the text of the message
                         'arg'  a code for the type of argument
                         'ec'   a 3 character code prefaciing the message
                         'uc'   a 6 character UUO name

     FATAL$    $ERROR    write a fatal error message to the error file and           FATAL$   <text>,arg,ec,uc        1         9.6
                         exit through $$FERR.
                         'text'  the text of the message
                         'arg'   a code for the type of the argument
                         'ec'    a 3 character code which prefixes the message
                         'uc'    a 6 character UUO name

     WARN$     $ERROR    send a warning error message to the error file              WARN$   <text>,arg,ec,uc         1         9.6
                         'text'  the text of the error message
                         'arg'   a code for the data type of the argument
                         'ec'    a 3 character code prefacing the message
                         'uc'    a 6 character UUO name
IOLIB MACROS                                                                                                               Page B-11


                                                                                                                      Inline
     Macro     Routine                  Description                                       Call                         code  Section
     =====     =======                  ===========                                       ====                        ====== =======


     B.9 Utility Routine Macros
     --- ------- ------- ------

     BATCH$    $BATCH    discover whether job running from PTY                       BATCH$                           1          
                                                                                       not PTY return

     CLBUF$    $CLBUF    clear buffer for job's terminal; read to                    CLBUF$                           1          
                         endline otherwise

     CLLIN$    $CLLIN    read to endline                                             CLLIN$                           1          

     CNVNU$    $CNVNU    return now as a Universal date/time                         CNVNU$                           1          

     CNVUI$    $CNVUI    convert Universal date/time to internal                     CNVUI$                           1          

     CNVIU$    $CNVIU    convert internal date/time to Universal                     CNVIU$                           1          

     FDTTY$    $FDTTY    check whether the current file in a terminal                FDTTY$                           1
                                                                                       not TTY
                                                                                     TTY

     MATCH$    $MATCH    match a SIXBIT name against a table                         MATCH$                           1         10.2

     MONRT$    $MONRT    return to monitor mode                                      MONRT$                           1          

     RESTT$    $RESTT    restore T1-T4 from the stack                                RESTT$                           1          

     SAVET$    $SAVET    save acs T1-T4 on the stack                                 SAVET$                           1          

     SAVE1$    $SAVE1    preserve ac(P1) during a subroutine                         SAVE1$                           1          

     SAVE2$    $SAVE2    preserve acs P1-P2 during a subroutine                      SAVE2$                           1          

     SAVE3$    $SAVE3    preserve acs P1-P3during a subroutine                       SAVE3$                           1          

     SAVE4$    $SAVE4    preserve acs P1-P4 during a subroutine                      SAVE4$                           1          

     SLEEP$    SLEEP     sleep by HIBER or SLEEP UUO for given time                  SLEEP$  ac                       1!2        
                         Time may be give in 'ac'.

     ZERO$     $ZERO     zero a chunk or memory                                      ZERO$                            1          











                                APPENDIX C

                            CONTENTS OF THE FDB





     Index     Symbol    Description
     =====     ======    ===========

     C.1 Words within the FDB
     --- ----- ------ --- ---

     0         $FDFPT    forward pointer.  The left half is  used  to  link
                         FDBs  together  to  form  a linked list.  The left
                         half is unused but reserved for IOLIB.

     1         $FDCHN    channel  number.   The  right  half  contains  the
                         software  IO channel number in bits 29 to 32.  The
                         user may select a channel number but  normally  he
                         will  let  IOLIB  do  this for him.  The left half
                         contains  flags  showing  the  status  of  the  IO
                         process  on  this  file.   The flags are described
                         below.

     2         $FDTYP    argument returned by a DEVTYP UUO on the  channel.
                         Set by the $OPEN routine.

     3         $FDNBK    current record number  for  the  FDB,,next  record
                         number for the FDB.  The next record number may be
                         set before calling $INPUT or  $OUTPU  for  a  disk
                         device  only.   Updated by $INPUT, $OUTPU, $USETI,
                         $USETO and initialised by $OPEN only if zero.

     4         $FDBUF    buffering details.  The right  half  contains  the
                         length  of  each  buffer  in words.  The left half
                         contains the number  of  buffers.   IOLIB  assumes
                         that  these  details  are  identical for input and
                         output sides  of  a  channel.   Defaults  are  two
                         buffers  of the standard size for the device.  Set
                         up by $OPEN.

     5         $FDIOW    Point to IOWD chain for dump  mode  IO.   Normally
                         zero for buffered modes, but may be the address of
                         the next buffer if out of sequence.
CONTENTS OF THE FDB                                                Page C-2


     6-10      $FDOPN    3  word  OPEN  UUO  data  block.   The  words  are
                         described  indiviually  below,  and in the Monitor
                         Calls Handbook.

     6         $FDSTS    IO channel status.  The $open routine takes values
                         supplied   in  $FDMOD,  for  parity,  density  and
                         physical-only, and puts  them  into  $FDSTS.   All
                         other  fields  default to zero, in particular, the
                         default mode is ASCII (.IOASC).  $GETST writes the
                         current IO status into the right half of $FDSTS.

     7         $FDDEV    device name, left-justified.  The default is 'DSK'
                         for IOLIB IO.

     10        $FDBHD    buffer header addresses.  The  left  half  is  the
                         output buffer header address and the right half is
                         the  input  buffer  header  address.   The  buffer
                         headers are within the FDB at $FDOBH and $FDIBH.

     11-21     $FDPTH    path specification in a form  suitable  for  PATH.
                         UUOs.   The first 2 words are unused, the 3rd word
                         is the PPN and further words are  SFDs  terminated
                         by a zero word.

     13        $FDPPP    PPN word in the path specification

     14        $FDSFD    first SFD name in the path specification

     22-25     $FDOBH    output buffer header (4 words).  Also used for the
                         path mask for command scanning.

     22-27     $FDPTM    path mask block of 6 words masking the PPN and the
                         SFDs.   Set  by  the  filename  scanner  RFILE  to
                         indicate wildcards typed.

     26-31     $FDIBH    input buffer header (4 words).  Also used for part
                         of  the  path  mask  and  for the filename mask in
                         command scanning.

     30        $FDNMM    filename name mask.  Set by the filename  scanner,
                         $RFILE,   to   indicate   which   characters  were
                         wildcards.

     32        $FDMOD    modifier  word.   A   vector   of   switches   and
                         parameters  that may be set by the user by program
                         or by  command.   The  individual  fields  in  the
                         modifier word are described below.

     33        $FDMOM    modifier mask.  A vector of masks corresponding to
                         the  various  fields  in  $FDMOD.   If the mask in
                         $FDMOM is set, then that field in $FDMOD has  been
                         given.

     34        $FDBFR    /BEFORE specification.  Set by the command scanner
                         to give the /BEFORE date and time.
CONTENTS OF THE FDB                                                Page C-3


     35        $FDSNC    /SINCE specification.  Set by the command  scanner
                         to give the /SINCE date and time.

     36        $FDABF    /ABEFORE  specification.   Set  by   the   command
                         scanner to give the access BEFORE date and time.

     37        $FDASN    /ASINCE specification.  Set by the command scanner
                         to give the access SINCE date and time.

     40-46     $FDRIB    RIB block data.   The  format  of  the  RIB  block
                         section  is as for extended disk UUOs.  A standard
                         FDB contains the RIB block from .RBCNT to  .RBVER,
                         but  further  words  may  be  added by building an
                         extended FDB.  The RIB data is physically the last
                         information  in  an FDB.  For further details, see
                         the Monitor Calls Handbook.

     40        $FDCNT    the count of words in the extended RIB.

     41        $FDPPN    either the PPN or a point to a PATH.   UUO  block.
                         MAKFD$  and  FDESC$  set  up  $FDPPN  to  point to
                         $FDPTH, but the user may write  a  PPN  over  this
                         pointer or even a pointer to another path block.

     42        $FDNAM    the filename in SIXBIT, left justified.

     43        $FDEXT    Extension.  The left half contains  the  extension
                         in 3 SIXBIT characters, left-justified.  The right
                         half is  used  by  the  command  scanner  for  the
                         extension mask.

     44        $FDPRV    privilege word.   Contains  protection,  mode  and
                         create time and date information.

     45        $FDSIZ    file size in words.

     46        $FDVER    version number.

     46        $ENFDB    end of the FDB.

     47        $LNFDB    length of an FDB in words.
CONTENTS OF THE FDB                                                Page C-4


     Bits      Symbol    Description
     ====      ======    ===========


     C.2 Bits definitions for $FDCHN
     --- ---- ----------- --- ------

     0         FC$OPN    an OPEN UUO has been done on this channel

     1         FC$LUK    a LOOKUP UUO has been done on this channel.

     2         FC$ENT    an ENTER UUO has been done on this channel.

     3         FC$TCI    Tempcore input has been done on this channel

     4         FC$CSC    channel number set by caller.






     C.3 Bit definitions in $FDMOD and $FDMOM
     --- --- ----------- -- ------ --- ------

     0         FM$NDV    null device specification.

     1         FM$NUL    null extension.  The extension was  specified  but
                         was   null;    therefore  do  not  use  a  default
                         extension.

     2         FM$DIR    directory specified.

     3         FM$PHY    /PHYSICAL;  physical only IO on this channel.

     4         FM$NOM    /OKNONE;    ok   if   no   file    matches    this
                         specification.

     5         FM$DFX    wild fixup unnecessary for this directory.

     6-8       FM$TRM    code for terminator of file specification.

     9         FM$STR    /STRS

     10-23               unused

     24        FM$PAR    magtape recording parity (1=even).

     20-26     FM$DEN    magtape recording density  (0=std,  1=250,  2=556,
                         3=800)

     27-35     FM$PRO    protection code as 3 octal digits.











                                APPENDIX D

                            CONTENTS OF THE IDB



     Index     Symbol    Description
     =====     ======    ===========


     0         $IDDYC    pointer to a linked list of chunks  of  free  core
                         for allocation to any routine that requires space.
                         The dynamic core pointer is not used by the static
                         core allocater.

     1         $IDTOP    maximum core that may be used by this program, set
                         by program or by command using the /MAXCOR switch.
                         The core is measured in words  and  the  value  is
                         actually the maximum+1.

     2         $IDLAC    look-ahead character.  Used by the command scanner
                         to  store  the  extra character when it has had to
                         look ahead to interpret the current character.

     3         $IDCPC    PC for the command scanning coroutine.

     4         $IDLSC    last character read by the command scanner $REDCH.

     5         $IDNXC    next character  to  be  read.   If  this  word  is
                         non-zero,  it  forces  the command scanner to read
                         this character instead of reading from  the  input
                         file.

     6         $IDPNM    program name.  Set by the BEGIN$ macro by GETTAB.

     7         $IDPPN    program PPN.  As $IDPNM.

     10        $IDPEX    low segment extension name (left half).

     11        $IDPDV    program device name.

     12        $IDIFD    input FDB pointer.  The address of the  FDB  being
                         used  for  command  input.   Set  to TTY:  or to a
                         tempcore file by the BEGIN$ macro.

     13        $IDOFD    output FDB pointer.  The address of the FDB  being
                         used  for  message  output.   Set  to TTY:  by the
CONTENTS OF THE IDB                                                Page D-2


                         BEGIN$ macro.

     14        $IDEFD    error FDB pointer.  The address of the  FDB  being
                         used  for  error  message output.  Set to TTY:  by
                         the BEGIN$ macro.

     15        $IDCCL    CCL entry point flag (0=normal, -1=CCL).   Set  up
                         by the BEGIN$ macro.

     16        $IDSWT    point to standard switch table.  Used by $RSWIT to
                         compare  switch  against  standard switches, if it
                         doesn't match against user-provided switches.

     17        $IDRUN    runoffset,,point to run FDB.  Details for  program
                         to be run on termination of this program.

     20        $IDECD    error codes.  The  left  half  contains  3  SIXBIT
                         characters  to  preface all error messages written
                         by the  program.   The  right  half  contains  the
                         verbosity   code   for   error   messages  (0=low,
                         1=normal, 2=high).  Set to 'normal' by the  BEGIN$
                         macro.

     21        $IDHNM    file name for 'help'.

     22        $IDDFD    point to FDB containing  defaults  for  file  name
                         scanning.

     23        $IDJNO    reserved,,job number:  set by BEGIN$ macro

     24        $IDJPP    job's PPN:  set by BEGIN$ macro

     25-35     $IDJPT    default path specification for this task.  Set  by
                         the BEGIN$ macro, and should be used to change the
                         default path spec.

     36        $IDCPU    code for the CPU type, set by  the  BEGIN$  macro.
                         $CPKAX==0, and $CPKIX==1.

     36        $ENIDB    end of the IDB

     37        $LNIDB    length of the IDB.











                                APPENDIX E

                              IO ERROR CODES





     Index     Symbol    Description
     =====     ======    ===========


     E.1 UUO codes
     --- --- -----

     0         UUUUO$    error for undefined UUO

     1         UUOPN$    OPEN UUO error

     2         UUENT$    ENTER UUO error

     3         UULUK$    LOOKUP UUO error

     4         UUREN$    RENAME UUO error

     5         UUINP$    INPUT UUO error

     6         UUOUT$    OUTPUT UUO error

     7         UURUN$    RUN UUO error

     10        UUGET$    GETSEG UUO error

     11        UUCLO$    CLOSE UUO error

     12        UUTMP$    TMPCOR UUO error
IO ERROR CODES                                                     Page E-2


     E.2 IO Error codes
     --- -- ----- -----

     0-27      ER???%    LOOKUP/ENTER/RENAME error codes as defined in  the
                         Monitor  Calls  Handbook  appendix  E.  IOLIB sets
                         some of these codes for UUOs  other  than  LOOKUP,
                         ENTER   and   RENAME   when   the   messages   are
                         appropriate,  for  instance,   ERNEC%,   no   core
                         available  is  set when the is no space to build a
                         buffer ring.

     -1        EREOF$    endfile, which may be an error in some cases

     -2        ERBKT$    block too large, which includes the  'no  room  or
                         quota exceeded' cases for DSK:.

     -3        ERDTE$    data error, most likely parity or checksum errors.

     -4        ERDER$    device error.  This normally  means  real  trouble
                         with  the  device,  although  the  real meaning is
                         device dependent.

     -5        ERIMP$    improper mode for device.

     -6        ERQTA$    code reserved for no room or quota exceeded case.

     -7        ERRSD$    restricted device.  Attempt  to  access  a  device
                         that is available, and is not spooled by the user,
                         but is restricted by the operator.

     -10       ERNFC$    no free IO software channels.   The  user  program
                         has used at least 15 out of the 16 possible.  Note
                         that IOLIB does not attempt IO on channel 0 unless
                         forced.

     -11       ERUNK$    unknown error.  This error can be produced  on  IO
                         when  no  error  bit  was  set in the status word,
                         which may be due to e.g.   write-ring  missing  in
                         magtape.











                                APPENDIX F

                         IOLIB STANDARD ERROR IDS



          All the 3 character error identifications produced by  IOLIB  are
     listed  here,  together  with  their  meanings.   The  error  ids that
     correspond to LOOKUP/ENTER/RENAME error codes are flagged by  an  '*'.
     More  details  about  these  codes  can  be found in the Monitor Calls
     Handbook, Appendix E.  Error ids flagged with 'S' are produced by  the
     IOLIB command string reading routines.

          Id                  Description
          ==                  ===========

          AEF       *         File already exists

          ASW       S         ambiguous switch name

          BKT                 block too large ($INPUT/$OUTPU)

          BNF       *         block busy

          CSD       *         subfile directory already exists

          DER                 device error ($INPUT/$OUTPU)

          DNA       *         device not available ($OPEN also)

          DNE       *         directory not empty

          DTE       *         data error, e.g.  checksum  or  parity  error
                              ($INPUT/$OUTPU)

          EOF                 end of file ($INPUT)

          FBM       *         file being modified

          FNF       *         file not found

          ILC       S         illegal character in input string

          ILU       *         processor doesn't have 2 segment capability

          IMP                 improper   IO   mode    for    this    device
                              ($OPEN/$INPUT/$OUTPU)
IOLIB STANDARD ERROR IDS                                           Page F-2


          IPG       S         programmer number zero or too big

          IPJ       S         project number zero or too big

          ISU       *         incorrect sequence of UUOs

          LVL       *         too many levels of SFDs

          NCE       *         can't create in directory

          NDV       s         Null device name in device specification

          NEC       *         not enough core (also $INPUT/$OUTPU)

          NET       *         not enough table space in monitor (also $OPEN
                              if no spare DDBs in monitor)

          NFC                 no free IO channels($OPEN)

          NOR       S         number out of range

          NRM       *         no room on structure

          NSD       *         no such device (also $OPEN)

          NSF       *         not a save file

          POA       *         no room (??)

          PRT       *         protection failure

          QTA                 quota exceeded

          RSD                 restricted device ($OPEN)

          SLE       *         search list empty

          SNF       *         no directory

          SNS       *         no segment 

          STI       S         switch tables built incorrectly

          TRN       *         transmission error

          UKW       S         unknown keyword in switch specification

          UNK                 unknown error code

          USW       S         unknown switch name

          VIL       S         value illegal in switch specification

          WDV       S         wild device name in device specification

          WLK       *         write-locked device
IOLIB STANDARD ERROR IDS                                           Page F-3


          2DV       S         two device names in one file specification

          2EX       S         two extensions in one file specification

          2NM       S         two file names in one file specification

          2PT       S         two   path   specifications   in   one   file
                              specification