Google
 

Trailing-Edge - PDP-10 Archives - walsh_goodStuff_1600 - more-uns/blilib.mem
There are no other files named blilib.mem in the archive.


CHAPTER 1       INTRODUCTION TO THE BLISS LIBRARY.

1.1       LIBRARY OVERVIEW. . . . . . . . . . . . . . . 1-1
1.2       LIBRARY AND NOTEBOOK ORGANIZATION . . . . . . 1-1


CHAPTER 2       SYSTEM INTERFACES.

2.1       OVERVIEW AND SCOPE. . . . . . . . . . . . . . 2-1
2.2       USING THE VARIOUS INTERFACES. . . . . . . . . 2-1
2.2.1       RSX-11M . . . . . . . . . . . . . . . . . . 2-1
2.2.1.1       $ Form  . . . . . . . . . . . . . . . . . 2-2
2.2.1.2       $S Form . . . . . . . . . . . . . . . . . 2-3
2.2.2       TOPS-10 . . . . . . . . . . . . . . . . . . 2-4
2.2.2.1       UUOSYM  . . . . . . . . . . . . . . . . . 2-4
2.2.2.2       TENDEF  . . . . . . . . . . . . . . . . . 2-6
2.2.3       TOPS-20 . . . . . . . . . . . . . . . . . . 2-7
2.2.3.1       MONSYM  . . . . . . . . . . . . . . . . . 2-7
2.2.3.2       TENDEF  . . . . . . . . . . . . . . . . . 2-8
2.2.4       VAX/VMS . . . . . . . . . . . . . . . . . . 2-9
2.2.5       RT-11 . . . . . . . . . . . . . . . . . . . 2-10
2.2.5.1       Implementation Differences  . . . . . . . 2-10
2.2.6       FCS-11  . . . . . . . . . . . . . . . . . . 2-12
2.2.6.1       Additional Macros . . . . . . . . . . . . 2-12
2.2.6.2       Using FCS From BLISS Programs . . . . . . 2-13
2.2.7       RMS . . . . . . . . . . . . . . . . . . . . 2-15
2.2.7.1       Introduction  . . . . . . . . . . . . . . 2-15
2.2.7.2       Initialization Of The RMS Program . . . . 2-20
2.2.7.3         Allocation Of Control Blocks  . . . . . 2-23
2.2.7.4       The Fields Of The RMS Control Blocks  . . 2-40
2.2.7.5       Calling The Executable Functions Of RMS . 2-42
2.2.7.6       Status (Completion) Codes Of RMS  . . . . 2-44
2.2.7.7         Summary Of Conventions  . . . . . . . . 2-46
2.2.7.8       Example . . . . . . . . . . . . . . . . . 2-48


CHAPTER 3       AN EASY TO USE I/O PACKAGE (EZIO)

3.1       OVERVIEW  . . . . . . . . . . . . . . . . . . 3-1
3.2       PRODUCT GOALS . . . . . . . . . . . . . . . . 3-1
3.2.1       Performance . . . . . . . . . . . . . . . . 3-1
3.2.2       Environments  . . . . . . . . . . . . . . . 3-2
3.2.3       Reliability Goals . . . . . . . . . . . . . 3-2
3.2.4       Non Goals . . . . . . . . . . . . . . . . . 3-2
3.3       FUNCTIONAL DEFINITION . . . . . . . . . . . . 3-2
3.3.1       Operational Description . . . . . . . . . . 3-3
3.3.1.1       The FILOPN Routine  . . . . . . . . . . . 3-3
3.3.1.2       The FILIN Routine . . . . . . . . . . . . 3-5
3.3.1.3       The FILOUT Routine  . . . . . . . . . . . 3-5
3.3.1.4       The FILCLS Routine  . . . . . . . . . . . 3-6
3.3.2       Restrictions  . . . . . . . . . . . . . . . 3-6
3.3.4       Loading With User Programs  . . . . . . . . 3-8
3.3.4.1       EZIOFC  . . . . . . . . . . . . . . . . . 3-8
3.3.4.2       EZIORT  . . . . . . . . . . . . . . . . . 3-9
3.3.4.3       EZIO10  . . . . . . . . . . . . . . . . . 3-9
                                                      Page 2


3.3.4.4       EZIO20  . . . . . . . . . . . . . . . . . 3-9
3.5       PACKAGING AND INSTALLATION  . . . . . . . . . 3-9
3.6       DOCUMENTATION . . . . . . . . . . . . . . . . 3-10
3.7       REFERENCES  . . . . . . . . . . . . . . . . . 3-10











                         CHAPTER 1

             INTRODUCTION TO THE BLISS LIBRARY.



1.1  LIBRARY OVERVIEW.

     The BLISS Library is intended to provide  a  convenient
environment  for  development  programmers to use BLISS.  It
provides interfaces to interact with the  various  supported
monitors, and provides some packages that have functionality
commonly found in high level languages.

     The Library is updated as packages are created and  are
generally  felt  to  be useful.  All packages that are added
are supported by the Development Methods, and are of product
quality.



1.2  LIBRARY AND NOTEBOOK ORGANIZATION

     This Notebook is divided into chapters  describing  the
various packages in the Library.  Since most packages in the
library function in the same way on more than  one  monitor,
the chapters may have several monitor dependent sections.

     The Library is distributed as a collection of files for
a  TOPS-10,  TOPS-20,  or  VAX system.  The PDP-11 files are
transfered to the target -11 system the same way that object
files   from   the  BLISS  compilers  are  transfered  (e.g.
DECtape, Magtape, DECNET, etc.).  The Library is distributed
as  a  whole,  not  just  the  files  for  a specific system
implementation.











                         CHAPTER 2

                     SYSTEM INTERFACES.



2.1  OVERVIEW AND SCOPE.

     The System Interfaces Package of the  Library  provides
the development programmer with tools which allow the use of
BLISS where  assembly  language  was  commonly  used.   More
specifically,  the  package  documents  how  to  use  either
existing interfaces, or interfaces specifically written  for
BLISS.

     The use of the  various  interfaces  is  discussed  and
short  examples are provided.  Each system interface closely
parallels the existing assembly language interface,  so  the
reader is refered to the appropriate manual for a functional
explanation of an interface.



2.2  USING THE VARIOUS INTERFACES.

     This section describes  the  various  system  interface
packages  available  in  the  library,  how  to  use them at
compile-time, and how to invoke their load-time libraries.



2.2.1  RSX-11M

     The RSX-11M interface (file RSX11M.R16) implements  the
directives described in Chapter 4 of the Executive Reference
Manual.  (DEC Order number DEC-11-OMERA-C-D.)

     All directives have been implemented as macros.   There
are  two  forms of the directive macros, the $ form, and the
$S form.  (The $C form is redundant  in  BLISS  and  is  not
provided.)

     The symbol names in this BLISS  interface  differ  from
those listed in the manual.  Specifically, all occurances of
"." have been replaced with  "$"  in  the  interface.   This
avoids  the  use  of the %NAME lexical function, thus making
SYSTEM INTERFACES.                                  Page 2-2


programs easier to read.



2.2.1.1  $ Form - 

     The $ form is used when declaring a BLISS data  segment
that  will  contain  a  DPB.   This is useful when a program
executes the same directive several times, and changes  only
one or two parameters.

     Macros of this form expand into the BLOCK,  FIELD,  and
INITIAL  attributes.  The order of parameters is the same as
described in the manual.  For example:

Declaring:


     OWN RQSTDPB :  RQST$('COTASK', , , %O'10', %O'100');

Expands to:

        OWN RQSTDPB : BLOCK[7] FIELD(RQST$F) INITIAL(
        7^8+11, %RAD50_11 'COTASK', 0, 0, %O'10', %O'100');


     To reference various portions of  the  DPB,  the  field
names in the RQST$F set should be used.  For example:


     RQSTDPB[R$QSGC] = .GROUP_INPUT;


     Note that the field names correspond to  those  in  the
manual.   Also,  all parameters that require a Radix-50 name
do not require that the lexeme "%RAD50_11" preceed it.  This
is  automatically  generated  by the macro as illustrated in
the above example.

     The DIR$ macro executes a directive with a static  DPB.
Its  parameters  are  the  DPB address and an optional error
expression.  For example:

        OWN RQSTDPB : RQST$( ... );
        ...
        DIR$( RQSTDPB, SIGNAL ERROR);
        ...


     The DIR$ call has a value of 1  if  the  directive  was
successfully processed, 0 otherwise.
SYSTEM INTERFACES.                                  Page 2-3


2.2.1.2  $S Form - 

     The $S form is used to directly  execute  a  directive.
It behaves the same way as the macros in the manual.

     The arguments are processed exactly as  passed  to  the
macro.    With   the  exception  of  defaulting  of  omitted
parameters, no convenient argument processing is  done,  (ie
conversion  of  strings to Radix 50, zero filling multi-word
parameters, etc.).

     The last argument is optional.  If specified,  it  will
be  expanded  as  a BLISS expression and will be executed if
the directive failed.  For example:

        OWN REGPARMS : VECTOR[3];
        GREG$S(.MYREGION, REGPARMS, WARN() );


     If an error occurred while the executive was processing
the  directive,  then  routine  WARN  is  called with a null
parameter list.  If the last parameter is omitted, then  the
value  of GREG$S would have been 0 if an error occured.  For
example:

        IF NOT GREG$S(.MYREGION, REGPARMS)
        THEN (WARN(); SIGNAL ERROR);


     For those  directives  requiring  parameters  occupying
more  than  one  word,  (e.g.   task names, partition names,
etc), then use the following technique:

        TSKBLK[0] = %RAD50_11 'TAS';
        TSKBLK[1] = %RAD50_11 'K02';
        ABRT$S(TSKBLK,SIGNAL ERROR);

        Or:

        ABRT$S(UPLIT(%RAD50_11 'TASK02'), SIGNAL ERROR);


     The idea is to pass the address of the two  word  block
containing the task name.
SYSTEM INTERFACES.                                  Page 2-4


2.2.2  TOPS-10

     The TOPS-10 interface has the same  symbol  values  and
names  as  defined in UUOSYM.MAC.  The use of the symbols is
described throughout the TOPS-10 Monitor Calls  Manual  (DEC
Order Number AA-0974C-TB).



2.2.2.1  UUOSYM - 

     The symbol names in the  BLISS  Interface  differ  from
those  in  UUOSYM.MAC.   Specifically, all occurances of "%"
and "." in UUOSYM.MAC become "_" and "$" in respectively  in
UUOSYM.R36.   This  is to avoid the use of the %NAME lexical
function, which could make programs  difficult  to  read  if
used frequently.  For example:

     UUOSYM.MAC               UUOSYM.R36
     PC%USR                   PC_USR
     .CHLFD                   $CHLFD


     The  OPDEF  symbols  (eg.   RESET,  OPEN,  GETTAB)  are
expected  to  be  used  in  conjunction  with  the BLISS UUO
machine specific function.  For example:

	IF .JOB EQL 12
	THEN
	    BEGIN
	    REGISTER
		AC1=1;
	    AC1 = $GTSTS + .JOB^18;

	    IF NOT UUO(1, GETTAB(AC1))
	    THEN ERMSG(...);
	    END;

     In this example, a GETTAB is performed.  If  it  fails,
then  Routine  ERMSG  is invoked.  (The UUO function returns
TRUE if the function skipped and the first parameter  was  1
or  if the function did not skip and the first parameter was
0;   FALSE  is  otherwise  returned.    See   the   BLISS-36
Functional   Description   for  details  regarding  the  UUO
machine-specific  function.)   The   parameter   to   GETTAB
specifies  to  return  information  in  the Job Status table
($GTSTS) about job number 12 (contents of JOB).

     The  symbols  in  UUOSYM.MAC  defined  by  OPDEFs   are
equivalently  BLISS  Macros  suitable  for  use  in  the UUO
function, (as illustrated with GETTAB in the above example).
These macros take one, two, or no parameters;  the number is
dependent  upon  the  OPDEF  specification  in   UUOSYM.MAC.
However, these general rules may be used:
SYSTEM INTERFACES.                                  Page 2-5


     1.  All CALLIs take one parameter:  either  a  register
         number or a register name.

     2.  All MUUO Macros (eg.  OPEN, RENAME, USETO) take two
         parameters:  either a register number or a register
         name, as the first parameter, and an  address,  (or
         number  depending  on  the  MUUO  function)  as the
         second parameter.

     3.  The macros that take no parameters are usually user
         defined.


     The expansion of the Macros depends upon  the  form  of
the  OPDEF  in  UUOSYM.MAC.   If  the OPDEF specifies a zero
accumulator field, then the Macro would take an  accumulator
as  a  parameter.   If  the  OPDEF  specifies a zero address
field, then the MACRO would take an address as a  parameter.
If  both the accumulator and the address fields of the OPDEF
are non-zero, then  the  Macro  does  not  take  parameters.
Whatever  the case, the macro always expands to three fields
of the form:


     %O'op', %O'ac', %O'adr'


     Where 'op' is the operation  code  (second  parameter),
'ac'  is  the accumulator field (third parameter), and 'adr'
is the effective address field (fourth parameter) of the UUO
function.  For example:

          TTCALL(0,AC1)                 OUTCHR(CHAR)
          expands to                    expands to
          %O'51', 0, AC1                %O'51, %O'1', CHAR


     And to use them in the UUO function:

     UUO(0, TTCALL(0, AC1));  UUO(0, OUTCHR(CHAR));
     expands to               expands to
     UUO(0, %O'51', 0, AC1);  UUO(0, %O'51', %O'1', CHAR);


     Because the above TTCALL functions won't skip-return, 0
