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