Trailing-Edge
-
PDP-10 Archives
-
decuslib10-06
-
43,50362/iolib5.man
Click 43,50362/iolib5.man to
see without markup as text/plain
There are no other files named iolib5.man in the archive.
IOLIB Reference Manual
----- --------- ------
Rob Cook
LaTrobe University Computer Centre
10-Aug-74
NOTE
This manual describes the subroutine library, IOLIB version
5(205), and the parameter program IO version 5(153). The
information in this document is subject to change without
notice and should not be construed as a commitment to the
author or to LaTrobe University.
Actual distribution of the software described in this document
will be subject to terms and conditions that will be announced
by the author.
IOLIB Reference Manual
Abstract
IOLIB is a system of subroutines, macros and parameters for
use in MACRO-10 programs. The system is intended to provide a
prewritten set of commonly used subroutines and macros that
rely on a standardised method of IO, and that make assembly
language programming simple, and programs readable. IOLIB may
be used by wizards for the most complicated systems
programming, but it is also an extremely useful tool for
teaching assembly language programming.
IOLIB Reference Manual
Table of Contents
Table of Contents
Chapter 1 - IOLIB Explained
1.1 What is IOLIB? 1-1
1.2 Some Features of IOLIB 1-2
1.3 Who can usefully use IOLIB? 1-2
1.4 How to use this manual 1-3
1.5 Software Support 1-4
1.6 Credits 1-4
Chapter 2 - Concepts
2.1 Components of IOLIB 2-1
2.2 Files and FDBs 2-2
2.3 The IOLIB Data Base 2-4
2.4 Routines and Macros 2-4
2.5 Error Messages 2-5
2.6 Replaceable Routines 2-5
2.7 Formatted IO 2-6
2.8 User Program Structure 2-6
Chapter 3 - Programming Techniques
3.1 General Description 3-1
3.2 Compiling and Loading Programs with IOLIB 3-1
3.3 Program Structure 3-2
3.4 Symbol Naming Conventions 3-3
3.5 Accumulator Conventions 3-3
3.6 Subroutine Calls 3-5
3.7 Assembly Switches 3-6
3.8 Push Down Stack 3-7
3.9 BEGIN$ - Program Initialisation 3-7
3.10 Global Parameters 3-8
3.11 Segmentation 3-9
3.12 FDESC$ - Build an FDB and Set Values 3-9
3.13 MAKFD$ - Produce Code to Build an FDB 3-10
3.14 Version Number Macros 3-11
3.15 Debugging Aids 3-11
Chapter 4 - IOLIB Tables
4.1 General Description 4-1
4.2 $TBWAD - Table of Write Routine Addresses 4-1
4.3 Switch Tables 4-2
4.4 Switch Table Building Macros 4-2
Chapter 5 - Memory Management
5.1 General Description 5-1
5.2 Dynamic Memory Management 5-2
IOLIB Reference Manual
Table of Contents
5.3 Static Memory Management 5-2
Chapter 6 - Basic IO Routines
6.1 General Description 6-1
6.2 $INPUT - Read a Physical Record from a File 6-2
6.3 $OUTPU - Write a Physical record to a File 6-3
6.4 $LUKUP - LOOKUP a File 6-4
6.5 $ENTER - ENTER a File 6-5
6.6 $OPEN - OPEN an IO Channel 6-5
6.7 $CLOSE - Disconnect a File from a Channel 6-7
6.8 $RLEAS - Release an IO Channel 6-7
6.9 $RENAM - Change RIB Details for a File 6-8
6.10 $DELET - Delete a File 6-9
6.11 $USETI/O - Set the Disk Record Number 6-9
6.12 $GETST - Read the IO Channel Status 6-9
6.13 $SETST - Set the IO Channel Status 6-9
6.14 $XTUUO - Execute an IO UUO 6-9
6.15 $XTCAL - Execute an IO Oriented CALLI UUO 6-10
6.16 $XTDCL - Execute a Device Oriented CALLI UUO 6-10
6.17 $MKBUF - Make a Ring of Buffers 6-11
6.18 $DLBUF - Delete a Ring of Buffers 6-11
6.19 $UPDAT - Open a File for Updating 6-11
6.20 $UPDWT - Open for Updating, Wait if Being Modified 6-11
6.21 $APEND - Open a File for Appending 6-11
6.22 $APDWT - Open a File for Appending and Wait 6-12
6.23 $MTxxx - Execute an MTAPE UUO for a File 6-12
Chapter 7 - Formatted Reading and Writing
7.1 General Description 7-1
7.2 $WRITE - Write one Byte to the Current File 7-2
7.3 $$WBYT - Write one Byte to the Current File 7-2
7.4 $$WCHR - Write a Character to the Current File 7-2
7.5 $READ - Read one Byte from the Currrent File 7-3
7.6 $$RBYT - Read one Byte from the Current File 7-3
7.7 $$RCH0 - Read a Character from the Current File 7-4
7.8 $$RCHR - Read a Character from the Current Command File 7-4
7.9 $REDCH - Read a Character and do Basic Editing 7-5
7.10 $RCCHR - Read a Character and Edit as a Command Character 7-5
7.11 $RFILE - Read a File Specification from the Current File 7-6
7.12 Read Path and PPN Specifications 7-7
7.13 $RSWIT - Read a Switch Name and Value 7-7
Chapter 8 - Tempcore Routines
8.1 General Description 8-1
8.2 $TMPFD - Build a Tempcore FDB 8-1
8.3 $TMPIN - Read a File from Tempcore 8-2
8.4 $TMPDL - Delete a File from Tempcore 8-2
8.5 $TMPOU - Close a Tempcore Output File 8-2
IOLIB Reference Manual
Table of Contents
Chapter 9 - Error Reporting
9.1 General Description 9-1
9.2 Message Format 9-1
9.3 Error Severity 9-3
9.4 $ERROR - The Error Reporter 9-3
9.5 $FATAL and $WARN 9-5
9.6 The FATAL$ and WARN$ macros 9-5
9.7 IO Error Reporting 9-6
9.8 Syntax Error Reporting 9-6
9.9 $$FERR - the Fatal Error Trap Routine 9-7
Chapter 10 - Utility Routines
10.1 General Description 10-1
10.2 $MATCH - Match a Name in a Table of Names 10-1
Chapter 11 - Examples
11.1 Formatted IO 11-1
11.2 Copy a File to LPT 11-2
11.3 Subroutine to Read a Filename 11-2
Appendix A - List of all IOLIB Routines
A.1 Basic IO Routines A-1
A.2 Formatted Read Routines A-5
A.3 Formatted Write Routines A-11
A.4 Core Management Routines A-14
A.5 Data Block Manipulation Routines A-15
A.6 Tempcore Routines A-16
A.7 Error Routines A-17
A.8 Utility Routines A-18
Appendix B - List of all IOLIB macros
B.1 Programming Macros B-1
B.2 Basic IO Macros B-3
B.3 Read Macros B-5
B.4 Write Macros B-7
B.5 Core Management Macros B-9
B.6 Data Block Manipulation Macros B-9
B.7 Tempcore Macros B-9
B.8 Error Macros B-10
B.9 Utility Routine Macros B-11
Appendix C - Contents of the FDB
C.1 Details of Words in the FDB C-1
C.2 Bit Definitions for $FDCHN C-4
IOLIB Reference Manual
Table of Contents
C.3 Bit Definitions for $FDMOD and $FDMOM C-4
Appendix D - Contents of the IDB
Appendix E - IO Error Codes
E.1 UUO IO Error Codes E-1
E.2 IO Error Codes E-2
Appendix F - IOLIB Standard Error IDs
CHAPTER 1
IOLIB EXPLAINED
1.1 WHAT IS IOLIB?
IOLIB is a MACRO-10 assembly language programming system
comprising subroutines and definitions of macros and symbols. The
subroutines are a collection of routines commonly used and commonly
written by assembly language programmers. IOLIB contains definitive
versions of these routines written to be correct, consistent and
versatile so that they may be used in almost any situation that
requires them, and they can be relied upon. The programming is
modular, all the routines having well-defined consistent interfaces
with each other, and with the caller and most of the routines are
separate units that can be loaded individually, together with any
other routines that they call. The base of the system is a module
that will execute the IO UUOs on files described by a standard data
block. The various routines in the module are organised
hierarchically, so that the programmer needs only to call the function
he requires and all prerequisites are organised for him. The basic IO
module is general enough to be used for the most complicated
algorithms.
The rest of the package is built on the basic IO module. There
are routines for reading and writing data in a number of common
formats, for memory management, for error reporting, for tempcore
handling and many others. The routines that read data in various
formats make up a useful command scanner with a power similar to that
of the DEC SCAN module.
The macros and symbols come in a parameter file which is
assembled with the user programs. Each IOLIB routine has a
corresponding macro, which may be used to call it, making programs
very readable and the calls shorter. Other macros are used to write
program initialisation code, to define version numbers and control
assembly. IOLIB forms a useful programming standard that makes
assembly language programs easier to write and read, and therefore
more maintainable.
It is so easy to write simple programs in IOLIB that the system
can be used to teach MACRO-10 assembly language programming. Students
can use IOLIB macros for program initialisation and for all IO, and
can concentrate on learning the instruction set and the use of the
assembler and hardware.
IOLIB EXPLAINED Page 1-2
SOME FEATURES OF IOLIB
1.2 SOME FEATURES OF IOLIB
* basic IO module for executing IO UUOs on any file.
* files described by standard data block. A large number of defaults
are supplied.
* buffer sizes are variable because IOLIB creates buffer rings itself
* any IO call for a file ensures that all prerequisites for that
function are fulfilled first.
* routines for writing data in a wide variety of formats; decimal,
date/time, filename, cash ... IOLIB has them all
* routines for reading data in all the same formats. This feature
gives a command scanner of similar power to the DEC SCAN module,
but smaller.
* dynamic memory management using the ALGOL heap algorithm
* comprehensive routines for reporting errors in the DEC standard
format. Verbosity level can be set by program or user.
* critical routines replaceable by user programmer, so that IOLIB's
simple approach can be replaced by something more complicated for
e.g. fatal error traps.
* a macro to call each IOLIB routine, making code shorter and more
readable.
* a macro to write program initialisation code
* macros to define file data blocks
* all the SAVEn and POPJ/POPJ1 utility routines
* all symbols are parametised. All contain the character '$' so that
they are easily recognisable. IOLIB uses C.MAC, so that all the C
symbols are available to the programmer.
* DEC compatibility
* will run on 5.06 and later monitors only.
1.3 WHO CAN USEFULLY USE IOLIB?
IOLIB is aimed at 3 main classes of programmer:
1. the professional systems programmer, who spends much of his time
coding in assembly langauge. For him IOLIB is a complete assembly
language programming system of standard modules that he would
IOLIB EXPLAINED Page 1-3
WHO CAN USEFULLY USE IOLIB?
otherwise write for himself for each program, as well as offering
features that he might not consider using if the code were not
prewritten. The basic IO routines handle all IO on all channels
in one module. They are extremely flexible, allowing the
programmer to manipulate his file transactions in the most
complicated ways. Most routines are written independently of the
other routines and are loaded separately so that the programmer
can use as much or as little of the system as he wants, and his
final program is not burdened with unused routines. Advertised
routines are easily replaceable by the programmer's own routines
and the clever programmer can make good use of rewriting specific
critical routines. Use of IOLIB ensures that programs are
reasonably standardised, and in particular text output and error
messages are in a standard form.
As well as standard routines, IOLIB defines a wealth of
standard symbols and macros and includes all those defined in
C.MAC. Together, IOLIB and C form a programming standard that
could usefully be adopted by installations to make programs
readable and maintainable.
2. the programmer who writes simple one-off programs. The main
reason such a user wants to write assembly language programs is
because the higher level languages cannot provide some feature.
IOLIB can be used to construct one-off programs easily, because
the command decoder, message writer and basic IO are laid on. At
the same time it offers access to all the machine characteristics
that straight assembly language code does. IOLIB is easy to use
reliably without detailed study of the system.
3. for teaching MACRO-10. IOLIB allows students to call macros for
initialising their programs and for all IO, so that they can
concentrate on the basics of assembly language. The IOLIB system
is so simple that students can be taught enough to construct
simple programs in a few minutes. This basic subset includes the
use of the SEARCH pseudo-op, the BEGIN$ macro to start programs, a
few formatted read and write macros, accumulator names and the
MONRT$ macro. Later they can be introduced to files through the
FDB system, using all the same macros together with MAKFD$. Using
IOLIB, students can write full assembly langage programs from the
first class; there is no need to bother with starting them on
writing FORTRAN subroutines with all the addressing technique that
that involves.
1.4 HOW TO USE THIS MANUAL
The manual is a reference manual rather than a teaching text, and
it is laid out so that the programmer can easily locate details of a
routine or macro to perform a specific task. The concepts and
conventions used in IOLIB are explained in chapters 2 and 3. Chapters
5 to 10 contain details of critical or complicated routines, including
full algorithms and even code in some places. Chapter 4 contains
IOLIB EXPLAINED Page 1-4
HOW TO USE THIS MANUAL
details of IOLIB tables that the user may need to use, build or
modify. The main reference parts of the manual lie in the appendices.
Appendix A is a full list of all the routines, and entry points,
available in IOLIB. It contains a specification, including details of
return addresses, input arguments and output results. Also included
are details of the acs altered by the routine, the size of the routine
in words, the macros that call the routine and a reference to a
section in the main part of the manual that contains further details,
if necessary. Appendix B is a full list of all macros available in
the IOLIB system. It contains full details of the macro call and
specification of the effect, as well as a reference to further
details. Appendices C and D list the words in the FDB and the IDB,
and explain them fully. Appendices E and F deal with error messages.
Appendix E gives the codes returned by the basic IO routines
indicating errors, and appendix F gives a list of the 3 character
error ids produced by IOLIB and explains them in full.
The files constituting this manual are distributed in sections so
that the appendices may be printed separately and used alone as a
quick reference document.
To use the manual, digest the contents of chapters 2 and 3
thoroughly and understand the simple examples given in chapter 11.
After a basic understanding is gained, the programmer can look up
routines that he requires in the appendices A and B.
1.5 SOFTWARE SUPPORT
The IOLIB system is maintained at Latrobe University by the
author. Software Performance Reports submitted to the author will be
answered promptly and problems solved as quickly as possible. Further
versions of IOLIB are under development.
Suggestions for routines to be included in future versions or for
changes and improvements to current routines are welcomed.
1.6 CREDITS
The original work and the development of the first 3 versions of
IOLIB was done at the University of Queensland computer centre.
Versions 4 and 5 were written at Latrobe University computer centre.
The author gratefully acknowledges the help and advice given by all
members of the staffs of the two computer centres.
When IOLIB was converted from the University of Queensland 4s72
(highly modified) monitor to DEC standard 5-series monitors, much
effort went into achieving DEC compatibility. Ideas and code from the
DEC SCAN and WILD modules were a great help and influence in meeting
this goal.
CHAPTER 2
CONCEPTS
2.1 COMPONENTS OF IOLIB
IOLIB is a set of subroutines contained in the subroutine library
file IOLIB.REL and a set of macro and parameter symbol definitions
contained in the UNIVERSAL parameter file IO.UNV, and in the source
file IO.MAC. Programs using IOLIB must be assembled with the IO and C
symbol tables, and they must be loaded with a library search of
IOLIB.REL. Full assembly and loading instructions are given in
section 3.2. All programs written to use IOLIB may use any of the
symbols defined in IO.MAC and the DEC parameter file C.MAC without
prior definition.
IOLIB subroutines fall into several broad categories, with the
main emphasis on making DECsystem-10 IO readily available to the
MACRO-10 programmer, and on giving him a broad range of standard
routines to perform common tasks:
1. routines to execute the basic IO UUOs for any file. These
routines smooth out the differences between devices, are channel
independant and are organised in a hierarchic fashion, so that a
call to one routine will ensure calls to other routines to execute
prerequisite UUOs and routines. For example, $LUKUP will call
$OPEN.
2. routines to read/write one byte with a file using buffered IO,
TTCALL UUOs or byte instructions, for a packing and unpacking like
function. These routines also ensure that prerequisite UUOs are
executed by calling the basic IO routines.
3. routines to read and write character strings with files as
described above, in a wide variety of formats. The formatted
input routines read characters through a command scanning
coroutine similar to that in the DEC SCAN module.
4. error message printers that will print fatal or warning messages
in DEC standard format. IO and command syntax errors can be
reported easily by these routines since all necessary codes are
set up on error return from the IO and command scanning routines.
CONCEPTS Page 2-2
COMPONENTS OF IOLIB
5. routines to handle tempcore files (input, output and delete).
6. a variety of utility routines that are commonly used by assembly
language programmers, such as accumulator save/restore routines,
POPJ routines, table scanning, and many others.
7. the IOLIB data base
The IO.MAC parameter file contains definitions of the IOLIB data
base symbols and of macros and OPDEFs that are useful (and some almost
essential) for writing programs that use IOLIB.
1. useful symbol definitions for all accumulators
2. a macro to call each IOLIB routine
3. a macro to initialise a program that includes setting up a stack
and the IOLIB data base, handling CCL calls and concealed mode
entry.
4. symbolic definition of all independant words and bits in the
various data blocks
5. macros to build file data blocks
6. macros to create calls to the error messages writers
7. macros to control version numbering
8. macros to aid assembly by setting assembly into high and low
segments etc
2.2 FILES AND FDBS
IOLIB is mostly concerned with reading and writing data to and
from files. Files are described to IOLIB basic IO routines by a
standard data block known as the File Descriptor Block, or FDB. This
block contains all the known information about a file and includes a
RIB area, an OPEN UUO block, two buffer headers, the channel number,
record number, buffering details and room for wildcard masks and other
file attributes associated with command scanning. Every file that is
to be accessed by IOLIB must be described by an FDB.
The programmer is responsible for building the FDB and for
filling in all his non-default values. The basic IO routines will
supply defaults for all unfilled words. IOLIB contains routines for
obtaining space for an FDB from the memory manager, for initialising
an FDB and for deallocating the space used by an FDB ($CLRFD and
$LOSFD). There are macros for building FDBs and for filling them with
basic data. The MAKFD$ macro produces inline code to obtain space (if
necessary) and fill in details. The FDESC$ macro builds an FDB at
CONCEPTS Page 2-3
FILES AND FDBS
assembly time, and fills it. The defaults are:
device DSK
name null
extension null
PPN null
IO mode .IOASC
buffers 2; standard size for device
sequential IO starting at block 1
The last item in an FDB is the RIB area for LOOKUP-class UUOs. A
standard length FDB contains the words of an extended RIB from .RBCNT
to .RBVER. If the programmer needs longer extended RIBs, all he has
to do is build a longer FDB. The routines that create FDBs will
accept a length as an argument, using the standard length by default.
If all FDBs are to be longer than normal, the programmer could
redefine the symbol, $LNFDB, which gives the length of a standard FDB,
e.g.
$LNFDB==$FDRIB+.RBALC+1 ;all FDBs continue until .RBALC
The basic IO routines perform their function on the file
described by the FDB pointed at by an accumulator named D. Therefore
ac(D) must be loaded with a pointer to the required FDB before calling
any basic IO routine, and therefore any routine that uses the basic
routines, such as the formatted IO routines. The FDB used by the
basic IO routines is known as the 'current FDB'. So, to execute a
LOOKUP on a file described by an FDB at location INPFDB:
...
MOVEI D,INPFDB ;load current FDB
LUKUP$ ;execute LOOKUP (including OPEN)
JRST ERROR ;
...
The routines which read and write one byte ($READ and $WRITE)
extend the current FDB concept so that it includes TTCALL UUO for the
job's terminal and byte pointers for reading and writing into memory.
If ac(D) contains zero, the routines use TTCALL. If bits 0-11 are
non-zero, ac(D) contains a byte pointer. Otherwise, the right half of
ac(D) is a point to the current FDB. The file described by this
extended pointer is known as the 'current file', and all formatted IO
routines perform their IO with the current file. IO.MAC defines ac(D)
to be ac15, and this ac is reserved for use as the current file by
IOLIB.
To write a message to the job's terminal:
...
SETZ D, ;set TTCALL IO
WTEXT$ <End of execution>
...
To read a character from an incore buffer called TMPBUF:
CONCEPTS Page 2-4
FILES AND FDBS
...
MOVE D,[POINT 7,TMPBUF] ;set up pointer
RCHAR$ ;read a character into ac(T1)
...
The BEGIN$ macro which initialises the IOLIB system at the start
of execution, sets up ac(D) to point to the command input file, which
is either the terminal or a CCL file. Pointers to the command input
and message output FDBs are kept in the IOLIB data base, and may be
loaded into ac(D) using the CMDFD$ and MSGFD$ macros. The TRMFD$
macro sets ac(D) to zero for terminal IO.
The contents of an FDB are explained in detail in Appendix C, and
the descriptions of the basic routines in Chapter 7 explain how each
routine uses and changes the FDB. $RFILE, the filename input routine,
also sets (and can create) FDBs.
2.3 THE IOLIB DATA BASE
IOLIB needs to keep a certain amount of data about the state of
the program and of the IOLIB system. It must be in the low segment so
that it is modifiable, and must be positioned independent of any
particular program so that high segments can call each other and pass
the address of the IOLIB data base between them. IOLIB keeps its data
in one block, the IOLIB data block, or IDB. An accumulator is
reserved to point to the IDB, and this pointer may be passed between
segments. The accumulator is given the name I, and is defined as ac16
by IO.MAC. This definition clashes with the standard use of ac16 as
ac(L), the link register, and this clash must be resolved by the user
programmer. The IDB contains data used internally by IOLIB routines,
such as the anchor for the linked list of free memory, and parameters
which may be set by the programmer such as the maximum core which may
be used by the program. The parameters which may be set by the
programmer are discussed in section 3.10, and each word of the IDB is
explained in full in appendix D.
2.4 ROUTINES AND MACROS
Each IOLIB routine has a corresponding macro associated with it.
This macro may be used to call the routine, and in some cases the
arguments to the routine may be specified in the macro call; e.g.
OPEN$ ;calls $OPEN to execute an OPEN UUO
WDECL$ 10 ;calls $WDECL to write decimal 10
Using the macros makes the program more readable (expansions are
SALLed by default) and helps to cut down programming errors.
CONCEPTS Page 2-5
ROUTINES AND MACROS
The complete list of IOLIB routines, their arguments and results
and calling macros is given in Appendix A. A complete list of macros
is given in Appendix B.
2.5 ERROR MESSAGES
IOLIB includes routines for writing error messages in DEC
standard format. The messages may include text and a value, which may
be written in one of several formats. The routines are called by the
FATAL$, WARN$ and ADVIS$ macros, which take a list of arguments
specifying the message in full. The macros create only one location
of inline code, so that they may be used in an error return location.
The basic IO routines return an error code in ac(T1), when they
detect an IO error, and a call to the error routines through the
FATAL$ and WARN$ macros with no arguments produces an informative
error message.
...
LUKUP$ ;LOOKUP a file
FATAL$ ;errors are fatal
...
might produce:
?RENAEF RENAME(4), Already exists: IOLIB.BAK
Some of the command decoding routines detect syntax errors and
these too have an error return with an error code in ac(T1). A call
to FATAL$ or WARN$ again produces a detailed diagnostic.
...
RFILE$ ;read a filename
FATAL$ ,SY ;write a syntax error message
...
might produce:
?DELILC Illegal character: <BEL>
2.6 REPLACEABLE ROUTINES
Since IOLIB.REL is searched as a subroutine library, the user
programmer may replace any of the routines by one of his own with the
same name. However some routines are specifically designed to be
rewritten by the user. These routines are called at critical parts of
the IO process where the user may want to gain control to perform some
extra functions. Examples of these routines are $$FERR, the fatal
error trap routine, and $$RCHR, the routine called by all the
formatted input routines to read one character. The standard $$FERR
merely returns to monitor mode, but the user programmer might want to
CONCEPTS Page 2-6
REPLACEABLE ROUTINES
clean up his program first, or restart the program at some point
instead. The standard $$RCHR uses the SCAN type command scanning code
to edit the characters it reads, but the user might want to do less
thorough editing or to treat different files in different ways.
The main replaceable routines in the current version of IOLIB
are:
$$ALLC allocate a chunk of free memory
$$DALC deallocate a chunk of memory
$$FERR fatal error trap routine
$$RBYT read a byte from the current file
$$RCHR read a command character (all formatted input)
$$RCH0 read a character (all command scanner input)
$$WBYT write a byte to the current file
$$WCHR write a character (all formatted output)
2.7 FORMATTED IO
Formatted IO is the transfer of data formatted in various ways
between the program and files, so that the formatted data in the files
becomes binary data in the correct format in the program. An example
is the reading of a string of decimal digits and producing a binary
number. The formatted IO routines are explained fully in Appendix A
with more detail about some of the important routines in Chapter 6.
The formatted input routines read characters from the current
file and interpret them according to the format of the data that is
being read. The general philosophy of the routines is to read until a
character is read which is outside the range of characters expected at
that stage, e.g. an endline, or an erroneous character. At that
stage, the simple routines return the value read so far and the
terminal character, and it is the caller's responsibility to work out
whether the character is correct. The more complicated routines must
detect some syntax errors within their own code, and these routines
have error returns.
In the terminology used throughout this manual, a number of
consecutive characters read or written through the formatted IO
routines is called a 'string' of characters, and a terminal character
is called a 'delimiter'.
2.8 USER PROGRAM STRUCTURE
IOLIB places few restrictions on the way a programmer writes his
code, but those that do exist are important. Firstly, the program
must contain a SEARCH pseudo-op to instruct the assembler to search
the C and IO symbol tables for missing symbols. Secondly, the program
must start execution with a BEGIN$ macro which initialises IOLIB.
CONCEPTS Page 2-7
USER PROGRAM STRUCTURE
IOLIB contains other features which assist the programmer to
structure his program such as the version number macros and the HISEG$
and LOSEG$ macros which organise programs into two segments.
CHAPTER 3
PROGRAMMING TECHNIQUES
3.1 GENERAL DESCRIPTION
This chapter covers a range of instructions and techniques that
have a bearing on writing programs using IOLIB. It includes some
tables of symbols defined in IO.MAC including the accumulator
definitions, and explains some of the important macros. The DEC
parameter program, C.MAC, is an essential part of IOLIB since
definitions in IO.MAC depend on C.MAC. C.MAC contains a number of
extremely useful macro definitions and a large range of symbol
definitions for all the various parameters available through the
monitor. Unfortunately the only documentation for C is in the code of
the program itself, and a long explanation is outside the scope of
this manual. However study and use of the symbols and macros in C.MAC
does make programs clearer and gives a better chance of correctness.
3.2 COMPILING AND LOADING PROGRAMS WITH IOLIB
The following instructions assume that the installation is using
MACRO-10 version 50 or later. They do not apply to MACRO version 47,
which does not support .UNV files. The files C.UNV and IO.UNV must be
on the ersatz device UNV:, and the library file IOLIB.REL should be on
the ersatz device MAC:, although your installation may prefer to keep
it on REL:.
To compile a user program, ensure that the program contains a
SEARCH pseudo-op for C and IO and then give a normal COMPIL command,
e.g.:
.COMPIL/CREF MYPROG
To LOAD, DEBUG or EXECUTE a user program, include the indirect
command file IOLO or IOHI in the command string. IOLO forces all
IOLIB routines into the low segment, whereas IOHI allows the code to
fall into the default segment which is the high segment.
.EXECUT MYPROG,@MAC:IOHI
.DEBUG MYPROG,@MAC:IOLO
PROGRAMMING TECHNIQUES Page 3-2
PROGRAM STRUCTURE
3.3 PROGRAM STRUCTURE
A suggested layout for the user program is as follows. The
reasons for the various parts are explained in the comments:
TITLE MYPROG - EXAMPLE OF PROGRAM LAYOUT
SUBTTL ROB COOK
SEARCH C,IO ;search UNIVERSAL files
;define version numbering
VERSN$ 1,101,3 ;see section 3.14
PATCH$ ;ditto
JBVER$ ;set version number into .JBVER
COMMENT ;
...
comments including description of
program and revision history
...
;
;assembly switch definitions
;symbol definitions
;OPDEF and macro definitions
;global symbol definitions
HISEG$ ;only if two segment program
MYPROG: ;start of program code
BEGIN$ ;initialisation macro
...
program code
...
data area definitions
...
END MYPROG
The ordering of most items is not important and most items are
optional, but are included in the majority of programs.
Logical execution of a program may be terminated by calling the
$MONRT routine which returns the program to monitor mode with an 'EXIT
1,' UUO. The routine returns to caller if the user types 'CONTINUE'
to the monitor.
...
WTEXT$ <All done> ;end of program
MONRT$ ;back to monitor
JRST START ;restart on 'CONTINUE'
END START ;
PROGRAMMING TECHNIQUES Page 3-3
SYMBOL NAMING CONVENTIONS
3.4 SYMBOL NAMING CONVENTIONS
By published DEC standard, symbol names containing the character
'$' are free for use by customers, and IOLIB uses exclusively symbols
containing '$' in an effort to keep the names of IOLIB symbols
distinct from names that DEC or the user might choose. IOLIB follows
DEC conventions for special symbol names as far as possible, using a
'$' where the equivalent DEC symbol would use a '.' or '%'. In
particular IOLIB uses the following templates for different types of
symbol:
Template Use
-------- ---
$ggsss number of general category 'gg', specific use 'sss'
gg$sss byte of general category 'gg', specific use 'sss'
mmmmm$ opcode definition, whether by macro or OPDEF
ggeee$ error code of category 'gg', specific error 'eee'
All symbols for entry points to IOLIB routines are of the form
'$xxxxx'. The routines advertised as replaceable, as well as some
concealed routines and debug points, have entry points of the form
'$$xxxx'. The first characters of the entry point name indicate the
broad type of the routine:
$Rxxxx formatted read routines
$Wxxxx formatted write routines
$TMPxx tempcore routines
$FTLxx fatal error routines
$WRNxx warning error routines
$ERRxx collective error routines
$CNVxx conversion routines
$INIxx initialisation routines
Secondary entry points are normally identical to the primary
entry point except that the last character is replaced by a digit:
$RFILE read a file specification
$RFIL0 as above, but with different arguments
The symbols for macro names are all of the form xxxxx$, except
for a few special purpose macros which are xxxx$$. The macro usually
takes its name from the routine it calls. The replaceable routines
are called by macros that have ordinary names; e.g. $$WCHR is called
by the WCHAR$ macro.
3.5 ACCUMULATOR CONVENTIONS
IOLIB breaks the accumulators down into 3 types of ac, temporary,
preserved and global. The differences lie in the conventions about
the way they are treated in subroutine calls. Temporary acs are just
that. They should be used for temporary workspace, and in particular
no caller routine should expect any temporary ac to be preserved
PROGRAMMING TECHNIQUES Page 3-4
ACCUMULATOR CONVENTIONS
across a subroutine call. It is the caller's responsibility to save
temporary acs if this is necessary.
Preserved acs can be used by a routine as workspace that is
permanent for the life of that routine. Any subroutine must save any
preserved ac that it uses before use, and must restore it before
returning to the caller. Any routine must be able to rely on all
subroutines obeying this convention.
Global acs are free for the program to use as it wishes. They
are normally used for quantities that are set in defined routines and
otherwise passed around from routine to routine.
IOLIB uses these conventions. However, not all IOLIB routines
destroy temporary acs, and in particular, frequently called routines,
such as the basic IO routines, are very careful not to destroy
temporaries. Appendix A details the temporaries that are destroyed by
each routine. IOLIB only changes T1-T4 and always preserves preserved
acs. IOLIB reserves 3 globals for itself. They are acs 15 16 and 17,
and they are used for the current file point, the IDB point and the
push down stack point respectively. They are named D, I and P. IOLIB
never touches any other global. Acs 0 and 11-14 are always free for
the caller.
IOLIB defines symbols for the various acs as given in the
following table:
Ac Name Use
-- ---- ---
0 T0 temporary (never by IOLIB)
1 T1 " (used by IOLIB)
2 T2 " "
3 T3 " "
4 T4 " "
5 P1 preserved
6 P2 "
7 P3 "
10 P4 "
11 G1 global
12 G2 "
13 G3 "
14 G4 "
15 G5 " (reserved to IOLIB)
16 G6 " (reserved to IOLIB)
17 G7 " (reserved to IOLIB)
0 F flag register (since non-index)
15 D current file point
16 I IDB point
16 L link ac (DEC standard)
17 P push down stack point
PROGRAMMING TECHNIQUES Page 3-5
ACCUMULATOR CONVENTIONS
IOLIB contains routines ($SAVEn) to save from 1 to 4 preserved
acs and to ensure that they are restored correctly on return. These
routines should be called by PUSHJ on entry to a routine. They save
preserved acs, starting at P1, on the stack and then call the rest of
the caller routine as a subroutine. When the caller routine exits by
POPJ, control returns to the $SAVEn routine which restores the saved
acs and jumps back to the original caller. $SAVE1 preserves P1, and
$SAVE3 preserves P1-P3 etc.
SUBROU:
SAVE2$ ;saves P1 & P2
...
body of subroutine
may use P1 & P2
...
POPJ P, ;returns to $SAVE2 to restore P1 & P2
; before returning out of SUBROU
There are routines, $SAVET and $RESTT, that save and restore the
4 temporary accumulators, T1-T4. These would normally be used by the
caller of a subroutine to ensure that acs are preserved.
The user programmer does not have to adhere to IOLIB's division
of acs into temporaries, preserved and globals. He need only be aware
that IOLIB reserves G5-G7, and that T1-T4 may be destroyed by IOLIB
calls. He may decide that he only needs two preserved acs, P1 and P2,
and that P3 and P4 will be used as globals or as temporaries. The
user programmer may define new symbols for the acs as he pleases.
IOLIB defines ac0 as F, a flag register, because many programs
use ac0 as a vector of 1 bit program flags. Ac0 is convenient for
this purpose since it is not an index register. IOLIB itself never
uses ac0.
3.6 SUBROUTINE CALLS
All calls to IOLIB subroutines are by 'PUSHJ P,' instruction and
returns are by a corresponding 'POPJ P,'. Arguments are passed in acs
and values are returned in acs also. The IOLIB argument convention is
that arguments are passed in acs T1-T4 except in special cases. Acs
are allocated to arguments in ascending order, so that T1 is used
first. The special cases are acs D and I. These acs must almost
always be set up to point to the current file and to the IDB
respectively. Appendix A shows which routines need acs D and I, and
which do not.
A common convention in MACRO-10 is that a subroutine (or UUO) may
have normal and abnormal returns. In these cases, the convention is
that abnormal returns are to the 'return address' and normal returns
are to the 'return address +1'.
PUSHJ P,SUBROU ;call subroutine
error return ;abnormal
PROGRAMMING TECHNIQUES Page 3-6
SUBROUTINE CALLS
o.k. return ;normal
IOLIB routines that have error returns adhere to this convention. The
only exceptions are the $READ and $INPUT routines which have 3
returns, for error, endfile and normal.
The routines $POPJ and $POPJ1 can be called to give returns to
the return address and the return address +1; e.g.
PJUMPE T1,$POPJ## ;return if zero
PJRST $POPJ1## ;skip return now
It is often useful to be able to pop ac(T1) from the stack and
then return either nonskip or skip. IOLIB contains routines $TOPJ and
$TOPJ1 which are the same as $POPJ and $POPJ1 except that ac(T1) is
popped before return.
There are also routines to pop the stack (but not destroy ac(T1))
and then return. They are $XOPJ and $XOPJ1.
Lastly, there are routines $POPJ2 and $TOPJ2 which give a double
skip return as with the normal return from $INPUT. The user must be
careful with these routines as they will not work with the $SAVEn
routines.
3.7 ASSEMBLY SWITCHES
IO.MAC defines a number of assembly switches, with symbols FT$xxx for
feature tests, that are used to control optional features which are
included for this program. The programmer may alter the standard
settings of these switches by including a symbol definition in his
program.
FT$DBG==-1 ;debug feature required
The assembly switches defined in IO.MAC and their standard
settings and effects are:
Switch Value Effect
------ ----- ------
Switches which the programmer may set:
FT$ALC -1 nonzero for dynamic memory management; zero for
static memory management
FT$CCL 0 nonzero for CCL entry points to be included in
the BEGIN$ macro; zero for no CCL entry points
FT$DBG 0 nonzero for debug features (such as caller address
printed in error messages); zero for no debug
features
Switches which the installation may change:
PROGRAMMING TECHNIQUES Page 3-7
ASSEMBLY SWITCHES
FT$SFD 6 level of SFDs supported by IOLIB.
Note that the level of SFDs supported by the monitor
will take
precedence.
3.8 PUSH DOWN STACK
IOLIB contains a push down stack and a pointer to the top of the
empty stack. The stack is replaceable, so that the programmer can
define his own stack if he needs a longer or shorter stack. The IOLIB
stack is called $STACK and is 100 (octal) locations long. The stack
pointer is called $PTSTK and is merely 'IOWD 100,$STACK'. To define a
replacement stack, write:
$PTSTK::
IOWD STLEN,$STACK ;stack pointer
$STACK::
BLOCK STLEN ;stack block
3.9 BEGIN$ - PROGRAM INITIALISATION
The BEGIN$ macro performs all the initialisation functions
required at the start of execution of a program. It must be the first
statement following the start address because it notices whether entry
was a 'start', or 'start+1' for the special CCL entry point. The code
produced by BEGIN$ runs to about 15BEGIN$ produces 5 words of code and
calls the $BEGIN (or $BEGCC) routines. BEGIN$ labels the first word
of the user's program with the internal symbol $$BEG, to aid
debugging.
1. unless FT$DBG is on, SALL, to suppress listings of macro
expansions. If debugging, load the patch area and special debug
code, otherwise load nondebug code.
2. if FT$ALC is zero, set the replaceable entry points, $$ALLC and
$$DALC, to the memory manager to use static management.
3.
produce PORTAL instructions for normal and CCL entry points
to implement concealed mode.
4. set T1=0 for normal entry and T1=-1 for CCL entry.
5. RESET UUO
6. load ac(P) from $PTSTK to set up the push down stack pointer.
7. call $INIID to initialise the IDB by clearing it and setting
default values.
PROGRAMMING TECHNIQUES Page 3-8
BEGIN$ - PROGRAM INITIALISATION
8. set the program name, extension, device and PPN provided in the
acs by the monitor into the IDB.
9. if FT$CCL is on, test ac(T1), and if entry was at the CCL entry
point build a tempcore FDB, and read the tempcore file.
10. set the current file, ac(D), from the command file point in the
IDB.
3.10 GLOBAL PARAMETERS
The IDB contains program parameters which may be set by the
programmer or by a user through standard switches. These parameters
are:
1. memory limit. A maximum on the amount of memory used by the
program can be imposed. Normally the memory managers will
continue expanding the program size on request, until the monitor
refuses to provide any more memory. But, the memory managers
check $IDTOP(I) first and will not exceed the size set there. To
limit the amount of memory to 16K, say, set $IDTOP(I) to the
memory limit can also be set by the user through the standard
/MAXCOR switch. The system default is 256K. 16K words +1, e.g.
MOVEI T0,^D16*^D1024
MOVEM T0,$IDTOP(I)
2. program id for error messages (see chapter 10). A 3 character
SIXBIT code can be set into the left half of $IDECD(I). The
default is none.
MOVSI T0,'IOL'
HLLM T0,$IDECD(I)
3. error message verbosity. May be set to 0,1 or 2 for 'low',
'standard' and 'high', by moving the code into the right half of
$IDECD(I). Also set by the /VERBOSITY switch. The default is
standard verbosity.
4. standard switch table. A pointer to the standard switch table can
be set into the right half of $IDSWT(I). See section 4.3 for
details.
5. help file name. The SIXBIT name of the file containing help text
may be set into $IDHNM(I). If no help name is set, and the user
gives a /HELP switch, IOLIB uses the program's name to look for
the help file.
6. the default FDB for filename decoding. A point to a default FDB
may be set into the right half of $IDDFD(I).
PROGRAMMING TECHNIQUES Page 3-9
GLOBAL PARAMETERS
7. the command input file. A point to an FDB may be set into
$IDIFD(I), and that point will be loaded into ac(D) by the CMDFD$
macro. The command input file is initialised by BEGIN$.
8. the message output file. A point to an FDB may be set into
$IDOFD(I), and that point will be loaded by the MSGFD$ macro. The
message output file is initialised by the BEGIN$ macro.
9. the error messge file. A point to an FDB may be set into
$IDEFD(I), and that point will be loaded by the ERRFD$ macro, and
will be used to write all error messages (unless it is for an IO
error in the message file).
10. the next character to be read by the command character input
routine, $RCCHR. An ASCII character or endline code may be set
into $IDNXC(I). The character should be right-justified.
11. the default path for the job should be changed by setting the path
into $IDJPT and then using the PATH. UUO.
3.11 SEGMENTATION
The programmer may set the segment that code will be assembled
into through two macros, HISEG$ and LOSEG$. The macros first check
that a change of segment is needed and then ensure that all
outstanding literals are assembled into the current segment before
issuing a RELOC to change segments. In a two segment program, a call
to HISEG$ should appear at the start of a program so that HISEG$ can
set up the TWOSEG pseudo-op to define this program as a two segment
program.
TITLE 2SEGEX - two segment example
HISEG$ ;set high segment
SEGEX:
BEGIN$
...
high segment code
...
LOSEG$ ;change to low segment
...
low segment code
...
HISEG$ ;back to high segment
END SEGEX
PROGRAMMING TECHNIQUES Page 3-10
FDESC$ - BUILD AN FDB AND SET VALUES
3.12 FDESC$ - BUILD AN FDB AND SET VALUES
The FDESC$ macro assembles an FDB in inline code and fills it
with any arguments supplied to the macro. The call is
FDESC$ dev,nam,ext,<path>,mode,length
where:
dev is the name of a device
nam is the file name
ext is the file extension
path is a path specification (without []). If no SFD names are
given, the PPN is set into $FDPPN; otherwise the macro
builds a path block, sets the components of the
specification into the block and sets a pointer to the block
into $FDPPN.
mode is the IO mode. In fact a complete IO status halfword may
be given.
length is the length of the FDB to be created. The default is a
standard length FDB.
For example:
FDESC$ DSK,ACCT,SYS,<,,ACCOUN>,.IOBIN
makes an FDB for the file 'DSK:ACCT.SYS[,,ACCOUN]' and sets binary
mode.
3.13 MAKFD$ - PRODUCE CODE TO BUILD AN FDB
MAKFD$ writes inline code to create an FDB if none is given, to
initialise the FDB using $CLRFD, and to set values given as arguments
into the FDB. At the end of execution of the macro code, a point to
the FDB is left in ac(D). as arguments into the FDB. The call is:
MAKFD$ dev,nam,ext,<path>,mode,length,address
where:
dev is the name of a device
nam is the file name
ext is the file extension
path is a path specification (without []). If no SFD names are
given, the PPN is set into $FDPPN; otherwise the macro
writes code to build a path block, set the components of the
specification into the block and set a pointer to the block
into $FDPPN.
mode is the IO mode. In fact a complete IO status halfword may
be given.
length is the length of the FDB to be created. The default is a
standard length FDB.
address is the address of an existing FDB. If no address is given
PROGRAMMING TECHNIQUES Page 3-11
MAKFD$ - PRODUCE CODE TO BUILD AN FDB
the macro creates a new FDB in space obtained from the
memory manager.
MAKFD$ DSK,INPFIL,DAT,<104,427>,,,INPFDB
creates the code to call $CLRFD for the FDB, and then set the details
for 'DSK:INPFIL.DAT[104,427]' into the FDB.
3.14 VERSION NUMBER MACROS
IOLIB contains 4 macros to help the programmer to define and
update version numbers of programs. The VERSN$ macro creates symbols
for the 4 fields of the version number and assigns values (given as
arguments) to them. The PATCH$ macro increments the edit-number for
each patch and defines a patch symbol that can be used in conditional
assembly of code added or deleted by the change. Each call to PATCH$
increments the minor version number. The JBVER$ macro sets the
version number into .JBVER in the job data area, and VTEXT$ produces
an ASCIZ string of the version number.
VERSN$ major-version,edit-number,who-edited
the minor version number is set to zero, and is incremented by the
PATCH$ macro. VERSN$ types out the version numbers of C.MAC and
IO.MAC used during assembly, while being assembled.
PATCH$ <patch numbers>
each patch is assigned a patch number and the numbers are given as the
argument. PATCH$ creates a symbol '$n' for each number and this
symbol can be used in IFDEF and IFNDEF conditionals. PATCH$ also
increments the edit number for each patch, and increments the minor
version number once per PATCH$ macro.
JBVER$
The JBVER$ macro takes no arguments, and sets the version number into
.JBVER.
VTEXT$
The VTEXT$ macro uses the values for the symbols generated by the
VERSN$ and PATCH$ macros to make an ASCIZ string of the version
number.
e.g.
VERSN$ 5,7,3 ;version 5(7)-3
PATCH$ <10,11,13,14> ;version 5A(14)-3
PATCH$ <15,16> ;version 5B(16)-3
JBVER$ ;137/ BYTE (3)3(9)5(6)2(18)16
VTEXT$ ;makes the string '5B(16)-3'
PROGRAMMING TECHNIQUES Page 3-12
DEBUGGING AIDS
3.15 DEBUGGING AIDS
Programmers writing programs using IOLIB often have trouble with
debugging when they see control disappearing into the basic IO
routines and then coming out with the wrong answer or with an illegal
memory reference. IOLIB code is written to be efficient, and does not
go to great lengths to defend itself against misuse, and this can make
life more difficult when debugging.
One useful technique is to watch the IO UUOs that are being
executed to find out at what point the trouble starts. IOLIB provides
two special symbols, $$XUUO and $$XCAL, which label the instructions
that execute IO UUOs and CALLI UUOs concerned with devices. The
debugger can place DDT breakpoints on these symbols and examine ac(T1)
to find the UUO. The point to the current FDB is always in ac(D).
Another internal symbol of use is $$BEG, which the BEGIN$ macro
uses to label the first word of the user program following the BEGIN$
macro code.
There is an assembly switch, FT$DBG, which invokes debugging
features if set to -1 by the programmer. In the present version of
IOLIB, FT$DBG suppresses the SALL, so that macros are expanded in
listings, and also ensures that the caller's address is printed in
octal in error messages.
If FT$DBG is on, a 200 word patch area is loaded from IOLIB,
which the debugger can use to insert extra words of code. The name of
the patch area is $PATCH, and there is a second symbol, $PAT, which
may be moved after inserting each patch to point to the first free
word in the patch area. Note that LINK-10 and LOADER load a patch
area, caled PAT.., if DDT is loaded.
CHAPTER 4
IOLIB TABLES
4.1 GENERAL DESCRIPTION
IOLIB contains a number of tables that the programmer may need to
know about so that he can replace them with his own versions or use
the contents. The table $TBWAD contains addresses of formatted write
routines that will be used to print value in error texts. It is
indexed by the error value code supplied to the FATAL$ or WARN$
macros.
The programmer who is using IOLIB to read commands will very
likely want to include switch specifictions in his command string. He
can define his own switches in a switch table using macros defined in
IO.MAC.
4.2 $TBEVL - TABLE OF ERROR VALUES
$TBWAD contains the address of the routine which prints the value
supplied by the user for each possible code in the EC$TYP field in
ac(T1) on a call to $ERROR. The standard IOLIB $TBWAD contains 6
possible types, but the user is free to define his own table if he
needs others. Each word in the table contains the address of the
formatted write routine in the right half. The table must be called
$TBWAD and the length symbol $LNEVL must be defined INTERNal also.
The contents of the standard table are:
Index Symbol Write Routine
----- ------ ----- -------
0 $ECTNO none
1 $ECTCH $WFCHA, write a 'funny' character
2 $ECTDE $WDECL, write a number in decimal
3 $ECTFI $WFILE, write a filename
4 $ECTOC $WOCTL, write a number in octal
5 $ECTTE $WTEXT, write an ASCIZ string
6 $ECTWO $WWORD, write a SIXBIT word
7 $LNWAD length symbol
IOLIB TABLES Page 4-2
SWITCH TABLES
4.3 SWITCH TABLES
Switch tables are lists of switch names, and details about the
values that those switches can take. Switch names and values are read
by the IOLIB subroutines $RSWIT and $RFILE (which calls $RSWIT). The
routines may be given the address of a switch table as an argument.
When $RSWIT reads a switch name, it searches the list of names in the
switch table for an unambiguous match. If it finds a match it uses
the details in the associated lists to read a value (if one is given)
check legality of the value, and set the value wherever the programmer
directs. In fact, $RSWIT can search two tables, the table provided by
the programmer as an argument, and a table of standard switches
pointed at by $IDSWT(I). Standard switches are ones such as those
provided in $TBSSW in IOLIB, which contains switches for changing
parameters in the IDB, and file switches. The point to the table of
standard switches must be set into $IDSWT(I) by the programmer.
A switch table is actually 5 tables, that can all be built by the
one macro, SWTAB$. There is a table of 4 pointers to the other 4
tables. These tables are a table of switch names in SIXBIT, a table
that tells $RSWIT where to put the value of the switch that $RSWIT
reads, a table giving either the address of a list of keyword values,
or a maximum value, and a table of default values for if no value is
given. All these tables can be built by the one macro SWTAB$. The
switches in $TBSSW are:
Value/
Name Keywords Default Deposit
---- -------- ------- -------
BLOCKSIZE decimal 4000 buffer size in FDB
DENSITY INSTAL/200/556/800 INSTAL FM$DEN in $FDMOD/MOM
HELP TEXT/SWITCHES TEXT call $WHELP to write text
MAXCOR kword 28K $IDTOP(I)
PARITY ODD/EVEN ODD FM$PAR in $FDMOD/MOM
PHYSICAL FM$PHY in $FDMOD/MOM
PROTECTION octal 157 FM$PRO in $FDMOD/MOM
RUN filename rh($IDRUN(I))
RUNOFFSET octal 1 lh($IDRUN(I))
VERBOSITY LOW/STANDARD/HIGH STD rh($IDECD(I))
4.4 SWITCH TABLE BUILDING MACROS
There are several macros involved in the complicated procedure of
building switch tables. SWTAB$ is the macro called by the user to do
the building, but the programmer must have already defined a SWIT$$
macro of his own to tell SWTAB$ the switch details. The programmer's
SWIT$$ macro definition contains calls to the SL$, SP$ and SS$ macros,
which define each individual switch. The switches which take keyword
values require a table of keywords which can be built by the KEYWD$
macro, and the switches which take numeric values need default values
and maximum values, which can be defined by the DM$ macro.
IOLIB TABLES Page 4-3
SWITCH TABLE BUILDING MACROS
SL$, SP$ and SS$ take several arguments which define the
attributes of the switch, and differ between the 3 macros. The first
argument is the switch name. If the first character is an '*', then
the first character of the switch is a sufficient abbreviation; i.e
if the name was given as '*HELP', then the user can always type '/H'
to get help, no matter what other switches begin with letter H. The
second argument is always a pointer, which is used to deposit the
value of the switch. The pointer may be a byte pointer, or a halfword
point to a full word, or a word with -1 in the left half and the
address of a user routine in the right half. The user routine does
the depositing itself. The other arguments are different for the
different macros.
e.g.
;the DM$ macro defines the symbols MX$MXC and PD$MXC
; for the /MAXCOR switch
DM$ MXC,256,28,28 ;defaults
;the SWIT$$ macro contains definitions for 3 switches
; HELP : takes keywords 'TEXT' and 'SWITCHES'
; (e.g. /HELP:TEXT)
; the default is TEXT (4th argument)
; the keyword table is HELP$T
; a user routine called 'SWHELP' is called to
; deposit the value.
; MAXCOR : takes values in pages or Kwords
; the maximum is MX$MXC and the default is PD$MXC
; the value will be set into $IDTOP(I)
; PHYSIC : takes no value
; if given, '1' will be set into $FDMOD in an FDB
; at FM$PHY
DEFINE SWIT$$,<
SL$ <*HELP>,<-1,,SWHELP>,HELP,HELPTEXT
SP$ <MAXCOR>,<$IDTOP(I)>,$SWKWD,MXC
SS$ <PHYSICAL>,<POINT 1,$FDMOD(T1),3>,1
>
HMPTAB: ;address of table
SWTAB$ HMP ;define tables
KEYWD$ HELP,<SWITCHES,TEXT> ;define HELP keywords
SWTAB$
------
A call to SWTAB$ produces the 5 switch tables. The macro takes
one argument, which is a 3 character name that is concatenated with
'$$x' to give names for the individual tables. A call to the macro
requires that the user has defined a macro, SWIT$$, that contains
calls to macros which define the individual switch details (see
below).
IOLIB TABLES Page 4-4
SWITCH TABLE BUILDING MACROS
SWTAB$ UTB ;define switch tables
The name table is called UTB$$N, the pointer table UTB$$P, the maximum
table UTB$$M, and the default table UTB$$D.
SWIT$$
------
The SWIT$$ macro must be defined by the programmer calling the
SWTAB$ macro. It contains calls to the macros, SS$, SL$ and SP$ which
are defined below.
SS$
---
SS$ defines a switch which has no value. If this switch is given
by the user, $RSWIT deposits a value given in the 3rd argument (and
usually a 1 bit flag), into the position specified by the second
argument. For an example, see the definition of SWIT$$ above. The
call is
SS$ name,deposit-point,value
SP$
---
SP$ defines switches which have values other than keywords, for
example decimal numbers or kword values. The 3rd argument is a code
for the name of the routine that will read the value. Available codes
are: DECL, FILE, KWRD, OCTL. The name of the code is concatenated
with '$SW' to form the name of the value reader.
The fourth argument is a 3 letter abbreviation for the switch
name, which is concatenated with the characters 'MX$' to give a symbol
for the maximum value, and with 'PD$' to give one for the default
value. The MX$xxx and PD$xxx symbols are defined by the DM$ macro.
If no maximum or default is wanted, this argument may be ommitted.
SP$ name,deposit-point,value-code,abbreviation
SL$
---
Defines a switch which takes keyword values. The keywords can be
defined by a separate KEYWD$ macro. The third argument is a code for
the name of the table defined by the keyword macro. It is the same
name as the first argument of the appropriate KEYWD$ macro.
The fourth argument is a symbol for the default index in the
table. It is a concatenation of the 4 characters of the table name
and the first two characters of the default keyword name.
SL$ name,deposit-point,keyword-table,default-index
DM$
---
IOLIB TABLES Page 4-5
SWITCH TABLE BUILDING MACROS
Defines three symbols, the maximum value of a parameter, the
default value if the switch is given but no value, and the default
value if the switch is not given. The symbols defined are, MX$xxx,
PD$xxx and AD$xxx respectively. Call:
DM$ abbreviation,MX-value,AD-value,PD-value
KEYWD$
------
Defines a table of keywords for switches and symbols for the
index of each keyword in the table. The name argument of the macro
should be 4 characters long, and it is concatenated with the first 2
characters of the keyword name to make the index symbol. The index
symbol for the default value should be used in the default argument of
the SL$ macro. Call:
KEYWD$ name,<keywords>
e.g. KEYWD$ DEN,<200,556,800,INSTALLATION>
The symbols for the indices of each keyword are DENS20, DENS55, DENS80
and DENSIN.
CHAPTER 5
MEMORY MANAGEMENT
5.1 GENERAL DESCRIPTION
Programs use free memory space for various purposes during their
execution, for arrays of data, for buffers, for linked lists and many
others. Sometimes it is convenient to build all the memory chunks
that a program needs into the program while it is being written.
Often however, it is easy and useful to be able to ask for and receive
a chunk of free memory during program execution. On the DECsystem-10,
the program is effectively broken into high and low segments, the high
segment being used for reentrant code, and the low segment for
non-reentrant code and data. Memory is allocated to the program in
chunks of 1P on a KI10 and 1K on a KA10 processor. The last location
used by the program is generally not the top of the allocated memory,
and the space between the last location and the top of allocated
memory is free for use by the user program. In addition, if this
space is insufficient, the user program can request more memory from
the monitor.
The IOLIB memory management routines allocate this free space to
any routine that requests it, and deallocate the space when the
routine announces that it has finished with it. The memory management
routines first allocate all the sace that was available when the
program was loaded, and then ask the monitor for more as required.
All the programmer has to do is to call the memory managers to ask for
a chunk, or to donate chunks back to the pool.
It is not always a good thing to allow programs to grab as much
memory as they ask for, since some programs are almost insatiable, but
will move onto secondary storage when memory is exhausted (e.g.
LINK-10). IOLIB allows the programmer or user to limit the absolute
size of his program. The location $IDTOP(I) in the IDB specifies the
maximum number of words that the memory managers may obtain for the
program. The BEGIN$ macro initialises $IDTOP(I) to 256K, the maximum
physically possible (without virtual memory). The program may alter
$IDTOP(I) to any required value, and the user can use the standard
/MAXCOR switch to do the same.
IOLIB contains two forms of memory management, static and
dynamic. They may be used in the same program, but this is
unsatisfactory and an excessive code overhead. Static memory
management satisfies each request by finding extra space starting at
MEMORY MANAGEMENT Page 5-2
GENERAL DESCRIPTION
the first unused location (pointed at by
.JBFF in the job data area). Chunks of memory cannot be
deallocated using static management. Dynamic memory management
maintains a chain of free chunks, and allocates and deallocates chunks
from the chain. It is much more versatile than static management but
the program overhead is higher and it uses one overhead word for each
chunk. IOLIB automatically selects dynamic management unless the user
opts for static management through the FT$ALC assembly feature test
switch. If FT$ALC is defined as FT$ALC=0, then static management is
used.
Both memory allocators zero chunks of memory before handing them
to the caller.
5.2 DYNAMIC MEMORY MANAGEMENT
The dynamic memory manager is basically the ALGOL heap routine
which was originally written for ALGOL-10 by R.M. DeMorgan, and was
adapted later for FOROTS. The manager routines keep a linked list of
free chunks of memory anchored to $IDDYC(I) in the IDB. The list is
linked through the first word (the overhead word) of each chunk, and
the last chunk has a link of 0. The left half of the overhead word is
a count of the words in the chunk including the overhead word, and
this count must never be altered by the programmer. The linked list
of chunks is ordered by size with the smallest chunk first.
When the manager is asked for a chunk, it scans the list for the
first chunk of the required size or larger. If there is a chunk of
the correct size, it is handed back as a pointer to the second word,
which is the first word available to the program. If not, the larger
chunk is split and the excess returned to the list. If there is no
chunk large enough, the manager garbage collects the list,
concatenating adjacent chunks and tries again. If the search fails
again, the manager resorts to asking the monitor for more memory, and
so on until either $IDTOP(I) is reached, or the monitor refuses to
supply any more memory. On failure, the manager returns code ERNEC%
in ac(T1).
When a user deallocates a chunk, the manager merely inserts the
chunk into the linked list at the correct point. The user may return
a linked list of chunks, linked through the overhead word. The chunks
need not be in order of size. When the program returns a chunk, he
must supply a point to the second word of the chunk; the word
following the overhead word.
MEMORY MANAGEMENT Page 5-3
STATIC MEMORY ALLOCATION
5.3 STATIC MEMORY ALLOCATION
The static allocator is very simple. It merely looks at .JBFF
for the first free location, increases it by the amount requested and
returns a point to the caller. If the new first free location pointer
exceeds the highest available the allocator requests more memory from
the monitor until either $IDTOP(I) is reached or the monitor refuses
to supply more memory. If the allocator fails it returns the error
code ERNEC% in ac(T1).
The static deallocator gives an immediate return. The space is
not made available for reallocation.
CHAPTER 6
BASIC IO ROUTINES
6.1 GENERAL DESCRIPTION
The basic IO routines execute UUOs, manipulate the contents of
FDBs to set default values and keep track of progress through the
labyrinth of monitor calls. The basic IO routines are called by all
formatted read and write routines, and by other IOLIB routines that
need to do IO.
It is quite possible to do IO operations without realising the
existence of the basic routines by setting up file details in the FDB
and using read and write calls. However, the individual UUOs may be
executed by descending to basic IO calls. The basic IO routines
reflect the structure of the monitor IO UUOs; there is an $INPUT
routine to execute an INPUT UUO and a $CLOSE routine for the CLOSE
UUO. Most of the routines do much more than execute the UUO that they
are named after. Firstly, the routines check that all prerequisite
UUOs have been executed, and if not, the appropriate routines are
called. So if the user calls $INPUT as his first IOLIB call for a
file, $INPUT will call $LUKUP to check whether the LOOKUP has been
done, and $LUKUP in turn will call $OPEN. After the OPEN UUO is done,
control returns to $LUKUP for the LOOKUP UUO, and finally to $INPUT
for the INPUT UUO. Secondly, some basic routines perform other
functions that would otherwise have to be done separately by the
calling program. $INPUT will create a buffer ring, if none is set up,
with the number and size of the buffers a parameter in the FDB.
$INPUT also calls $USETI, to find the required record, taking the next
record number from the FDB. The programmer can control all IO from
the highest level by making changes to the parameters in his FDB and
calling any read or write routine. IOLIB arranges to call other
necessary routines lower in the hierachy.
Calls to the basic routines are channel independent. The
programmer need not try to assign channels to individual files, but
should let IOLIB do it for him. $OPEN assigns the next free channel
to the user, starting with channel 1. Channel 0 is never used unless
the programmer explicitly directs $OPEN to use it. The caller cannot
specify an exact channel number for a file, but he can suggest where
the search for a free channel should begin.
BASIC IO ROUTINES Page 6-2
GENERAL DESCRIPTION
All the basic IO routines expect the pointer to the current FDB
to be set up in ac(D), to describe the file for which the IO operation
is to be performed. All non-default values must be set in the FDB.
Because the basic routines are called so frequently, they are
careful to save all acs, including temporaries, except those used to
transmit arguments. An exception is the error return, when ac(T1)
contains an error code with a UUO code in the left half and a specific
error code in the right half.
Most of the basic routines are assembled into one module, IOMOD,
which is always loaded with every program that uses IOLIB. The calls
for the basic routines are explained in Appendices A & B. Algorithms
for critical routines are given in the sections below.
6.2 $INPUT - READ A PHYSICAL RECORD FROM A FILE
To read a physical record from a file. There are 3 returns;
non-skip on an error, skip on endfile and double skip on a successful
return. An error code is returned in ac(T1) for both error and
endfile returns. The full algorithm is:
1. check the tempcore input flag (FC$TCI in $FDCHN(D)). If on, give
an immediate endfile return.
2. call $LUKUP to execute OPEN and LOOKUP UUOs if not already done
for this file.
3. if dump mode (check $FDSTS(D)), goto step 4. Otherwise, if no
input buffer ring is established, call $MKBUF to build one taking
the size and number of buffers from $FDBUF(D).
4. load the next block number from $FDNBK(D) and call $USETI to find
the required physical record.
5. set [this block number,,next block number] into $FDNBK(D).
6. execute the input by an 'INPUT ch,@$FDIOW(D)' instruction so that
for dump mode, $FDIOW(D) should point to a chain of IOWDs, and for
buffered modes $FDIOW should normally be zero, but may point to
the next buffer.
7. if ok, return double-skip now. Otherwise, call $GETST to read the
IO channel status, then call $SETST to clear error and endfile
bits.
8. calculate the error code from the error and endfile bits in the IO
channel status.
9. skip return if endfile. Otherwise normal return.
FDB words altered:
--- ----- --------
BASIC IO ROUTINES Page 6-3
$INPUT - READ A PHYSICAL RECORD FROM A FILE
$FDNBK set to [this-record-number,,next-record-number]. The next
record is just this record+1 for sequential reads.
$FDSTS on error and endfile, right half set to IO channel status word.
FDB words used:
--- ----- -----
$FDBUF to build buffer ring. $OPEN sets defaults from the monitor if
the user does not provide his own values. Either number or
size of buffers or both may be given.
$FDNBK the right half is used to determine which record to read next
(disk only). The programmer may set the next record number for
random input, otherwise $INPUT will read sequentially starting
from the beginning.
$FDIOW addressed by the INPUT UUO instruction. The user must set up
this word for dump mode IO.
6.3 $OUTPU - WRITE A PHYSICAL RECORD TO A FILE
To write a physical record to a file. There are 2 returns;
non-skip on an error, and skip on a successful return. An error code
is returned in ac(T1) for error return. The full algorithm is:
1. call $ENTER to execute OPEN and ENTER UUOs if not already done for
this file.
2. if dump mode (check $FDSTS(D)), goto step 4. If an output buffer
ring is established, goto step 4 to avoid a dummy output.
Otherwise call $MKBUF to build one taking the size and number of
buffers from $FDBUF(D).
3. clear $FDNBK(D) because this is a dummy output. Before return,
$FDNBK(D) will be incremented for the first output. Goto step 5
to avoid USETO.
4. load the next block number from $FDNBK(D) and call $USETO to find
the required physical record.
5. set this block number,,next block number into $FDNBK(D).
6. execute the output by an 'OUTPUT ch,@$FDIOW(D)' instruction so
that for dump mode, $FDIOW(D) should point to a chain of IOWDs,
and for buffered modes $FDIOW should normally be zero, but may
point to the next buffer.
7. if ok, return skip now. Otherwise, call $GETST to read the IO
channel status, then call $SETST to clear error bits.
8. calculate the error code from the error bits in the IO channel
status.
BASIC IO ROUTINES Page 6-4
$OUTPU - WRITE A PHYSICAL RECORD TO A FILE
9. non-skip return to show error.
FDB words altered:
--- ----- --------
$FDNBK set to [this-record-number,,next-record-number]. The next
record is just this record+1 for sequential writes.
$FDSTS on error, right half set to IO channel status word.
FDB words used:
--- ----- -----
$FDBUF to build buffer ring. $OPEN sets defaults from the monitor if
the user does not provide his own values. Either number or
size of buffers or both may be given.
$FDNBK the right half is used to determine which record to write next
(disk only). The programmer may set the next record number for
random output, otherwise $OUTPU will write sequentially
starting from the beginning.
$FDIOW addressed by the OUTPUT UUO instruction. The user must set up
this word for dump mode IO.
6.4 $LUKUP - LOOKUP A FILE
Check if the file has already been LOOKUPed. If so, give a good
return. Otherwise, execute a LOOKUP UUO for the file. The routine
executes an extended LOOKUP for disk files, and a short LOOKUP for all
other devices. The length of the extended LOOKUP is taken from
$FDCNT(D) which is initialised by $CLRFD. The full algorithm is:
1. call $OPEN to execute an OPEN UUO if necessary.
2. check whether $LUKUP has already been called for this file (FC$LUK
in $FDCHN on). If so, give an immediate skip return.
3. execute a LOOKUP UUO. If error, set error code and non-skip
return.
4. otherwise, set FC$LUK in $FDCHN(D) and skip return.
FDB words altered:
--- ----- --------
$FDCHN FC$LUK is set on a skip return so that $LUKUP will know next
time it is called.
$FDRIB see Monitor Calls Handbook for words affected by the LOOKUP
UUO.
FDB words used:
--- ----- -----
BASIC IO ROUTINES Page 6-5
$LUKUP - LOOKUP A FILE
$FDRIB used by LOOKUP UUO
6.5 $ENTER - ENTER A FILE
Check if the file has already been ENTERed. If so, give a good
return. Otherwise, execute a ENTER UUO for the file. The routine
executes an extended ENTER for disk files, and a short ENTER for all
other devices. The length of the extended ENTER is taken from
$FDCNT(D) which is initialised by $CLRFD. If FM$PRO is set to ones in
$FDMOM(D), then the contents of FM$PRO in $FDMOD(D) is set into
$FDPRV(D).
$ENTER has two entry points, $ENTER and $ENTE0. $ENTER assumes
that the caller does not want to set the protection, the mode, or the
create time and date from $FDRIB(D), so it clears $FDPRV(D) and
rh($FDEXT(D)). $ENTE0 does not alter $FDRIB(D) in any way other than
that described below. Note that all IOLIB routines higher in the
hierachy enter this routine at $ENTER. The full algorithm is:
1. ENTER entry: zero $FDPRV(D) and rh($FDEXT(D)).
2. ENTE0 entry: call $OPEN to execute an OPEN UUO if necessary.
3. check whether $ENTER has already been called for this file (FC$ENT
in $FDCHN on). If so, give an immediate skip return.
4. execute a ENTER UUO. If error, set error code and non-skip
return.
5. otherwise, set FC$ENT in $FDCHN(D) and skip return.
FDB words altered:
--- ----- --------
$FDCHN FC$ENT is set on a skip return so that $ENTER will know next
time it is called.
$FDPRV contents of protection field in $FDMOD added if masked by
$FDMOM.
$FDRIB see Monitor Calls Handbook for words affected by the ENTER UUO.
FDB words used:
--- ----- -----
$FDMOD protection field used if masked by $FDMOM
$FDMOM FM$PRO mask used.
$FDRIB used by ENTER UUO
BASIC IO ROUTINES Page 6-6
$OPEN - OPEN AN IO CHANNEL
6.6 $OPEN - OPEN AN IO CHANNEL
A software IO channel must be OPENed to initiate IO with any
file. $OPEN takes the file described by the current FDB, finds a free
channel, inserts defaults for all values not given by the caller and
then executes an OPEN UUO. $OPEN does not attempt to reopen a file
that has already been OPENed. The full algorithm is:
1. check whether the channel is already open ($FDOPN in $FDCHN(D))
and skip return if so.
2. call $FRCHN to find the first free channel starting with the
channel number supplied by the user if $FDCHN(D) is non-zero, and
with channel 1 otherwise. Set the channel number into FC$CHN in
$FDCHN(D). If no free channels are found, set ERNFC$ and non-skip
return.
3. check $FDDEV(D), and set 'DSK' if zero.
4. do a DEVTYP UUO. If the result is zero set ERNSD% and error
return. Otherwise, set the result into $FDTYP(D).
5. check the DEVTYP word to see whether the device is available. If
not, set ERDNA% and error return.
6. check whether the device is not spooled and is restricted. If so,
check that we have the device assigned and if not give ERRSD$ and
error return.
7. execute a DEVSIZ UUO. if dump mode, goto step 9. If improper
mode set, set ERIMP$ and error return.
8. use the user settings or the defaults returned by the DEVSIZ UUO
to set $FDBUF(D) with the buffer number and size. Set pointers to
the buffer headers, $FDIBH(D) and $FDOBH(D) into $FDBHD(D).
9. check if the device is a magtape. If not, goto step 11
10. check whether the magtape parity and density were set in $FDMOD(D)
were they masked in $FDMOM(D)), and if so transfer the settings to
$FDSTS(D).
11. check whether 'physical-only' set in $FDMOD(D) (FM$PHY masked in
$FDMOM(D)) and if so, set it in $FDSTS(D).
12. execute the OPEN UUO. The only unchecked error is no available
DDBs, so if error, set ERNET% and error return.
13. if the next block number is zero, set it to 1
14. set FC$OPN in $FDCHN(D) and skip return.
FDB words altered:
--- ----- --------
BASIC IO ROUTINES Page 6-7
$OPEN - OPEN AN IO CHANNEL
$FDCHN channel number into FC$CHN and FC$OPN on.
$FDTYP filled with result of DEVTYP UUO.
$FDDEV if zero, filled with 'DSK'.
$FDBUF if buffered mode, and either half zero, that half is filled
with the system default returned by the monitor on a DEVSIZ
UUO.
$FDBHD if buffered mode, filled with points to $FDIBH and $FDOBH.
$FDSTS may have physical-only and magtape parity and density set if
those fields are masked by $FDMOM.
FDB words used:
--- ----- -----
$FDCHN if non-zero, channel number is used as a starting point for
free channel search.
$FDOPN see Monitor Calls Handbook for usage by OPEN and DEVSIZ UUOs.
$FDMOD holds magtape density and parity and physical-only bit if
corresponding masks in $FDMOM are ones.
$FDMOM masks for fields in $FDMOD.
6.7 $CLOSE - DISCONNECT A FILE FROM AN IO CHANNEL
$CLOSE severs the connection between a file and a software
channel, but does not RELEAS the channel. There are two entry points.
$CLOSE closes both sides of the channel, and does not allow the caller
to set any CLOSE bits. $CLOS0 takes CLOSE bits as an argument. $OPEN
must have already been called for this file. The algorithm is:
1. CLOSE entry: zero CLOSE bits
2. CLOS0 entry: execute CLOSE UUO.
3. zero the block number in $FDNBK(D).
4. if CL.OUT was not set, clear FC$ENT in $FDCHN(D).
5. if CL.IN was not set, clear FC$LUK in $FDCHN(D), and return.
FDB words altered:
--- ----- --------
$FDNBK zeroed
$FDCHN bits FC$ENT and FC$LUK may be cleared.
BASIC IO ROUTINES Page 6-8
$RLEAS - RELEASE AN IO CHANNEL
6.8 $RLEAS - RELEASE AN IO CHANNEL
The IO channel used by the current FDB is released, and any
buffer rings are returned to the pool of free core chunks. $OPEN
should have been called for the current FDB before calling $RLEAS.
$RLEAS has two entry points: $RLEAS executes the UUO and deletes
buffer rings but $RLEA0 saves the buffer rings. The algorithm is:
1. call $DLBUF to return output buffer ring to pool of free core
chunks
2. call $DLBUF to return input buffer ring
3. $RLEA0: execute the RELEAS UUO.
4. clear $FDCHN(D) to zero the flags and channel number
FDB words altered:
--- ----- --------
$FDCHN zeroed
FDB words used:
--- ----- -----
$FDBHD to find the buffer headers and rings.
6.9 $RENAM - CHANGE RIB DETAILS FOR A FILE
To execute a RENAME UUO for the current file. A RENAME can be
used to delete a file from disk or DECtape, and to change the name and
extension. In addition, it can be used to change other details kept
in the RIB block, such as protection and create date/time. $RENAM
does an extended RENAME for disk files using the length in $FDCNT(D),
and a short RENAME for other devices.
The programmer should call $LUKUP for the file to obtain the
current file details, and then change the FDB and call $RENAM. If the
protection field in $FDMOM(D) is on (FM$PRO is 777) then the
protection code is taken from the FM$PRO field in $FDMOD(D).
FDB words altered:
--- ----- --------
$FDPRV the protection field is changed if FM$PRO is on in $FDMOM.
FDB words used:
--- ----- -----
$FDRIB used by RENAME UUO.
$FDMOD used if FM$PRO is on in $FDMOM.
$FDMOM for FM$PRO mask
BASIC IO ROUTINES Page 6-9
$DELET - DELETE A FILE
6.10 $DELET - DELETE A FILE
Delete a file from disk or DECtape by calling $LUKUP to find the
file, and then $RENAM to delete the file. There is no need for the
file to have been referenced before a call to $DELET.
6.11 $USETI/O - SET THE DISK FILE RECORD NUMBER
These routines execute USETI or USETO UUOs to ensure that the
next block read or written with the disk is the correct one. A word
containing the last record number in the left helf and the required
block number in the right half is an argument. If the required record
is the last record + 1, then no UUO is executed. These routines do
not defend against asynchronous IO, therefore they are only suitable
for use with dump mode, or with synchronous buffered modes.
FDB words altered:
--- ----- --------
$FDNBK returns with right half set to this record number, and the left
half set to this record - 1.
6.12 $GETST - READ THE IO CHANNEL STATUS
Read the IO channel status from the monitor and store it in the
right half of $FDSTS(D). This routine requires that $OPEN has already
been called.
FDB words altered:
--- ----- --------
$FDSTS right half receives IO status word.
6.13 $SETST - SET THE IO CHANNEL STATUS
Set the given IO status word into the monitor for the current
FDB. This routine requires that $OPEN has already been called.
6.14 $XTUUO - EXECUTE AN IO UUO
Execute the given IO UUO for the current FDB. The channel number
is obtained from FC$CHN in $FDCHN(D) and or'ed into the A field of the
UUO instruction. The routine has skip and non-skip returns, but the
skip return may be ignored for UUOs that have no skip return
A useful feature for debugging programs is that every IO UUO is
executed by an XCT instruction from the location labelled '$$XUUO', so
that a breakpoint on $$XUUO will catch every IO UUO. Examine ac(T1),
to find the UUO.
BASIC IO ROUTINES Page 6-10
$XTCAL - EXECUTE AN IO ORIENTED CALLI UUO
6.15 $XTCAL - EXECUTE AN IO ORIENTED CALLI UUO
For some CALLI UUOs it is important to know whether IO on the
associated file is 'physical only' e.g. a GETSEG UUO must be executed
physical only if this is specified. $XTCAL, checks the current FDB to
see whether either UU.PHS is set in $FDSTS(D) or UU.PHY is set in
$FDMOM(D) and $FDMOD(D), and if so, makes the UUO physical only before
executing it. As a side effect, if physical only was set in $FDMOM,
then the setting in $FDMOD(D) is set into $FDSTS(D).
A useful debugging feature is that all CALLI UUOs executed
through a $XTCAL (or $XTDCL) call are executed by an XCT instruction
at '$$XCAL'. Examine ac(T1) to find the UUO. The full algorithm is:
1. check whether physical only is implemented. If not, clear the
indicator. Goto step 4.
2. check whether FM$PHY is set on in $FDMOM(D). If not, goto step 5.
3. read the physical-only setting from FM$PHY in $FDMOD(D) into the
indicator.
4. set the indicator into $FDSTS(D).
5. check the physical only flag in $FDSTS(D). If on, complement
bit19 of the UUO, to show physical only. Execute the UUO and
return.
FDB words altered:
--- ----- --------
$FDSTS bit0 is set if FM$PHY is on in $FDMOM. Bit0 is set to FM$PHY
in $FDMOD.
FDB words used:
--- ----- -----
$FDMOD FM$PHY field checked and used.
$FDMOM FM$PHY mask used
6.16 $XTDCL - EXECUTE A DEVICE ORIENTED CALLI UUO
This routine is an entry point to the $XTCAL routine. The
distinction is that this routine is for CALLI UUOs that take a device
name as an argument. $XTDCL takes the device name from $FDDEV(D), and
uses 'DSK' as a default. 'DSK' is set into $FDDEV(D) if it was empty.
FDB words altered:
--- ----- --------
$FDDEV if empty on entry, it is set to 'DSK'.
BASIC IO ROUTINES Page 6-11
$MKBUF - BUILD A RING OF BUFFERS
6.17 $MKBUF - BUILD A RING OF BUFFERS
Use the size and number of buffers stored in $FDBUF(D) to build a
ring of buffers of the requied size, and link them into the given
buffer header. Initialise the ring-use bit.
FDB words used:
--- ----- -----
$FDBUF uses both number and size of buffers to create ring
6.18 $DLBUF - DELETE A RINF OF BUFFERS
Given the address of a buffer header, garbage collect the buffer
ring and return all buffers to the pool of free chunks of core. This
routine is ineffective if static core allocation is being used.
6.19 $UPDAT - OPEN A FILE FOR UPDATING
Open the file with a LOOKUP and ENTER on the same channel.
6.20 $UPDWT - OPEN A FILE FOR UPDATING AND WAIT
Call $UPDAT to open the file for updating. If the error return
gives 'file being modified', wait for a given time and try again.
Repeat for a given number of times, and finally give up.
6.21 $APEND - OPEN A FILE FOR APPENDING
Open the current file for updating, by executing a call to
$UPDAT, then setup the FDB so that the first block written will be the
last block. If IO is in a buffered mode, set the output buffer header
to point to the first free word of the last block. Return a count of
the number of free words in the last block.
Note that $APEND assumes that the current file is an append-only
file, and this routine will fail if the protection is more liberal.
The full algorithm is:
1. open the file for updating using $UPDAT
2. calculate the number of blocks in the file, and the words
remaining in the last block from $FDSIZ. Set $FDNBK to write the
last block.
BASIC IO ROUTINES Page 6-12
$APEND - OPEN A FILE FOR APPENDING
3. check the channel IO mode. If a dump mode, goto step 6.
4. do a dummy output for buffered modes
5. set the byte pointer in the output buffer header to point to the
first free word, and alter the remaining byte count accordingly.
6. set ac(T1) to the count of free words and skip return.
FDB words used
--- ----- ----
$FDSIZ gives the size of the file in words
$FDSTS gives the channel IO mode
FDB words altered
--- ----- -------
$FDNBK set to the last block of the file
$FDOBH byte pointer set to the first free word and byte count set to
reflect free bytes remaining
6.22 $APDWT - OPEN A FILE FOR APPENDING AND WAIT
Call $UPDWT to open the file for updating. If the file is opened
successfully, call $APEND to set up the block number and buffer header
for appending to the file.
6.23 $MTXXX - EXECUTE AN MTAPE UUO
There are 12 $MTxxx routines, each of which executes a different
function of the MTAPE UUO for the current file. The 'xxx' is the code
for the various functions e.g. $MTREW does a MTREW. to rewind the
tape. A complete list of functions may be found in the Monitor Calls
Handbook.
The $MTxxx routines all wait for completion of the function with
an MTWAT. before returning control. $MTBSF (backspace file), skips
forward over the endfile unless at beginning of tape.
CHAPTER 7
FORMATTED READING AND WRITING
7.1 GENERAL DESCRIPTION
IOLIB contains routines for reading and writing data as ASCII
strings and converting them into an internal form according to a wide
variety of formats. For example, the $RDECL routine reads a string
from the current file and converts it as a signed decimal integer into
a binary number. The $WDECL routine takes a binary number, converts
it as a signed decimal integer into a string and writes it to the
current file.
All the formatted input and output routines work on the current
file, so that they need the current file point set up in ac(D). All
the input routines use a single routine, $$RCHR, to read the next
character from the file, and all the output routines use one routine,
$$WCHR, to write the next character. These routines do not have an
error return, but assume that all IO errors are fatal, and trap to the
fatal error handler, $FTLIO. The user programmer may rewrite $$WCHR
and $$RCHR to provide his own error handling or to provide other
features at a low level. $$WCHR merely calls $WRITE, the routine
which writes one byte to the current file, and traps error returns.
$$RCHR interprets the input string as a DECsystem-10 standard command
string, and uses the DEC algorithm to edit the input string before
passing the characters back to the calling routine. $$RCHR compresses
sequences of spaces, removes spaces at the beginning and end of lines,
handles continuation lines and returns standard codes for endline,
endfile and altmode. The user programmer may redefine $$RCHR to use a
lower level of editing or no editing at all, or even to edit or not
depending on the current file, if he wishes.
The formatted output routines are straightforward, and full
details may be found in Appendix A. Formatted input is a little more
complicated. The input routines read the input string interpreting
characters until they find one that does not belong to the format
being read. Then they return the values read to the caller, including
the delimiting character in ac(T1). Therefore, the caller has the
responsibility to check the delimiter to ensure that it is correct.
The routines to read filenames and switches are special cases and are
dealt with in some detail in this chapter.
FORMATTED READING AND WRITING Page 7-2
$WRITE - WRITE ONE BYTE TO THE CURRENT FILE
7.2 $WRITE - WRITE ONE BYTE TO THE CURRENT FILE
This is the basic buffered-write routine. It is called to write
one byte, of the size defined by the current file, to that file. It
ensures that all prerequisite UUOs have been performed and that a
buffer ring is built and initialised, by calling $OUTPU for a dummy
output. It has error and skip returns. There is a write byte
routine, $$WBYT, that performs the same function as $WRITE, but has no
error return and instead calls $FTLIO. The algoritm is:
1. if the current file point is zero (TTCALL IO), write the character
using OUTCHR and skip return immediately.
2. if the current file point is a byte pointer (bits 0-11 nonzero),
write the byte using IDPB and skip return immediately.
3. otherwise, check the byte count in the buffer header $FDOBH(D);
unless the buffer is full, goto step 5.
4. call $OUTPU to empty the buffer. This also ensures a dummy OUTPUT
on the first call. If error, nonskip return.
5. decrement byte pointer in $FDOBH(D) and write the byte into the
buffer. Skip return.
FDB words altered:
--- ----- --------
$FDOBH the buffer header is altered by changing the byte pointer and
byte counts
7.3 $$WBYT - WRITE A BYTE TO THE CURRENT FILE
$$WBYT is a replaceable routine. The IOLIB version calls $WRITE,
and returns to caller if $WRITE gives a skip return, but calls $FTLIO
if $WRITE gives an error return. The user programmer may rewrite this
routine to perform additional functions if he wishes.
7.4 $$WCHR - WRITE A CHARACTER TO THE CURRENT FILE
The IOLIB version of $$WCHR is identical to $$WBYT, but the
routines are separately replaceable. The distinction is that $$WCHR
is called by all formatted output routines to write characters.
As an example of a replacement $$WCHR, suppose that a log file is
used for error messages and the point to the log file FDB is kept in
$IDEFD(I). We want to send messages that go to the log file, to the
terminal as well, so write:
$$WCHR::
CAME D,$IDEFD(I) ;is this the log file?
FORMATTED READING AND WRITING Page 7-3
$$WCHR - WRITE A CHARACTER TO THE CURRENT FILE
JRST WCH10 ;no
PUSH P,T1 ;yes, save character
TRMFD$ ;set FDB to terminal
WRITE$ ;send character to terminal
FATAL$ ;
POP P,T1 ;recover character
MOVE D,$IDEFD(I) ;recover log file FDB
WCH10:
WRITE$ ;send character to file
FATAL$ ;
POPJ P, ;
7.5 $READ - READ A BYTE FROM THE CURRENT FILE
This is the basic buffered-read routine. It is called to read
one byte, of the size defined by the current file, from the current
file. It ensures that all prerequisite UUOs are executed and that a
buffer ring is built and initialised, by calling $INPUT to read
records from the file. It has three returns, nonskip for errors, skip
for endfile and double-skip for normal return. There is a replaceable
read byte routine, $$RBYT, that performs the same function as $READ,
but has no error return, and instead calls $FTLIO. The algorithm is:
1. if the current file point is zero (TTCALL IO), read the character
using INCHWL and double-skip return immediately.
2. if the current file point is a byte pointer (bits 0-11 nonzero)
read a byte using ILDB. If the byte is zero, give an endfile
return with T1 0; otherwise give a double skip return.
3. otherwise, check the byte count in the buffer header, $FDIBH(D),
and unless the buffer is empty, go to step 5.
4. call $INPUT to read the next record. If error or endfile, give
the appropriate returns.
5. read the next character from the buffer, and decrement the buffer
byte count. Double skip return.
FDB words altered:
--- ----- --------
$FDIBH the buffer header is altered by changing the byte pointer and
byte count.
7.6 $$RBYT - READ A BYTE FROM THE CURRENT FILE
$$RBYT is a replaceable routine. The IOLIB version calls $READ,
and returns to caller if $READ gives endfile or normal returns;
endfile is nonskip and normal is skip. If $READ gives an error
return, $$RBYT calls $FTLIO. The user programmer may rewrite $$RBYT
FORMATTED READING AND WRITING Page 7-4
$$RBYT - READ A BYTE FROM THE CURRENT FILE
to perform additional functions if he wishes.
7.7 $$RCH0 - READ A CHARACTER FRM THE CURRENT FILE
The IOLIB version of $$RCH0 is identical to $$RBYT, but the
routines are separately replaceable. The distinction is that $$RCH0
is called by the command string character editor $REDCH, and is used
for reading all command characters.
The user programmer may rewrite $$RCH0 to perform additional
functions. For example, he might want to be able to trap endfile and
move up one level of command file in a system that allowed nested
command files:
$$RCH0::
READ$ ;get next character
FATAL$ ;
CAIA ;endfile, so check nesting depth
PJRST $POPJ1## ;skip return
MOVE T1,CFSTKP ;pick up point to command file stack
CAMN T1,CFSTK0 ;compare with empty stack
POPJ P, ;empty - user typed control-Z
RLEAS$ ;lose current command file
POP T1,D ;recover next command FDB
POP T1,CFSTKP ;recover last character from this file
EXCH T1,CFSTKP ;swap stack point and character
PJUMPE D,$POPJ1## ;return if TTCALL
;back to previous command file. Reopen it
HLRS $FDNBK(D) ;reread last block
PUSH P,$FDIBH+1(D) ;save buffer header pointer and count
PUSH P,$FDIBH+2(D) ;
INPUT$ ;read block
FATAL$ ;error
FATAL$ ;endfile is error too
POP P,$FDIBH+2(D) ;set up for next read
POP P,$FDIBH+1(D) ;
PJRST $POPJ1## ;good return
7.8 $$RCHR - READ A CHARACTER FROM THE CURRENT COMMAND FILE
$$RCHR is the replaceable routine called by all the formatted
read routines to read the next character. It has no error or endfile
returns. The endfile condition should be converted into a $CHEOF
special character. The IOLIB version of $$RCHR calls $RCALT, which is
one of the entry points to the command character editing coroutine,
$RCCHR. $RCALT has the property that if the last character read was
an altmode ($CHALT), then another altmode is returned to the caller
without reading anything from the input file. Therefore if the user
FORMATTED READING AND WRITING Page 7-5
$$RCHR - READ A CHARACTER FROM THE CURRENT COMMAND FILE
ends a line with an altmode, and the altmode condition is not cleared,
the caller routine will have altmodes returned for all subsequent
requests for characters. This is just what is required for a program
asking a series of questions, when an altmode means that all future
questions take the default answer. If this feature is not required,
redefine $$RCHR as a jump to $RCCHR:
$$RCHR::
PJRST $RCCHR## ;no altmode defaulting
If the command character interpreting is not required, but the basic
editing provided in $REDCH is, then redefine $$RCHR as a jump to
$REDCH:
$$RCHR::
PJRST $REDCH## ;just basic editing
Of course, $$RCHR can be rewritten to perform additional functions as
well, but since it is called by all the formatted input routine it
must at least return the codes:
0 $CHALT altmode (ASCII 033)
-1 $CHEOL endline (ASCII 012,013,014)
-2 $CHEOF endfile (ASCII 003,032)
7.9 $REDCH - READ A CHARACTER AND DO BASIC COMMAND EDITING
Read a character from the current command file and perform some
preliminary editing. $$RCH0 is used to read the character.
1. make the endfile return look like a control-Z character.
2. ignore nul (ASCII 000), carriage return (ASCII 015) and delete
(ASCII 177).
3. make tab (ASCII 011) into space (ASCII 040)
4. if escape (ASCII 033) give terminal user a <cr><lf> and set code
$CHALX (0).
5. make vertical tab (ASCII 013), form feed (ASCII 014) and line feed
(ASCII 012) into $CHEOL (-1).
6. if control-C (ASCII 003) clear the command scanning coroutine pc
7. if either control-C or control-Z (ASCII 032) turn into $CHEOF
(-2).
FORMATTED READING AND WRITING Page 7-6
$RCCHR - READ A CHARACTER AND EDIT AS A COMMAND CHARACTER
7.10 $RCCHR - READ A CHARACTER AND EDIT AS A COMMAND CHARACTER
Return the next character in a command string. This may involve
reading a character from the command file or rereading a character
already processed. The routine compresses multiple spaces into one
space, ignores leading and trailing spaces on a line, ignores comments
(all characters following a ';') and ignores endline immediately
preceded by a '-', so that continuation lines are possible.
$RCCHR is a coroutine whose pc is kept in $IDCPC(I) in the IDB.
The coroutine often has to look ahead one character to determine the
meaning of the current character, and the lookahead character is kept
in $IDLAC(I) in the IDB. The last character read is always available
in $IDLSC(I).
If any character is set in $IDNXC(I) on entry to $RCCHR, then the
routine will take this character as the next character to be read.
The programmer can force a character to be read by placing it in
$IDNXC(I).
There is a second entry point to $RCCHR, $RCALT, which checks if
the last character was an altmode, and if so returns an altmode
immediately instead of reading another character. This is the default
entry point to $RCCHR.
Note: This routine may only be used for one file at a time.
7.11 $RFILE - READ A FILENAME FROM THE CURRENT FILE
$RFILE will read a complete file specification written in a form
compatible with that accepted by SCAN, the DEC command scanner. The
filename read by $RFILE can contain the components: one device, one
name, one extension, one path specification and a number of switches
written in any order. The name, extension and path specification may
contain wild cards. No individual field is compulsory and the
specification is terminated by some character not belonging to the
specification.
The filename is decoded into an FDB, which may be supplied by the
caller, but if not will be obtained by $RFILE from the memory manager.
The FDB is intialised by calling $CLRFD.
$RFILE maintains an extra FDB known as the default file FDB. Any
parts of the file specification that are typed before the name are
assumed to be 'sticky' for any other file specifications typed on the
same line, and these sticky defaults are remembered in the default
FDB. The current defaults are applied to a filename after reading the
specification and before returning to the caller. The user programmer
may supply the default FDB by putting a point to the FDB into
$IDDFD(I) in the IDB. Otherwise, $RFILE obtains space for the FDB
from the memory manager. The user programmer may preset defaults into
the default FDB, if for instance he wishes the default extension to be
'.REL'.
FORMATTED READING AND WRITING Page 7-7
$RFILE - READ A FILENAME FROM THE CURRENT FILE
Wildcard characters are set into the appropriate fields in the
FDB and are masked by the corresponding field in the appropriate mask
word. Non-wild characters are masked by ones, and wild characters are
masked by zeros. The programmer must call $LKWLD The caller can
provide a table of switches that may be encountered in this file
specification. He can also specify standard switches by placing a
pointer to the standard switch table into $IDSWT(I) in the IDB. IOLIB
defines a set of standard file switches in the table $TBSSW and the
user programmer can use this as the standard table. Some of the
standard file switches set fields in $FDMOD in the FDB and set the
corresponding mask in $FDMOM. These switches will also be set in the
default FDB, and become sticky if they are given before the name
field.
$RFILE returns the delimiting character and a point to the FDB.
The point to the FDB is in ac(T2), and the left half of that ac
contains flags:
1B0 FF$NUL file specification was null except possibly
for switches. No meaningful file name fields
were typed.
1B1 FF$WLD the file specification contains wild
characters
7.12 READ PATH AND PPN SPECIFICATIONS
There are three routines for reading parts of a path
specification. $RPJPG reads a project-programmer number (without [])
including wildcards, and checks to make sure that the numbers are
within range. $RPPN reads a full PPN specification including the [],
and $RPATH can read SFD names as well.
All the routines return a delimiter (in the case of $RPPN and
$RPATH, the character following ']'), a value, a mask and a flag word
which has bit0 set if the PPN