was used as the first parameter to UUO.

     The equated symbols (eg.  _VMSWP,  $PCWAK)  defined  in
UUOSYM.MAC   can  be  used  anywhere  a  BLISS  compile-time
constant expression can be used;  as $GTSTS was in the above
example.
SYSTEM INTERFACES.                                  Page 2-6


2.2.2.2  TENDEF - 

     An ancillary file to UUOSYM.R36  is  TENDEF.R36.   This
file  defines  the  program  counter  bits,  version  number
subfields, control character symbols, and the POINTR and FLD
macros.

     The  program  counter  bits  (PC_XXX),  version  number
subfields   (VI_XXX),   and   control   character  subfields
($CHXXX), are all LITERAL definitions.

     The FLD macro has two parameters:  the first is a value
and  the  second  is a bit mask.  It is used to position the
value in  a  subfield  specified  by  the  one-bits  in  the
bit-mask.  For instance:  FLD(2,%O'60') expands to ((2)^4).

     The POINTR macro also has two parameters:  the first is
an  address,  and  the  second is a bit mask.  It is used to
point to the subfield specified by the one-bits of the  mask
within  the  word  a  the  specified address.  For instance:
POINTR(X, %O'60') expands to X<4,2>.

     However, when using a structured  data-segment  as  the
first  argument,  the  structure  access must be enclosed in
parenthesis.  For example:

	INCORRECT		CORRECT
	POINTR(X[F1], %O'60')	POINTR((X[F1]), %O'60')
SYSTEM INTERFACES.                                  Page 2-7


2.2.3  TOPS-20

     The TOPS-20 interface has the  same  symbol  names  and
values  as  are  in  MONSYM.MAC.  The use of the symbols are
described throughout the  TOPS-20  Monitor  Calls  Reference
Manual   (DEC  Order  No:   AA-4166C-TM).   Also,  the  file
TENDEF.R36  that  is  provided  has  some  Operating  System
independent definitions that are generally useful.



2.2.3.1  MONSYM - 

     All of the symbols  in  MONSYM.R36  are  LITERALs,  and
duplicate the definitions in MONSYM.MAC.  However, there are
differences in  the  symbol  names  between  MONSYM.MAC  and
MONSYM.R36.   Specifically, all occurances of "%" and "." in
MONSYM.MAC have been changed to "_" and "$" respectively, in
MONSYM.R36.   This  is to avoid the use of the %NAME lexical
function, which can make programs difficult to read if  used
frequently.  For example:

     MONSYM.MAC               MONSYM.R36
     .CMFIL                   $CMFIL
     CM%ESC                   CM_ESC


     The JSYS machine-specific function is designed to  take
symbols  of  this  type  and perform a TOPS-20 monitor call.
For example:

        BEGIN
        REGISTER
            AC1=1,
            AC2=2;
        AC1 = GJ_NEW + GJ_SHT + GJ_FNS;
        AC2 = $PRIIN^18 + $PRIOU;
        IF NOT JSYS(1, GTJFN, AC1, AC2)
        THEN ERMSG(...);
        END;


     In this example, the GTJFN monitor call  is  issued  to
obtain  a  JFN  for a filename typed on the terminal.  If it
failed to skip-return, then Routine ERMSG is invoked.   (The
JSYS  function returns TRUE if the JSYS monitor call skipped
in  this   case.    Refer   to   the   BLISS-36   Functional
Specification for details about the JSYS function.)
SYSTEM INTERFACES.                                  Page 2-8


2.2.3.2  TENDEF - 

     An ancillary file to UUOSYM.R36  is  TENDEF.R36.   This
file  defines  the  program  counter  bits,  version  number
subfields, control character symbols, and  the  POINTER  and
FLD macros.

     The  program  counter  bits  (PC_XXX),  version  number
subfields   (VI_XXX),   and   control   character  subfields
($CHXXX), are all LITERAL definitions.

     The FLD macro has two parameters:  the first is a value
and  the  second  is a bit mask.  It is used to position the
value in  a  subfield  specified  by  the  one-bits  in  the
bit-mask.  For instance:  FLD(2,%O'60') expands to ((2)^4).

     The POINTR macro also has two parameters:  the first is
an  address,  and  the  second is a bit mask.  It is used to
point to the subfield specified by the one-bits of the  mask
within  the  word  a  the  specified address.  For instance:
POINTR(X, %O'60') expands to X<4,2>.

     However, when using a structured  data-segment  as  the
first  argument,  the  structure  access must be enclosed in
parenthesis.  For example:

     INCORRECT                CORRECT
     POINTR(X[F1], %O'60')    POINTR((X[F1]), %O'60')
SYSTEM INTERFACES.                                  Page 2-9


2.2.4  VAX/VMS

     The system interface for VAX/VMS consists of two files:
STARLET.R32  or  LIB.R32.   The STARLET file contains all of
the user calls and definitions  documented  in  the  VAX/VMS
System  Services  Reference  Manual.   The LIB file contains
everything  STARLET  does,  plus  the  VMS   internal   data
structures.

     Using the System Services from BLISS  is  described  in
detail in section 2.3 of the VAX/VMS System Services Manual.
(DEC Order No:  None).
SYSTEM INTERFACES.                                 Page 2-10


2.2.5  RT-11

     The RT-11 System Interface  consists  of  the  RT11.R16
REQUIRE  file.  It contains one macro that parallels each of
the EMTs documented in the RT-11  System  Reference  Manual.
However,  there are some macros that are NOT included, these
are:

          $INTEN              $SYNCH
          $MFPS               $$V1$$
          $MTPS               $$v2$$
          $REGDEF             


     In addition to the EMT macros, the  ERR_EMT  and  $DATE
macros are provided.

     The ERR_EMT macro takes one, two, or  more  parameters.
The  first  parameter  is the error-return expression and is
optional.  If supplied, the expression will be  executed  if
the  EMT  returned  with  the  carry  bit on, (indicating an
error).  If absent from the  call,  then  the  ERR_EMT  will
evaluate  into an expression that returns either TRUE (1) or
FALSE (0).  (TRUE is returned if  the  carry  bit  is  clear
after  the EMT;  indicating no errors.  False is returned if
the carry bit is set after the EMT.) The second parameter is
the  EMT number and is mandatory.  All succeeding parameters
are placed on the stack as one word values.



2.2.5.1  Implementation Differences - 

     Some differences between the macro calls documented  in
the  RT-11  System Reference Manual and those implemented in
RT11.R16 do exist.

     Perhaps the major difference is that none of the  BLISS
macros  return values in the registers.  All directives that
return a value in R0  for  MACRO-11  programs,  return  that
value as the result of the directive expression in BLISS, or
in a parameter to the macro.

     To illustrate:

          MACRO-11             BLISS
          .TTYIN CHAR         $TTYIN(CHAR);
          .LOOKUP 1,#BLK,CNT  V = $LOOKUP (1, BLK, .CNT);


     This means that all directives which return  values  in
registers  in  MACRO-11  return  those  values as either the
result of  evaluating  the  macro,  or  change  a  parameter
supplied to the macro.
SYSTEM INTERFACES.                                 Page 2-11


     In the following example, CHAR  is  where  a  character
read from the terminal will be placed.

          MACRO-11:           .TTYIN CHAR
          BLISS:              $TTYIN (CHAR);


     In this example, MACRO-11  returns  the  value  in  R0,
whereas BLISS returns it as the result of the expression.

          MACRO-11            BLISS
          .LOOKUP 1,BLK,CNT   VAL = $LOOKUP(1,.BLK,.CNT);
          MOV R0,VAL
SYSTEM INTERFACES.                                 Page 2-12


2.2.6  FCS-11

     The FCS-11 System Interface consists of  the  FCS11.R16
Require  file.  It contains a number of macros that parallel
the  ones  described  in  the  IAS/RSX-11   I/O   Operations
Reference Manual.  However, there are several differences:

     o None of the compile-time macros  are  provided  (e.g.
FDOP$A).

     o All offset and value symbols are pre-declared.

     o Only the general  calls  for  OPEN$  and  OPFID$  are
provided.

     All macro calls take their parameters in the same order
as  the  MACRO-11  macros,  (parameters, then optional error
expression).

     All  symbols  and  macros  replace  the  "."  in  their
MACRO-11 names with "$" in the BLISS names.



2.2.6.1  Additional Macros - 

     The following macros  appear  in  the  FCS11.R16  file.
They are used in most of the FCS-11 Interface macros.

     1.  %CALL(exp,err) - Used to  generate  code  depending
         upon  the presence of an error expression.  The EXP
         parameter is mandatory, and ERR is  optional.   EXP
         is  always  evaluated regardless of ERR.  If ERR is
         present, then an expression is generated such  that
         ERR  (assumed  to be an expression), is executed if
         the carry bit is set.  If ERR is  absent,  then  an
         expression  is generated such that the value of the
         %CALL invocation (at runtime) is TRUE if the  Carry
         bit  is  clear,  FALSE  if the Carry bit is set (to
         indicate error).

     2.  %CA(x,y)   -   Generates   the   BLISS   assignment
         expression  X  =  Y  only if the Y parameter is not
         null.

     3.  %CD(x,y)   -   Generates   the   BLISS   assignment
         expression  X  =  Y  only if the X parameter is not
         null.

     4.  %DEF(x,y) - Used for providing default values.   If
         X  is  absent,  then Y is generated, otherwise X is
         generated.
SYSTEM INTERFACES.                                 Page 2-13


2.2.6.2  Using FCS From BLISS Programs - 

     This section briefly describes the basic use of the FCS
System Interface in a BLISS program.



2.2.6.2.1  The FSR - 

     The File Storage Region (FSR) is declared  by  invoking
the  FSRSZ$  macro in the declaration section of the module.
The parameters of the BLISS macro are the same as  those  of
its MACRO-11 counterpart.

     The FSR is initialized by invoking the FINIT$ macro  as
a  BLISS  expression.   This  macro  parallels  its MACRO-11
counterpart, and has no parameters.



2.2.6.2.2  The FDB - 

     The FDB can be declared by using the FDB$ macro as in:

     OWN FDB1 :  FDB$;

or it can be "manually" declared using the FDB$SIZE symbol:

     OWN FDBS :  BLOCKVECTOR [FDB$SIZE] FIELD (FDB$FIELD);

     The FDB offset symbols are all defined as field  names,
so use BLOCK or BLOCKVECTOR for FDB declarations.

     To access FDB values, use the  structure  access.   For
example:

	    I = .FDBS [.CHAN, F$ERR];

		    or

	    LOCAL FDB : REF (BLOCK);
	    ...
	    FDB = FDBS [.CHAN, 0, 0, 16, 0];
	    I = .BLOCK [.FDB, F$ERR];
	    ...



2.2.6.2.3  The Dataset Block - 

     The  user  must  manually  construct   the   data   set
descriptor  block.   It  is  six  words  long  and  has  the
following format:
SYSTEM INTERFACES.                                 Page 2-14


     1.  Number of characters in the device name.

     2.  Address of the device name in ASCII.  (Without  the
         colon).

     3.  Number of characters in the UIC.

     4.  Address of the UIC string in ASCII.   (Without  the
         brackets, but with the comma.)

     5.  Number of characters in the filename.

     6.  Address of the filename in ASCII.  (With the period
         and optionally the semicolon and version number.)


     An example of how to do this in BLISS is:

	    MACRO DESC (TXT) = %CHARCOUNT (TXT), UPLIT (TXT) %;
	    OWN FBLK : VECTOR [6] INITIAL
		(DESC ('SY0'), 0, 0, DESC('FILE.EXT'));



2.2.6.2.4  The Default Filename Block - NMBLK$ - 

     The NMBLK$ macro declares a default filename block.  It
must  be  used  in  a  OWN  or GLOBAL declaration because it
expands to the VECTOR and INITIAL  attributes.   It  exactly
parallels the MACRO-11 version.

     For example:

     OWN DEFBLK :  NMBLK$ ('FILE', 'TYP', 1, 'DV', 0);
SYSTEM INTERFACES.                                 Page 2-15


2.2.7  RMS

2.2.7.1  Introduction - 

     RMS is a record management system intended for wide use
on  most Digital Operating systems.  The various releases of
RMS are described in the following documents:

          RMS-32 Functional Specification
          LDM # 130-958-049-00

          IAS/RSX-11M
          RMS-11 MACRO PROGRAMMER'S
          REFERENCE MANUAL, 1977, AA-0002A-TC

          INTRODUCTION TO RMS-11
          1977, AA-0001A-TC

RMS is accessed thru an Assembly Language Interface which is
well documented in the references cited.  The Interface from
BLISS makes  RMS  accessible  from  BLISS-16,  BLISS-32  and
BLISS-36 as well.

     The programmer wishing to use  RMS  through  the  BLISS
Interface  should  begin  his preparation by reading the RMS
documentation.

     It will be assumed in the remainder  of  this  document
that  the  reader  understands RMS and the assembly language
Interfaces to it.  It is further  assumed  that  the  reader
requires no introduction to BLISS.



2.2.7.1.1  Mechanics Of Using The BLISS Interface To RMS - 

     The BLISS Interface to RMS  is  a  Require  File  which
defines various macros, literals, etc.  The declaration:

     REQUIRE 'BLI:RMSINT';

