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$ ... 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: 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$ ;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,,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,,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$ 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$ ,<$IDTOP(I)>,$SWKWD,MXC SS$ ,,1 > HMPTAB: ;address of table SWTAB$ HMP ;define tables KEYWD$ HELP, ;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, 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 and set code $CHALX (0). 5. make vertical tab (ASCII 013), form feed (ASCII 014) and line feed (ASCII 012) into $CHEOL (-1). 6. if control-C (ASCII 003) clear the command scanning coroutine pc 7. if either control-C or control-Z (ASCII 032) turn into $CHEOF (-2). FORMATTED READING AND WRITING Page 7-6 $RCCHR - READ A CHARACTER AND EDIT AS A COMMAND CHARACTER 7.10 $RCCHR - READ A CHARACTER AND EDIT AS A COMMAND CHARACTER Return the next character in a command string. This may involve reading a character from the command file or rereading a character already processed. The routine compresses multiple spaces into one space, ignores leading and trailing spaces on a line, ignores comments (all characters following a ';') and ignores endline immediately preceded by a '-', so that continuation lines are possible. $RCCHR is a coroutine whose pc is kept in $IDCPC(I) in the IDB. The coroutine often has to look ahead one character to determine the meaning of the current character, and the lookahead character is kept in $IDLAC(I) in the IDB. The last character read is always available in $IDLSC(I). If any character is set in $IDNXC(I) on entry to $RCCHR, then the routine will take this character as the next character to be read. The programmer can force a character to be read by placing it in $IDNXC(I). There is a second entry point to $RCCHR, $RCALT, which checks if the last character was an altmode, and if so returns an altmode immediately instead of reading another character. This is the default entry point to $RCCHR. Note: This routine may only be used for one file at a time. 7.11 $RFILE - READ A FILENAME FROM THE CURRENT FILE $RFILE will read a complete file specification written in a form compatible with that accepted by SCAN, the DEC command scanner. The filename read by $RFILE can contain the components: one device, one name, one extension, one path specification and a number of switches written in any order. The name, extension and path specification may contain wild cards. No individual field is compulsory and the specification is terminated by some character not belonging to the specification. The filename is decoded into an FDB, which may be supplied by the caller, but if not will be obtained by $RFILE from the memory manager. The FDB is intialised by calling $CLRFD. $RFILE maintains an extra FDB known as the default file FDB. Any parts of the file specification that are typed before the name are assumed to be 'sticky' for any other file specifications typed on the same line, and these sticky defaults are remembered in the default FDB. The current defaults are applied to a filename after reading the specification and before returning to the caller. The user programmer may supply the default FDB by putting a point to the FDB into $IDDFD(I) in the IDB. Otherwise, $RFILE obtains space for the FDB from the memory manager. The user programmer may preset defaults into the default FDB, if for instance he wishes the default extension to be '.REL'. FORMATTED READING AND WRITING Page 7-7 $RFILE - READ A FILENAME FROM THE CURRENT FILE Wildcard characters are set into the appropriate fields in the FDB and are masked by the corresponding field in the appropriate mask word. Non-wild characters are masked by ones, and wild characters are masked by zeros. The programmer must call $LKWLD The caller can provide a table of switches that may be encountered in this file specification. He can also specify standard switches by placing a pointer to the standard switch table into $IDSWT(I) in the IDB. IOLIB defines a set of standard file switches in the table $TBSSW and the user programmer can use this as the standard table. Some of the standard file switches set fields in $FDMOD in the FDB and set the corresponding mask in $FDMOM. These switches will also be set in the default FDB, and become sticky if they are given before the name field. $RFILE returns the delimiting character and a point to the FDB. The point to the FDB is in ac(T2), and the left half of that ac contains flags: 1B0 FF$NUL file specification was null except possibly for switches. No meaningful file name fields were typed. 1B1 FF$WLD the file specification contains wild characters 7.12 READ PATH AND PPN SPECIFICATIONS There are three routines for reading parts of a path specification. $RPJPG reads a project-programmer number (without []) including wildcards, and checks to make sure that the numbers are within range. $RPPN reads a full PPN specification including the [], and $RPATH can read SFD names as well. All the routines return a delimiter (in the case of $RPPN and $RPATH, the character following ']'), a value, a mask and a flag word which has bit0 set if the PPN is the default ([-]) and bit1 set if any wildcards were seen. The value is the PPN if there were no SFDs, and the mask is the PPN mask. If $RPATH did read SFD names, the the value is a point to a path block, and the mask is a point to a mask block. $RPATH obtains the path and mask blocks from the memory manager. 7.13 $RSWIT - READ A SWITCH NAME AND VALUE $RSWIT reads a switch name and compares it with a table of switch names supplied by the caller. If this does not succeed unambiguously, $RSWIT looks for a point to a table of standard switches in $IDSWT(I) in the IDB. If there is one, $RSWIT tries to match the switch with those in this second table. Assuming that $RSWIT succeeds somewhere, it then uses data in the switch tables to determine whether to read a value and if so, what data format to read the value in. $RSWIT reads the value, and uses further information in the switch tables to FORMATTED READING AND WRITING Page 7-8 $RSWIT - READ A SWITCH NAME AND VALUE determine where to deposit either the value, or default data if there was no value. $RSWIT can deposit data using a byte pointer. The macros that build switch tables are discussed in sections 4.2 and 4.3. CHAPTER 8 TEMPCORE ROUTINES 8.1 GENERAL DESCRIPTION Tempcore is a device whereby small files of data may be kept in core storage within the monitor for ultra fast access by user programs. It is mainly intended for use by the CCL command interpreter which keeps small files of commands in tempcore for one of the invoked processors to read. The amount of space allocated to tempcore is small and if enough users generate enough tempcore files at once it overflows. So the programs that read and write tempcore are built to try tempcore first, and if that is unsuccessful, to try a file on the disk with a certain name. The tempcore read, write and delete routines handle the file whether it is in tempcore or on the disk. A convention on the DECsystem-10 is that if a program is entered at its start address then everything is normal, but if the program is entered at the location following the start address ('start+1'), then commands are to be taken from a tempcore file. IOLIB allows this feature as an assembly parameter. If FT$CCL=-1, then the feature is included. If FT$CCL=0, it is not. If it is included and entry is a start+1, IOLIB sets up the command input file to be a tempcore file. The user programmer must ensure that he calls $TMPIN before reading that file, and deletes the file with $TMPDL at some stage. Tempcore files have 3 character filenames, and by default IOLIB chooses the first 3 characters of th program name. If the file is on disk, the name is 'jjjnnn.TMP', where jjj is the job number, and nnn is the name. e.g. 023MAC.TMP 8.2 $TMPFD - BUILD A TEMPCORE FDB $TMPFD obtains an FDB from the memory manager and initialises it with the extension 'TMP', and a name made from the job number and the 3 character name supplied. The point to the FDB is returned in ac(D). TEMPCORE ROUTINES Page 8-2 $TMPIN - READ A FILE FROM TEMPCORE 8.3 $TMPIN - READ A FILE FROM TEMPCORE Build a one buffer ring using $MKBUF, and then try to read the file from tempcore. On success, set up the buffer header, so that the first call to $READ will return the first character, and set FC$TCI in $FDCHN(D) to ensure that the next call to $INPUT will give an endfile return. If the tempcore read fails, read the file from disk using $INPUT. The technique for reading tempcore files is to define FT$CCL=-1 for assembly, which ensures that the FDB is set up correctly. Call $TMPIN and then read the file using normal formatted read routines. Finally, when the program finishes, delte the tempcore file with $TMPDL. 8.4 $TMPDL - DELETE A TEMPCORE FILE Tempcore files should be deleted after they have been read so that they don't clutter up an overcrowded tempcore area and so that the disk directory doesn't fill up with .TMP files. $TMPDL deletes the file from both tempcore and disk. 8.5 $TMPOU - CLOSE A TEMPCORE OUTPUT FILE Tempcore files are normally short. If they have exceeded one buffer in length then the file may already have been entered on the disk, and $TMPOU merely releases the file. If not, then $TMPOU attempts to write the file into tempcore, and if that fails, then the file is written to disk and released. The technique for writing a tempcore file, is to set up the FDB using $TMPFD (one buffer is sufficient), then to write to the file normally using formatted output routines, and finally to end with a call to $TMPOU instead of to $RLEAS. CHAPTER 9 ERROR REPORTING 9.1 GENERAL DESCRIPTION IOLIB contains macros and routines for writing error messages to a specified file with the minimum of programmer effort. The messages are written in the standard DECsystem-10 error format with a one character severity indicator, then two optional 3 character codes identifying the program and the error, and lastly the error text. A value can be included in the message, printed in one of a number of possible formats. Fatal errors do not return to the caller, but fall into a special trap routine, $$FERR, which may be written by the caller. The standard $$FERR routine merely tidies up and returns to monitor mode. Other errors always return to the caller. There are special routines to print error messages for syntax and IO errors, which may be called on an error return from the command scanners and IO routines. These routines print standard messages and give the caller the decision as to whether the error is fatal or not. Any character may be used as a severity indicator, e.g. $ for messages to the operator from batch programs, but three characters have special entry points to the error routines. ? is a fatal error, % is a warning error, and a message enclosed in [] is an advisory message. All the error routines can be called by the error macros, FATAL$, WARN$ and ADVIS$ which take arguments which allow the user to define the form of the message in the macro call. Each macro call uses only one word of inline code so that the calls may be used in the error return location from subroutines and UUOs. The error reporters are driven by several tables of messages and output routines, any of which may be replaced by the caller. 9.2 MESSAGE FORMAT The messages have a maximum of 8 fields, although only two, the severity indicator and the message text are mandatory. An example of a full message is: ERROR REPORTING Page 9-2 MESSAGE FORMAT ?(400140)DELFNF LOOKUP(0), No file: ACCT.SYS[1,2] ^ ^ ^ ^ ^ ^ ^ ^ s aaaaaa pppeee uuuuuu c mmmmmmm vvvvvvvvvvvvv where: s is the severity flag (e.g. '?' '%' '[') a is the caller's address in octal. It is only printed if FT$DBG is -1, that is, if the user is debugging his program. p is the 3 character program identifier. The program identifier is set by the caller program in the left half of $IDECD(I). If these identifier is not set, this field is not printed. e is the 3 character error identifier. The error identifier is unique for each message, and must be supplied as a parameter to the $FATAL and $WARN routines. All IO and syntax errors provided by IOLIB have an error identifier. The identifiers and their meanings are detailed in full in Appendix F. u is a 6 character UUO or type indicator. This indicator must be supplied as a parameter when calling $FATAL or $WARN. IOLIB IO routines put the UUO name of the UUO that found the error into this field, and syntax errors put the word 'SYNTAX'. c is an octal code that is traditionally printed for IO errors. It is printed if a flag is set on the $FATAL or $WARN call. m is the message text. v is a value which may be written in one of a variety of formats. The format is given by a format code in the routine call, and the value is supplied by the caller. All the characters in the example not masked in the line below are added by the IOLIB routine. Some examples of the messages that can be generated are: %DELILC SYNTAX, Illegal character: ?REACAS Cannot access system files: ACCT.SYS [DOR Out of range: 677777] %Name does not match: FORMET ?I don't like you, go away ERROR REPORTING Page 9-3 MESSAGE FORMAT Normally the whole of an error message is output, but this can be controlled through the 'message verbosity'. The user can set the verbosity so that some combination of the 'prefix', the 'first line' and the 'continuation lines' are typed, by command to the monitor. If the message level is set to (PREFIX,NOFIRST) then only the s, a, p and e fields of the message are typed. If the message level is (NOPREFIX,FIRST), the u, c, m and v fields are typed. The default is (PREFIX,FIRST). See Appendix F for explanations of all IOLIB error ids. ?(400140)DELFNF 9.3 ERROR SEVERITY IOLIB treats fatal errors differently from warnings, advisory messages and all others. Fatal errors are those that cause immediate termination of execution of the program, or a restart from some point in the program. Warning errors are normally local to some phase of execution of a program, and do not necessarily cause termination of the whole program. The program may proceed normally after issuing a warning, or it may jump to some other phase of execution. For example, if a delete program couldn't find one file to delete, it would only need a warning and it could proceed to delete other files in the same command, but if all the files were missing it might prompt a fatal message. The $FATAL routine flags fatal errors with a '?', and $WARN flags warning errors with a '%'. Calls to the $WARN routine write the error message and then return to the calling routine, but calls to $FATAL trap to a special routine labelled $$FERR. The standard IOLIB version of $$FERR merely cleans up and returns the program to monitor mode, but users may write their own $$FERR routines to e.g. restart their program at some point. Advisory messages are enclosed in square brackets, [], but are treated in the same way as warnings by the error routines. Other severity indicators may be used by the appropriate call to $ERROR and these calls return in the same way. 9.4 $ERROR - THE ERROR REPORTER The routine, $ERROR, is used to handle all error messages whether fatal or warning. The inputs to $ERROR are: Ac Bits Description -- ---- ----------- T1 0-4 flags, see full description below 5-11 severity flag character in ASCII. FATAL$, WARN$ and ADVIS$ set up this field. Other ERROR REPORTING Page 9-4 $ERROR - THE ERROR REPORTER severity characters must be set by the caller before entering $ERROR. 12-17 value type code, which is used as the index to a table of addresses of write routines. 18-35 pointer to either ASCIZ message text, or a word containing: lh: error code in SIXBIT rh: pointer to ASCIZ message text depending on EC$IND. T2 value to be printed in a format specified by the error code type T3 UUO name in SIXBIT, to be printed if flag, EC$UUO, is set P top of stack contains return address that will be printed if FT$DBG=-1. The flag field in ac(T1) contains 1 bit flags indicating which fields of the message are to be printed. They are: Bit Symbol Description --- ------ ----------- 0 EC$IND right half of ac(T1) points to a word containing the error id in the left half. text in the right half. If not set, then the right half of ac(T1) points to the ASCIZ message text. 1 EC$UUO the u field is to be written, so that the contents of ac(T3) are to be interpreted as a SIXBIT name. 2-4 unused, but reserved 5-11 EC$FLG severity flag character in ASCII 12-17 EC$TYP an index+1 to $TBWAD, the table of address of write routines for printing the value. The indices to the standard IOLIB $TBWAD are given symbolic values (see below). $ERROR writes the error message to a file described by an FDB pointed at by $IDEFD(I). The BEGIN$ macro sets this to the job's terminal, but the programmer may modify it to be a log file or even to be some flag for the write routine, $$WCHR, to recognise and send the message to several files. The message verbosity and the program id are taken from $IDECD(I). The program id is 3 SIXBIT characters in the left half, and is ignored if blank. ERROR REPORTING Page 9-5 $ERROR - THE ERROR REPORTER If the message is fatal, the $ERROR routine prints the message and then traps to $$FERR. Otherwise the routine returns to the caller. 9.5 $FATAL, $WARN AND $ADVIS These routines set the appropriate severity character into EC$FLG and call $ERROR to do all the hard work. They may be conveniently called through the FATAL$, WARN$ and ADVIS$ macros, which use only one instruction of inline code and set up all the routine parameters from the macro arguments. 9.6 THE FATAL$, WARN$ AND ADVIS$ MACROS These macros normally call the $FATAL, $WARN and $ADVIS routines, but they may call other routines, depending on the arguments. The format of the macro call is FATAL$ ,value-format-code,error-id,UUO-name If the first two arguments are absent, the macro generates a call to $FTLIO, or $WRNIO, which print IO error messages. If the message-text argument is absent, the macro generates a call to a routine $FTLxx or $WRNxx, where 'xx' is the first 2 characters of the value-format-code. This means that the programmer can write his own routines, and call them using FATAL$ and WARN$. The syntax error writing routines, $FTLSY and $WRNSY, may also be called in this way. If both the first two arguments are present, then the macro generates a call to a literal, which sets arguments into acs T1-T3 and calls $FATAL or $WARN. ADVIS$ always calls $ADVIS. The value-format-codes available in the standard IOLIB table of value formats are: CHAR ASCII character, right-justified DECL decimal number FILE filename,given by pointer to FDB OCTL octal number TEXT ASCIZ string WORD SIXBIT word Examples: i) .... LUKUP$ ;lookup a file FATAL$ ;error - fatal, call $FTLIO. .... ii) .... RFILE$ ;read a filename from command string FATAL$ ,SY ;error - call $FTLSY to report ERROR REPORTING Page 9-6 THE FATAL$, WARN$ AND ADVIS$ MACROS .... iii) .... MOVE T2,NUMLIN ;pick up number of lines WARN$ ,DECL,EOD .... iv) .... DAEMON T0, ;issue DAEMON UUO FATAL$ ,,NIM,DAEMON .... 9.7 IO ERROR REPORTING The basic IO modules in IOLIB produce error codes in a standard form when they detect errors. An error return is given with ac(T1) containing an error code in the right half, and a UUO code in the left half. An endfile return from $INPUT, $READ, $$RBYT or $$RCH0 also have an error code in ac(T1) so that the caller may treat endfile as an error if he wishes. The UUO codes are given in Appendix E. The error code range is an extension of the range for DEC LOOKUP/ENTER/RENAME errors. DEC error codes, ERxxx%, range from 0 to 27. The IOLIB codes, ERxxx$, range from -1 to -11, and include the error bits in the IO status word, endfile, restricted device, unknown error and others. In addition, the IOLIB $OPEN, $INPUT and $OUTPU routines can generate some of the ERxxx% codes, when the message is appropriate. The ERxxx$ codes are discussed in Appendix E. The routines, $FTLIO and $WRNIO, are called with the error code in ac(T1) and the pointer to the offending FDB in ac(D). They write the entire error message. If the error file was the one with the error, then the routines use the job's terminal instead of the error file. The $FTLIO and $WRNIO routines may be called through the FATAL$ and WARN$ macros. The call uses only one word of inline code. 9.8 SYNTAX ERROR REPORTING Some of the IOLIB formatted read routines detect syntax errors while they are scanning the input string. These routines have an error return, and return an error code in ac(T1) and the error value in ac(T2). The routines $FTLSY and $WRNSY process these values and write error messages from them. The $FTLSY and $WRNSY routines may be called through the $FATAL and WARN$ macros. The call uses only one word of inline code. ERROR REPORTING Page 9-7 $$FERR - FATAL ERROR TRAP ROUTINE 9.9 $$FERR - FATAL ERROR TRAP ROUTINE The error reporter, $ERROR, transfers control to a routine called $$FERR after writing any fatal error message. $$FERR may be a user written routine or it may be the standard routine from IOLIB. The standard $$FERR merely tidies up and returns to monitor mode; the exact code is reproduced below. A user written $$FERR might do more tidying up before returning to monitor mode, or might be the same location as the program start address so that the program starts again, or might execute some of the same code as the user's control-C intercept routine. In any case, the user must have an INTERNal symbol called $$FERR if he writes his own code. The code of IOLIB's $$FERR reads: $$FERR:: CLRBFI ;clear job's terminal input MONRT$ ;return to monitor mode HRRZ T1,.JBSA ;load program start address JUMPN T1,(T1) ;restart program if possible EXIT ;curses! Thwarted CHAPTER 10 UTILITY ROUTINES 10.1 GENERAL DESCRIPTION 'Utility Routines' is a convenient heading for all those routines that do not fall into any other category, and do not form a sufficiently numerous or important class to merit a chapter on their own. 10.2 $MATCH - MATCH A SIXBIT NAME WITH A TABLE $MATCH accepts a SIXBIT name as input and the IOWD address of a table of SIXBIT names. The routine searches through the table linearly. If the first character of the table name is '*', and the second charater matches the argument name, then the match is found. Otherwise the whole name may match, or the whole argument name may match the first n characters of the table name or there is no match. If the whole name matches, the search terminates. If there is no match, the search continues. If there is a partial match, the index is remembered and the search continues. If there is no match, the routine gives an error return with ac(T1)<0. If there are several partial matches, error return with ac(T1)=0. Otherwise normal return, with the index in ac(T1), and ac(T1)<0 for partial match, and =0 for exact match. CHAPTER 11 EXAMPLES 11.1 FORMATTED IO To read two numbers and add them together: TITLE ADDTWO - ADD TWO NUMBERS TOGETHER SUBTTL ROB COOK SEARCH C,IO ; ADDTWO: BEGIN$ ;initialise WTEXT$ RDECL$ ;read number JUMPG T1,ERRCHR ;error if not endline MOVE G1,T2 ;save number WTEXT$ < and the second: > RDECL$ ;read number JUMPG T1,ERRCHR ;again, error unless endline ADD G1,T2 ;add two numbers WLINE$ WTEXT$ <....and the answer is: > MOVE T1,G1 ;load number WDECL$ WCRLF$ ;endline MONRT$ ;exit JRST ADDTWO ;start again ERRCHR: ;here to report errors and start again MOVE T2,T1 ;set up value for error message WARN$ ,CHAR,ILC WLINE$ <...now we have to start everything again.> JRST ADDTWO END ADDTWO EXAMPLES Page 11-2 COPY A FILE TO THE LPT: 11.2 COPY A FILE TO THE LPT: TITLE COPLPT - COPY A FILE TO THE LPT SUBTTL ROB COOK SEARCH C,IO ; COPLPT: BEGIN$ ;as always COP10: ;loop here to copy each character MOVEI D,INPFDB ;set input FDB RBYTE$ ;read next character JRST ENDFIL ;end of file MOVEI D,LPTFDB ;set LPT FDB WBYTE$ ;write character JRST COP10 ;loop back ENDFIL: ;here at endfile RLEAS$ ;release input file MOVEI D,LPTFDB ;LPT FDB WCHAR$ .CHFFD ;send formfeed RLEAS$ ;release LPT TRMFD$ ;tell user good news WLINE$ MONRT$ ;back to monitor JRST COPLPT ;start again INPFDB: ;input FDB (SYS:NOTICE.TXT e.g.) FDESC$ SYS,NOTICE,TXT LPTFDB: ;LPT FDB FDESC$ LPT END COPLPT 11.3 SUBROUTINE TO READ A FILENAME This subroutine takes an FDB point as input and reads a filename into that FDB. If the filename was null, the routine asks for another name. If the name was wild, the routine prints an error message and asks again. If the delimiter was not endline it does the same. READFN:: PUSH P,T1 ;save FDB point RFN10: ;here to reread a filename after error EXAMPLES Page 11-3 SUBROUTINE TO READ A FILENAME MSGFD$ ;load message FDB point WTEXT$ CMDFD$ ;load command FDB point SETZ T1, ;no switch table MOVE T2,(P) ;recover FDB point RFILE$ T1 ;read filename JRST SYNERR ;syntax error JUMPG T1,ILCHAR ;endline is ok TXNE T2,FF$NUL ;null specification? JRST RFN10 ;yes, reask question TXNN T2,FF$WLD ;any wildcards? PJRST $XOPJ## ;return popping stack ;wild character in file spec. WARN$ ,FILE,WCI,SYNTAX JRST RFN10 ;try again ILCHAR: ;illegal character MOVE T2,T1 ;setup character as value WARN$ ,CHAR,ILC,SYNTAX JRST RFN10 ;try again SYNERR: ;syntax error WARN$ ,SY JRST RFN10 ;try again APPENDIX A LIST OF ALL IOLIB ROUTINES This appendix lists all the IOLIB routines in several categories. If a category contains some critical routines, these are listed before the rest separated from them by a line. Otherwise, within a category, the routines are listed in alphabetical order. The columns in the table are mostly self-explanatory. The 'DI' column indicates whether the routine requires that ac(D) points to the current file and/or ac(I) points to the IDB. If the 'size' column contains a name instead of a number of words, then the routine is an entry point to the named routine. Many routines are in IOMOD, the basic IO module. The current size of IOMOD is 360 words long. Note that all sizes are given in decimal. If the 'section' column is empty, then this appendix is the defining and only mention of that routine. Acs Size Routine Macro DI Description destroyed (words) Section ======= ===== == =========== ========= ======= ======= A.1 Basic IO Routines --- ----- -- -------- $APDWT APDWT$ D open the current file for appending. If the file is being modified T1 5 6.21 wait for a given period before giving up. Inputs: T1 : sleep seconds,,number of sleeps Returns: error : non-skip o.k. : skip Outputs: T1 : bytes free in block (o.k. only) T1 : IO error code (error only) $APEND APEND$ D open the current file for appending, including setting the buffer T1 21 6.22 pointer for buffered modes. $APEND will not work correctly for files with more liberal protections. Returns: error : non-skip o.k. : skip Outputs: T1 : bytes free in block (o.k. only) T1 : IO error code (error only) $CLOSE CLOSE$ D execute a CLOSE UUO for the current file. All CLOSE bits are zeroed. T1 IOMOD 6.7 Inputs: taken from FDB $CLOS0 CLOSE$ D as $CLOSE but allow caller to set CLOSE bits T1 IOMOD 6.7 Inputs: T1 : CLOSE bits $DELET DELET$ DI delete the current file none IOMOD 6.10 LIST OF ALL IOLIB ROUTINES Page A-2 Returns: error : non-skip (LOOKUP or RENAME failure) o.k. : skip Outputs: T1 : IO error code (error only) $DLBUF DLBUF$ DI return a buffer ring to the memory manager T1 IOMOD 6.18 Inputs: T1 : point to buffer header $ENTER ENTER$ DI execute an ENTER UUO on the current file T1 IOMOD 6.5 Inputs: taken from FDB Returns: error : non-skip o.k. : skip Outputs: T1 : IO error code (error only) $ENTE0 ENTER$ DI as $ENTER, but allow the caller to set the protection and create T1 IOMOD 6.5 date/time. $FRCHN FRCHN$ find the first free channel starting with a given channel T1 IOMOD Inputs: T1 : starting channel Returns: none free : non-skip o.k. : skip Outputs: T1 : channel number $GETST GETST$ D get the IO status halfword for the current file T1 IOMOD 6.12 Outputs: T1 : status halfword (rh) $LUKUP LUKUP$ DI execute a LOOKUP on the current file T1 IOMOD 6.4 Inputs: taken from FDB Returns: error : non-skip o.k. : skip Outputs: T1 : IO error code (error only) $INPUT INPUT$ DI read a physical record from the current file. T1 IOMOD 6.2 Inputs: taken from FDB Returns: error : non-skip endfile : skip o.k. : double-skip $MKBUF MKBUF$ DI create a ring of buffers for the current file. The size and number T1 IOMOD 6.17 of the buffers is taken from $FDBUF. Inputs: T1 : point to buffer header $FDBUF(D) Returns: no core : non-skip o.k. : skip Outputs: T1 : 0,,ERNEC% (error only) $MTxxx MTxxx$ D execute an MTAPE UUO for the current file. 'xxx' can be any of the T1 35 6.23 codes for MTAPE functions: e.g. MTREW$, MTBSF$. All functions wait for completion using MTWAT$. MTBSF$ skips over EOF unless at BOT. $OPEN OPEN$ DI execute an OPEN UUO for the current file. If the caller does not T1 IOMOD 6.6 specify a channel number, $OPEN chooses the 1st free channel. Inputs: taken from FDB Returns: error : non-skip o.k. : skip Outputs: T1 : IO error code (error only) LIST OF ALL IOLIB ROUTINES Page A-3 $OUTIN OUTIN$ DI write the last physical record read back to the current file. T1 IOMOD 6.3 as $OUTPU, but subtracts 1 from the block number before writing. $OUTPU OUTPU$ DI write a physical record to the current file T1 IOMOD 6.3 Inputs: taken from FDB Returns: error : non-skip o.k. : skip Outputs: T1 : IO error code (error only) $RLEAS RLEAS$ DI execute a RELEAS UUO for the current file. Return all buffers to T1 IOMOD 6.8 the heap. Inputs: taken from FDB $RLEA0 RLEAS$ DI as $RLEAS, but don't return rings to memory manager T1 IOMOD 6.8 $RENAM RENAM$ DI change the name and/or other details of the current file T1 IOMOD 6.9 The file must have been opened. Inputs: taken from FDB Returns: error : non-skip o.k. : skip Outputs: IO error code (error only) $SETST SETST$ D set the status halfword for the current file T1 IOMOD 6.13 Inputs: T1 : 0,,status halfword $UPDAT UPDAT$ DI open the current file for updating T1 7 6.19 Returns: error : non-skip (LOOKUP or ENTER failure) o.k. : skip Outputs: T1 : IO error code (error only) $UPDWT UPDWT$ DI open the current file in update mode. If the file is being modified T1 17 6.20 wait for a given period before giving up. Inputs: T1 : sleep seconds,,number of sleeps Returns: error : non-skip o.k. : skip Outputs: T1 : IO error code (error only) $USETI USETI$ DI position the current file to a given physical record for input T1 IOMOD 6.11 This routine is only effective for disk. Inputs: T1 : last record number,,this record number $USETO USETO$ D position the current file to a given physical record for output T1 IOMOD 6.11 This routine is only effective for disk. Inputs: T1 : last record number,,this record number $XTCAL XTCAL$ D execute a CALLI UUO for the current file, setting physical-only T1 IOMOD 6.15 if required Inputs: T1 : UUO T2 : argument Returns: non-skip : non-skip skip : skip $XTDCL XTDCL$ D execute a device dependent CALLI UUO for the current file. T1 IOMOD 6.16 As $XTCLI, but set DSK if no device given. $XTUUO XTUUO$ D execute a UUO for the current file none IOMOD 6.14 LIST OF ALL IOLIB ROUTINES Page A-4 Inputs: T1 : UUO (without channel number) Returns: non-skip : non-skip skip : skip LIST OF ALL IOLIB ROUTINES Page A-5 Acs Size Routine Macro DI Description destroyed (words) Section ======= ===== == =========== ========= ======= ======= A.2 Formatted Read Routines --- --------- ---- -------- $READ READ$ DI read one byte from the current file T1 16 7.5 Returns: error : non-skip endfile : skip o.k. : double-skip Outputs: T1 : byte, right-justified (o.k. only) : IO-error-code (error and endfile only) $$RBYT RBYTE$ DI read one byte from the current file. Fatal errors go to $FTLIO. T1 4 7.6 Returns: endfile : non-skip o.k. : skip Outputs: T1 : byte, right-justified (o.k. only) : IO-error-code (endfile only) $$RCH0 DI read a character from the current file. Fatal errors goto $FTLIO. T1 1 7.7 Returns: endfile : non-skip o.k. : skip Outputs: T1 : character, right justified (o.k. only) : IO error code (endfile only) $$RCHR RCHAR$ DI read a character from the current file and interpret it as T1 1 7.8 command character. Outputs: T1 : character, right justified or endline indicator (0 : ALT, -1 : EOL, -2 : EOF) ------------------------------------------------------------------------------------------------------------------------- $RANCH RANCH$ DI read one character from the current file and test whether it is T1-T4 8 alphanumeric. Returns: not alphanumeric : non-skip alphanumeric : skip Outputs: T1 : character $RANC0 RANCH$ DI as $RANCH, but the character has already been read T1 $RANCH Note: this routine can be used to check whether a character is alphanumeric. Inputs: T1 : character $RCASH RCASH$ DI read a cash value in dollars and cents from the current file. T1-T4 29 The string may appear as '$dddd.cc' with or without the '$'. If there is no '.' or '$', the number is assumed to be cents. Returns: error : non-skip o.k. : skip Outputs: T1 : delimiting character (o.k. only) : syntax error code (error only) T2 : value in cents $RCAS0 RCASH$ DI as $RCASH but leading character already read T1-T4 $RCASH Inputs: T1 : character LIST OF ALL IOLIB ROUTINES Page A-6 $RCALT DI as $RCCHR, but check first if last character was altmode, and if so, T1 $RCCHR 7.10 return $CHALX without reading another character Outputs: T1 : character $RCCHR DI read a character from the current file as a command character which T1 70 7.10 means that a certain amount of editing is done, to wit: the editing done by $REDCH leading spaces on a line are deleted multiple spaces are compressed trailing spaces are deleted comments are ignored '-' followed by is ignored (continuation line) Outputs: T1 : character $RDATE RDATE$ DI read the date from the current file in the format 'dd-mmm-yy' T1-T4 37 Returns: error : non-skip o.k. : skip Outputs: T1 : delimiting character (o.k. only) : syntax error code (error only) T2 : date in internal format $RDAT0 RDATE$ DI as $RDATE but leading character already read T1-T4 $RDATE Inputs: T1 : character $RDECL RDECL$ DI read a signed decimal number from the current file. If the 1st T1-T4 17 character is '#' read the rest as an octal number. The '#' may also follow the sign. Outputs: T1 : delimiting character T2 : number $RDEC0 RDECL$ DI as $RDECL but leading character already read T1-T4 $RDECL Inputs: T1 : character $RDECM RDECM$ DI read a decimal number (+ possible multiplier) from the current T1-T4 3 file. The number is as $RDECL, but may have a multiplier, 'K' kilo, 'M' mega or 'G' giga. Note that 1K = 1000, not 1024. Outputs: T1 : delimiting character T2 : number $RDCM0 RDECM$ DI as $RDECM but leading character already read T1-T4 $RDECM Inputs: T1 : character $RDVIC RDVIC$ DI read a device name from the current device. $RDVIC insists on a T1-T3 14 terminating ':'. Null names are forbidden. Returns: error : nonskip o.k. : skip Outputs: T1 : delimiting character (o.k. only) : syntax error code (error only) T2 : device name in SIXBIT $RDVI0 RDVIC$ DI as for $RDVIC but enter with the leading character already read T1-T4 $RDVIC Inputs: T1 : ASCII character $REDCH REDCH$ DI read a character from the current file and perform some basic T1 24 7.9 editing: endfile is converted to ^Z LIST OF ALL IOLIB ROUTINES Page A-7 , , & are ignored is converted to & are converted to is converted to -1 is converted to 0 ^C and ^Z are converted to -2 Outputs: T1 : character $REDC0 REDCH$ DI as $REDCH but the character has already been read T1 $REDCH 7.9 Inputs: T1 : character $RFILE RFILE$ DI read a filename from the current file. The filename may T1-T4 170 7.11 contain wild characters, and may include standard switches and switches defined by the caller. $RFILE remembers and applies sticky parts of filenames. Returns: error : nonskip o.k. : skip Outputs: T1 : delimiting character (o.k. return) : syntax error code (error return) T2 : flags,,point to FDB containing file details $RFIL0 RFILE$ DI as for $RFILE, but the FDB and the user switches may be given T1-T4 $RFILE 7.11 Inputs: T1 : point to switch tables T2 : length,,point to FDB $RKWRD RKWRD$ DI read a Kword value from the current file in the format 'nnnx', where T1-T4 11 x maybe 'K' or 'P' or blank. e.g. 20P, 13K, 128. Default is K. Returns: error : non-skip o.k. : skip Outputs: T1 : delimiting character (o.k. only) : syntax error code (error only) T2 : value in words $RKWR0 RKWRD$ DI as $RKWRD but leading character already read T1-T4 $RKWRD Inputs: T1 : character $RNAME RNAME$ DI read an alphanumeric word from the current file. Only the 1st T1-T4 11 6 characters are remembered. Outputs: T1 : delimiting character T2 : word of SIXBIT characters $RNAM0 RNAME$ DI as $RNAME but leading character already read T1-T4 $RNAME Inputs: T1 : charatcer $ROCTL ROCTL$ DI read a signed octal number from the current file. If the number T1-T4 17 terminates with a period, treat the number as if it had been decimal. Outputs: T1 : delimiting character T2 : number $ROCT0 ROCTL$ DI as $ROCTL but leading character already read T1-T4 $ROCTL Inputs: T1 : character $ROCTM ROCTM$ DI read an octal number (+ possible multiplier) from the current T1-T4 3 file. The number is as $ROCTL, but may have a multiplier, 'K' kilo, 'M' mega or 'G' giga. Note that 1K = 1000 octal or 512 decimal. LIST OF ALL IOLIB ROUTINES Page A-8 Outputs: T1 : delimiting character T2 : number $ROCM0 ROCTM$ DI as $ROCTM but leading character already read T1-T4 $ROCTM Inputs: T1 : character $RPATH RPATH$ DI read a path specification from the current file. The spec. may T1-T4 49 7.12 contain wild numbers and SFDs. Returns: error : nonskip o.k. : skip Outputs: T1 : delimiting character (o.k. only) syntax error code (error only) T2 : PPN or point to path spec. block T3 : PPN mask or point to path mask block T4 : flags $RPAT0 RPATH$ DI as $RPATH but enter with leading '[' already read T1-T4 $RPATH 7.12 Inputs: T1 : ASCII character $RPJPG RPJPG$ DI read a project-programmer pair from the current file (no []). T1-T4 43 7.12 Both project and programmer may be wild. Returns: error : non-skip o.k. : skip Outputs: T1 : delimiting character (o.k. only) : syntax error code (error only) T2 : PPN T3 : wildcard mask T4 : flags $RPJP0 RPJPG$ DI as $RPJPG but leading character already read. T1-T4 $RPJPG 7.12 Inputs: T1 : character $RPPN RPPN$ DI read a PPN in the form [PPN] from the current device. The PPN T1-T4 12 7.12 may be wild. Returns: error : non-skip o.k. : skip Outputs: T1 : delimiting character (o.k. only) syntax error code (error only) T2 : PPN T3 : wildcard mask T4 : flags $RPPN0 RPPN$ DI as $RPPN but leading '[' already read T1-T4 $RPPN 7.12 Inputs: T1 : character $RREAL RREAL$ DI read a signed floating point number from the current file. T1-T4 39 The number may have a signed exponent as Esnn. Outputs: T1 : delimiting character T2 : number $RREA0 RREAL$ DI as $RREAL but leading character already read T1-T4 $RREAL Inputs: T1 : character $RSWIT RSWIT$ DI read a switch spec. from the current file in the form T1-T4 122 7.13 '/name:value', where the name is a switch name either defined by the caller, or a standard name, and the value is optional and may be in LIST OF ALL IOLIB ROUTINES Page A-9 one of a number of predefined forms. Returns: error : non-skip o.k. : skip Outputs: T1 : delimiting character (o.k. only) : syntax error code (error only) $RSWI0 RSWIT$ DI as $RSWIT but leading '/' already read T1-T4 $RSWIT 7.13 Inputs: character $RTDAY RTDAY$ DI read a date and time from the current file in the format T1-T4 16 'dd-mmm-yy hh:mm:ss'. Either date or time may be omitted. Assumptions are today, and midnight. Returns: error : non-skip o.k. : skip Outputs: T1 : delimiting character : syntax error code (error only) T2 : time in milliseconds T3 : date in internal format $RTDA0 RTDAY$ DI as $RTDAY but leading character already read T1-T4 $RTDAY Inputs: T1 : character $RTIME RTIME$ DI read the time from the current file in the format 'hh:mm:ss' T1-T4 22 Trailing fields may be omitted. Returns: error : non-skip o.k. : skip Outputs: T1 : delimiting character (o.k. only) : syntax error code (error only) T2 : time in milliseconds $RTIM0 RTIME$ DI as $RTIME but leading character already read T1-T4 $RTIME Inputs: T1 : character $RUCCH RUCCH$ DI read a character from the current file and convert lower case T1 6 alphabetics to upper case. Note: this routine may be called to convert a character to upper case. Outputs: T1 : character $RUCC0 RUCCH$ DI as $RUCCH but character already read T1 $RUCCH Inputs: T1 : character $RWNAM RWNAM$ DI read a name from the current file, where the name can include T1-T4 65 wildcards. The name is treated as alphanumeric and converted to SIXBIT unless the leading character is '#' when it is octal with a possible multiplier, and is converted to binary. Outputs: T1 : delimiting character T2 : word (SIXBIT or binary) T3 : wildcard mask T4 : flags $RWNA0 RWNAM$ DI as $RWNAM but leading character already read T1-T4 $RWNAM Inputs: T1 : character $RWNUM RWNUM$ DI as $RWNAM, but octal is assumed unless the 1st character is alpha. T1-T4 $RWNAM $RWNU0 RWNUM$ DI as $RWNUM but leading character already read T1-T4 $RWNAM LIST OF ALL IOLIB ROUTINES Page A-10 Inputs: T1 : character $RWORD RWORD$ DI read a word of characters from the current file delimited by or T1-T4 12 any non-SIXBIT character. Only the 1st 6 characters are remembered Outputs: T1 : delimiting character T2 : word of SIXBIT characters $RWOR0 RWORD$ DI as $RWORD, but leading character already read T1-T3 $RWORD Inputs: T1 : character LIST OF ALL IOLIB ROUTINES Page A-11 Acs Size Routine Macro DI Description destroyed (words) Section ======= ===== == =========== ========= ======= ======= A.3 Formatted Write Routines --- --------- ----- -------- $WRITE WRITE$ DI write one byte to the current file. T1 14 7.2 Inputs: T1 : byte, right-justified Returns: error : non-skip o.k : skip Outputs: T1 : IO-error-code (error return only) $$WBYT WBYTE$ DI write one byte to the current file. Fatal errors go to $FATAL. T1 1 7.3 Inputs: T1 : byte, right justified $$WCHR WCHAR$ DI write one character to the current file. Fatal errors go to $FATAL. T1 $$WBYT 7.4 Inputs: T1 : ASCII character, right justified ------------------------------------------------------------------------------------------------------------------------- $WADDR WADDR$ DI write the contents of a halfword (e.g. an address) as 6 octal T1-T3 7 digits, zero filled Inputs: T1 : binary halfword (rh) $WBWRD WBWRD$ DI write a number as blocks (128 words) rounded up T1-T3 $WWWRD Inputs: T1 : number of words $WCASH WCASH$ DI write a sum in dollars and cents in the format '$ddddd.cc' T1-T3 15 Inputs: T1 : value in cents $WCRLF WCRLF$ DI write a none 5 Inputs: none $WCWRD WCWRD$ DI write a number as a number of words of core choosing kwords or words T1-T3 $WWWRD Inputs: T1 : number of words $WDATE WDATE$ DI write a date in the format 'dd-mmm-yy' T1-T3 15 Inputs: T1 : date in internal form $WDECL WDECL$ DI write a number in decimal T1-T3 $WRADX Inputs: T1 : number $WDNOW WDNOW$ DI write the date today in the format 'dd-mmm-yy' T1-T3 $WDATE Inputs: none $WDVIC WDVIC$ DI write a device name to the current file as 'nnn:' T1-T2 3 Inputs: T1 : device name in SIXBIT $WFCHA WFCHA$ DI write a character exactly, by flagging control characters with ^, T1-T3 34 lower case characters with ', and naming special control characters. e.g. ^A, 'Z, Inputs: T1 : ASCII character, right justified $WFILE WFILE$ DI write a filename to the current file T1-T2 22 LIST OF ALL IOLIB ROUTINES Page A-12 Inputs: T1 : pointer to FDB containing filename $WKWRD WKWRD$ DI write a number as Kwords rounded up T1-T3 $WWWRD Inputs: T1 : number of words $WNAME WNAME$ DI write a name which maybe in XWD format T1-T2 3 Inputs: T1 : name in SIXBIT $WOCTL WOCTL$ DI write a number in octal T1-T3 $WRADX Inputs: T1 : number $WPATH WPATH$ DI write a path specification in []s T1-T3 18 Inputs: T1 : PPN or pointer to PATH. UUO block $WPWOR WPWOR$ DI write a character followed by a word of SIXBIT characters T1-T2 $WWORD Inputs: T1 : ASCII prefix character T2 : word of SIXBIT characters $WPWRD WPWRD$ DI write a core size in pages rounded up T1-T3 $WWWRD Inputs: T1 : size in words $WRADX WRADX$ DI write an integer in a given radix T1-T3 18 Inputs: T1 : number T2 : radix $WREAL WREAL$ DI write a word as a floating point number (F format if T1-T4 54 0.1 .le. n .ge. 1.0 and E format otherwise) Inputs: T1 : number $WTDAY WTDAY$ DI write a time and date in format 'hh:mm:ss dd-mmm-yy' T1-T3 6 Inputs: T1 : time in milliseconds T2 : date in internal format $WTDNW WTDNW$ DI write the time and date now (i.e. write a timestamp) T1-T3 4 Inputs: none $WTEXT WTEXT$ DI write a text string to the current file T1 9 WLINE$ Inputs: T1 : pointer to ASCIZ text string $WTIME WTIME$ DI write a time in hours and minutes 'hh:mm' T1-T3 8 Inputs: T1 : time in milliseconds $WTIMS WTIMS$ DI write a time accurate to seconds 'hh:mm:ss' T1-T3 9 Inputs: T1 : time in milliseconds $WTMTS WTMTS$ DI write a time accurate to tenths of a second 'hh:mm:ss.t' T1-T3 8 Inputs: T1 : time in milliseconds $WTNOW WTNOW$ DI write the time now as 'hh:mm:ss' T1-T3 $WTIMS Inputs: none $WVERS WVERS$ DI write out all fields of a version number in standard format T1-T3 25 Inputs: T1 : version number $WWORD WWORD$ DI write out a word as 6 SIXBIT characters T1-T2 7 Inputs: T1 : word of SIXBIT characters LIST OF ALL IOLIB ROUTINES Page A-13 $WWWRD WWWRD$ DI write a number as a number of words e.g. 123W T1-T3 18 Inputs: T1 : number of words $WXWD WXWD$ DI write a word as two halfwords, blank filled, separated by , T1-T3 8 Inputs: T1 : word $W2FIL W2FIL$ DI write a 2 digit number with a given fill character T1-T3 8 Inputs: T1 : number T2 : ASCII fill character $W2FLB W2FLB$ DI write a number in 2 digits filled with a space T1-T3 $W2FIL Inputs: T1 : number $W2FL0 W2FL0$ DI write a number in 2 digits filled with a zero T1-T3 $W2FIL Inputs: T1 : number LIST OF ALL IOLIB ROUTINES Page A-14 Acs Size Routine Macro DI Description destroyed (words) Section ======= ===== == =========== ========= ======= ======= A.4 Core Management Routines --- ---- ---------- -------- $$ALLC ALLOC$ I allocate a block of free core. This routine exists to decide between T1 2 5.1 dynamic and static core allocation. Inputs: T1 : number of words required Returns: no core : non-skip o.k. : skip Outputs: T1 : point to word 1 of allocated block (o.k. only) : 0,,ERNEC% (error only) $$DALC DEALC$ I deallocate a block of core by returning it to the pool of T1 $$ALLC 5.1 free blocks Inputs: T1 : point to word 1 of core block -------------------------------------------------------------------------------------------------------------------------- $CRGET I allocate a block of core from above .JBFF, by moving .JBFF and T1 17 5.3 obtaining more core from the monitor if need be. Inputs: T1 : size of chunk required Returns: no core : non-skip o.k. : skip Outputs: T1 : point to 1st word of chunk (o.k. only) : 0,,ERNEC% (error only) $CRREL I it is not possible to deallocate a chunk using static management. none $CRGET 5.3 This call is a noop. $HPGET I allocate a block of core from a linked list of free chunks of core. T1 108 5.2 If there is insuffient space, first garbage collect the list and then get more space from the monitor. Inputs: T1 : size of chunk required or 0 for largest available Returns: no core : non-skip o.k. : skip Outputs: T1 : point to 1st word of chunk : 0,,ERNEC% (error only) $HPREL I deallocate a chunk (or chunks) of core by linking it back into T1 $HPGET 5.2 the chain of free chunks. Several chunks may be deallocated together chaining them through their -1th word. Inputs: T1 : point to 1st word of chunk LIST OF ALL IOLIB ROUTINES Page A-15 Acs Size Routine Macro DI Description destroyed (words) Section ======= ===== == =========== ========= ======= ======= A.5 Data Block Manipulation Routines --- ---- ----- ------------ -------- $CLRFD CLRFD$ I create a new standard length FDB, clear it, set the length in $FDCNT T1 20 MAKFD$ and initialise $FDBFR and $FDSNC to -1. Returns: no core : non-skip o.k. : skip Outputs: T1 : point to FDB (o.k. only) : 0,,ERNEC% (error only) $CLRF0 CLRFD$ I as $CLRFD, but allow caller to specify address and/or length of FDB T1 $CLRFD If the address is given, the old FDB is used. Inputs: T1 : length,,address of FDB $INIID I clear the IDB, set the verbosity to standard, set MAXCOR to all core I 10+19 and set the last command character to endline. This routine contains the IDB. $LOSFD LOSFD$ I deallocate the space occupied by an FDB. If $FDPPN points to a path T1 7 block, the path block is deallocated also. This routine only succeeds if dynamic core management is used. Inputs: T1 : point to 1st word of FDB $PATCH patch area loaded if FT$DBG is on none 0+200 $STACK pushdown stack and pointer thereto none 1+100 3.8 LIST OF ALL IOLIB ROUTINES Page A-16 Acs Size Routine Macro DI Description destroyed (words) Section ======= ===== == ========== ========= ====== ======= A.6 Tempcore Routines --- -------- -------- $TMPDL TMPDL$ DI delete a tempcore file from core and/or disk T1-T3 13 8.4 It is not an error if the file does not exist. Returns: error : non-skip o.k. : skip Outputs: T1 : IO error code (error only) $TMPFD TMPFD$ create an FDB for a tempcore file given a 3 character name T1-T4 17 8.2 The name of the file is nnnccc.TMP, where 'nnn' is the job number and 'ccc' is the 3 character name. Inputs: T1 : 3 SIXBIT characters, right justified Outputs: D : point to FDB $TMPIN TMPIN$ DI read 1 block of a tempcore file from core or from disk. If core, T1-T4 31 8.3 set flag FC$TCI to ensure that further calls to $INPUT give endfile return. Inputs: taken from FDB Returns: error : non-skip o.k. : skip Outputs: T1 : IO error code (error only) $TMPOU TMPOU$ DI close off a tempcore file. If the file is not yet ENTERed, try to T1-T4 19 8.5 write the file to tempcore. If so, or if tempcore fails, write to disk and release channel. Returns: error : non-skip o.k. : skip Outputs: T1 : IO error code (error only) LIST OF ALL IOLIB ROUTINES Page A-17 Acs Size Routine Macro DI Description destroyed (words) Section ======= ===== == =========== ========= ======= ======= A.7 Error Routines --- ----- -------- $ADVIS ADVIS$ I write an advisory error message. Call as for $ERROR T1-T4 $ERROR 9.5 Inputs: as for $ERROR Returns: yes $ERROR I write an error message to the error file whose point is in $IDEFD(I) T1-T4 57 9.4 Full documentation may be found in section 9.4 Inputs: T1 : message point and flags T2 : value T3 : UUO or error type name (optional) Returns: depends; yes if warning, no if fatal $FATAL FATAL$ I write a fatal error message. Call as for $ERROR. T1-T4 $ERROR 9.5 Inputs: as for $ERROR Returns: never; traps to $$FERR $FTLIO FATAL$ DI write a fatal error message for the current file based on an IO error T1-T4 21 9.7 code, returned by basic IO module routines Inputs: T1 : UUO-code,,error code $FTLSY FATAL$ I write a fatal error message based on an error code returned by T1-T4 8 9.8 the command scanning subroutines. Inputs: T1 : syntax error code T2 : value $WARN WARN$ I write a warning error message. Call as for $ERROR T1-T4 $ERROR 9.5 Inputs: as for $ERROR Returns: yes $WRNIO WARN$ DI write a warning error message about the current file. A code is T1-T4 $FTLIO 9.7 returned by the routines in the basic IO module. Inputs: T1 : UUO-code,,error-code $WRNSY WARN$ I write a warning error about bad syntax, given a code returned T1-T4 $FTLSY 9.8 by the command scanners on error. Inputs: T1 : syntax error code T2 : value $$FERR exit to monitor mode after clearing input buffer. If CONTINUEd, T1 5 9.9 try to start at start address, if fail, exit. Returns: only to program start address LIST OF ALL IOLIB ROUTINES Page A-18 Acs Size Routine Macro DI Description destroyed (words) Section ======= ===== == =========== ========= ======= ======= A.8 Utility Routines --- ------- -------- $POPJ execute a POPJ P, instruction none IOMOD $POPJ1 increment the return address and POPJ, thus doing a skip return none IOMOD $POPJ2 double increment the return address and POPJ, thus doing a double none IOMOD skip return. Cannot be used with $SAVEn. $TOPJ POP the top of the stack into T1 and POPJ return T1 IOMOD $TOPJ1 POP the top of the stack into T1 and skip POPJ return T1 IOMOD $TOPJ2 POP the top of the stack into T1 and double skip POPJ return T1 IOMOD Cannot be used with $SAVEn. $XOPJ POP the top off the stack (to nowhere) and POPJ return none IOMOD $XOPJ1 POP the top off the stack and skip POPJ return none IOMOD -------------------------------------------------------------------------------------------------------------------------- $RESTT RESTT$ restore T1-T4 from the stack T1-T4 $SAVET $SAVET SAVET$ save T1-T4 on the stack none 13 $SAVE1 SAVE1$ called on entry to a subroutine to save P1 and to restore P1 on exit none IOMOD The caller is called as a subroutine so that his eventual POPJ returns to $SAVE1 to restore P1. POPJ and POPJ1 are catered for $SAVE2 SAVE2$ as $SAVE1, but P1 and P2 are saved and restored none IOMOD $SAVE3 SAVE3$ as $SAVE1, but P1, P2 and P3 are saved and restored none IOMOD $SAVE4 SAVE4$ as $SAVE1, but P1, P2, P3 and P4 are saved and restored none IOMOD -------------------------------------------------------------------------------------------------------------------------- $BATCH BATCH$ determine whether the job's terminal is a PTY none 6 Returns: not PTY : non-skip PTY : skip $BEGCC BEGIn$ DI initialise a program and set up CCL tempcore input file if entry T1-T2 10 3.9 was at 'start+1'. $BEGIN BEGIN$ DI initialise a program T1-T2 5 3.9 $CLBUF CLBUF$ DI clear command input by clearing the TTCALL TTY buffer or by reading T1 18 to endline. LIST OF ALL IOLIB ROUTINES Page A-19 $CLLIN CLLIN$ DI clear the current command input line none 5 $CNVNU CNVNU$ return the universal date/time now T1-T4 $CNVUI As $CNVIU but uses the date/time from the monitor $CNVUI CNVUI$ convert a date/time in universal format to internal format T1-T4 102 Inputs: T1 : universal date,,time Outputs: T1 : time in milliseconds T2 : date in internal format $CNVIU CNVIU$ convert internal date/time to universal format T1-T4 $CNVUI Inputs: T1 : time in milliseconds T2 : date in internal format Outputs: T1 : universal date,,time $FDTTY FDTTY$ DI check whether the current file is a terminal or not. none 6 Returns: not TTY : normal TTY : skip $MATCH MATCH$ match a SIXBIT name against a table of names, selecting T1-T3 36 10.1 either an exact match or an unambiguous abbreviation. A name in the table may begin with '*' to say that the first letter is enough to identify this name. Inputs: T1 : IOWD length,address of table T2 : SIXBIT name to match Returns: error, no or several matches o.k. :skip Outputs: T1 : flag,,table index. lh=0 if exact, lt 0 if not (o.k. only) : lt 0 : no match; ge 0 :several (error only) $MONRT MONRT$ return to monitor mode by EXIT 1, unless job not logged in. Then T1 13 use LOGOUT. Return to caller on 'CONTINUE'. Return: only if CONTINUE is typed at monitor mode $SLEEP SLEEP$ send the job to sleep for a specified period using HIBER or SLEEP T1 9 Inputs: T1 : sleep time in seconds $ZERO ZERO$ zero a chunk of core by BLT none 10 Inputs: T1 : length,,address APPENDIX B IOLIB MACROS This appendix is a complete list of all IOLIB macros. The macros are listed under several headings but within those headings the macros are listed in alphabetical order. The macros that are useful in writing the program, rather than macros which merely call routines, are listed first. The macro name is given, along with the names of any routines called, a brief description, the call, the number of lines of inline code generated, and a further reference. The descriptions in this appendix are not as full as those of the routines in appendix A, and the user should refer to appendix A if he needs clarification. Inline Macro Routine Description Call code Section ===== ======= =========== ==== ====== ======= B.1 Programming Macros --- ----------- ------ BEGIN$ $BEGIN perform all program initialisation including concealed BEGIN$ tfn 5 3.9 mode entry points, CCL entry points, RESET UUO, stack setup, IDB initialisation and command FDB setup 'tfn' 3 character tempcore filename (otherwise program name) CMDFD$ set ac(D) to point to the current command file. CMDFD$ 1 Load ac(D) from $IDIFD(I). ERRFD$ set ac(D) to point to the current error file. ERRFD$ 1 Load ac(D) from $IDEFD(I). FDESC$ create an inline FDB and fill it with values FDESC$ dv,nm,ex,pt,md,ln $LNFDB+ 3.12 'dv' device name 'nm' file name 'ex' extension name 'pt' path spec. in <>, e.g. <104,427> 'md' IO mode 'ln' length of FDB, if longer than standard HISEG$ if first call of program, create 'TWOSEG' and HISEG$ 0 3.11 'RELOC 400000' pseudo-ops to start two-segmenting otherwise, if assembling high segment code, do nothing; otherwise, set outstanding literals into low segment and switch segments IOLIB MACROS Page B-2 JBREN$ load .JBREN (reenter address) with the given address JBREN$ ac,adr 2 The user may choose the temporary ac. 'ac' temporary ac to be used 'adr' reenter address JBVER$ set the version number defined by the $$V??? symbols JBVER$ 0 3.14 into .JBVER in DEC format LDFD$ move an FDB point into ac(D) LDFD$ adr 1 'adr' address of FDB point LDFDI$ move immediate an FDB point into ac(D) LDFDI$ adr 1 'adr' FDB point LOSEG$ if assembling code into the low segment, do nothing LOSEG$ 0 3.11 otherwise, set all outstanding literals into high segment and switch segments MAKFD$ write code to create or initialise an FDB and MAKFD$ dv,nm,ex,pt,md,ln,ad 5+ 3.13 fill the FDB with values. 'dv' device name 'nm' file name 'ex' extension name 'pt' path spec. inside <>, e.g. <104,427,SF1> 'md' IO mode 'ln' length of FDB if non-standard 'ad' address of FDB; if none make a new FDB if an ac, use it as point to address MSGFD$ set ac(D) to point to the current message file. MSGFD$ 1 Load ac(D) from $IDOFD(I). PATCH$ increment $$VEDT for each patch; increment $$VMIN by one PATCH$ 0 3.14 and make a symbol '$n' for each pn to be used if adding and subtracting code with IFDEF and IFNDEF 'p1,..pn' patch numbers TRMFD$ set ac(D) to point to the job's terminal. Zero ac(D). TRMFD$ 1 VERSN$ define values for the symbols, $$VMAJ, $$VMIN VERSN$ vm,ve,vw 0 3.14 $$VEDT and $$VCOD. These symbols are used by the other version number macros and are explained in section 3.14. 'vm' is the major version number 've' is the edit number (updated by PATCH$) 'vw' is the who last edited code the minor version is set to zero (updated by PATCH$) The versions of C and IO used are PRINTXed during assembly. VTEXT$ creates an ASCIZ string of the version number from VTEXT$ 1+ 3.14 the version number symbols e.g. '5B(107)-1' IOLIB MACROS Page B-3 Inline Macro Routine Description Call code Section ===== ======= =========== ==== ====== ======= B.2 Basic IO Macros --- ----- -- ------ APDWT$ $APDWT as APEND$ but on 'file being modified' failure APDWT$ 1 6.21 wait and try again a given number of times error return APEND$ $APEND open a file for appending, setting buffer pointers APEND$ 1 6.22 appropriately. Only works for append mode files. error return CLOSE$ $CLOSE execute a CLOSE UUO. If the call has an argument, two CLOSE$ bits 1!2 6.7 instructions are generated, and the arguments are used as CLOSE UUO bits. 'bits' CLOSE UUO bits DELET$ $DELET delete the current file DELET$ 1 6.10 error return DLBUF$ $DLBUF deallocate a buffer ring DLBUF$ 1 6.18 ENTER$ $ENTER Execute an ENTER UUO for the current file. If the ENTER x 1 6.5 macro has an argument then the UUO may change the error return create date/time field 'x' any argument (just a flag) FRCHN$ $FRCHN locate the first free software IO channel starting FRCHN$ 1 with the contents of ac(T1) error return GETST$ $GETST get the IO status halfword from the monitor. The status GETST$ 1 6.12 returned in ac(t1) LUKUP$ $LUKUP execute a LOOKUP UUO for the current file. LUKUP$ 1 6.4 error return INPUT$ $INPUT execute an INPUT UUO for the current file. Make a INPUT$ 1 6.2 buffer ring and find the required record if needed error return endfile return MKBUF$ $MKBUF build a buffer ring (see Appendix A) MKBUF$ 1 6.17 error return MTxxx$ $MTxxx execute an MTAPE UUO for the current file. MTxxx$ 1 6.23 'xxx' may be any of the codes for the various MTAPE functions, e.g. MTREW$ executes a rewind. All functions are followed by an MTWAT$ to wait for completion. MTBSF$ skips over the EOF unless at BOT. OPEN$ $OPEN execute an OPEN UUO for the current file, setting OPEN$ 1 6.6 defaults and finding a free channel error return OUTIN$ $OUTIN output the last record input (to a disk device) OUTIN$ 1 6.3 error return IOLIB MACROS Page B-4 OUTPU$ $OUTPU execute an OUTPUT UUO for the current file OUTPU$ 1 6.3 making a buffer ring and finding required record if error return necessary RLEAS$ $RLEAS execute a RELEAS UUO for the current file and RLEAS$ x 1 6.8 deallocate buffers 'x' flag. If given, don't deallocate buffers. RENAM$ $RENAM execute a RENAME UUO for the current file. The file RENAM$ 1 6.9 have been LUKUP$ed first. error return SETST$ $SETST set the IO channel status from ac(T1) into the monitor SETST$ 1 6.13 UPDAT$ $UPDAT open a file for updating UPDAT$ 1 6.19 error return UPDWT$ $UPDWT as UPDAT$, but on 'file being modified' failure UPDWT$ 1 6.20 wait and try again a given number of times error return USETI$ $USETI find the required record for disk files. On entry USETI$ 1 6.11 ac(T1) contains 'last-record,,next record' USETO$ $USETO find the required record for output for disk files USETO$ 1 6.11 On entry ac(T1) contains 'last-record,,this-record' XTCAL$ $XTCAL execute a CALLI UUOZ for the current file, setting XTCAL$ uuo 2 6.15 physical-only if required error return 'uuo' CALLI UUO to be executed (arg in ac(T2)) XTDCL$ $XTDCL execute a device dependent CALLI UUO for the current XTDCL$ uuo 2 6.16 file. error return 'uuo' CALLI UUO to be executed XTUUO$ $XTUUO execute an IO UUO for the current file XTUUO$ uuo 2 6.14 'uuo' UUO name error return IOLIB MACROS Page B-5 Inline Macro Routine Description Call code Section ===== ======= =========== ==== ====== ======= B.3 Read macros --- ---- ------ RBYTE$ $$RBYT read a byte, and trap to $FATAL on error RBYTE$ 1 7.6 endfile RCALT$ $RCALT read a character with command editing, but if last RCALT$ 1 7.10 character was altmode, return altmode instead. RCCHR$ $RCCHR read a character with command editing RCCHR$ 1 7.10 RCHAR$ $$RCHR read a character with command editing RCHAR$ 1 7.8 READ$ $READ read a byte READ$ 1 7.5 error return endfile ----------------------------------------------------------------------------------------------------------------------------- The following macros will accept an argument. If an argument is provided it is assumed to be the address of the leading character of the string to be read. If that address is ac(T1), the macro merely assembles a jump to the secondary entry point of the routine. If the address is elsewhere, then the macro assembles an extra instruction to move the character into ac(T1). If there is no argument, the macro assembles a PUSHJ to the routine as described in appendix A. All the macros given below return the delimiting character in ac(T1) and the value read in ac(T2). Some routines return a wildcard mask in ac(T3), and a few return extra data in ac(T4). Refer to the description of the routines for specific details of parameters. RANCH$ $RANCH read a character and check whether alphanumeric RANCH$ ac 1!2 error return means not alphanumeric error return RCASH$ $RCASH read a cash value in dollars and cents RCASH$ ac 1!2 error return RDATE$ $RDATE read a date from the current file in the format RDATE$ ac 1!2 dd-mmm-yy. error return RDECL$ $RDECL read a decimal number RDECL$ ac 1!2 RDECM$ $RDECM read a decimal number possibly with a K, M or G RDECM$ ac 1!2 multiplier RDVIC$ $RDVIC read a device name RDVIC$ ac 1!2 REDCH$ $REDCH read a character and perform basic editing REDCH$ ac 1!2 7.9 RFILE$ $RFILE read a file specification into an FDB. Note that this RFILE$ ac 1!2 7.11 macro is different. If there is no argument, there is error return no switch table, and $RFILE creates an FDB. If there is an argument, it is an ac which holds a point to the switch table (possibly zero). If this is ac(T1), no IOLIB MACROS Page B-6 extra code is created. A point to an FDB or zero must be in ac(T2). RKWRD$ $RKWRD read a core size as Kwords or pages RKWRD$ ac 1!2 RNAME$ $RNAME read an alphanumeric name and convert to a SIXBIT word RNAME$ ac 1!2 ROCTL$ $ROCTL read an octal number ROCTL$ ac 1!2 ROCTM$ $ROCTM read an octal number possibled postfixed by a K, M or G ROCTM$ ac 1!2 multiplier. RPATH$ $RPATH read a path specification RPATH$ ac 1!2 7.12 error return RPJPG$ $RPJPG read a project,programmer pair (no []) RPJPG$ ac 1!2 7.12 error return RPPN$ $RPPN read a PPN RPPN$ ac 1!2 7.12 error return RREAL$ $RREAL read a floating point number expressed in FORTRAN E or F RREAL$ ac 1!2 format. RSWIT$ $RSWIT read a switch name and value RSWIT$ ac 1!2 7.13 error return RTDAY$ $RTDAY read a tme and date RTDAY$ ac 1!2 error return RTIME$ $RTIME read a time in the format hh:mm:ss RTIME$ ac 1!2 error return RUCCH$ $RUCCH read a character and convert lower to upper case RUCCH$ ac 1!2 RWNAM$ $RWNAM read a possibly wild name RWNAM$ ac 1!2 RWNUM$ $RWNUM read a possibly wild number (or name if 1st character is RWNUM$ ac 1!2 alphabetic). IOLIB MACROS Page B-7 Inline Macro Routine Description Call code Section ===== ======= =========== ==== ====== ======= B.4 Write Macros --- ----- ------ WADDR$ $WADDR write an octal address in 6 digits filled by zeros WADDR$ 1 WBWRD$ $WBWRD write a number as a number of blocks (128 words) WBWRD$ 1 WBYTE$ $$WBYT write a byte but trap to $FATAL on error WBYTE$ 1 7.3 WCASH$ $WCASH write a number of cents as dollars and cents WCASH$ 1 WCHAR$ $$WCHR write character WCHAR$ "c" 1!2 7.4 'c' an ASCII character WCRLF$ $WCRLF write an endline WCRLF$ 1 WCWRD$ $WCWRD write a number as a multiple of core size WCWRD$ 1 which may be P, K or W. WDATE$ $WDATE write a date as dd-mmm-yy WDATE$ 1 WDECL$ $WDECL write a decimal number WDECL$ n 1!2 'n' a positive decimal number WDNOW$ $WDNOW write the date now WDNOW$ 1 WDVIC$ $WDVIC write a device name as 'dev:' WDVIC$ 1 WFCHA$ $WFCHA write a funny character, making code explicit WFCHA$ 1 by flagging control and lower case characters WFILE$ $WFILE write the filename from an FDB WFILE$ 1 WHELP$ $WHELP write a help text WHELP$ 1 WKWRD$ $WKWRD write a core size in Kwords WKWRD$ 1 WLINE$ $WTEXT write a text string adding a WLINE$ 1!2 'text' a string of ASCII characters WNAME$ $WNAME write a name in SIXBIT or halfwords WNAME$ 1 WOCTL$ $WOCTL write an octal number WOCTL$ n 1!2 'n' a positive octal number WPATH$ $WPATH write a path specification (or just PPN) WPATH$ 1 WPWOR$ $WPWOR write a word of SIXBIT characters preceded by an WPWOR$ "c",word 1!2!3 ASCII character. Either argument may be ommitted. 'c' an ASCII character 'word' up to 6 SIXBIT characters IOLIB MACROS Page B-8 WPWRD$ $WPWRD write a core size in pages WPWRD$ 1 WRADX$ $WRADX write a number in a given radix (given in ac(T2)) WRADX$ 1 WREAL$ $WREAL write a floating point number WREAL$ n 1!2 'n' a number in FORTRAN E-format WRITE$ $WRITE write a byte WRITE$ 1 7.2 error return WTDAY$ $WTDAY write time and date as dd-mmm-yy hh:mm WTDAY$ 1 WTDNW$ $WTDNW write time and date now WTDNW$ 1 WTEXT$ $WTEXT write a text string WTEXT$ 1!2 'text' a string of ASCII characters WTIME$ $WTIME write time as hh:mm WTIME$ 1 WTIMS$ $WTIMS write time as hh:mm:ss WTIMS$ 1 WTMTS$ $WTMTS write time as hh:mm:ss.t WTMTS$ 1 WTNOW$ $WTNOW write time now as hh:mm:ss WTNOW$ 1 WWORD$ $WWORD write a word of SIXBIT characters WWORD$ word 1!2 'word' a string of up to 6 characters WWWRD$ $WWWRD write a number as a number of words WWWRD$ 1 WXWD$ $WXWD write a word as two halfwords WXWD$ 1 W2FIL$ $W2FIL write 2 digits, filled on left W2FIL$ 1 W2FLB$ $W2FLB write 2 digits, filled on left by space W2FLB$ 1 W2FL0$ $W2FL0 write 2 digits, filled on left by zero W2FL0$ 1 IOLIB MACROS Page B-9 Inline Macro Routine Description Call code Section ===== ======= =========== ==== ====== ======= B.5 Core Management Macros --- ---- ---------- ------ ALLOC$ $$ALLC call the memory manager to allocate space ALLOC$ 1 5.1 error return DEALC$ $$DALC call the memory manager to deallocate space DEALC$ 1 5.1 B.6 Data Block Manipulation Macros --- ---- ----- ------------ ------ CLRFD$ $CLRFD maybe create, but certainly zero and initialise an CLRFD$ adr 1!2 FDB. If the macro has an argument use this as the address error return (no core) of the FDB. 'adr' address of FDB LOSFD$ $LOSFD deallocate space occupied by FDB. Deallocates path LOSFD$ 1 block, if any, too B.7 Tempcore Macros --- -------- ------ TMPDL$ $TMPDL delete a tempcore file TMPDL$ 1 8.4 error return TMPFD$ $TMPFD create an FDB for a tempcore file TMPFD$ 1 8.2 TMPIN$ $TMPIN read a tempcore file TMPIN$ 1 8.3 error return TMPOU$ $TMPOU write and close a tempcore file TMPOU$ 1 8.5 error return IOLIB MACROS Page B-10 Inline Macro Routine Description Call code Section ===== ======= =========== ==== ====== ======= B.8 Error Macros --- ----- ------ ADVIS$ $ADVIS write an advisory message to the error file ADVIS$ ,arg,ec,uc 1 9.6 'text' the text of the message 'arg' a code for the type of argument 'ec' a 3 character code prefaciing the message 'uc' a 6 character UUO name FATAL$ $ERROR write a fatal error message to the error file and FATAL$ ,arg,ec,uc 1 9.6 exit through $$FERR. 'text' the text of the message 'arg' a code for the type of the argument 'ec' a 3 character code which prefixes the message 'uc' a 6 character UUO name WARN$ $ERROR send a warning error message to the error file WARN$ ,arg,ec,uc 1 9.6 'text' the text of the error message 'arg' a code for the data type of the argument 'ec' a 3 character code prefacing the message 'uc' a 6 character UUO name IOLIB MACROS Page B-11 Inline Macro Routine Description Call code Section ===== ======= =========== ==== ====== ======= B.9 Utility Routine Macros --- ------- ------- ------ BATCH$ $BATCH discover whether job running from PTY BATCH$ 1 not PTY return CLBUF$ $CLBUF clear buffer for job's terminal; read to CLBUF$ 1 endline otherwise CLLIN$ $CLLIN read to endline CLLIN$ 1 CNVNU$ $CNVNU return now as a Universal date/time CNVNU$ 1 CNVUI$ $CNVUI convert Universal date/time to internal CNVUI$ 1 CNVIU$ $CNVIU convert internal date/time to Universal CNVIU$ 1 FDTTY$ $FDTTY check whether the current file in a terminal FDTTY$ 1 not TTY TTY MATCH$ $MATCH match a SIXBIT name against a table MATCH$ 1 10.2 MONRT$ $MONRT return to monitor mode MONRT$ 1 RESTT$ $RESTT restore T1-T4 from the stack RESTT$ 1 SAVET$ $SAVET save acs T1-T4 on the stack SAVET$ 1 SAVE1$ $SAVE1 preserve ac(P1) during a subroutine SAVE1$ 1 SAVE2$ $SAVE2 preserve acs P1-P2 during a subroutine SAVE2$ 1 SAVE3$ $SAVE3 preserve acs P1-P3during a subroutine SAVE3$ 1 SAVE4$ $SAVE4 preserve acs P1-P4 during a subroutine SAVE4$ 1 SLEEP$ SLEEP sleep by HIBER or SLEEP UUO for given time SLEEP$ ac 1!2 Time may be give in 'ac'. ZERO$ $ZERO zero a chunk or memory ZERO$ 1 APPENDIX C CONTENTS OF THE FDB Index Symbol Description ===== ====== =========== C.1 Words within the FDB --- ----- ------ --- --- 0 $FDFPT forward pointer. The left half is used to link FDBs together to form a linked list. The left half is unused but reserved for IOLIB. 1 $FDCHN channel number. The right half contains the software IO channel number in bits 29 to 32. The user may select a channel number but normally he will let IOLIB do this for him. The left half contains flags showing the status of the IO process on this file. The flags are described below. 2 $FDTYP argument returned by a DEVTYP UUO on the channel. Set by the $OPEN routine. 3 $FDNBK current record number for the FDB,,next record number for the FDB. The next record number may be set before calling $INPUT or $OUTPU for a disk device only. Updated by $INPUT, $OUTPU, $USETI, $USETO and initialised by $OPEN only if zero. 4 $FDBUF buffering details. The right half contains the length of each buffer in words. The left half contains the number of buffers. IOLIB assumes that these details are identical for input and output sides of a channel. Defaults are two buffers of the standard size for the device. Set up by $OPEN. 5 $FDIOW Point to IOWD chain for dump mode IO. Normally zero for buffered modes, but may be the address of the next buffer if out of sequence. CONTENTS OF THE FDB Page C-2 6-10 $FDOPN 3 word OPEN UUO data block. The words are described indiviually below, and in the Monitor Calls Handbook. 6 $FDSTS IO channel status. The $open routine takes values supplied in $FDMOD, for parity, density and physical-only, and puts them into $FDSTS. All other fields default to zero, in particular, the default mode is ASCII (.IOASC). $GETST writes the current IO status into the right half of $FDSTS. 7 $FDDEV device name, left-justified. The default is 'DSK' for IOLIB IO. 10 $FDBHD buffer header addresses. The left half is the output buffer header address and the right half is the input buffer header address. The buffer headers are within the FDB at $FDOBH and $FDIBH. 11-21 $FDPTH path specification in a form suitable for PATH. UUOs. The first 2 words are unused, the 3rd word is the PPN and further words are SFDs terminated by a zero word. 13 $FDPPP PPN word in the path specification 14 $FDSFD first SFD name in the path specification 22-25 $FDOBH output buffer header (4 words). Also used for the path mask for command scanning. 22-27 $FDPTM path mask block of 6 words masking the PPN and the SFDs. Set by the filename scanner RFILE to indicate wildcards typed. 26-31 $FDIBH input buffer header (4 words). Also used for part of the path mask and for the filename mask in command scanning. 30 $FDNMM filename name mask. Set by the filename scanner, $RFILE, to indicate which characters were wildcards. 32 $FDMOD modifier word. A vector of switches and parameters that may be set by the user by program or by command. The individual fields in the modifier word are described below. 33 $FDMOM modifier mask. A vector of masks corresponding to the various fields in $FDMOD. If the mask in $FDMOM is set, then that field in $FDMOD has been given. 34 $FDBFR /BEFORE specification. Set by the command scanner to give the /BEFORE date and time. CONTENTS OF THE FDB Page C-3 35 $FDSNC /SINCE specification. Set by the command scanner to give the /SINCE date and time. 36 $FDABF /ABEFORE specification. Set by the command scanner to give the access BEFORE date and time. 37 $FDASN /ASINCE specification. Set by the command scanner to give the access SINCE date and time. 40-46 $FDRIB RIB block data. The format of the RIB block section is as for extended disk UUOs. A standard FDB contains the RIB block from .RBCNT to .RBVER, but further words may be added by building an extended FDB. The RIB data is physically the last information in an FDB. For further details, see the Monitor Calls Handbook. 40 $FDCNT the count of words in the extended RIB. 41 $FDPPN either the PPN or a point to a PATH. UUO block. MAKFD$ and FDESC$ set up $FDPPN to point to $FDPTH, but the user may write a PPN over this pointer or even a pointer to another path block. 42 $FDNAM the filename in SIXBIT, left justified. 43 $FDEXT Extension. The left half contains the extension in 3 SIXBIT characters, left-justified. The right half is used by the command scanner for the extension mask. 44 $FDPRV privilege word. Contains protection, mode and create time and date information. 45 $FDSIZ file size in words. 46 $FDVER version number. 46 $ENFDB end of the FDB. 47 $LNFDB length of an FDB in words. CONTENTS OF THE FDB Page C-4 Bits Symbol Description ==== ====== =========== C.2 Bits definitions for $FDCHN --- ---- ----------- --- ------ 0 FC$OPN an OPEN UUO has been done on this channel 1 FC$LUK a LOOKUP UUO has been done on this channel. 2 FC$ENT an ENTER UUO has been done on this channel. 3 FC$TCI Tempcore input has been done on this channel 4 FC$CSC channel number set by caller. C.3 Bit definitions in $FDMOD and $FDMOM --- --- ----------- -- ------ --- ------ 0 FM$NDV null device specification. 1 FM$NUL null extension. The extension was specified but was null; therefore do not use a default extension. 2 FM$DIR directory specified. 3 FM$PHY /PHYSICAL; physical only IO on this channel. 4 FM$NOM /OKNONE; ok if no file matches this specification. 5 FM$DFX wild fixup unnecessary for this directory. 6-8 FM$TRM code for terminator of file specification. 9 FM$STR /STRS 10-23 unused 24 FM$PAR magtape recording parity (1=even). 20-26 FM$DEN magtape recording density (0=std, 1=250, 2=556, 3=800) 27-35 FM$PRO protection code as 3 octal digits. APPENDIX D CONTENTS OF THE IDB Index Symbol Description ===== ====== =========== 0 $IDDYC pointer to a linked list of chunks of free core for allocation to any routine that requires space. The dynamic core pointer is not used by the static core allocater. 1 $IDTOP maximum core that may be used by this program, set by program or by command using the /MAXCOR switch. The core is measured in words and the value is actually the maximum+1. 2 $IDLAC look-ahead character. Used by the command scanner to store the extra character when it has had to look ahead to interpret the current character. 3 $IDCPC PC for the command scanning coroutine. 4 $IDLSC last character read by the command scanner $REDCH. 5 $IDNXC next character to be read. If this word is non-zero, it forces the command scanner to read this character instead of reading from the input file. 6 $IDPNM program name. Set by the BEGIN$ macro by GETTAB. 7 $IDPPN program PPN. As $IDPNM. 10 $IDPEX low segment extension name (left half). 11 $IDPDV program device name. 12 $IDIFD input FDB pointer. The address of the FDB being used for command input. Set to TTY: or to a tempcore file by the BEGIN$ macro. 13 $IDOFD output FDB pointer. The address of the FDB being used for message output. Set to TTY: by the CONTENTS OF THE IDB Page D-2 BEGIN$ macro. 14 $IDEFD error FDB pointer. The address of the FDB being used for error message output. Set to TTY: by the BEGIN$ macro. 15 $IDCCL CCL entry point flag (0=normal, -1=CCL). Set up by the BEGIN$ macro. 16 $IDSWT point to standard switch table. Used by $RSWIT to compare switch against standard switches, if it doesn't match against user-provided switches. 17 $IDRUN runoffset,,point to run FDB. Details for program to be run on termination of this program. 20 $IDECD error codes. The left half contains 3 SIXBIT characters to preface all error messages written by the program. The right half contains the verbosity code for error messages (0=low, 1=normal, 2=high). Set to 'normal' by the BEGIN$ macro. 21 $IDHNM file name for 'help'. 22 $IDDFD point to FDB containing defaults for file name scanning. 23 $IDJNO reserved,,job number: set by BEGIN$ macro 24 $IDJPP job's PPN: set by BEGIN$ macro 25-35 $IDJPT default path specification for this task. Set by the BEGIN$ macro, and should be used to change the default path spec. 36 $IDCPU code for the CPU type, set by the BEGIN$ macro. $CPKAX==0, and $CPKIX==1. 36 $ENIDB end of the IDB 37 $LNIDB length of the IDB. APPENDIX E IO ERROR CODES Index Symbol Description ===== ====== =========== E.1 UUO codes --- --- ----- 0 UUUUO$ error for undefined UUO 1 UUOPN$ OPEN UUO error 2 UUENT$ ENTER UUO error 3 UULUK$ LOOKUP UUO error 4 UUREN$ RENAME UUO error 5 UUINP$ INPUT UUO error 6 UUOUT$ OUTPUT UUO error 7 UURUN$ RUN UUO error 10 UUGET$ GETSEG UUO error 11 UUCLO$ CLOSE UUO error 12 UUTMP$ TMPCOR UUO error IO ERROR CODES Page E-2 E.2 IO Error codes --- -- ----- ----- 0-27 ER???% LOOKUP/ENTER/RENAME error codes as defined in the Monitor Calls Handbook appendix E. IOLIB sets some of these codes for UUOs other than LOOKUP, ENTER and RENAME when the messages are appropriate, for instance, ERNEC%, no core available is set when the is no space to build a buffer ring. -1 EREOF$ endfile, which may be an error in some cases -2 ERBKT$ block too large, which includes the 'no room or quota exceeded' cases for DSK:. -3 ERDTE$ data error, most likely parity or checksum errors. -4 ERDER$ device error. This normally means real trouble with the device, although the real meaning is device dependent. -5 ERIMP$ improper mode for device. -6 ERQTA$ code reserved for no room or quota exceeded case. -7 ERRSD$ restricted device. Attempt to access a device that is available, and is not spooled by the user, but is restricted by the operator. -10 ERNFC$ no free IO software channels. The user program has used at least 15 out of the 16 possible. Note that IOLIB does not attempt IO on channel 0 unless forced. -11 ERUNK$ unknown error. This error can be produced on IO when no error bit was set in the status word, which may be due to e.g. write-ring missing in magtape. APPENDIX F IOLIB STANDARD ERROR IDS All the 3 character error identifications produced by IOLIB are listed here, together with their meanings. The error ids that correspond to LOOKUP/ENTER/RENAME error codes are flagged by an '*'. More details about these codes can be found in the Monitor Calls Handbook, Appendix E. Error ids flagged with 'S' are produced by the IOLIB command string reading routines. Id Description == =========== AEF * File already exists ASW S ambiguous switch name BKT block too large ($INPUT/$OUTPU) BNF * block busy CSD * subfile directory already exists DER device error ($INPUT/$OUTPU) DNA * device not available ($OPEN also) DNE * directory not empty DTE * data error, e.g. checksum or parity error ($INPUT/$OUTPU) EOF end of file ($INPUT) FBM * file being modified FNF * file not found ILC S illegal character in input string ILU * processor doesn't have 2 segment capability IMP improper IO mode for this device ($OPEN/$INPUT/$OUTPU) IOLIB STANDARD ERROR IDS Page F-2 IPG S programmer number zero or too big IPJ S project number zero or too big ISU * incorrect sequence of UUOs LVL * too many levels of SFDs NCE * can't create in directory NDV s Null device name in device specification NEC * not enough core (also $INPUT/$OUTPU) NET * not enough table space in monitor (also $OPEN if no spare DDBs in monitor) NFC no free IO channels($OPEN) NOR S number out of range NRM * no room on structure NSD * no such device (also $OPEN) NSF * not a save file POA * no room (??) PRT * protection failure QTA quota exceeded RSD restricted device ($OPEN) SLE * search list empty SNF * no directory SNS * no segment STI S switch tables built incorrectly TRN * transmission error UKW S unknown keyword in switch specification UNK unknown error code USW S unknown switch name VIL S value illegal in switch specification WDV S wild device name in device specification WLK * write-locked device IOLIB STANDARD ERROR IDS Page F-3 2DV S two device names in one file specification 2EX S two extensions in one file specification 2NM S two file names in one file specification 2PT S two path specifications in one file specification