should appear in the outermost block  of  any  module  which
uses  RMS  and must precede any declaration which relates to
RMS.  (The precise location of the file RMSINT.L??   on  the
system  where  compilation  is  being  done  is installation
dependent.)


                            NOTE

               For  VAX   systems,   RMS   is
               incorporated      into     the
               STARLET.L32 file.  So, specify
               "LIBRARY       'BLI:STARLET';"
               instead      of       "LIBRARY
SYSTEM INTERFACES.                                 Page 2-16


               'BLI:RMSINT';".





2.2.7.1.1.1  Linking With TKB - After compiling the  modules
with  BLISS-16,  it  is  necessary to link with parts of the
BLISS-16 Object Time Library and with the RMS-11 Object Time
Library,  invoking  the  Taskbuilder  as  in  the  following
example:

     TKB X=MOD_1,...,MOD_n,FORT,SAVREG,RMSLIB.OLB/LB

     (The precise location and name of the RMS-11 OLB  file,
and  of  the BLISS-16 support files FORT.OBJ and SAVREG.OBJ,
are installation dependent.)



2.2.7.1.1.2  Linking On VAX - 

     After  compiling  the  modules  with  BLISS-32,  it  is
necessary  to  link  with the RMS-32 Run Time System.  Since
this linking  is  done  automatically  by  the  VMS  Linker,
nothing more need be said here on the subject.



2.2.7.1.2  A Warning About Names - 

     Most of the names used in the RMS Interface, as well as
most  of  the  names  appearing  as  global symbols or PSECT
names, make use of the currency character ("$").

     The user of this Interface is  strongly  urged  not  to
include  this  character  in  any  of his own names so as to
avoid possible conflicts with RMS names.  (If the program is
or  becomes  transportable,  this  will  also  avoid  naming
conflicts on other systems.)



2.2.7.1.3  Notational Conventions Used In This Document - 

     The  syntax  and  semantics  of  this   Interface   are
described  in  the  following  Sections  in  terms  both  of
examples and of formal syntactic definitions.   The  present
Section   discusses  the  conventions  used  in  the  formal
syntactic definitions.

     Each formal definition is of the form:
SYSTEM INTERFACES.                                 Page 2-17


     item_defined ::= definitional_text

where the definitional_text consists of one  or  more  lines
without intervening blank lines.

     The formal syntax is intended to be used as follows.  A
user  wishing  to  include  a  particular  construct  in his
program  must  find  the  definition  of   the   appropriate
"item_defined".   He then inserts into his program a section
of code derived from the "definitional_text" associated with
that   "item_defined".    The   remainder  of  this  Section
describes how to derive code  for  a  user  program  from  a
formal "definitional_text".

     Each item within definitional_text is  of  one  of  the
following three types:

	 name_in_upper_case	 for example, ALQ0
	 name_in_lower_case	 for example, rms_all_xab
	 other_symbol		 for example, = , [ ] ,... |

     A name_in_upper_case shows a form which is to  be  used
in  the  user's  program  exactly  as shown.  (BLISS permits
lower case letters in names and treats each such lower  case
letter   as  equivalent  to  the  corresponding  upper  case
letter.) Thus, the user  wishing  to  use  the  item_defined
"foo":

     foo ::= ABC

must use "ABC" (or "abc", "aBc", etc.) in his program.

     A name_in_lower_case is the  name  of  an  item_defined
defined  elsewhere in this document, often immediately below
the point where the name_in_lower_case first  appears  in  a
definitionaltext.   A  name_in_lower_case is to be replaced,
in  the  user's  program,  by  any  character  string  which
satisfies the definition of that name.  Thus, a user wishing
to use the item_defined "xyz":

     xyz ::= ABC def GHI

     def ::= DEF

must use "ABC DEF GHI", (or "abc  def  ghi",  etc.)  in  his
program.

     Except  as  described  in  the  following   list,   all
other_symbol's appearing in definitional_text must appear in
the user's program exactly  as  shown.   Of  course,  normal
BLISS   rules   apply.    Thus,   anything   showing   in  a
definitional_text as white space  may  be  rendered  in  the
user's program as a mixture of blanks and horizontal tabs.
SYSTEM INTERFACES.                                 Page 2-18


     1.  The vertical stroke, "|", is used to  separate  two
         or  more alternatives exactly one of which is to be
         chosen.   Thus,  the  user  wishing  to   use   the
         item_defined "pdq":

              pdq ::= A | B | rms

              rms ::= R | M | S

         might use "A" or "B" or "R" or "M" or  "S"  in  his
         program.

     2.  The square brackets,  "["  and  "]",  are  used  to
         enclose  something  which  is  optional,  that  is,
         something which may either be  present  or  absent.
         Thus  the  user  wishing  to  use  the item_defined
         "bat":

              bat ::= A [ (B) ] C

         might use "A C" or "A (B) C" in his program.

     3.  The form ",..." is used after a  name_in_lower_case
         to indicate that one or more items corresponding to
         that name_in_lower_case are to appear, separated by
         commas,  in  the  user's  program.   Thus  the user
         wishing to use the item_defined "lst":

              lst ::= last ,...

              last ::= A | B | C

         might  use  "A",  or  "B",  or  "C",  or  "C,C"  or
         "A,B,C,A" or the like in his program.


                                NOTE


                  Although   the   ",..."   construction
             generally  allows  repetition  of items, no
             item of the form:

                  X = ...

             (that is, a keyword parameter)  may  appear
             more   than   once   in   a  single  ",..."
             expansion.



     4.  A name_in_lower_case ending in "_ltce" means a link
         time constant expression.  That is, such a name may
         be replaced by any BLISS expression which satisfies
         BLISS's  requirements  for  a  link  time  constant
SYSTEM INTERFACES.                                 Page 2-19


         expression.   The  nature  of  that  expression  is
         suggested  by  the initial part of the name.  Thus,
         the user wishing to use the item_defined "xad":

              xad ::= xab_addr_ltce

         might replace it, in his  program,  with  something
         like  "A",  where "A" is the name of a data segment
         used as an XAB.

     5.  A name_in_lower_case  ending  in  "_ctce"  means  a
         compile  time constant expression.  That is, such a
         name may be replaced by any BLISS expression  which
         satisfies  BLISS's  requirements for a compile time
         constant expression.  The nature of that expression
         is  suggested  by  the  initial  part  of the name.
         Thus, the user  wishing  to  use  the  item_defined
         "int":

              int ::= integer_ctce

         might replace it, in his  program,  with  something
         like "5", "2*17", or the like.

     6.  A name_in_lower_case ending in "_name" is  used  in
         the  following  Sections, though not in definitions
         as such, to hold the place of a data  segment  name
         being declared.  Such a name is to be replaced by a
         name of  the  user's  choice.   Thus  we  see,  for
         example,

              OWN pro_xab_name :  rms_pro_xab

         showing that the user program may declare an XABPRO
         (Protection  XAB) with a name (pro_xab_name) chosen
         by himself by supplying program text satisfying the
         rule:

              :  rms_pro_xab

              Thus, for example,  a  programmer  wishing  to
         create  an  XABPRO  called  PRO_01  might place the
         following text in his program:

              OWN PRO_01 :  $XABPRO();

     7.  Last, as a semantic note, let it be said that  most
         of  the  names  used  in this Interface are derived
         from the RMS three character names.  In such cases,
         the  reader  should  refer to the RMS documentation
         for information on the meaning of these names  and,
         thus, for information on the use of this Interface.
SYSTEM INTERFACES.                                 Page 2-20


2.2.7.2  Initialization Of The RMS Program - 

     In order to allow for the development of  transportable
RMS  programs, the RMS interface includes and allows for the
use of  all  the  initialization  macros  for  all  the  RMS
implementations.    Each   macro   is  implemented  in  this
Interface as an executable expression  evaluating  to  zero.
It  is convenient to code these three constructs together as
in the following example:

	 BEGIN			 ! Example of RMS Initialization
				 ! Code

	 $RMS_INITIF(); 	 ! Initialize RMS unless it has
				 ! already been initialized (e.g., by
				 ! another module).

	 $RMS_POOL(		 ! allocate private space for RMS
		 BDB , 8 ,	 ! 8 buffer descriptor blocks
		 FAB , 3 ,	 ! 3 simultaneously open files
		 RAB , 3 ,	 ! 3 simultaneous non-indexed
				 ! record access streams
		 RABX ,<4,10,2>, ! 4 simultaneous indexed record
				 ! access streams, largest key not
				 ! larger than 10 characters, at
				 ! most 2 keys change on update.
		 IDX , 2 ,	 ! 2 defined keys

		 BUF , <6*512>); ! 6 512-byte buffers needed

	 $RMS_ORG(		 ! Set up transfer vector and
				 ! external declarations
		 SEQ,<GET,PUT>,  ! No operations on SEQuential
				 ! files will be performed other than
				 ! GET, PUT, and the implied operations
				 ! of OPEN, CLOSE, CONNECT, and
				 ! DISCONNECT.
		 IDX,<GET,UPD,FIN>, ! On Indexed files, no operations
				 ! will be performed except GET, UPDATE,
				 ! FIND, and the implied operations.
		 REL,OPE);	 ! No operations will be performed
				 ! on RELative files except the
				 ! specifically named OPEN and the
				 ! operations implied.
	 END



2.2.7.2.1  $RMS_INIT And $RMS_INITIF - 

     The first executable expression directly  invoking  RMS
in  a  program  should  be one or the other of the following
two:

	 $RMS_INIT()
SYSTEM INTERFACES.                                 Page 2-21


	 $RMS_INITIF()
The second is the preferred form in cases where  the  module
may  possibly  be  linked  with  another  module which might
initialize  RMS  independently.   $RMS_INITIF()  initializes
only if no initialization has already occurred.  $RMS_INIT()
initializes unconditionally.

     Neither expression returns any form  of  status.   Each
evaluates to zero.



2.2.7.2.2  $RMS_POOL - 

     The $RMS_POOL construct serves to reserve space for the
private  use of RMS through the placing of blocks of storage
on PSECTs whose names are known to RMS.  It  is  recommended
that  exactly  one  $RMS_POOL  construct  appear  in a given
linked task.  This is not, however, a technical restriction.
If  more  than one instance of $RMS_POOL is coded in a task,
as would happen if two modules using RMS were  put  together
in  one  task,  there is the possibility that too much space
will be allocated to RMS's private use.  This possibility is
the only cost of multiple $RMS_POOL constructs.

     The syntax of this construct is as  follows  (see  also
the example in Section 2.2.7.2 above):

	 rmspool ::=	 $RMS_POOL ( rmspool_item ,... )

	 rmspool_item ::=		   bdb_item
			 | buf_item
			 | fab_item
			 | idx_item
			 | rab_item
			 | rabx_item

	 bdb_item ::=	 BDB , integer_ctce

	 buf_item ::=	 BUF , integer_ctce

	 fab_item ::=	 FAB , integer_ctce

	 idx_item ::=	 IDX , integer_ctce

	 rab_item ::=	 RAB , integer_ctce

	 rabx_item ::=	 RABX , < integer_ctce , integer_ctce ,
			  integer_ctce >
SYSTEM INTERFACES.                                 Page 2-22


2.2.7.2.3  $RMS_ORG - 

     The $RMS_ORG construct informs  RMS  which  among  many
possible  runtime  routines  will  actually  be needed for a
given program.  This information allows  RMS  to  link  only
those routines which will actually be needed into the user's
task and so to minimize its size.  This construct allows and
requires   the   user   to   specify  which  types  of  file
organization  will  be  used  in  his  program   and   which
operations  will  be  invoked  in  respect  of each of those
organizations.

     Three types of  file  organization  may  be  specified:
sequential,  indexed,  and relative.  These are referred to,
in $RMS_ORG, as SEQ, IDX, and REL.

     For each type of file  organization,  seven  operations
may  be  specified,  namely, OPEN, GET, PUT, UPDATE, CREATE,
DELETE, and FIND, each being represented by its first  three
characters  (see  syntax  below).   If,  in $RMS_ORG, a file
organization is named, one or more of these operations  must
be  specified.   Each operation implies the four operations:
OPEN, CLOSE, CONNECT, and DISCONNECT.   Thus,  for  example,
the  construct  $RMS_ORG(REL,GET) will permit the program to
OPEN, CONNECT, DISCONNECT, CLOSE, and, of course,  GET,  for
files of relative organization.

     The  linked  task  may  contain  one  or  more  modules
containing  one or more instances of the $RMS_ORG construct.
The result of multiple $RMS_ORG constructs is to specify all
the  runtime  routines specified by any of them, that is, to
specify the union of all the routines specified.

     The syntax of $RMS_ORG is  as  follows  (see  also  the
example in Section 2.2.7.2 above):

	 rmsorg ::=	 $RMS_ORG ( rmsorg_item ,... )

	 rmsorg_item ::=   idx_item
			 | rel_item
			 | seq_item


	 idx_item ::=	 IDX , use_list

	 rel_item ::=	 REL , use_list

	 seq_item ::=	 SEQ , use_list

	 use_list ::=	 use_item | <use_item ,... >

	 use_item ::=	 OPE | GET | PUT | UPD | CRE | DEL | FIN
SYSTEM INTERFACES.                                 Page 2-23


2.2.7.3  Allocation, Initialization, And Declaration Of Control Blocks - 

     RMS defines the following control blocks:

	 FAB
	 NAM
	 RAB
	 XABALL
	 XABDAT
	 XABKEY
	 XABPRO
	 XABSUM

     The BLISS Interface provides three kinds of declarative
and/or initializing macros for each of these control blocks.
These are discussed in detail  in  the  following  Sections.
The names of these constructs are of the form:

	 $x
	 $x_DECL
	 $x_INIT

where "x" takes on the values "FAB", "RAB", "XABKEY", etc.

     The form "$x" is used in a  static  declaration  (i.e.,
GLOBAL  or  OWN)  to  allocate  space  for and to statically
initialize the fields  of  the  control  block.   (In  other
words,  the  declarations of the form "$x" cause the control
block to be permanently allocated and to be  initialized  at
link  time.)  The  "$x"  form initializes every field of the
control block, using default values except where non-default
values  for  fields  are  explicitly  specified  by the user
program.  Its use is illustrated in the following examples:

	 OWN	r : $RAB(......);
	 GLOBAL f : $FAB(......);

     The form "$x_DECL" is used to declare a  control  block
without  initializing  it.   Its  use  is illustrated in the
following examples:

	 LOCAL	  f :	  $FAB_DECL;
	 MAP  param : REF $RAB_DECL;
	 EXTERNAL k :	  $XABKEY_DECL;

     The form "$x_INIT" is used as an executable expression,
having  value 0, which initializes a control block for which
space  has  already  been  allocated.   Its  parameters  are
exactly  as  for  the corresponding "$x" form except that an
additional parameter is required which specifies the address
of  the  control  block  to  be  initialized.   Its  use  is
illustrated in the following example:

	 LOCAL f : $FAB_DECL;
	 $FAB_INIT(	 ! initialize space as a FAB dynamically
SYSTEM INTERFACES.                                 Page 2-24


		 FAB=f,  ! giving the address of the control
			 ! block
		 ORG=SEQ);

     The  "$x_INIT"  form  initializes  each  field  of  the
designated  control  block, initializing with default values
except where non-default values for fields are  specifically
given  by  the  user (i.e., "ORG=SEQ" in the example above).
The default values are exactly the same as those used by the
corresponding "$x" form.

     The "$x_INIT" form thus provides for the full  "dynamic
initialization" of RMS control blocks.



2.2.7.3.1  Initializing Declarations Of Control Blocks - 

     The BLISS  Interface  provides  constructs  which  both
declare  and  initialize control blocks.  These are coded as
keyword macros and supply structure and initial  attributes.
They  may  accordingly  be  used  only  in  OWN  and  GLOBAL
declarations and may be  supplemented  by  other  (suitable)
attributes.

     The constructs provided are called:

	 $FAB
	 $NAM
	 $RAB
	 $XABALL
	 $XABDAT
	 $XABKEY
	 $XABPRO
	 $XABSUM

     Each of these is used to allocate space for the control
block   and   to   initialize   user-specified  fields  with
user-given values, unspecified fields to be initialized with
default values.  The form of use is:

     OWN p :  $x(A=B, C=D,..., Y=Z);

where the field called A  is  to  be  initialized  with  the
(link-time-constant)  value  B,  the field C with D,..., and
the field Y with Z.   All  fields  not  specified  among  A,
B,...,  Z  are  to  be initialized with a default value.  No
field name may be specified more than once in  any  instance
of one of these initializing declarations.

     Three types of initial  values  are  supported  by  the
BLISS  Interface,  and each field of a control block must be
correctly initialized with a value of its  associated  type.
(The associations between fields and initial value types are
indicated below in the formal syntax.) The  three  types  of
SYSTEM INTERFACES.                                 Page 2-25


initial values are:

     1.  RMS  specific  symbols  which  are  the  names   of
         numerical values.

              Where it is appropriate to use such a  symbol,
         exactly  one  (taken  from  the set of such symbols
         associated  with  the  field)  may  be  used.   For
         example,

              $FAB( ORG=SEQ )

     2.  RMS specific symbols which are the  names  of  bits
         (or sets of bits) within the associated field.

              In this case one or more symbols may  be  used
         in an initial value, as in these illustrations:

         		 $FAB( FAC=GET )
         		 $FAB( FAC=<GET,PUT,FIN> )

              In this case, where more than  one  symbol  is
         used to specify an initial value, the initial value
         is determined from all of the bits named.

     3.  General values.

              In this case, the initializing  value  may  be
         any   single   link-time-constant-expression,  most
         often  an  address  or  count.    This   usage   is
         illustrated:

         		 $FAB(
         		     FNA=UPLIT('abcde'),
         		     FNS=5
         			 )



                            NOTE

               Before   giving   the   formal
               syntax,  a  word  must be said
               about "large values".  Certain
               of the (logical) fields of the
               RMS control blocks are  larger
               than   one  BLISS  value.   In
               order  to  make  these  fields
               accessible,      they      are
               represented by numbered  pairs
               (or triples) of sub-fields.

                    The following table shows
               the  "large fields" of RMS and
               their      breakdown      into
SYSTEM INTERFACES.                                 Page 2-26


               accessible sub-fields:

               	 Block	 Field	 Sub-Fields
               
               	 FAB	 ALQ	 ALQ0, ALQ1
               	 FAB	 MRN	 MRN0, MRN1
               	 RAB	 BKT	 BKT0, BKT1
               	 XABALL  ALQ	 ALQ0, ALQ1
               	 XABALL  LOC	 LOC0, LOC1
               	 XABALL  RFI	 RFI0, RFI1, RFI2

                    Each of the sub-fields is
               a BLISS value.  Where a single
               integer is to  initialize  the
               "large  field",  the ALQ field
               of the FAB  for  example,  the
               low-order  bits  of the 32-bit
               value   must    be    assigned
               explicitly by the user program
               to the xxx0 sub-field and  the
               high-order  bits  to  the xxx1
               sub-field.  Where this must be
               done, the user should refer to
               RMS    documentation.      The
               following  is  an  example  of
               such an initialization:

               	 $FAB(
               		 ALQ0=%O'034567',	 ! Assign octal value
               		 ALQ1=%O'05'		 ! 1234567 to ALQ
               	     )

                    In    considering    this
               example,   it   is   well   to
               remember that neither  decimal
               nor  octal  representations of
               numbers fit nicely into  BLISS
               values.    Thus,  in  breaking
               down the octal value  1234567,
               it is necessary (for PDP-11s),
               to split off the lower 16 bits
               as  the  lower  16 bits of the
               18-bit octal value 034567  and
               to  code  the high-order bits,
               corresponding      to      the
               high-order 5 bits of the 6-bit
               octal value 12, as 05.



     The  formal  syntax  for  each  of   the   initializing
declarations is described in the following Sections.
SYSTEM INTERFACES.                                 Page 2-27


2.2.7.3.1.1  FAB - 

     Allocation   and   initialization   of   the   FAB   is
accomplished  by an OWN or GLOBAL declaration of the name of
the FAB of the form:

     OWN fab_name :  rmsfab

where *'ed items are RMS-11 specific,  +'ed  items  are  VAX
specific, and $'ed items are RMS-20 specific:

	 rmsfab ::=	 $FAB ( [ fab_item ,... ] )

	 fab_item ::=	   ALQ = integer_ltce (+)
			 | ALQ0= integer_ltce (*)
			 | ALQ1= integer_ltce (*)
			 | BKS = integer_ltce
			 | BLS = integer_ltce
			 | BPA = buffer_pool_addr_ltce
			 | BPS = integer_ltce
			 | CTX = any_user_value_ltce
			 | DEQ = integer_ltce
			 | DNA = default_name_string_addr_ltce
			 | DNS = integer_ltce
			 | FAC = fac_options
			 | FNA = file_name_string_addr_ltce
			 | FNS = integer_ltce
			 | FOP = fop_options
			 | FSZ = integer_ltce
			 | JNL = log_block_addr_ltce
			 | LCH = integer_ltce
			 | MRN = integer_ltce (+)
			 | MRN0= integer_ltce (*)
			 | MRN1= integer_ltce (*)
			 | MRS = integer_ltce
			 | NAM = nam_block_addr_ltce
			 | ORG = org_item
			 | RAT = rat_options
			 | RFM = rfm_item
			 | RTV = integer_ltce
			 | SHR = shr_options
			 | XAB = xab_addr_ltce

	 fac_options ::= fac_item | <fac_item ,... >

	 fac_item ::=	   BIO
			 | BRO (+)
			 | DEL
			 | GET
			 | PUT
			 | REA (*)
			 | TRN
			 | UPD
			 | WRT (*)
SYSTEM INTERFACES.                                 Page 2-28


	 shr_options ::= shr_item | <shr_item ,... >

	 shr_item ::=	   BIO (*)
			 | DEL
			 | GET
			 | MSE (+)
			 | NIL
			 | PUT
			 | REA (*)
			 | TRN (*)
			 | UPD
			 | WRI (*)
			 | WRT (*)

	 org_item ::=	 | DIR (+)
			 | HSH (*)
			 | IDX
			 | REL
			 | SEQ
			 | DBM (*)

	 rat_options ::= rat_item | < rat_item ,... >

	 rat_item ::=	   BLK
			 | CBL (+)
			 | PRN
			 | CR
			 | FTN

	 fop_options ::= fop_item | < fop_item ,... >

	 fop_item ::=	   ACK (*)
			 | CIF (+)
			 | CTG
			 | DFW (*)
			 | DLK
			 | DMO (+)
			 | FID (*)
			 | INP (+)
			 | JNL
			 | LKO (+)
			 | MKD (*)
			 | MXV (+)
			 | NAM (+)
			 | NEF
			 | NFS (+)
			 | POS
			 | PPF (+)
			 | RCK (+)
			 | RWC
			 | RWO
			 | SQO (+)
			 | SUP
			 | TMD (+)
			 | TMP
SYSTEM INTERFACES.                                 Page 2-29


			 | UFO (+)
			 | WAT (*)
			 | WCK (+)

	 rfm_item ::=	   FIX
			 | STM (*)
			 | UDF
			 | VAR
			 | VFC

     Fields that may be accessed but may not be  initialized
are:

	 BID
	 BLN
	 DEV
	 IFI
	 SDC
	 STS
	 STV

     Non-zero default values are:

	 BKS = 1
	 BLS = 512
	 FAC = GET
	 ORG = SEQ
	 RFM = VAR
	 SHR = GET



2.2.7.3.1.2  RAB - 

     Allocation   and   initialization   of   the   RAB   is
accomplished  by an OWN or GLOBAL declaration of the name of
the RAB of the form:

     OWN rab_name :  rmsrab

where:

	 rmsrab ::=	 $RAB ( [ rab_item ,... ] )

	 rab_item ::=	   ASYN=     ASYN_item
			 | BKT = integer_ltce (+)
			 | BKT0= integer_ltce (*)
			 | BKT1= integer_ltce (*)
			 | CTX = any_user_value_ltce
			 | FAB = fab_block_addr_ltce
			 | KBF = key_buf_addr_ltce
			 | KRF = integer_ltce
			 | KSZ = integer_ltce
			 | MBC = integer_ltce (+)
			 | MBF = integer_ltce
SYSTEM INTERFACES.                                 Page 2-30


			 | PBF = prompt_string_addr_ltce (+)
			 | PSZ = integer_ltce (+)
			 | RAC = rac_item
			 | RBF = record_addr_ltce
			 | RHB = header_addr_ltce
			 | ROP = rop_options
			 | RSZ = integer_ltce
			 | TMO = integer_ltce (+)
			 | UBF = buffer_addr_ltce
			 | USZ = integer_ltce

	 asyn_item ::=	   YES
			 | NO or any lexeme other than YES

	 rac_item ::=	   KEY
			 | RFA
			 | SEQ

	 rop_options ::=   ASY
			 | CCO (+)
			 | CVT (+)
			 | EOF
			 | FDL
			 | HSH
			 | KGE
			 | KGT
			 | LOA
			 | LOC
			 | LOK (*)
			 | MAS
			 | PMT (+)
			 | PTA (+)
			 | RAH
			 | RLK (*)
			 | RNE (+)
			 | RNF (+)
			 | TMO (+)
			 | UIF
			 | ULK
			 | WAT (*)
			 | WBH

     Fields that may be accessed but may not be  initialized
are:

	 BID
	 BLN
	 ISI
	 RFA
	 STS
	 STV

     Non-zero default values are:
SYSTEM INTERFACES.                                 Page 2-31


     1.  ASYN = NO implying the shorter  RAB  allowing  only
         synchronous    transmissions.     Only   the   form
         "ASYN=YES" will result in the larger RAB needed for
         asynchronous operations.

     2.  RAC = SEQ




2.2.7.3.1.3  NAM - 

     Allocation   and   initialization   of   the   NAM   is
accomplished  by an OWN or GLOBAL declaration of the name of
the NAM of the form:

     OWN nam_name :  rmsnam

where:

	 rmsnam ::=	 $NAM ( [ nam_item ,... ] )

	 nam_item ::=	   ESA = ex_str_addr_ltce
			 | ESS = integer_ltce
			 | RLF = fab_addr_ltce
			 | RSA = res_str_addr_ltce
			 | RSS = integer_ltce

     Fields that may be accessed but may not be  initialized
are:

	 DID
	 DVI
	 ESL
	 FID
	 FNB
	 RSL
	 WCC

     Non-zero default values are:

     (None)



2.2.7.3.1.4  XABFHC (RMS-32 Only) - 

     Allocation  and  initialization  of   the   XABFHC   is
accomplished  by an OWN or GLOBAL declaration of the name of
the XABFHC of the form:

     OWN fhcxabname :  rmsfhcxab

where:
SYSTEM INTERFACES.                                 Page 2-32


     rmsfhcxab ::= $XABFHC ( [ fhcitem ,...  ] )

     fhcitem ::= NXT = xabaddrltce 

     Fields which may be  accessed  but  which  may  not  be
initialized:
         ATR
         BKZ
         BLN
         COD
         DXQ
         EBK
         FFB
         HBK
         HSZ
         LRL
         MRZ
         RFO
         SBN

     Non-zero default values:

     (None)



2.2.7.3.1.5  XABKEY (RMS-11 Only) - 

     Allocation  and  initialization  of   the   XABKEY   is
accomplished  by an OWN or GLOBAL declaration of the name of
the XABKEY of the form:

     OWN key_xab_name :  rms_key_xab

where:

	 rms_key_xab ::= $XABKEY ( [ key_item ,... ] )

	 key_item ::=	   DAN = integer_ltce
			 | DFL = integer_ltce
			 | DTP = dtp_item
			 | FLG = flg_options
			 | HAL = integer_ltce
			 | IAN = integer_ltce
			 | IFL = integer_ltce
			 | KNM = key_name_xaddr_ltce
			 | LAN = integer_ltce
			 | NUL = integer_ltce
			 | NXT = xab_addr_ltce
			 | POS = < integer_ltce ,... >
			 | RFF = integer_ltce
			 | SIZ = < integer_ltce ,... >
                            NOTE

               It is an error to specify more
               than  8  integers  in a POS or
               SIZ parameter.


	 flg_options ::= flg_item | < flg_item ,... >

	 flg_item ::=	   CHG
			 | DUP
			 | INI
			 | NUL

	 dtp_item ::=	   BN2
			 | BN4
			 | IN2
			 | IN4
			 | PAC
			 | STG

     Fields that may be accessed but may not be  initialized
are:

	 COD
	 RVB

     Non-zero default values are:

	 DTP = STG
	 POS = <0,0,0,0,0,0,0,0>
	 SIX = <0,0,0,0,0,0,0,0>



2.2.7.3.1.6  XABDAT - 

     Allocation  and  initialization  of   the   XABDAT   is
accomplished  by an OWN or GLOBAL declaration of the name of
the XABDAT of the form:

     OWN dat_xab_name :  rms_dat_xab

where:

	 rms_dat_xab ::= $XABDAT ( [ dat_item ,... ] )

	 dat_item ::=	   NXT = xab_addr_ltce
			 | RVN = integer_ltce (*)
			 | EDT0= integer_ltce (+)
			 | EDT4= integer_ltce (+)


     Fields that may be accessed but may not be  initialized
are:

	 BLN (+)
	 CDT
SYSTEM INTERFACES.                                 Page 2-34


	 CDT0 (+)
	 CDT4 (+)
	 COD
	 EDT
	 RDT
	 RDT0 (+)
	 RDT4 (+)
	 RVN (+)


     Non-zero default values are:

     (None)



2.2.7.3.1.7  XABPRO - 

     Allocation  and  initialization  of   the   XABPRO   is
accomplished  by an OWN or GLOBAL declaration of the name of
the XABPRO of the form:

     OWN pro_xab_name :  rms_pro_xab

where:

	 rms_pro_xab ::= $XABPRO ( [ pro_item ,... ] )

	 pro_item ::=	   NXT = xab_addr_ltce
			 | PRO = < prot , prot , prot , prot >
			 | UIC = < integer_ltce , integer_ltce >

	 prot ::=	 zero to four letters from among RWED

     Fields that may be accessed but may not be  initialized
are:

	 COD
	 BLN (+)

     Non-zero default values are:

	 PRO = <RWED,RWED,RWED,RWED>
	 UIC = <0,0>



2.2.7.3.1.8  XABALL - 

     Allocation  and  initialization  of   the   XABALL   is
accomplished  by an OWN or GLOBAL declaration of the name of
the XABALL of the form:
SYSTEM INTERFACES.                                 Page 2-35


     OWN all_xab_name :  rms_all_xab

where:

	 rms_all_xab ::= $XABALL ( [ all_item ,... ] )

	 all_item ::=	   ALN = aln_item
			 | ALQ = integer_ltce (+)
			 | ALQ0= integer_ltce (*)
			 | ALQ1= integer_ltce (*)
			 | AOP = aop_options
			 | LOC = integer_ltce (+)
			 | LOC0= integer_ltce (*)
			 | LOC1= integer_ltce (*)
			 | NXT = xab_addr_ltce
			 | RFI = < integer_ltce ,
				   integer_ltce ,
				   integer_ltce >
			 | VOL = integer_ltce

	 aln_item ::=	   CYL
			 | LBN
			 | RFI
			 | VBN

	 aop_options ::= aop_item | < aop_item ,... >

	 aop_item ::=	   CTG (*)
			 | HRD

     Fields that may be accessed but may not be  initialized
are:

     AID (+)

     BKZ (+)

     BLN (+)

     COD

     DEQ (+)

     Non-zero default values are:

	 ALN = ANY (+)
	 ALN = VBN (*)
	 RFI = <0,0,0>
SYSTEM INTERFACES.                                 Page 2-36


2.2.7.3.1.9  XABSUM (RMS-11 Only) - 

     Allocation  and  initialization  of   the   XABSUM   is
accomplished  by an OWN or GLOBAL declaration of the name of
the XABSUM of the form:

     OWN sum_xab_name :  rms_sum_xab

where:

	 rms_sum_xab ::= $XABSUM ( [ sum_item ] )

	 sum_item ::=	 NXT = xab_addr_ltce

     Fields that may be accessed but may not be  initialized
are:

	 COD
	 NOA
	 NOK
	 NOR

     Non-zero default values are:

     (None)



2.2.7.3.2  Non-initializing Declarations Of Control Blocks - 

     The   BLISS   Interface    provides    the    following
non-initializing   declarative   constructs,  as  introduced
above:

	 $FAB_DECL
	 $NAM_DECL
	 $RAB_DECL
	 $XABALL_DECL
	 $XABDAT_DECL
	 $XABKEY_DECL
	 $XABPRO_DECL
	 $XABSUM_DECL

	 and

	 $RAB_DECL_ASYN

     These declarations are used in LOCAL, MAP, EXTERNAL, or
other  non-initializing declarative contexts for the purpose
of declaring a name to be that  of  a  control  block  of  a
particular kind.  A name must be declared as a control block
if the  field  accessing  mechanisms  described  in  Section
2.2.7.4  are  to  be  used.  An example of the use of one of
these constructs follows:
SYSTEM INTERFACES.                                 Page 2-37


	 ROUTINE RR(FAB1)=
		 BEGIN
		 MAP FAB1 : REF $FAB_DECL;	 ! FAB1 points to
						 ! a FAB control block.
		 IF .FAB1[FAB$B_ORG] EQL FAB$C_REL
		 THEN ...			 ! Test the ORG field
						 ! of this FAB ...
		 ...
		 END;

     Each of these is coded as a macro  specifying  no  more
than a structure attribute of the form:

     BLOCK[size-in-bytes,BYTE]

     and may be used with other  appropriate  attributes  in
any data declaration, e.g.:

     STACKLOCAL f :  $FAB_DECL VOLATILE;

     Two  non-initializing  declarations  for  the  RAB  are
provided:

     $RAB_DECL_ASYN

     $RAB_DECL

     The first is provided to allow the declaration of a RAB
intended  for asynchronous use, which is longer than the RAB
intended only  for  synchronous  use.   $RAB_DECL_ASYN  thus
corresponds   to  the  initializing  declaration,  described
below,

     $RAB( ...  ASYN=YES ...)

     The construct $RAB_DECL declares a  RAB  intended  only
for  synchronous use and thus corresponds to an initializing
declaration such as:

     $RAB( ...  ASYN=NO ....)

or to a $RAB declaration which doesn't mention ASYN.



2.2.7.3.3  Dynamic Initialization Of Control Blocks - 

     The  BLISS  Interface  provides   constructions   which
dynamically  initialize  a  block  of  storage  as a control
block.  These are coded as keyword  macros  to  be  used  as
executable expressions evaluating to zero.
                            NOTE

               The   following    definitions
               refer   to  definitions  which
               were    given    in    Section
               2.2.7.3.1      above.      The
               semantics of those definitions
               is  relaxed when they are used
               for dynamic initializations as
               follows:

                    The  requirement  that  a
               value  be a link time constant
               expression does not apply when
               that  value  is  assigned in a
               dynamic  initialization.   The
               value   of   a  general  BLISS
               expression may be used.



     An example of the use of a dynamic  initializing  macro
is the following:

	 BEGIN
	 ...
	 EXTERNAL ROUTINE GET_SPACE;	 ! Returns pointer to space
	 LOCAL DYN_FAB; 		 ! Will hold pointer to
					 ! dynamically allocated FAB
	 ...
	 DYN_FAB = GET_SPACE(FAB$C_BLN); ! Get and save pointer to FAB
	 $FAB_INIT(			 ! Initialize as a FAB
		 FAB = .DYN_FAB,	 ! the space pointed to
		 FAC = <GET,PUT>,	 ! by DYN_FAB
		 DNA = UPLIT('TI:'),	 ! with default initial values
		 DNS = 3		 ! except as explicitly
		 );			 ! provided, e.g., for DNS
	 ...
	 $OPEN( FAB = .DYN_FAB );
	 ...
	 END

     The  formal  syntax  for  the  dynamic   initialization
constructs is as follows:

	 dynamic_fab_init ::=	 $FAB_INIT( d_fab_item ,... )

	 d_fab_item ::= 	   FAB = control_block_addr
				 | fab_item

	 dynamic_rab_init ::=	 $RAB_INIT( d_rab_item ,... )

	 d_rab_item ::= 	   RAB = control_block_addr
				 | rab_item

	 dynamic_nam_init ::=	 $NAM_INIT( d_nam_item ,... )

	 d_nam_item ::= 	   NAM = control_block_addr
SYSTEM INTERFACES.                                 Page 2-39


				 | nam_item

	 dynamic_key_init ::=	 $XABKEY_INIT( d_key_item ,... )

	 d_key_item ::= 	   XAB = control_block_addr
				 | key_item

	 dynamic_dat_init ::=	 $XABDAT_INIT( d_dat_item ,... )

	 d_dat_item ::= 	   XAB = control_block_addr
				 | dat_item

	 dynamic_pro_init ::=	 $XABPRO_INIT( d_pro_item ,... )

	 d_pro_item ::= 	   XAB = control_block_addr
				 | pro_item

	 dynamic_all_init ::=	 $XABALL_INIT( d_all_item ,... )

	 d_all_item ::= 	   XAB = control_block_addr
				 | all_item

	 dynamic_sum_init ::=	 $XABSUM_INIT( d_sum_item ,... )

	 d_sum_item ::= 	   XAB = control_block_addr
				 | sum_item

	 control_block_addr ::=  any BLISS expression evaluating
				 to the address of a control block.


                            NOTE

               In all of the foregoing syntax
               definitions,   the   parameter
               which assigns the  address  of
               the     control    block    is
               mandatory.      All      other
               parameters are optional.



     The semantics of the dynamic initialization  constructs
are  as  follows.  Each such construct evaluates the control
block address expression and saves the address so  obtained.
A  block of correct length beginning at that address is then
zeroed.  Next, all expressions given for  field  values  are
then evaluated and their values stored appropriately.  Where
no other value is specified  for  a  field  of  the  control
block, the default value, if non-zero, will be stored.

     The order of evaluation of expressions  during  such  a
dynamic initialization is not defined.
SYSTEM INTERFACES.                                 Page 2-40


2.2.7.4  The Fields Of The RMS Control Blocks, - Their
Associated Values, Sub-fields, and Masks

     This Section discusses the naming and accessing of  the
fields  of  the  control  blocks  of  RMS,  the  naming  and
accessing of their sub-fields,  where  applicable,  and  the
naming  and  use of masks and literal values associated with
the fields, where applicable.

     The conventions for naming fields,  sub-fields,  masks,
and   values   in   this  Interface  are  derived  from  the
conventions established for VAX/VMS, the first DEC system to
develop  conventions  for  names  longer  than 6 characters.
They are used here both for their intrinsic value and as  an
aid  to  transportability  of  RMS  programs between RMS-11,
RMS-20, and RMS-32.

     Each name is of the form:

     aaa$b_ccc

where "aaa" is the control block  designator  (and  must  be
"FAB", "RAB", "NAM", or "XAB"), "b" is a special code, to be
discussed below, and "ccc" is the three character  RMS  name
for the field, sub-field, mask, or value.

     The names of fields are in one of the  following  three
formats:

	 aaa$B_ccc		 B: Byte (8-bits)
	 aaa$W_ccc		 W: Word (16-bits)
	 aaa$L_ccc		 L: Longword (32-bits)
	 aaa$Q_ccc		 Q: Quadword (64-bits)
	 aaa$Z_ccc		 Z: more than 16-bits for RMS-11,
				    more than 64-bits for VAX

     Note that the name is according to the  field  size  in
RMS-32,  which  is  not  necessarily  the  same  in  all RMS
implementations.  Field names (except those with  "$Z_",  or
"$Q_")  are  used  to  store into and extract from the named
field as illustrated in this example:

	 BEGIN
	 LOCAL E;
	 OWN F : $FAB();
	 ...
	 E = .F[FAB$B_ORG];
	 F[FAB$L_DNA] = UPLIT('[1,1]A.B');
	 ...
	 END

     Where (logical) fields are larger than a word and hence
have   names   of  the  form  "aaa$Z_ccc",  or  "aaa$Q_ccc",
additional names of the form "aaa$W_ccc0", "aaa$W_ccc1", and
"aaa$W_ccc2"  have  usually  been made available by means of
SYSTEM INTERFACES.                                 Page 2-41


which the user may access the first, second, and third words
of  the  large  field, respectively (as appropriate).  Where
names for the sub-fields have not been provided (namely, for
RAB$Z_RFA,  NAM$Z_DVI,  NAM$Z_FID, and NAM$Z_DID), it is not
expected that the user will wish to access  the  sub-fields.
Where  this  is neccessary, the address of a $Z field can be
obtained as follows:

	 BEGIN
	 LOCAL ADDRESS;
	 ...
	 ADDRESS = R[RAB$Z_RFA];	! NOTE NO DOT ON R.
	 ...
	 END

     Certain fields, namely those thought of as bit strings,
have  named  sub-fields  and related named masks.  The names
for bit sub-fields and for masks are of the following forms:

	 aaa$V_ccc		 V: Bit Sub-fields
	 aaa$M_ccc		 M: Masks

     Examples of storing into and extracting from named  bit
sub-fields, and of the use of named masks, are given next:

	 BEGIN
	 LOCAL R : $RAB_DECL;
	 LOCAL X;
	 ...
	 R[RAB$V_EOF] = 1;	 ! Set the EOF bit of
				 ! the ROP field of the
				 ! RAB named R.

	 X = .R[RAB$V_ASY];	 ! Extract the ASY bit
				 ! of the same RAB.

	 R[RAB$L_ROP] =
		 RAB$M_KGE OR	 ! Set the KGE,
		 RAB$M_KGT OR	 ! KGT, and EOF bits
		 RAB$M_EOF;	 ! in the ROP field of R,
				 ! clearing all other bits.

	 R[RAB$V_KGE] = 1;	 ! Set the KGE,
	 R[RAB$V_KGT] = 1;	 ! KGT, and EOF bits
	 R[RAB$V_EOF] = 1;	 ! in the ROP field of R,
				 ! leaving all other bits
				 ! unchanged.

     It is often necessary to test for the values of one  or
more  bits  in a bit-string field.  Examples of testing code
follow:

	 IF .R[RAB$V_ASY]
	 THEN ...
SYSTEM INTERFACES.                                 Page 2-42


	 IF (.R[RAB$L_ROP] AND (RAB$M_ASY OR RAB$M_EOF)) NEQ 0
	 THEN ...

     Please note that names of sub-fields  are  semantically
and  syntactically  equivalent to names of fields:  the name
of a sub-field is used to store into and  extract  from  the
sub-field which it identifies just as the name of a field is
used to store into and  extract  from  the  field  which  it
identifies.   A  mask, on the other hand, is a literal whose
value is determined only by the position of the  bit  within
its  containing  field and not by the position of that field
within the control block.

     Certain fields take specific named literals (constants)
as  values rather than general values.  These named literals
have names of the form:

	 aaa$C__ccc		    C: Constant

     Such named literals are used  as  illustrated  in  this
example:

	 BEGIN
	 LOCAL R : $RAB_DECL;
	 ...
	 R[RAB$B_RAC] = RAB$C_KEY;
	 IF .R[RAB$B_RAC] NEQ RAB$C_SEQ THEN ...
	 ...
	 END



2.2.7.5  Calling The Executable Functions Of RMS - 

     The names of the runtime  functions  are  the  same  as
those used in MACRO-11, MARS, and MACRO-20.

     The constructs provided  by  the  BLISS  Interface  for
invoking  the  RMS  runtime  functions  are coded as keyword
macros.  Thus, as may be seen in the following example,  the
parameters  may  appear  in any order and must be written in
the form of assignments.

	 BEGIN
	 LOCAL STATUS;

	 EXTERNAL ROUTINE
		 S : FORTRAN NOVALUE,	 ! Success Handler
		 F : FORTRAN NOVALUE;	 ! Failure Handler

	 OWN FAB01: $FAB();
	 GLOBAL RAB01: $RAB();
	 ...
	 STATUS = $OPEN( ERR=F, FAB=FAB01 );
	 STATUS = $CONNECT( SUC=S, RAB=RAB01, ERR=F );
SYSTEM INTERFACES.                                 Page 2-43


	 STATUS = $GET( RAB=RAB01 );
	 ...
	 END

     As illustrated in the preceding example, each call (via
the  BLISS  Interface)  on  an  RMS runtime function returns
status.  The status value returned is the value (at the time
the  function  returns)  of  the STS field of the FAB or RAB
with which the function was called.   RMS  itself  does  not
return   status   from  the  functional  calls.   The  BLISS
Interface does so both as a convenience to the user  and  to
maintain  conformity  with  RMS-20  and  RMS-32 which return
status normally.  The testing of status values is  discussed
in Section 2.2.7.6.

     The  formal  syntax  for  invocations  of  the  runtime
functions is:

	 rmscall ::=	 $name ( op_arg ,... )

	 op_arg  ::=	 cb_arg | err_arg | suc_arg

	 cb_arg  ::=	 FAB = name | RAB = name

	 err_arg ::=	 ERR = name

	 suc_arg ::=	 SUC = name

     The  syntax  of  these  invocations   imposes   further
restrictions.   First,  each  invocation must have a cb_arg.
Second, this cb_arg must be of the right type.  Third,  some
invocations  allow  a  suc_arg  and  others  do  not.  These
further restrictions are set out in the following table.

	$name		cb_arg		optional
			required	parameters


	$CLOSE		FAB		ERR
	$CONNECT	RAB		ERR,SUC
	$CREATE    	FAB		ERR
	$DELETE    	RAB		ERR,SUC
	$DISCONNECT	RAB		ERR,SUC
	$DISPLAY   	FAB		ERR
	$ERASE	   	FAB		ERR
	$EXTEND    	FAB		ERR
	$FIND	   	RAB		ERR,SUC
	$FLUSH	   	RAB		ERR,SUC
	$FREE	   	RAB		ERR,SUC
	$GET	   	RAB		ERR,SUC
	$NXTVOL    	RAB		ERR,SUC
	$OPEN	   	FAB		ERR
	$PUT	   	RAB		ERR,SUC
	$READ	   	RAB		ERR,SUC
	$RELEASE   	RAB		ERR,SUC
SYSTEM INTERFACES.                                 Page 2-44


	$REWIND    	RAB		ERR,SUC
	$SPACE	   	RAB		ERR,SUC
	$TRUNCATE  	RAB		ERR,SUC
	$UPDATE    	RAB		ERR,SUC
	$WAIT	   	RAB
	$WRITE	   	RAB		ERR,SUC



2.2.7.5.1  Success And Error Handlers - 

     RMS accepts, as optional parameters  in  calls  on  its
executable  functions,  the  specification of success and/or
error handling routines.  Such routines, if  specified,  are
called  in  the  manner and at the time described in the RMS
documentation.

     Success and  error  handlers  are  coded  in  BLISS  as
NOVALUE  routines  of  the  FORTRAN  linkage  type,  and  in
BLISS-32 as routines with just the NOVALUE attribute.   Each
is  called  with  a single parameter, the RAB or FAB address
which was passed to RMS when the function was  called  whose
success  or  failure  caused invocation of the handler.  The
following example shows the  coding  and  use  of  an  error
handler:

	 BEGIN
	 ROUTINE NO_GOOD(RABX) : NOVALUE FORTRAN =
		 BEGIN
		 MAP RABX : REF $RAB_DECL;
		 ... . .
		 END;
	 OWN RAB01 : $RAB(...);
	 $GET(RAB=RAB01,ERR=NO_GOOD);
	 ...
	 END




2.2.7.6  Status (Completion) Codes Of RMS - 

     RMS returns status (or completion)  codes  in  the  STS
fields  of RAB and FAB for all functional invocations.  This
value is also returned  as  a  return  value  by  the  BLISS
function invocations (RMS itself does not return a value).

     The  BLISS  Interface  supplies  three  constructs  for
examining    status    values:    $RMS_OK,   $RMS_SUC,   and
$RMS_OKSTATUS.

     The  construct  $RMS_OK  takes  a   status   value   as
parameter, and evaluates to 1 if the actual parameter is one
of RMS's non-error status values and to 0 otherwise.
SYSTEM INTERFACES.                                 Page 2-45


     The  construct  $RMS_SUC  takes  a  status   value   as
parameter,  and  evaluates  to  1 if the actual parameter is
RMS's  unqualified  success  value  (called  SU$SUC  in  the
Assembly  Language  Interface  and  RMS$_OK_SUC in the BLISS
Interface), and to 0 otherwise.

     $RMS_OK and $RMS_SUC are used  as  illustrated  in  the
following example:

	 BEGIN
	 LOCAL STATUS;
	 OWN R : $RAB();
	 ...
	 STATUS = $GET(RAB=R);
	 IF $RMS_SUC(.STATUS) THEN ...
	 ...
	 IF $RMS_OK ( $PUT(RAB=R) ) THEN ...
	 ...
	 IF $RMS_SUC(.R[RAB$L_STS]) THEN ...
	 ...
	 END

     $RMS_OKSTATUS, invoked with the name of a RAB or FAB as
in the following example, evaluates to 1 if the STS field in
that RAB or FAB  contains  one  of  RMS's  non-error  status
values,  and  evaluates  to  0 otherwise.  It may be used as
follows:

	 BEGIN
	 OWN R : $RAB_DECL;
	 ...
	 $GET(RAB=R);
	 IF $RMS_OKSTATUS(R) THEN ...	 ! No error
	 $PUT(RAB=R);
	 IF NOT $RMS_OKSTATUS(R) THEN .. ! It is as error
	 ...
	 END



2.2.7.6.0.1  RMS-11 Status Values - 

     The names  of  the  status  values  themselves  in  the
BLISS-16  Interface  are  derived  from  their  names in the
Assembly Language Interface by this rule:

	 SU$XXX  - - >	 RMS$_OK_XXX
	 ER$XXX  - - >	 RMS$_XXX

     A few examples may be helpful:

	 RMS$_OK_SUC	 ! Operation successful
	 RMS$_OK_DUP	 ! Record inserted with duplicated key
	 RMS$_OK_IDX	 ! Index update error, record inserted
	 RMS$_OK_RRV	 ! RMS unable to update one or
SYSTEM INTERFACES.                                 Page 2-46


			 ! more RRVs ...

	 RMS$_ABO	 ! Operation aborted
	 RMS$_ACC	 ! F11ACP could not access file



2.2.7.6.0.2  RMS-32 Status Values - 

     RMS-32's status values have not been made part of  this
interface.   The  user  wishing  to  use a status value must
declare it as  an  external  literal  as  in  the  following
example:

	BEGIN
	EXTERNAL LITERAL RMS$_EOF;
	...
	IF $RMS_GET(...) EQL RMS$_EOF THEN ...
	...
	END



2.2.7.7  Summary Of Conventions, BLISS Interface To RMS - 

     Constructs to declare, allocate, and initialize control
blocks have names of the form:

	 $x		 e.g., $RAB, $FAB, $XABKEY

     Constructs to declare but not initialize control blocks
have names of the form:

	 $x_DECL	 e.g., $RAB_DECL, $FAB_DECL,
			       $XABKEY_DECL

			 also the special $RAB_DECL_ASYN
			 which declares the asynchronous
			 RAB without initialization.

     Constructs  to  initialize,  but  neither  declare  nor
allocate, control blocks have names of the form:

	 $x__INIT	 e.g., $XABKEY__INIT, $NAM__INIT

     Fields are named as follows:

	 aaa$B_ccc	 B: Byte sized fields
	 aaa$W_ccc	 W: Word sized fields
	 aaa$L_ccc	 L: Longword sized fields
	 aaa$Q_ccc	 Q: Quadword sized fields (RMS-32 only)
	 aaa$Z_ccc	 Z: Fields larger than 16 or 32 bits

where "aaa" is a three character code for the control block,
i.e.,  "FAB",  "RAB", "NAM", or "XAB";  and where "ccc" is a
SYSTEM INTERFACES.                                 Page 2-47


three character code for the field's name,  the  code  being
specified  by  RMS.   In  some  cases, namely the word-sized
sub-fields of fields of 32 or 48 bits, the names have a four
character  field  name part.  Thus, to FAB$Z_ALQ corresponds
FAB$W_ALQ0 and FAB$W_ALQ1.

     Sub-fields and masks have names of the following forms:

	 aaa$V_ccc	 V: Sub-fields
	 aaa$M_ccc	 M: Masks

where "aaa" and "ccc" arise through the convention described
above.

     Named constants have names of the form:

     aaa$C_ccc C:  Constant

with "aaa" and "ccc" as before.

     Status (completion) codes have names of  the  following
forms:

	 RMS$_OK_ccc	 _OK_: Not an error,
			 RMS$_OK_SUC being the code
			 returned for unqualified success.
	 RMS$_ccc	 An error code.

     The names of the RMS executable functions, of  the  RMS
initializing  constructs,  and of other macros have names of
the following forms:

	$RMS_name	$RMS_INIT, $RMS_INITIF, $RMS_ORG,
			$RMS_POOL

	$name		e.g. $OPEN, $PUT, $GET, $TRUNCATE

     The reader of code, having  different  needs  from  the
writer  of  code, may be helped by the following list, which
lists the types of names "alphabetically":

	aaa$B_ccc	Name of a byte size field (on VAX).

	aaa$C_ccc	Name of a constant.

	aaa$L_ccc	Name of a longword size field (on VAX).

	aaa$M_ccc	Name of a bit mask.

	aaa$V_ccc	Name of a sub-field or field
			of size other than byte or word.

	aaa$W_ccc	Name of a word sized field (on VAX).

	aaa$Z_ccc	Name of a field larger than a word.
SYSTEM INTERFACES.                                 Page 2-48



	RMS$_OK_SUC	The unqualified success status code.

	RMS$_OK_ccc	A status or completion code
			showing qualified success.

	RMS$_ccc	A status or completion code showing an error.

	$RMS_INIT	Construct to initialize RMS unconditionally.

	$RMS_INITIF	Construct to initialize RMS conditionally.

	$RMS_ORG	Construct to declare the types of file
			organizations that will be used and the
			operations in respect of each that will
			be used.

	$RMS_POOL	Construct to provide space for RMS
			internal purposes.

	$ccc		Name of an executable function.

	$x		A macro for declaring, allocating, and
			initializing a control block.

	$x_DECL		A macro for declaring a control block
			without initializing it.

	$x_INIT		A macro for initializing a control block
			dynamically, neither declaring nor allocating it.



2.2.7.8  Example - 

     The following is a working example which may be used to
copy  the  un-line-numbered output of the RSX-11M SOS editor
to another, also un-line-numbered, file.




MODULE TEST01 (MAIN=START,IDENT='0001')=
BEGIN


!++
!
! Program to make a copy of an
! Un-Line-Numbered (SOS) ASCII File
!
!--


    LIBRARY 'BLI:RMSINT';
SYSTEM INTERFACES.                                 Page 2-49



    OWN
	RSIZ,				 ! space for MSG to keep
	RBUF;				 ! RAB$W_RSZ and RAB$L_RBF
					 ! temporarily

MACRO
    MSG(RABNAME)[]=			 ! to type a message
	(RSIZ=.RABNAME[RAB$W_RSZ];	 ! save RSZ
	RBUF=.RABNAME[RAB$L_RBF];	 ! save RBF
	RABNAME[RAB$W_RSZ]=%CHARCOUNT(%REMAINING);	 ! msg length
	RABNAME[RAB$L_RBF]=UPLIT(%STRING(%REMAINING));	 ! msg
	$PUT(RAB=RABNAME);	     ! put the message
	RABNAME[RAB$W_RSZ]=.RSIZ;	 ! restore RSZ
	RABNAME[RAB$L_RBF]=.RBUF)	 ! restore RBF
	    %;

    LITERAL
	BIG_BUF_SIZE = 512,		 ! size of general record
					 ! buffer
	SMALL_BUF_SIZE = 40;		 ! size of file name buffer


    OWN
	 FABTTY :			 ! User's Terminal
	    $FAB(			 ! FAB
		FAC = <GET,PUT>,
		LCH = 2,
		DNA = UPLIT('TI:'),
		DNS = 3,
		FNA = UPLIT(' '),
		FNS = 0,
		ORG = SEQ,
		RAT = CR,
		RFM = VAR
	    ),

	SPACE : VECTOR[CH$ALLOCATION(SMALL_BUF_SIZE)],


	 RABTTY :			 ! User's Terminal RAB
	    $RAB(
		 ASYN=NO,
		FAB = FABTTY,
		UBF = SPACE,
		USZ = SMALL_BUF_SIZE,
		RAC = SEQ
		);


    LITERAL
	COPYSIZE = 160;

    OWN
	RECBUF : VECTOR[CH$ALLOCATION(COPYSIZE)],
SYSTEM INTERFACES.                                 Page 2-50



	 FABOLD :			 ! FAB for source file
	    $FAB(
		FAC = GET,
		LCH = 3,
		DNA = UPLIT('SOURCE.FIL'),
		DNS = 10,
	    ),



	 RABOLD :			 ! RAB for source file
	    $RAB(
		 ASYN=YES,
		FAB = FABOLD,
		UBF = RECBUF,
		USZ = COPYSIZE,
		RAC = SEQ
		),

	 FABNEW :			 ! FAB for the copy
	    $FAB(
		FAC = PUT,
		LCH = 4,
		DNA = UPLIT('COPY.FIL'),
		DNS = 8,
		ORG = SEQ,
		RAT = CR,
		RFM = VAR
	    ),



	 RABNEW :			 ! RAB for the copy
	    $RAB(
		FAB = FABNEW,
		UBF = RECBUF,
		USZ = COPYSIZE,
		RAC = SEQ
		);

!++
!
! NOGOOD
!
!	 Routine to handle erroneous reads
!	 on the input file.  See invocation
!	 of $GET on RABOLD, below.
!
!--

ROUTINE NOGOOD(RABX) : NOVALUE FORTRAN=
	 BEGIN
	 MAP RABX : REF $RAB_DECL;
	 IF .RABX[RAB$L_STS] EQL RMS$_EOF
SYSTEM INTERFACES.                                 Page 2-51


	 THEN MSG(RABTTY,'nogood - eof')
	 ELSE MSG(RABTTY,'nogood - not eof');
	 END;

!++
!
! ISGOOD
!
!	 Routine to report successful reads
!	 on the input file.  See invocation
!	 of $GET on RABOLD, below.
!
!--

ROUTINE ISGOOD(RABX) : NOVALUE FORTRAN=
	 BEGIN
	 MAP RABX : REF $RAB_DECL;
	 IF .RABX[RAB$L_STS] EQL RMS$_OK_SUC
	 THEN MSG(RABTTY,'isgood - suc')
	 ELSE MSG(RABTTY,'isgood - not suc');
	 END;

!++
!
! START
!
!	 Routine to read the name of an existing SOS
!	 un-line-numbered file, to read the name
!	 of a file to be created, and to copy the
!	 contents of the first file into the second.
!
! SIDE EFFECTS
!
!	 Causes RMS-11 to call ISGOOD and NOGOOD
!	 (one or the other) upon each attempt
!	 to read a record of the input file.
!
!--


ROUTINE START =
BEGIN


!  INITIALIZE AND OPEN THE TTY FILE

    $RMS_INITIF();

    $RMS_POOL(
	BDB , 8 ,
	FAB , 3 ,
	RAB , 3 ,
	BUF , <6*BIG_BUF_SIZE>
	);
SYSTEM INTERFACES.                                 Page 2-52


    $RMS_ORG(
	SEQ , <GET,CRE,PUT>
	);

    $OPEN(FAB=FABTTY);
    $CONNECT(RAB=RABTTY);

! GET NAME OF INPUT FILE, ASSOCIATE IT WITH FABOLD

    MSG(RABTTY,'This program will copy an ASCII file.');
    MSG(RABTTY,'Please type name of file to be copied');
    $GET(RAB=RABTTY);
    FABOLD[FAB$L_FNA]=.RABTTY[RAB$L_RBF];
    FABOLD[FAB$B_FNS]=.RABTTY[RAB$W_RSZ];

! OPEN THE INPUT FILE
! UPON FAILURE, PRINT MESSAGE AND QUIT

    IF NOT $RMS_OK( $OPEN(FAB=FABOLD))
    THEN
	BEGIN
	MSG(RABTTY,'Error: couldn''t open input file');
	$DISCONNECT(RAB=RABTTY);
	$CLOSE(FAB=FABTTY);
	RETURN
	END;

! GET NAME OF OUTPUT FILE
! AND ASSOCIATE IT WITH FABNEW

    MSG(RABTTY,'Please type output file name:');
    $GET(RAB=RABTTY);
    FABNEW[FAB$L_FNA]=.RABTTY[RAB$L_RBF];
    FABNEW[FAB$B_FNS]=.RABTTY[RAB$W_RSZ];
    FABNEW[FAB$W_ALQ0]=.FABOLD[FAB$W_ALQ0];
    FABNEW[FAB$W_ALQ1]=.FABOLD[FAB$W_ALQ1];
    FABNEW[FAB$W_MRS]=.FABOLD[FAB$W_MRS];

! OPEN OUTPUT FILE
! IF FAIL, QUIT

    IF NOT $RMS_SUC(	$CREATE(FAB=FABNEW)  )
    THEN
	BEGIN
	MSG(RABTTY,'Error: can''t open output file.');
	$CLOSE(FAB=FABOLD);
	$DISCONNECT(RAB=RABTTY);
	$CLOSE(FAB=FABTTY);
	RETURN
	END;

! BOTH FILES ARE NOW OPEN.
! CONNECT THEIR RAB'S AND LETS START COPYING

    $CONNECT(RAB=RABOLD);
SYSTEM INTERFACES.                                 Page 2-53


    IF NOT $RMS_OKSTATUS(RABOLD)
    THEN
	BEGIN
	MSG(RABTTY,'Error: cannot connect for input file.');
	$CLOSE(FAB=FABNEW);
	$CLOSE(FAB=FABOLD);
	$DISCONNECT(RAB=RABTTY);
	$CLOSE(FAB=FABTTY);
	RETURN
	END;



    $CONNECT(RAB=RABNEW);
    IF NOT $RMS_OKSTATUS(RABNEW)
    THEN
	BEGIN
	MSG(RABTTY,'Error: cannot connect for OUTPUT file.');
	$DISCONNECT(RAB=RABOLD);
	$CLOSE(FAB=FABNEW);
	$CLOSE(FAB=FABOLD);
	$DISCONNECT(RAB=RABTTY);
	$CLOSE(FAB=FABTTY);
	RETURN
	END;

! BOTH FILES ARE CONNECTED NOW
! LETS COPY RECORDS

    WHILE 1 DO
    BEGIN

    $GET(RAB=RABOLD,ERR=NOGOOD,SUC=ISGOOD);
    IF NOT $RMS_OKSTATUS(RABOLD)
    THEN
	BEGIN
			 ! ASSUME E.O.F.
	MSG(RABTTY,'Done!');
	$DISCONNECT(RAB=RABNEW);
	$DISCONNECT(RAB=RABOLD);
	$CLOSE(FAB=FABNEW);
	$CLOSE(FAB=FABOLD);
	$DISCONNECT(RAB=RABTTY);
	$CLOSE(FAB=FABTTY);
	RETURN
	END;

    RABNEW[RAB$W_RSZ]=.RABOLD[RAB$W_RSZ];
    RABNEW[RAB$L_RBF]=.RABOLD[RAB$L_RBF];
    $PUT(RAB=RABNEW);
    IF NOT $RMS_OKSTATUS(RABNEW)
    THEN
	BEGIN
	! BAD OUTPUT
	MSG(RABTTY,'Error: cannot write output record!');
SYSTEM INTERFACES.                                 Page 2-54


	$DISCONNECT(RAB=RABNEW);
	$DISCONNECT(RAB=RABOLD);
	$CLOSE(FAB=FABNEW);
	$CLOSE(FAB=FABOLD);
	$DISCONNECT(RAB=RABTTY);
	$CLOSE(FAB=FABTTY);
	RETURN
	END;
    END;
    END;
END
ELUDOM











                         CHAPTER 3

             AN EASY TO USE I/O PACKAGE (EZIO)



3.1  OVERVIEW

     EZIO is an easy to use I/O package for BLISS  programs.
It  provides  only  sequential  I/O  facilities such as line
input and line output.  It is functionally the same  on  all
major Digital operating systems.

     It is aimed at the BLISS programmer who wants to  write
a  program with simple I/O that can be easily transported to
a number of systems.

     This  is  to  say  that  EZIO  is  intended  to  be   a
"disposable"  tool.   A  programmer  can use EZIO to test an
alogrithm without having to worry about the I/O.  Then, once
the  alogrithm  works, it can be transported to a version of
the product with more complete I/O facilities.



3.2  PRODUCT GOALS

3.2.1  Performance

     The performance of EZIO is not deemed to  be  critical,
other  than  it  should not introduce unacceptable overhead.
(For instance, the monitor will  not  be  invoked  for  each
character to input or output to a file.)

     The size of EZIO is also  not  of  a  critical  nature.
However,  there are some operating systems that require more
user code to do a simple  I/O  operation  than  others  (eg.
TOPS-10  requires  that  user programs do their own filename
parsing.)
AN EASY TO USE I/O PACKAGE (EZIO)                   Page 3-2


3.2.2  Environments

     EZIO  is  designed  to  be  run   in   a   time-sharing
environment.   That  is  to  say:   an  environment in which
novice users are expected to be comfortable in.



3.2.3  Reliability Goals

     EZIO is dependent upon the underlying operating  system
and file systems.  It performs a number of error checks, and
will inform the user if the file service gives an unexpected
return.   Thus, it is expected to never fail due to internal
logic flaws.  However, to keep overhead  low,  EZIO  is  not
extremely  robust.   For  instance,  channel  numbers aren't
validated on FILIN, FILOUT, and FILCLS, but are validated on
FILOPN.    Also,  the  LEN  parameter  is  not  checked  for
unreasonable  size,  and  characters  within  filenames  can
possibly be control characters.



3.2.4  Non Goals

     The EZIO package is not intended to provide a  complete
set  of  I/O  facilities for any system.  More specifically,
the following functionality is not provided in this release.

     o Binary I/O

     o Sequenced files (line and page numbers)

     o Random I/O

     o More than 3 file channels concurrently opened.

     o Use of  monitor  calls  for  I/O  processing  may  be
precluded due to the way that EZIO does file I/O.

     This functionality may be provided in a later  release,
or  the  user  can  tailor  the  supplied source to meet his
needs.



3.3  FUNCTIONAL DEFINITION
AN EASY TO USE I/O PACKAGE (EZIO)                   Page 3-3


3.3.1  Operational Description

     The EZIO programs provided with the BLISS  Library  are
actually  a  set  of  routines  that  are  called to perform
certain I/O operations.  The routines are:

     1.  FILOPN -  Opens  a  specified  file  on  a  logical
         channel.

     2.  FILIN - Reads a line of text from a file opened  on
         the  specified  channel.   It returns the number of
         characters actually transfered to the string.

     3.  FILOUT - Transfers data from a  string  to  a  file
         opened on the specified channel.

     4.  FILCLS - Closes the file on a specified channel.


     With the exception of FILIN, all the functions return 1
to  indicate  a successful completion of the file operation,
or 0 to indicate a failure.  FILIN returns a negative  value
to indicate a failure to complete its file operation.

     All of  the  routines  take  a  channel  number  for  a
parameter.   This  is  not  guarenteed  to correspond to any
logical unit number of the underlying  file  system.   Also,
the  channel  number should be within the range of -1 to the
maximum number of channels supported.

     Channel -1 is reserved for  terminal  operations.   All
calls  using this channel do a minimum of buffering, and use
the operating system primitives for communicating  with  the
terminal (if they exist).



3.3.1.1  The FILOPN Routine - 

     This routine call requires four parameters.  The  first
specifies  a  logical  channel that the file is to be opened
on.  The  second  parameter  specifies  the  length  of  the
filename string.  The third is a character string pointer to
the filename, (constructed by CH$PTR).  The  last  parameter
specifies  either  1 or 0 to indicate that the file is to be
opened for output or input respectively.

     For example, to open a file for output  whose  filename
was dynamically constructed:

 FILOPN( 1, .NAMLEN, CH$PTR(FILNAM), 1)
AN EASY TO USE I/O PACKAGE (EZIO)                   Page 3-4


     The value returned by the routine is 1 if the file  was
opened  and  subsequent  I/O  can  be done to its channel, 0
otherwise.  A return  value  of  0  usually  indicates  that
either  the  file was not present, there was an error in the
syntax of the filename, or the file could not be accessed in
the specified mode.

     The following conventions  usually  apply  to  programs
containing  "hard  coded" filenames that will be transported
to other systems:

     1.  Filenames should be a maximum  of  six  characters,
         and contain only the characters A-Z (upper or lower
         case is permitted, but will be converted  to  upper
         case), and 0-9.

     2.  File  extensions  should  be  a  maximum  of  three
         characters, and contain only the characters A-Z and
         0-9.  Also, they should follow the filename and  be
         seperated  from  the filename by a period (The same
         rule applies to case as did for filenames).

     3.  Hard coding device names in  a  program  should  be
         avoided  since  they  are  different across several
         operating systems.  The default device is disk  for
         I/O to channels 0 through 2.  All I/O to channel -1
         will go to the terminal.

     4.  Account information (eg, PPNs or  directory  names)
         should  not  be  specified  if  a  program is to be
         transportable across all operating systems.  In all
         implementations,   the   default   is  to  use  the
         directory established as the default when  EZIO  is
         first invoked (e.g.  The logged in directory).


     An example of a transportable filename is:

                    UPLIT( 'FILE.EXT' )

     Note that all of this can be  avoided  if  the  program
asks  the  user to type in his filenames rather than storing
them as static data in the module.  The user can  then  type
in  a  filename in the system's own syntax because EZIO uses
the system filename parser  in  all  implementations  except
TOPS-10 (where the parser is PIP like).

     For all implementations, the character string specifing
the  file name should not exceed a length of 127 characters.
However, there  may  be  other  restrictions  for  different
operating systems.
AN EASY TO USE I/O PACKAGE (EZIO)                   Page 3-5


3.3.1.2  The FILIN Routine - 

     This routine call requires three parameters.  The first
specifies  the logical channel associated with the file that
data is to be read from.  The second parameter specifies the
maximum   number  of  characters  that  will  fit  into  the
destination string.   The  last  parameter  is  a  character
string pointer to the string which will receive the text.

     The value of the routine is -1 if  a  read  beyond  the
file  EOF  was  attempted.   -2 is returned if any I/O error
occured.  Otherwise, an integer value  greater  than  -1  is
returned  to indicate the number of characters transfered to
the destination string.

     For example, to read a  line  of  text  from  the  file
opened on channel 1, and to put it in string BUFFR:

 LEN = FILIN( 1, 80, CH$PTR(BUFFR) );

     In this example, the variable LEN is  set  to  indicate
the  number  of  characters  actually  put  in the string at
BUFFR.

     A "line of  text"  is  a  string  of  ASCII  characters
delimited  according  to the file system's conventions.  Any
delimiting factors  (i.e.   length  field,  vertical  motion
characters,  etc),  will act as a stream "break" and will be
stripped on input.  On output, the format  expected  by  the
system's principle editors will be used.


                            NOTE

               On some systems, there is more
               than one way to delimit a line
               of text,  and  an  effort  has
               been  made  to use the methods
               of the  principle  editors  in
               each implementation.





3.3.1.3  The FILOUT Routine - 

     This  routine  call  three   parameters.    The   first
specifies  the logical channel associated with the file that
data is the be written on.  The second  parameter  specifies
the  number  of  characters  that  will be transfered to the
file.  The last parameter is a character string  pointer  to
the string which will be written.
AN EASY TO USE I/O PACKAGE (EZIO)                   Page 3-6


     For example, to write a line from string TITLE  to  the
file opened on channel 2:

 FILOUT( 2, .TITLIN, CH$PTR(TITLE) );

     Of course, if there was any doubt  that  the  operation
was  completed,  then an IF statement could be used to check
the return value of the call.

     The string is output as a line of text.  That is to say
that  the system's conventions are used to output the string
so that it will appear as  one  line  when  printed.   (Some
systems  delimit  lines  with  CRLF,  others  store  it as a
counted string.) In all cases, EZIO should be able  to  read
files that it creates.



3.3.1.4  The FILCLS Routine - 

     This  routine  one  parameter,  which  is  the  logical
channel associated with the file to be closed.

     The  FILCLS  routine  insures  that  all  EZIO  buffers
containing  data  are  either  flushed or written out before
informing the file system that all  data  transfers  to/from
the file are complete.

     For example:

     FILCLS( -1);

     Of course, the expression could be included  in  an  IF
conditional  to  determine  if  the operation failed.  (e.g.
not enough disk space.)



3.3.2  Restrictions

     There are no logical restrictions in the EZIO packages.
However, because EZIO is dependent on them, the restrictions
of the underlying file system and  of  BLISS  apply  to  all
programs using the EZIO package.

     There are physical constraints placed on the number  of
EZIO  channels  that  can  be  opened  at any one time.  The
maximum is three, plus channel -1  for  terminal  I/O.   The
reason  is to reduce the number of buffers and tables within
EZIO.
                            NOTE

               The maximum number of channels
               that   can   be   concurrently
               opened is  controlled  by  the
               compile-time  literal MAXCHANS
               in      most      of       the
               implementations.  The user may
               change   this   parameter   to
               change  the number of channels
               to his/her liking.





3.3.3  Example

     This example program prints a file on the terminal:
MODULE LISTER (MAIN = LSTR) =
!+
!   This program asks for a filename, opens the named file,
and copies
! the file to the terminal.
!--
    BEGIN
    EXTERNAL
        ROUTINE
            FILOPN,     ! EZIO open
            FILCLS,     ! EZIO Close
            FILOUT,     ! EZIO Output
            FILIN;      ! EZIO Input
    OWN ! Holds one line of text
        BUF : VECTOR[CH$ALLOCATION(120)];
    MACRO
        MSGS(S) =
            FILOUT(-1, %CHARCOUNT(S), CH$PTR(UPLIT(S))) %;
    ROUTINE LSTR =
        BEGIN
        LOCAL
            LEN,        ! Length of string
            PTR;        ! Pointer to buf
!
! Open the TTY:, Note: no filespec
!
    FILOPN( -1, 0, 0, 0);
    PTR = CH$PTR(BUF);      ! Get pointer
    MSG('Enter file name');     ! Prompt
    LEN = FILIN(-1, 60, .PTR);  ! Get file name
!
! Open the file on channel 0.
!
    IF NOT FILOPN(0, .LEN, .PTR, 0)
    THEN
        BEGIN           ! Open failed.
        MSG( 'Open failed.');
        RETURN;
        END;
AN EASY TO USE I/O PACKAGE (EZIO)                   Page 3-8


!
! Process each line
!
    WHILE 1 DO
        BEGIN
        LEN = FILIN(0, 120, .PTR);
        IF .LEN EQL -1
        THEN
            EXITLOOP;   ! End of file
        FILOUT(-1, .LEN, .PTR); ! Output the string
        END;
    FILCLS(0);
    MSG('DONE');
    END;
END
    ELUDOM



3.3.4  Loading With User Programs

     The procedures below describe the procedures  necessary
on  each  system  to  load  EZIO with a user program.  These
examples assume that the test program test.



3.3.4.1  EZIOFC - File Services 11 (RSX-11M) - 

     1.  Run the Task Builder

             MCR>TKB TEST=TEST,EZIOFC,BLS16X


              The TEST to the left of the equal sign is  the
         task  image  file.   The  TEST  to the right of the
         equal  sign  is  the  object  module  of  the  main
         program.  EZIOFC is the object module of EZIO.  And
         BLS16X  is  the  BLISS-16C   library   of   runtime
         routines.

     2.  When TKB finishes, give the run command  to  invoke
         the program:

             MCR>RUN TEST
AN EASY TO USE I/O PACKAGE (EZIO)                   Page 3-9


3.3.4.2  EZIORT - RT-11  - 

     For RT-11, simply use the DCL EXECUTE command:

    .EXECUTE TEST,EZIORT,BLS16X




3.3.4.3  EZIO10 - TOPS-10 - 

     After your program has been compiled with BLISS-36, use
the TOPS-10 EXECUTE command:

    .EXECUTE TEST.REL,BLI:EZIO10


     Note that a library file does not have to be specified,
(BLISS-36 generates a load request automatically).



3.3.4.4  EZIO20 - TOPS-20 - 

     After your program has been compiled by  BLISS-36  with
the  /TOPS-20  compilation  switch,  simply  use the EXECUTE
command:

    @EXECUTE TEST,BLI:EZIO20


     Note that a library file does not have to be specified,
(BLISS-36 generates a load request automatically).



     3.4  COMPATIBILITY

     EZIO is designed to be compatible with programs written
in  BLISS, and should create files that can be edited by the
system's editors.



3.5  PACKAGING AND INSTALLATION

     EZIO is distributed as several  files:   EZIOFC  for  a
Files-11  based  system,  EZIORM  for  a  RMS-11  based file
system, EZIORT for programs that run under RT-11, EZIOVX for
the  VAX/VMS  operating system, EZIO10 for TOPS-10 programs,
and EZIO20 for TOPS-20 programs.  

     EZIOFC, EZIORM and EZIORT  are  to  be  compiled  using
BLISS-16C.   EZIOVX  must  be  compiled using BLISS-32.  And
EZIO10 and EZIO20 must be compiled with BLISS-36  using  the
AN EASY TO USE I/O PACKAGE (EZIO)                  Page 3-10


/TOPS10 and /TOPS20 switches respectively.

     Both the source and object files are distributed, these
are  to  be  placed  in a public accessable directory.  This
allows users to tailor EZIO to their own needs.

     Some of the EZIO sources have REQUIRE's.  These require
the  various system interfaces also distributed in the BLISS
Library, and must be present in order to successfully modify
the sources.



3.6  DOCUMENTATION

     Documentation will consist of  a  help  file  and  this
document.  These will be distributed with the BLISS Library.



3.7  REFERENCES

     1.  BLISS-32 Primer, July 1977.  COMPANY  CONFIDENTIAL.
         Available from Educational Services.

     2.  BLISS-32  Language  Guide,  Second  Edition,  April
         1977.   COMPANY CONFIDENTIAL.  Available from BLISS
         Development, Central Engineering, ML3-5/E82.

     3.  RT-11  System  User's  Guide.   DEC  Order  Number:
         DEC-11-ORGDA-A-D

     4.  RT-11 System Reference Manual.  DEC  Order  Number:
         DEC-11-ORUGA-C-D,DN1,DN2

     5.  IAS/RSX-11 I/O Operations  Reference  Manual.   DEC
         Order Number:  DEC-11-OIORA-B-D

     6.  RSX-11M Operator's Procedures  Manual.   DEC  Order
         Number:  DEC-11-OMOGA-C-D

     7.  RSX-11M Task Builder Reference Manual.   DEC  Order
         Number:  DEC-11-OMTBA-C-D

     8.  TOPS-10   Monitor   Calls.    DEC   Order   Number:
         AA-0974C-TB

     9.  TOPS-10  Operating  System  Commands  Manual.   DEC
         Order Number:  DEC-10-OSCMA-A-D

    10.  TOPS-20 Monitor  Calls  User's  Guide.   DEC  Order
         Number:  AA-OMUGA-A-D
AN EASY TO USE I/O PACKAGE (EZIO)                  Page 3-11


    11.  TOPS-20   User's   Guide.    DEC   Order    Number:
         AA-4179B-TM