1 Pascal-6000 Library Information 27 May 86 Pascal-6000 Library Information =============================== Dave Bianchi Larry Daasch Jim Miner Academic Computing Services and Systems | University of Minnesota Version 4.1 | May, 1986 | Differences from version 4.0 are indicated by change bars in the right | margin. An asterisk indicates deleted text. | COPYRIGHT --------- Portions of Pascal-6000 Release 4 are copyright by the University of Minnesota. It is not to be sold or distributed without the express written permission of the University of Minnesota, Academic Computing | Services and Systems. All names and references are to be left intact. | The machine-retrievable documention on the release tape is under a limited copyright. That is, you are free to copy and distribute the writeups within your organization providing that it is not done for profit and that all names and references are left intact. 1 1 Pascal-6000 Library Information 27 May 86 The PASCLIB writeup contains information on each of the procedures and packages available on the Pascal library PASCLIB. Each procedure or package may be accessed by including certain declarations in a Pascal program. These declarations may include 'CONST', 'TYPE', 'VAR', 'PROCEDURE', and 'FUNCTION' declarations. Each writeup included here gives specific instructions on how to use a particular procedure or package. Particular procedure or package names may be chosen from the following list. Chapter Page Description ------- ---- ----------- COMPLEX 1 Mathematical routines for complex numbers. CSIMAGE 7 Return control-statement image. CSORT 8 Merge sort of a chain (list) of records. CSORTS 11 Stable sort of a chain (list) of records. | DOUBLE 13 Double-precision arithmetic routines. DUMP 14 Write snapshot dump. FREAD 15 Formatted READ procedures. GENSORT 17 Generalized Quicksort. IOAIDS 23 Text Input-Output aids. MATH 24 Standard and extended mathematical functions. OPECLO 32 Explicit open and close procedures. OPTION 34 Control-statement option processor. PAGSIZ 36 Page size routines. | PRNTPLT 37 Auto-scaling plotter package for line printers. QSORT 46 In-place quicksort of real or integer array. RADIXIO 48 Alternative radix input/output procedures. RANDOM 50 Pseudorandom number generators. The following chapters describe packages that are only available at sites running the NOS 1 or NOS 2 operating systems. Chapter Page Description ------- ---- ----------- LFM 52 Local file manager routines. PFM 59 Permanent file manager routines. ROUTE 72 Route files to queues. | SBCOPY 81 Single-buffer copy of file. SYSPROC 82 Miscellaneous system procedures. TSAIDS 85 Interactive computing aids. At the University of Minnesota, the PASCLIB writeup is an "indexed writeup". This allows retrieval of selected sub-writeups or of the entire writeup. Any of the following commands may be used at the U of M. The method to print separate entries may be different at other sites if it is possible at all. WRITEUP(PASCLIB) - (print this index listing) WRITEUP(PASCLIB=INDEX) - (print this index listing) WRITEUP(PASCLIB=C) - (print the chapter C) WRITEUP(PASCLIB=C1+C2+ ... +Cn) - (print the selected chapters) WRITEUP(PASCLIB=*) - (print the entire writeup) 1 1 COMPLEX - Pascal-6000 Complex Arithmetic Routines 27 May 86 Complex Arithmetic Routines =========================== This writeup describes a package containing routines for doing complex arithmetic in Pascal-6000. A complex number is defined as a RECORD type, so you cannot return a complex number as the result of a function. Therefore, most of the routines are procedures. Included in this package are one TYPE definition, one function, and eleven procedures. The declarations for COMPLEX can be included in your program by inserting the following directive immediately after your program heading on a line by itself. (*$I'COMPLEX' COMPLEX-ARITHMETIC DECLARATIONS. *) The inclusion of COMPLEX defines the following type: TYPE COMPLEX = RECORD RE, IM : REAL END; The definition of a complex number consisting of the real part (RE) and the imaginary part (IM). Conversion from REAL to COMPLEX is done by using the procedure CMPLX which takes two REAL numbers as the real and imaginary parts of a COMPLEX number. Finding the real and imaginary parts of the COMPLEX number is done by accessing the appropriate field of the record, ie. X := A.RE for the real part, Y := A.IM for the imaginary part. Functions: (declared by (*$I'COMPLEX'*) ) CABS(A) Absolute value of A. Procedures: (declared by (*$I'COMPLEX'*) ) CADD(A,B,RESULT) Complex addition (A+B,RESULT). CCOS(A,RESULT) Complex cosine of A. CCOSH(A,RESULT) Complex hyperbolic cosine of A. CDIV(A,B,RESULT) Complex division (A/B,RESULT). CEXP(A,RESULT) Complex exponential function of A. CLN(A,RESULT) Complex natural logarithm of A. CMPLX(X,Y,RESULT) Real to complex conversion. CMUL(A,B,RESULT) Complex multiplication (A*B,RESULT). CONJG(A,RESULT) Complex conjugate of A. CSIN(A,RESULT) Complex sine of A. CSINH(A,RESULT) Complex hyperbolic sine of A. CSQRT(A,RESULT) Complex square root of A. CSUB(A,B,RESULT) Complex subtraction (A-B,RESULT). The formulas for the above routines were found in: Churchill, Ruel V., "Complex Variables and Applications", McGraw-Hill Book Company, New York, 1960. COMPLEX.1 1 COMPLEX - Pascal-6000 Complex Arithmetic Routines 27 May 86 A description of each of the routines follows in the format: NAME - Definition. ---- Pascal definition. Sample use of the routine. Domain: Possible values passed as arguments to the routine. Range: Possible results of the routine. Algorithm: Description of the algorithm used. For each description below, assume A, B, and RESULT are of type COMPLEX and X and Y are REAL variables. For the Range of each description: pi = 3.141592653589793+ CABS(A) - absolute value of A. ------- FUNCTION CABS(A : COMPLEX) : REAL; X := CABS(A) Domain: all complex numbers Range: X >= 0.0 Algorithm: X := SQRT(SQR(A.RE) + SQR(A.IM)) CADD(A,B,RESULT) - complex addition. ---------------- PROCEDURE CADD(A,B : COMPLEX; VAR RESULT : COMPLEX); CADD(A,B,RESULT) Domain: all complex numbers Range: all complex numbers Algorithm: RESULT.RE := A.RE + B.RE RESULT.IM := A.IM + B.IM COMPLEX.2 1 COMPLEX - Pascal-6000 Complex Arithmetic Routines 27 May 86 CCOS(A,RESULT) - complex cosine of A. -------------- PROCEDURE CCOS(A : COMPLEX; VAR RESULT : COMPLEX); CCOS(A,RESULT) Domain: ABS(A.RE) < 1.4E14, ABS(A.IM) < 740.3 Range: all complex numbers Algorithm: RESULT.RE := COS(A.RE) * COSH(A.IM) RESULT.IM := -SIN(A.RE) * SINH(A.IM) CCOSH(A,B,RESULT) - complex hyperbolic cosine of A. ----------------- PROCEDURE CCOSH(A : COMPLEX; VAR RESULT : COMPLEX); CCOSH(A,RESULT) Domain: ABS(A.RE) < 740.3, ABS(A.IM) < 1.4E14 Range: all complex numbers Algorithm: RESULT.RE := COS(A.IM) * COSH(A.RE) RESULT.IM := SIN(A.IM) * COSH(A.RE) CDIV(A,B,RESULT) - complex division. ---------------- PROCEDURE CDIV(A,B : COMPLEX; VAR RESULT : COMPLEX); CDIV(A,B,RESULT) Domain: B <> (0.0, 0.0) Range: all complex numbers Algorithm: RESULT.RE := (A.RE * B.RE + A.IM * B.IM) / (SQR(CABS(B))) RESULT.IM := (A.IM * B.RE - A.RE * B.IM) / (SQR(CABS(B))) COMPLEX.3 1 COMPLEX - Pascal-6000 Complex Arithmetic Routines 27 May 86 CEXP(A,RESULT) - complex exponential. -------------- PROCEDURE CEXP(A : COMPLEX; VAR RESULT : COMPLEX); CEXP(A,RESULT) Domain: A.RE < 740.3, ABS(A.IM) < 1.4E14 Range: all complex numbers Algorithm: RESULT.RE := EXP(A.RE) * COS(A.IM) RESULT.IM := EXP(A.RE) * SIN(A.IM) CLN(A,RESULT) - complex natural logarithm of A. ------------- PROCEDURE CLN(A : COMPLEX; VAR RESULT : COMPLEX); CLN(A,RESULT) Domain: A <> (0.0, 0.0) Range: -pi < angle of CLN(A) <= pi Algorithm: RESULT.RE := LN(CABS(A)) RESULT.IM := ARCTAN(A.IM / A.RE) CMPLX(X,Y,RESULT) - type conversion from real to complex. ----------------- PROCEDURE CMPLX(X,Y : REAL; VAR RESULT : COMPLEX); CMPLX(X,Y,RESULT) Domain: all reals Range: all complex numbers Algorithm: RESULT.RE := X RESULT.IM := Y COMPLEX.4 1 COMPLEX - Pascal-6000 Complex Arithmetic Routines 27 May 86 CMUL(A,B,RESULT) - complex multiplication. ---------------- PROCEDURE CMUL(A,B : COMPLEX; VAR RESULT : COMPLEX); CMUL(A,B,RESULT) Domain: all complex numbers Range: all complex numbers Algorithm: RESULT.RE := A.RE * B.RE - A.IM * B.IM RESULT.IM := A.IM * B.RE + A.RE * B.IM CONJG(A,RESULT) - complex conjugate of A. --------------- PROCEDURE CONJG(A : COMPLEX; VAR RESULT : COMPLEX); CONJG(A,RESULT) Domain: all complex numbers Range: all complex numbers Algorithm: RESULT.RE := A.RE RESULT.IM := - A.IM CSIN(A,RESULT) - complex sine of A. -------------- PROCEDURE CSIN(A : COMPLEX; VAR RESULT : COMPLEX); CSIN(A,RESULT) Domain: ABS(A.RE) < 1.4E14, ABS(A.IM) < 740.3 Range: all complex numbers Algorithm: RESULT.RE := SIN(A.RE) * COSH(A.IM) RESULT.IM := COS(A.RE) * SINH(A.IM) COMPLEX.5 1 COMPLEX - Pascal-6000 Complex Arithmetic Routines 27 May 86 CSINH(A,RESULT) - complex hyperbolic sine of A. --------------- PROCEDURE CSINH(A : COMPLEX; VAR RESULT : COMPLEX); CSINH(A,RESULT) Domain: ABS(A.RE) < 740.3, ABS(A.IM) < 1.4E14 Range: all complex numbers Algorithm: RESULT.RE := COS(A.IM) * SINH(A.RE) RESULT.IM := SIN(A.IM) * COSH(A.RE) CSQRT(A,RESULT) - complex square root of A. --------------- PROCEDURE CSQRT(A : COMPLEX; VAR RESULT : COMPLEX); CSQRT(A,RESULT) Domain: A <> (0.0, 0.0) Range: -pi/2 < angle of CSQRT(A) <= pi/2 Algorithm: RESULT.RE := SQRT(CABS(A)) * COS(ARCTAN(A.IM / A.RE) / 2) RESULT.IM := SQRT(CABS(A)) * SIN(ARCTAN(A.IM / A.RE) / 2) CSUB(A,B,RESULT) - complex subtraction. ---------------- PROCEDURE CSUB(A,B : COMPLEX; VAR RESULT : COMPLEX); CSUB(A,B,RESULT) Domain: all complex numbers Range: all complex numbers Algorithm: RESULT.RE := A.RE - B.RE RESULT.IM := A.IM - B.IM COMPLEX.6 VF::RM 1 CSIMAGE - Return Control Statement Image 27 May 86 Return Control Statement Image ============================== CSIMAGE is a procedure designed to allow you to acquire a copy of the control statement which is currently executing. In most cases this is something like: LGO( some parameters ) CSIMAGE returns a space-filled image of that control statement to a variable in your program. To use CSIMAGE, you need to insert the following line after the program heading. (*$I'CSIMAGE' CSIMAGE DECLARATIONS. *) This INCLUDE directive defines one constant and one type, and declares one procedure. The constant and type are defined by the INCLUDE package as: CONST CSIMAGELENGTH = 80; TYPE CSIMAGETYPE = PACKED ARRAY [1 .. CSIMAGELENGTH] OF CHAR; Somewhere in your program, you must declare a variable of type CSIMAGETYPE. CSIMAGE itself is declared by the INCLUDE package in the following way: PROCEDURE CSIMAGE(VAR CS : CSIMAGETYPE); CSIMAGE uses an 'X' compiler option setting of 'X1'. The INCLUDE package provides the correct setting for the declaration. CSIMAGE.7 1 CSORT - A Merge Sort for Chained Records 27 May 86 Merge Sort for Chained Records ============================== CSORT performs a sort of a chain (list) of records in primary storage. The chain may be of arbitrary length. The method used is a modified merge sort algorithm designed and developed by Coen Bron, and described in his technical report: "On a Practical Sorting Algorithm," T. H. Twente, Enschede, Netherlands, 1980. (Also see the references below.) CSORT is able to sort a sequence of singly-linked records with a space overhead comparable to Quicksort and similar array-sorting algorithms. The convenience of CSORT is that you don't have to convert the linked structure to an array to sort your data. CSORT assumes that you supply a record type containing the field "NEXT" which is a pointer reference to the next record in a sequence. The ordering relation used for sorting must be in the form of a function that you must write and pass as a parameter to CSORT. Declarations ------------ CSORT requires you to declare the type identifier "PSORTRECORD" as a pointer to the type of record to be sorted. The record must be singly linked through the field "NEXT". (Unfortunately, the rules of Pascal do not allow a redefinition facility for record-field identifiers!) The third requirement is that you write a Boolean function which compares one or more key fields in the record for sorting purposes; this is the "ordering relation." Thus CSORT allows you to sort on several keys simultaneously. (For further information about sorting on several keys, see the description of GENSORT.) CSORT resides in the Pascal library and may be declared by inserting the Pascal-6000 text inclusion directive: (*$I'CSORT' CHAINSORT PACKAGE. *) after the declaration of "PSORTRECORD". This directive includes the text of the CSORT package which declares several procedures. The procedure CHAINSORT is declared as: PROCEDURE CHAINSORT (VAR HEAD : PSORTRECORD; FUNCTION PRECEDES(LEFT, RIGHT : PSORTRECORD) : BOOLEAN); HEAD The pointer to the first record in the chain. PRECEDES A function which returns TRUE if LEFT should precede RIGHT in the sorted chain of records and returns FALSE otherwise. CSORT.8 1 CSORT - A Merge Sort for Chained Records 27 May 86 In summary, to use CSORT, you must declare the type PSORTRECORD, include the package with the compiler directive given above, and write one or more functions which will eventually be passed to the PRECEDES parameter of CSORT. See the examples below. Example ------- The program below reads an arbitrary number of ten character strings, builds a chain of records out of them, and writes the strings before and after sorting. PROGRAM TESTCHAINSORT(INPUT,OUTPUT); TYPE PSORTRECORD = ^SORTRECORD; SORTRECORD = RECORD NAME : PACKED ARRAY[1..10] OF CHAR; NEXT : PSORTRECORD END; (*$I'CSORT' INCLUDE CHAINSORT PACKAGE *) VAR P, HEAD : PSORTRECORD; I : INTEGER; FUNCTION PRECEDES(LEFT,RIGHT : PSORTRECORD) : BOOLEAN; BEGIN PRECEDES := LEFT^.NAME < RIGHT^.NAME END; PROCEDURE WRITECHAIN; BEGIN WRITELN; P := HEAD; WHILE P <> NIL DO BEGIN WRITELN(P^.NAME); P := P^.NEXT END; WRITELN END (* WRITECHAIN *); BEGIN (* TESTCHAINSORT *) NEW(HEAD); P := HEAD; WHILE NOT EOF(INPUT) DO (* READ A NAME *) BEGIN NEW(P^.NEXT); P := P^.NEXT; FOR I := 1 TO 10 DO BEGIN P^.NAME[I] := INPUT^; IF NOT EOLN(INPUT) THEN GET(INPUT); END; READLN END; P^.NEXT := NIL; IF HEAD^.NEXT <> NIL THEN HEAD := HEAD^.NEXT; WRITELN('UNSORTED CHAIN:'); WRITECHAIN; CHAINSORT(HEAD,PRECEDES); WRITELN('SORTED CHAIN:'); WRITECHAIN END (* TESTCHAINSORT *). CSORT.9 1 CSORT - A Merge Sort for Chained Records 27 May 86 Performance Measures ----------- -------- For purposes of comparision and evaluation, CSORT was timed against Quicksort on both the PDP-11/45 and the CDC Cyber 172. Given a linked list of records containing random integers, sort them from low to high. In order to run Quicksort, the list had to be converted to an array, sorted, and then converted back. On the PDP-11/45, Chainsort was found to be five times faster than Quicksort in sorting 1000 records containing random integers. On the CDC Cyber 172, Chainsort was run against a pure Quicksort and GENSORT (a modified Quicksort). Sorting times for the CDC Cyber 172: Routine Sorting Time ------- ------- ---- CHAINSORT 1.287 QUICKSORT 1.465 GENSORT 1.136 References ---------- 1. Bron, Coen, Algorithm 426, "Merge Sort Algorithm M1", Comm. ACM 15,5 (May 1972) Pg. 358. 2. Bron, Coen, "Remark on Algorithm 426," Comm. ACM 17,12 (December 1974) Pg. 706. CSORT.10 1 CSORTS - A Stable Merge Sort for Chained Records 27 May 86 Stable Merge Sort for Chained Records ===================================== CSORTS is equivalent to the package CSORT, with the following exceptions. (1) You access CSORTS by using the following include directive: (*$I'CSORTS' STABLE CHAINSORT PACKAGE *) (2) The procedure CHAINSORT defined by the package CSORTS performs a "stable" sort. This means that when two records have the same key value, one will precede the other in the sorted list if and only if it preceded the other in the original list. A sort must be stable if it is to be used to sort on multiple keys by sorting once on each key. An unstable sort cannot be used this way. Let's consider an example. Suppose each record in the list has two data fields (in addition to the NEXT field) named A and B. and the list is pointed to by the variable LIST. We might have the following declarations. TYPE PSORTRECORD = ^ SORTRECORD; SORTRECORD = RECORD NEXT: PSORTRECORD; A: INTEGER; B: INTEGER; END; VAR LIST: PSORTRECORD; Suppose also that we wish to have the records sorted with increasing values of A, and within each value of A to be sorted by decreasing values of B. There are two basic methods for doing this. First, we can sort just once with a PRECEDES function that compares both keys. The following declaration and statement might be used. FUNCTION PRECEDESAB(LEFT,RIGHT: PSORTRECORD): BOOLEAN; BEGIN PRECEDESAB := (LEFT^.A < RIGHT^.A) OR ((LEFT^.A = RIGHT^.A) AND (LEFT^.B < RIGHT^.B)) END; ... CHAINSORT(LIST,PRECEDESAB) CSORTS.11 1 CSORTS - A Stable Merge Sort for Chained Records 27 May 86 As a second method, we could use CSORTS first to sort the list into decreasing order of B, and then sort again into increasing order of A. Then we might use the following declarations and statements. FUNCTION PRECEDESA(LEFT,RIGHT: PSORTRECORD): BOOLEAN; BEGIN PRECEDESA := LEFT^.A < RIGHT^.A (* INCREASING SORT *) END; FUNCTION PRECEDESB(LEFT,RIGHT: PSORTRECORD): BOOLEAN; BEGIN PRECEDESB := LEFT^.B > RIGHT^.B (* DECREASING SORT *) END; ... CHAINSORT(LIST,PRECEDESB); CHAINSORT(LIST,PRECEDESA) Which of these two approaches is more appropriate depends on the problem being solved. (3) CSORTS uses a "natural" merge sort, which takes advantage of any ordered sequences in the original list. Thus, CSORTS should take less time to sort a nearly-ordered list than CSORT. On the other hand, the machine code for CSORTS is slightly larger than that for CSORT. CSORTS.12 1 DOUBLE - Pascal-6000 Double Precision Arithmetic Routines 27 May 86 Double Precision Arithmetic Routines ==================================== DOUBLE is a package of routines for doing double-precision arithmetic in Pascal-6000. DOUBLE includes a TYPE definition, five procedures, and one function. The declarations for DOUBLE may be included in your program by inserting the following compiler directive immediately after your program heading. (*$I'DOUBLE' DOUBLE-PRECISION DECLARATIONS. *) DOUBLE defines the following symbols: TYPE DOUBLE = RECORD UPPER : REAL; LOWER : REAL END; The type of a double precision number consisting of the most significant part (UPPER) and the less significant part (LOWER). PROCEDURE DBLE(VAR RESULT : DOUBLE; A : REAL); A type transfer routine that sets RESULT to a double precision value equal to A. An equivalent operation is RESULT.UPPER := A; RESULT.LOWER := 0.0 PROCEDURE DADD(VAR RESULT : DOUBLE; A,B : DOUBLE); Performs the operation RESULT := A + B in double precision. PROCEDURE DDIV(VAR RESULT : DOUBLE; A,B : DOUBLE); Performs the operation RESULT := A / B in double precision. PROCEDURE DMUL(VAR RESULT : DOUBLE; A,B : DOUBLE); Performs the operation RESULT := A * B in double precision. PROCEDURE DSUB(VAR RESULT : DOUBLE; A,B : DOUBLE); Performs the operation RESULT := A - B in double precision. FUNCTION SNGL(A : DOUBLE) : REAL; Returns the single precision value which is closest to A. This is done by rounding the upper precision part of A by the next most significant bit in the lower precision part. An equivalent operation is A.UPPER + A.LOWER DOUBLE.13 1 DUMP - Pascal-6000 Snapshot Dump 27 May 86 Snapshot Dump ============= DUMP is a snapshot-dump procedure for Pascal programs. The dump is formatted like the post-mortem dump, and in fact, the same procedure is used. The snapshot dump may be written to any text file, an informative message is included, and you may specify how many levels of procedure calls are to be printed. To use this procedure, you must insert the following line after the program heading. (*$I'DUMP' DUMP PROCEDURE DECLARATION. *) This include package declares the DUMP procedure as follows: PROCEDURE DUMP(VAR F : TEXT; MSG : PACKED ARRAY [LO .. HI: INTEGER] OF CHAR; NLEV : INTEGER); The DUMP procedure requires the 'X' compiler option to be set to at least 'X3'. The INCLUDE package sets 'X3' for the declaration of DUMP. DUMP has three parameters: F The file to receive the snapshot dump. You will most likely want to use OUTPUT. MSG A character message which you may use to identify the snapshot dump. If you are using batch, you should leave the first character blank since it will be printed in the first column. NLEV The number of levels of procedure calls to be printed. Passing 1 will print only the current procedure, and passing 0 will print only the dump heading, which tells you where the dump routine was called. If you want all levels to be printed, the easiest way to do this is to pass MAXINT. A sample call to the DUMP routine: DUMP(OUTPUT,' SCANNING DATA FILE.',1) DUMP.14 1 FREAD - Pascal-6000 Formatted Read Procedures. 27 May 86 Formatted Read Procedures ========================= The procedures described in this section are designed to allow the processing of 'fixed-format' data or text files by Pascal applications programs. Such data files are characterized by the absence of blanks as delimiters between adjacent data fields and by the use of blank for the digit zero. In particular, these procedures have the ability to read numeric fields which are normally read (or written) by FORTRAN programs. The package consists of the four procedures listed in the following table. Name Description ---- ----------- FREADCHAR Read one character. FREADINTEGER Read integer. FREADREAL Read real, with or without decimal point or exponent. FSKIP Skip a given number of characters. Each procedure reads one field whose size is given by the formal parameter 'WIDTH'. The field starts at the current position of the file at the time of the procedure call. The procedures always leave the file positioned at the character immediately following the field which was read or at the end of line. In all cases, fields which extend beyond the end of line will be treated as though the line is extended indefinitely with blanks. None of the procedures described here will read past the end of a line. However, as with the normal Pascal read procedure, reading a new line is made possible by using the predefined procedure READLN(f). Declarations ------------ The four procedures must be declared as external to your Pascal program. A declaration package is provided in the Pascal library, and may be included in your Pascal program by inserting the following compiler directive immediately after your program heading. (*$I'FREAD' FORMATTED-READ DECLARATIONS. *) All procedures assume that the 'X' compiler option is set to 'X4'. This is the default value of the X-option, and to be sure, the FREAD declaration package sets 'X4' for itself, and then restores to the old value. PROCEDURE FREADCHAR(VAR F : TEXT; VAR RESULT : CHAR); Reads one character from file F into the character variable RESULT. FREAD.15 1 FREAD - Pascal-6000 Formatted Read Procedures. 27 May 86 PROCEDURE FREADINTEGER(VAR F : TEXT; VAR RESULT : INTEGER; WIDTH : INTEGER); Reads an integer number from file F into the integer variable RESULT. WIDTH is the field width for the integer number. PROCEDURE FREADREAL(VAR F : TEXT; VAR RESULT : REAL; WIDTH, FRACWIDTH : INTEGER); Reads a real number from file F into the real variable RESULT. WIDTH is the total field width for the real number. FRACWIDTH is the assumed width of the fractional part of the real number, and is used only if no explicit decimal point appears in the real number. PROCEDURE FSKIP(VAR F : TEXT; WIDTH : INTEGER); Skips a certain number of characters on file F. WIDTH specifies the number of characters to skip. FREAD.16 1 GENSORT - Generalized Quicksort 27 May 86 Generalized Quicksort ===================== GENSORT performs an in-core sort of an arbitrary length data array. The method used is a modified Quicksort algorithm designed by Richard C. Singleton [3]. Quicksort is generally considered to be a superior, non-stable, in-core sorting algorithm. GENSORT also takes advantage of several programming suggestions from Steve Legenhausen [1] and Andy Mickel [2]. GENSORT is a generalized version of the Quicksort algorithm that allows the following possibilities: 1. Arrays of any length can be sorted because GENSORT uses conformant array parameters [5]. 2. The elements of the array to be sorted can be of any type. 3. Arrays can be sorted into non-increasing order, non-decreas- ing order, or any other user-defined order. 4. Arrays can be sorted on any key in the data record, or simultaneously on several keys. 5. A single data array can be sorted on a certain key (or keys) and later re-sorted on another key (or keys). A stable sorting algorithm preserves the original ordering of records that have equal keys. This allows sorting on several keys by sorting on the least significant key first, resorting on intermediate keys, and finally resorting on the most significant key. This method of sorting on several keys is not possible with GENSORT because Quicksort is a non-stable algorithm and therefore does not preserve the original ordering of records with equal keys. As an alternative to sorting repeatedly on several keys, GENSORT allows you to sort simultaneously on several keys. Declarations ------------ GENSORT requires you to declare the type identifier "SORTRECORD" to be the type of data records to be sorted. The array to be sorted must be indexed by some subrange of type INTEGER, and its element type must be SORTRECORD. In addition, you must write one or more functions which have two parameters of type SORTRECORD and return a boolean value which specifies whether the first parameter must precede the second in | the sorted array. Each function represents the key (or keys) and order to be used in a call to GENSORT. GENSORT.17 1 GENSORT - Generalized Quicksort 27 May 86 The GENSORT package itself is declared by inserting the text inclusion directive [4] (*$I'GENSORT' GENSORT PACKAGE. *) after the declaration of the type SORTRECORD. This directive includes the text of the GENSORT package which declares a single procedure. The procedure GENSORT is declared as PROCEDURE GENSORT (VAR A: ARRAY [LO .. HI: INTEGER] OF SORTRECORD; FIRST,LAST: INTEGER; FUNCTION SEQUENCE(VAR R1,R2: SORTRECORD): BOOLEAN); A The array to be sorted. FIRST The position in A of the first element to be sorted. LAST The position in A of the last element to be sorted. SEQUENCE A function which returns TRUE if R1 must precede R2 in | the sorted array and returns FALSE otherwise. In summary, to use GENSORT, you must declare type SORTRECORD, include the package itself with the compiler directive given above, and write one or more functions which will eventually be passed to the SEQUENCE parameter of GENSORT. See the examples below. NOTE | ---- | | The function call SEQUENCE(A,B) returns the truth of either the | statement "A is less than B" for an ascending sort, or else the | statement "A is greater than B" for a descending sort. GENSORT will | halt with the message | | FUNCTION PASSED TO GENSORT IS INVALID. | | if SEQUENCE(A,B) returns true when A = B. | GENSORT.18 1 GENSORT - Generalized Quicksort 27 May 86 Example 1 --------- The following example program sorts into non-decreasing order an array of real numbers that are read from file INPUT. PROGRAM SIMPLESORT(INPUT, OUTPUT); CONST MAX = 1000 (* MAXIMUM NUMBER OF DATA ELEMENTS *); TYPE SORTRECORD = REAL; (*$I'GENSORT' INCLUDE GENSORT PACKAGE. *) VAR DATA : ARRAY[1..MAX] OF SORTRECORD; COUNT: INTEGER; X : REAL; FUNCTION SEQ(VAR R1,R2: SORTRECORD): BOOLEAN; BEGIN SEQ := R1 < R2 END (* SEQ *); BEGIN (* SIMPLESORT *) COUNT := 0; READ(X); WHILE NOT EOF(INPUT) DO BEGIN COUNT := COUNT + 1; IF COUNT > MAX THEN HALT(' TOO MANY NUMBERS.'); DATA[COUNT] := X; READ(X) END; GENSORT(DATA,1,COUNT,SEQ); FOR COUNT := 1 TO COUNT DO WRITELN(DATA[COUNT]) END (* SIMPLESORT *). GENSORT.19 1 GENSORT - Generalized Quicksort 27 May 86 Example 2 --------- The following program fragment shows how you might set up type declarations and functions to sort student records on several keys. TYPE NAMETYPE = RECORD FIRST, MIDDLE, LAST: ALFA END; SORTRECORD = RECORD NAME : NAMETYPE (* STUDENT NAME *); IDNUMBER: INTEGER (* STUDENT ID NUMBER *); GPA : REAL (* GRADE-POINT AVERAGE *); CREDITS : INTEGER (* TOTAL CREDITS EARNED *) END; (*$I'GENSORT' INCLUDE GENSORT PACKAGE. *) FUNCTION NAMESORT(VAR R1,R2: SORTRECORD): BOOLEAN; BEGIN IF R1.NAME.LAST = R2.NAME.LAST THEN IF R1.NAME.FIRST = R2.NAME.FIRST THEN NAMESORT := R1.NAME.MIDDLE < R2.NAME.MIDDLE ELSE NAMESORT := R1.NAME.FIRST < R2.NAME.FIRST ELSE NAMESORT := R1.NAME.LAST < R2.NAME.LAST END (* NAMESORT *); FUNCTION IDSORT(VAR R1,R2: SORTRECORD): BOOLEAN; BEGIN IDSORT := R1.IDNUMBER < R2.IDNUMBER END (* IDSORT *); FUNCTION GPASORT(VAR R1,R2: SORTRECORD): BOOLEAN; BEGIN IF R1.GPA = R2.GPA THEN GPASORT := NAMESORT(R1,R2) ELSE GPASORT := R1.GPA < R2.GPA END (* GPASORT *); By defining several sorting functions, the student records can be sorted by name, ID number, or GPA simply by passing the appropriate function to the SEQUENCE parameter of GENSORT. The NAMESORT function checks all 3 fields of the student name to achieve correct ordering in the case that two students have the same last names or same last and first names. The GPASORT function references NAMESORT in order that students with the same GPA will be sorted into alphabetical order by name. GENSORT.20 1 GENSORT - Generalized Quicksort 27 May 86 Timing ------ For purposes of comparison and evaluation, GENSORT was timed against QSORT (which is also available in the Pascal library). An array of n real numbers was sorted after initializing it to the following values: 1. random values between 0.0 and 1.0, 2. natural order (1, 2, ..., n), 3. reverse order (n, n-1, ..., 1), 4. sorted by halves (2, 4, ..., n, 1, 3, ..., n-1), and 5. constant value (0, 0, ..., 0). Sorting times are given in seconds, and are based on the average of five trials. In all cases, GENSORT takes 3 to 4 times longer than QSORT (which is also uses Quicksort). QSORT, however, is only able to sort arrays of real or integer numbers. From the timing information you can see that if you want to sort real or integer numbers, you should use QSORT instead of GENSORT. For sorting non-trivial data, GENSORT should be used. Sorting times for GENSORT and QSORT on the CDC Cyber 172: Original order and Routine number of items GENSORT QSORT ------------------ -------------------- Random values 500 0.486 0.142 1000 1.084 0.319 Natural order 500 0.384 0.132 1000 0.862 0.296 Reverse order 500 0.382 0.131 1000 0.860 0.295 Sorted by halves 500 0.880 0.230 1000 2.122 0.540 Constant value 500 0.378 0.132 1000 0.863 0.290 GENSORT.21 1 GENSORT - Generalized Quicksort 27 May 86 References ---------- 1. Legenhausen, S., Quicksort: A Tutorial, University of Minnesota Computer Center Technical Report 73006, July 1973. 2. Mickel, A., Software Tool 2 (see PROCEDURE SORT), Pascal News 12 (June 1978), pp. 23-32. 3. Singleton, R. C., Algorithm 347, Comm. ACM 12,3 (March 1969), pp. 185-187. 4. Bianchi, D. and Miner, J., Pascal-6000 Release 4, September 1983. 5. "Specification for Computer Programming Language Pascal", BS 6192: 1982, British Standards Institution. GENSORT.22 1 IOAIDS - Pascal-6000 Text Input-Output Aids 27 May 86 Text Input-Output Aids ====================== Doing text input-output in Pascal can be somewhat tedious, since there are no built-in procedures for doing things such as reading character strings or skipping blanks. IOAIDS is a package of procedures designed to fill some of those deficiencies. For discussions of text and interactive input-output, see the chapters TEXTIO and INTERIO in the Pascal writeup. For a discussion of formatted input, see the chapter FREAD in this writeup. Declarations ------------ IOAIDS is a source-library entry in the Pascal library PASCLIB, and can be included in your program by entering the following compiler directive immediately after your program heading. (*$I'IOAIDS' TEXT INPUT-OUTPUT AIDS. *) IOAIDS defines one type, three functions, and two procedures: TYPE SEGTEXT = SEGMENTED TEXT; FUNCTION EOLNS(VAR F : TEXT) : BOOLEAN; Skip blanks and then test for the end of line. FUNCTION EOFS(VAR F : TEXT) : BOOLEAN; Skip blanks and then test for the end of file. FUNCTION EOSS(VAR F : SEGTEXT) : BOOLEAN; Skip blanks and then test for the end of segment. PROCEDURE READSTRING(VAR F : TEXT; VAR S : PACKED ARRAY [LO..HI:INTEGER] OF CHAR; LEN : INTEGER); Read a character string into S from file F. If LEN is greater than or equal to zero, that many characters are read into the string, and the remainder of the string is blank filled. If LEN exceeds the length of S, characters past the end of S are skipped. This is the strictly formatted READSTRING. If LEN is less than zero, READSTRING skips blanks, and then reads characters into S until a blank is read. The remainder of S is blank filled. This is the unformatted READSTRING. PROCEDURE SKIPBLANKS(VAR F : TEXT); Skip characters until a non-blank character or end of file is reached. IOAIDS.23 1 MATH - Pascal-6000 Mathematical Functions 27 May 86 Mathematical Functions ====================== This writeup describes mathematical functions available to users of Pascal-6000. The functions included are the simple trigonometric, logarithmic, and exponential functions most often needed for numerical applications. Six of these functions are available with any Standard implementation of Pascal (see below). Efficient implementations of these and some additional (extended) functions were adapted for the Pascal-6000 library from the MNF FORTRAN library. The original algorithms were developed and copyrighted by Professor K. Frankowski, University of Minnesota, 1970, and were coded and optimized by Lawrence A. Liddiard, University Computer Center. There are two classes of math functions available - standard and extended. Standard functions are predeclared, and extended functions are not. An INCLUDE package for the extended math functions is available. Insert the following line into your program right after the program heading and on a line by itself. (*$I'MATH' EXTENDED MATH DECLARATIONS. *) Standard functions: (no declaration) ARCTAN(X) Inverse tangent of X. COS(X) Cosine of X. EXP(X) Exponential function of X. LN(X) Natural logarithm of X. SIN(X) Sine of X. SQRT(X) Square root of X. Extended functions: (declared by (*$I'MATH' *) ) ARCCOS(X) Inverse cosine of X. ARCSIN(X) Inverse sine of X. ARCTAN2(Y,X) Inverse tangent of Y/X. COSH(X) Hyperbolic cosine of X. LOG(B,X) Logarithm base B of X. LOG10(X) Common logarithm of X. POWER(X,Y) Real to real power function. POWERI(X,I) Real to integer power function. SINH(X) Hyperbolic sine of X. TAN(X) Tangent of X. TANH(X) Hyperbolic tangent of X. Two constants are defined by the MATH include package: CONST PI = 3.141592653589793; E = 2.718281828459045; MATH.24 1 MATH - Pascal-6000 Mathematical Functions 27 May 86 A description of each of the functions follows in the format: NAME - definition of the function. ---- equivalent expression in terms of other functions. Pascal definition. Sample use of the function. Domain: possible values passed as arguments to the function. Range: possible results of the function. Error messages: possible error messages printed to OUTPUT and in the dayfile. Assume X, Y, Z, and B are REAL variables and I is an INTEGER variable. pi = 3.141592653589793+ e = 2.718281828459045+ ** denotes exponentiation. Standard Functions -------- --------- ARCTAN(X) - inverse tangent of X. --------- FUNCTION ARCTAN(X:REAL) : REAL; Z := ARCTAN(X) Domain: all reals Range: ABS(Z) <= pi/2 radians Error messages: INDEFINITE ARGUMENT OF ARCTAN. MATH.25 1 MATH - Pascal-6000 Mathematical Functions 27 May 86 COS(X) - cosine of X. ------ FUNCTION COS(X:REAL) : REAL; Z := COS(X) Domain: ABS(X) < 2**47 radians Range: ABS(Z) <= 1 Error messages: INFINITE OR INDEF ARGUMENT OF SIN/COS. ABS(ARG) 2**47 OR MORE IN SIN/COS. EXP(X) - exponential function of X (e**X). ------ [ POWER(e,X) ] FUNCTION EXP(X:REAL) : REAL; Z := EXP(X) Domain: ABS(X) <= 740.3 Range: Z > 0 Error messages: INFINITE OR INDEF ARGUMENT OF EXP. ABS(ARG) GREATER THAN 740.3 IN EXP. LN(X) - natural logarithm of X. ----- [ LOG(e,X) ] FUNCTION LN(X:REAL) : REAL; Z := LN(X) Domain: X > 0 Range: all reals Error messages: INFINITE OR INDEF ARGUMENT OF LN. NEGATIVE OR ZERO ARGUMENT OF LN. MATH.26 1 MATH - Pascal-6000 Mathematical Functions 27 May 86 SIN(X) - sine of X. ------ FUNCTION SIN(X:REAL) : REAL; Z := SIN(X) Domain: ABS(X) < 2**47 radians Range: ABS(Z) <= 1 Error messages: INFINITE OR INDEF ARGUMENT OF SIN/COS. ABS(ARG) 2**47 OR MORE IN SIN/COS. SQRT(X) - square root of X. ------- [ POWER(X,0.5) ] FUNCTION SQRT(X:REAL) : REAL; Z := SQRT(X) Domain: X >= 0 Range: Z >= 0 Error messages: INFINITE OR INDEF ARGUMENT OF SQRT. NEGATIVE ARGUMENT OF SQRT. Extended Functions -------- --------- ARCCOS(X) - inverse cosine of X. --------- FUNCTION ARCCOS(X:REAL) : REAL; Z := ARCCOS(X) Domain: ABS(X) <= 1 Range: 0 <= Z <= pi radians Error messages: INFINITE OR INDEF ARGUMENT OF ARCCOS. ABS(ARG) GREATER THAN 1.0 IN ARCCOS. MATH.27 1 MATH - Pascal-6000 Mathematical Functions 27 May 86 ARCSIN(X) - inverse sine of X. --------- FUNCTION ARCSIN(X:REAL) : REAL; Z := ARCSIN(X) Domain: ABS(X) <= 1 Range: ABS(Z) <= pi/2 radians Error messages: INFINITE OR INDEF ARGUMENT OF ARCSIN. ABS(ARG) GREATER THAN 1.0 IN ARCSIN. ARCTAN2(Y,X) - inverse tangent of Y/X. ------------ FUNCTION ARCTAN2(Y,X:REAL) : REAL; Z := ARCTAN2(Y,X) Domain: all reals except X=Y=0 Range: ABS(Z) <= pi radians Error messages: INFINITE OR INDEF ARGUMENT OF ARCTAN2. BOTH ARGUMENTS OF ARCTAN2 ARE ZERO. COSH(X) - hyperbolic cosine of X. ------- [ (EXP(X) + EXP(-X)) / 2 ] FUNCTION COSH(X:REAL) : REAL; Z := COSH(X) Domain: ABS(X) <= 740.3 Range: Z >= 1 Error messages: INFINITE OF INDEF ARGUMENT OF COSH. ABS(ARG) GREATER THAN 740.3 IN COSH. MATH.28 1 MATH - Pascal-6000 Mathematical Functions 27 May 86 LOG(B,X) - logarithm base B of X. -------- [ LN(X) / LN(B) ] FUNCTION LOG(B,X:REAL) : REAL; Z := LOG(B,X) Domain: X > 0 Range: all reals Warning: LOG(B,X) is actually programmed as LN(X)/LN(B). This means that any error messages given will be those for the LN function and may not always be appropriate. LOG10(X) - common logarithm of X. -------- [ LOG(10,X) ] FUNCTION LOG10(X:REAL) : REAL; Z := LOG10(X) Domain: X > 0 Range: all reals Error messages: INFINITE OR INDEF ARGUMENT OF LOG10. NEGATIVE OR ZERO ARGUMENT OF LOG10. POWER(X,Y) - real to real power function (X**Y). ---------- [ EXP(LN(X) * Y) ] FUNCTION POWER(X,Y:REAL) : REAL; Z := POWER(X,Y) Domain: X > 0 with all real Y X = 0 with Y > 0 X**Y <= maximum real Range: Z >= 0 Error messages: INFINITE OR INDEF ARGUMENT OF POWER. BASE ARGUMENT OF POWER IS NEGATIVE. ZERO BASE WITH ZERO OR NEG. EXPONENT IN POWER. ARGUMENTS OF POWER TOO LARGE. MATH.29 1 MATH - Pascal-6000 Mathematical Functions 27 May 86 POWERI(X,I) - real to integer power power function (X**I). ----------- [ EXP(LN(X) * I) ] FUNCTION POWERI(X:REAL; I:INTEGER) : REAL; Z := POWERI(X,I) Domain: X <> 0 with all integer I X = 0 with I > 0 X**I <= maximum real Range: all reals Error messages: INFINITE OR INDEF ARGUMENT OF POWERI. ZERO BASE WITH ZERO OR NEG. EXPONENT IN POWERI. ARGUMENT TOO LARGE FOR POWERI. SINH(X) - hyperbolic sine of X. ------- [ (EXP(X) - EXP(-X)) / 2 ] FUNCTION SINH(X:REAL) : REAL; Z := SINH(X) Domain: ABS(X) <= 740.3 Range: all reals Error messages: INFINITE OR INDEF ARGUMENT OF SINH. ABS(ARG) GREATER THAN 740.3 IN SINH. TAN(X) - tangent of x. ------ [ SIN(X) / COS(X) ] FUNCTION TAN(X:REAL) : REAL; Z := TAN(X) Domain: abs(x) < 2**47 radians Range: all reals Error messages: INFINITE OR INDEF ARGUMENT OF TAN. ABS(ARG) 2**47 OR MORE IN TAN. MATH.30 1 MATH - Pascal-6000 Mathematical Functions 27 May 86 TANH(X) - hyperbolic tangent of X. ------- [ SINH(X) / COSH(X) ] FUNCTION TANH(X:REAL) : REAL; Z := TANH(X) Domain: all reals Range: ABS(Z) < 1 Error messages: INFINITE OR INDEF ARGUMENT OF TANH. MATH.31 1 OPECLO - Pascal-6000 Explicit Open and Close Routines. 27 May 86 Explicit Open and Close Routines ================================ OPECLO is a package of routines which allow you to explicitly open and close files in the middle of a Pascal program. The external (actual) file name can be changed. Internal (local) files can be changed into external files and external files can be changed into internal scratch files. Files can be opened to read or write from the current position on the file. The actual file name of a Pascal file can be retrieved and assigned to an ALFA variable. You might use the OPECLO package to read a file name from INPUT, open it, and then read from it, or you might want to determine at run-time the actual file name of an external file. The OPECLO package is made up of three routines which are described below. The description of each routine includes the declaration which must be typed into your program before calling the routine. In the descriptions, 'filetypename' represents the type name for the files you wish to pass to the routines. This name will most likely be 'TEXT', but any file type may be used. These routines should be declared with the compiler 'X' option set to at least 'X3'. Since the default is 'X4', you do not need to worry about this unless you have changed the option setting within your program. PROCEDURE FILENAME(VAR F : filetypename; VAR N : ALFA); EXTERN; Sets the ALFA variable N to the actual file name of the external or internal file F. Internal files always have a file name of the form 'SCRn' where 'n' is a decimal integer number between 1 and 9999. PROCEDURE CLOSE(VAR F : filetypename); EXTERN; Closes the file F. If F is an external file and has been written on, the input-output buffer is flushed. If F is an internal file, it is returned. PROCEDURE OPEN(VAR F : filetypename; N : ALFA; OPENWRITE : BOOLEAN); EXTERN; Opens the file F and sets the actual file name to the name in the first seven characters of N. If N is all blanks, a new internal file name is created, and the file is opened as an internal file. If OPENWRITE is true, the file is opened in write mode, otherwise it is opened in read mode. The file is not repositioned, which allows reading or writing the file from its current position. If you wish to read or write the file from the beginning, the open call may be followed by a RESET(F) or REWRITE(F). RESET and REWRITE rewind the file unless its actual name is 'INPUT' or 'OUTPUT'. OPECLO.32 1 OPECLO - Pascal-6000 Explicit Open and Close Routines. 27 May 86 Three important interactions must be considered when using these open and close routines: 1) Pascal always opens external files at the beginning of the execution of your program and opens internal files when entering the procedure, function, or program that they are declared in. Thus you should not need to use these routines unless you want to do something fancy. 2) If a file is re-opened without first closing it, the open routine will automatically close it for you. 3) If a file is read or written after it has been closed but not re-opened, the results are unpredictable. You should always be sure that a file is open before you reference it in any way. OPECLO.33 1 OPTION - Return Control Statement Option Settings. 27 May 86 Return Control Statement Option Settings ======================================== Like many other compilers, Pascal provides you with a means of writing programs which can be executed later through operating system control statements, either in relocatable binary or absolute binary form. The function OPTION gives you the ability to obtain the settings of program options from the control statement. Ordinarily, Pascal program parameters (actual external file names) may appear as parameters on the control statement calling the program. Following the precedent set by the Pascal control statement (as documented in the Pascal writeup), a '/' followed by other parameters may be added. For example, the full form of the Pascal control statement is: PASCAL(I=INPUT,L=OUTPUT,B=LGO/A+,B4,E-,O+,P+,Q-,S+,T+,U-,X4,Z+) Similarly, the function OPTION requires user-defined options to appear after a '/' on the control statement and in a syntax identical to options used on the Pascal compiler control statement. To use OPTION in your Pascal program, enter the following compiler directive immediately after your program heading. (*$I'OPTION' CONTROL-STATEMENT OPTION PROCESSOR. *) OPTION defines the following type and function: TYPE SETTING = PACKED RECORD CASE SWITCH: BOOLEAN OF TRUE : (ONOFF: CHAR); FALSE: (SIZE : 0..999999) END; FUNCTION OPTION(NAME: CHAR; VAR S: SETTING): BOOLEAN; EXTERN; OPTION must be used with the Pascal compiler X option set to at least X2. Since the X option is set in the Include package, you should not have to set it yourself. Once you have entered the include package, you must declare a variable of type SETTING to hold the desired setting: VAR S: SETTING; OPTION is used assuming that you want to determine the existence of a parameter appearing on the control statement, and if it does appear, determine its value: either a 'switch' setting (+ - =) as in L+ on the Pascal control statement, or a integer value as in B2 on the Pascal control statement. OPTION.34 1 OPTION - Return Control Statement Option Settings. 27 May 86 Example: Suppose your program needs a parameter to specify that 72 columns are to be processed on each input source line - just like the Pascal compiler control statement U option. Then in your program use OPTION as follows: IF OPTION('U',S) THEN IF S.SWITCH AND (S.ONOFF = '+') THEN LINEWIDTH := 72 Note: 1) OPTION returns the value FALSE and sets S.SWITCH to FALSE and S.SIZE to zero if the parameter sought did not appear on the control statement. 2) OPTION does not check for valid parameter syntax. 3) OPTION allows no embedded blanks within the parameter list that follows the '/' (just like the compiler options on the Pascal control statement). OPTION.35 1 PAGSIZ - Pascal-6000 Page Size Routines 27 May 86 Page Size Routines | ================== | | PAGSIZ is a package of routines for manipulating page size parameters | (page density, page length, page width). This package can be used to | write programs that change report formats according to the terminal | characteristics of the user. | | To use PAGSIZ, include the following line after the program heading: | | (*$I'PAGSIZ' INCLUDE PAGSIZ DECLARATIONS *) | | The PAGSIZ include package defines one type and declares two | procedures. | | TYPE | PAGESIZEREC = | RECORD | PD : INTEGER; (* PAGE DENSITY *) | PS : INTEGER; (* PAGE LENGTH *) | PW : INTEGER; (* PAGE WIDTH *) | END; | | PROCEDURE GETPAGE(VAR P : PAGESIZEREC); | GETPAGE returns the current values for the page density, page | length, and page width. | | PROCEDURE SETPAGE(P : PAGESIZEREC); | SETPAGE updates the current values for the page size parameters | by providing SETPAGE with new values. The user should ensure | that the values passed are acceptable: PD should be 6 or 8; PS | must be in the range 16 to 255; PW must be in the range 40 to | 255. | | NOTE: SETPAGE affects subsequent job steps only under the NOS 2.2 | (or later) operating system. | | After including the PAGSIZ package, you must declare a variable of | type PAGESIZEREC in your program. That variable can then be passed to | GETPAGE to return values, or to SETPAGE to set values. | | | For example: { Get and print the current page size values } | | PROGRAM REPORT(OUTPUT); | (*$I'PAGSIZ' INCLUDE PAGSIZ DECLARATIONS *) | VAR P : PAGESIZEREC; | BEGIN | GETPAGE(P); | WITH P DO | BEGIN | WRITELN(OUTPUT,' PAGE DENSITY = ',PD); | WRITELN(OUTPUT,' PAGE LENGTH = ',PS); | WRITELN(OUTPUT,' PAGE WIDTH = ',PW) | END | END (* REPORT *). | PAGSIZ.36 1 PRNTPLT - Pascal-6000 Printer Plotter 27 May 86 Printer Plotter =============== This PRINTER PLOTTER consists of four Pascal-callable procedures: SCLINITIAL, SCLWINDOW, SCLPLOT, and SCLPRINT. A high-speed line-printer or a 132-column hard-copy interactive terminal (such as a DECwriter) is used for output. The plots are X-Y graphs scaled to fit a single sheet of printer-paper. X values run horizontally while Y values are vertical. Axis labels and axes are automatically set up. The user need only provide data points, titles, and plotting characters. Nearly any range of data is suitable. Plots overlayed on one another (multiplots) can be generated just as easily as single plots. Using SCLWINDOW, enlargements and reductions can be made. That is, a tiny piece of a plot can literally be blown-up and made into a new plot. The Pascal PRINTER PLOTTER was created primarily because the printer-plotting routines, available in the FORTRAN library do not offer the features and simplicity described herein. Besides, they are not compatible with Pascal. Using the PRINTER PLOTTER ------------------------- The Pascal PRINTER PLOTTER is easy to use. Only a few declarations are necessary. Four separate procedures must be considered: SCLINITIAL, SCLWINDOW, SCLPLOT, and SCLPRINT. Single plots are made by calling the basic procedures once, first SCLINITIAL, then SCLPLOT, and finally SCLPRINT. Multiplots are made by repetitively calling SCLPLOT. The first call establishes the scale, and all further calls will then be handled according to that scale. Any points lying outside the boundaries established by either SCLPLOT (first call), or a call to SCLWINDOW will be ignored. SCLWINDOW acts as if it were the first call to SCLPLOT except there is no plotting. SCLWINDOW provides the expansion facility by allowing the user to specify ranges of X and Y values directly. Certain declarations are required for use of the Pascal printer plotter. Most of these declarations can be included in your program by inserting the following compiler directive on the line immediately after your program heading. (*$I'PRNTPLT' PRNTPLT DECLARATIONS. *) This directs the Pascal compiler to include all the TYPE and PROCEDURE declarations necessary for using PRNTPLT. You, as the user of PRNTPLT are responsible for the variable declarations which are described in the next section. PRNTPLT.37 1 PRNTPLT - Pascal-6000 Printer Plotter 27 May 86 Variable Declarations --------------------- Variable declarations are required by the Pascal PRINTER PLOTTER. The user should insert them into his main program. The most important is an array which PRNTPLT uses as a large work area. The type of this array is automatically defined to have the name SCRATCH by the PRNTPLT include package. Since the four procedures also communicate through this array, it is very important that it not be altered by the user. Identifiers used in the following illustration are only suggested. In other words, the large work area, which will be referred to as IMAGE, could just as well be called XYZ. Example 1 --------- PROGRAM TESTPLOTTER(INPUT,OUTPUT); (*$I'PRNTPLT' PRNTPLT DECLARATIONS. *) CONST NUM = 50; (*MAX NUMBER OF DATA POINTS TO BE PLOTTED*) TYPE ARDATA = ARRAY[1..MAX] OF REAL; VAR X : ARDATA; (*ARRAY OF X-VALUES*) Y : ARDATA; (*ARRAY OF CORRESPONDING Y-VALUES*) IMAGE : SCRATCH; (*WORK AREA FOR PASCAL PRINTER PLOTTER*) PRNTPLT.38 1 PRNTPLT - Pascal-6000 Printer Plotter 27 May 86 Procedure Declarations ---------------------- The PRNTPLT package consists of the four procedures SCLINITIAL, SCLWINDOW, SCLPLOT, and SCLPRINT. These are automatically declared by the PRNTPLT include package. The array type SCRATCH is also declared. To help you understand the PRNTPLT package, these declarations are shown here. TYPE SCRATCH = ARRAY[1 .. 700] OF INTEGER; PROCEDURE SCLINITIAL(VAR IMAGE : SCRATCH); PROCEDURE SCLWINDOW(VAR IMAGE : SCRATCH; X1,X2,Y1,Y2 : REAL); PROCEDURE SCLPLOT(VAR IMAGE : SCRATCH; N : INTEGER; VAR X : ARRAY [XLO .. XHI : INTEGER] OF REAL; VAR Y : ARRAY [YLO .. YHI : INTEGER] OF REAL; CH : CHAR); PROCEDURE SCLPRINT(VAR IMAGE : SCRATCH; VAR PRFILE : TEXT; TITLE : PACKED ARRAY [TLO .. THI : INTEGER] OF CHAR; XLEG : PACKED ARRAY [XLO .. XHI : INTEGER] OF CHAR; YLEG : PACKED ARRAY [YLO .. YHI : INTEGER] OF CHAR); IMAGE Work area used by the four procedures. X1,X2 Minimum and maximum X values for SCLWINDOW. Y1,Y2 Minimum and maximum Y values for SCLWINDOW. N Number of X and Y values to plot. X Array of X values to plot. Y Array of Y values to plot. CH Plotting character PRFILE File to recieve the plotter output. TITLE Title of the plot. XLEG X-axis legend. YLEG Y-axis legend. PRNTPLT.39 1 PRNTPLT - Pascal-6000 Printer Plotter 27 May 86 Typical PROCEDURE Usage ----------------------- The following are four examples of typical PROCEDURE usage. Examples 2 through 4 are single plots. Example 5 is a multiplot. Example 3 is an expansion of the first using SCLWINDOW. Example 4 shows how convenient it can be to substitute constants directly as ACTUAL PARAMETERS, thus eliminating extra variables. Notice that TITLE, XLEG, and YLEG are actually string variables or constants. Strings are defined in Pascal as PACKED ARRAY [1..n] OF CHAR. Also, note that SCLPRINT writes the graph on the file, OUTPUT. A different external file, other than OUTPUT, can be used. Example 2 --------- SCLINITIAL(IMAGE); (* INITIALIZE *) SCLPLOT(IMAGE,N,X,Y,CH); (* PLOT *) SCLPRINT(IMAGE,OUTPUT,TITLE,XLEG,YLEG); (* PRINT *) Example 3 --------- SCLINITIAL(IMAGE); (* INITIALIZE *) SCLWINDOW(IMAGE,X1,X2,Y1,Y2); (* EXPAND *) SCLPLOT(IMAGE,N,X,Y,CH); (* PLOT *) SCLPRINT(IMAGE,OUTPUT,TITLE,XLEG,YLEG); (* PRINT *) Example 4 --------- SCLINITIAL(IMAGE); SCLPLOT(IMAGE,47,X,Y,'P'); (* CONSTANTS SUBSTITUTED FOR N AND CH *) SCLPRINT(IMAGE,OUTPUT, 'THIS IS THE TITLE', 'THIS IS THE X-LEGEND', 'THIS IS THE Y-LEGEND'); (* CONSTANTS SUBSTITUTED FOR TITLE, XLEG, AND YLEG *) Example 5 --------- SCLINITIAL(IMAGE); SCLPLOT(IMAGE,N,X,Y,'A'); (* ESTABLISH SCALING *) SCLPLOT(IMAGE,N,X,Y,'B'); (* ALL FURTHER REFERENCES TO SCLPLOT *) . (* ARE DEPENDENT UPON THE SCALE JUST *) . (* ESTABLISHED. *) . . . . SCLPLOT(IMAGE,N,X,Y,'Y'); SCLPLOT(IMAGE,N,X,Y,'Z'); SCLPRINT(IMAGE,OUTPUT,TITLE,XLEG,YLEG); (* PRINT THE MULTIPLOT *) PRNTPLT.40 1 PRNTPLT - Pascal-6000 Printer Plotter 27 May 86 Programming Examples -------------------- Three different programming examples will be given at the end of this writeup. Example 6 is an example of a single plot. It shows what happens if the data is too large or small to have properly displayed axis labels. A scale factor message is printed beside each axis affected. Example 7 is a multiplot. Finally, example 8 is an expansion of the second showing where B, C, and D intersect. The range of X-values is from 4.5 to 5.5 while the range of Y-values is from 0.4 to 0.6. Notice that when using SCLWINDOW for expansion purposes, the more data points provided, the more resolution possible. That is, if the user generates more X and Y values, (by making delta X smaller), more expansions are possible. Expansions of expansions are easily obtained in this manner. If the user is running out of data points after repetitively expanding a plot, then decreasing delta X and generating more points will help. In examples 7 and 8 be sure to notice how Y is declared as an ARRAY of ARRAYs of Y-values. This makes overplotting convenient in a looping situation. Do not forget that it is either the first call to SCLPLOT, or a single call to SCLWINDOW which determines the overall scale. Any calls thereafter are treated according to that scale. Do not call SCLWINDOW more than once. Nothing will happen except time will be wasted. For the same reason, do not call SCLWINDOW if SCLPLOT has previously been called. Also, if either the X-values or the Y-values for SCLWINDOW are accidentally given as being equal, no scaling will occur. The first SCLPLOT call would then provide the scaling. The parameters following IMAGE can be in any numerical order as long as the first two are X-values and the second two are Y-values. Hints, Cautions, Errors ----------------------- There is one mistake a user could make which can cause unpredictable results, that is, failure to call SCLINITIAL. If for each call to SCLPLOT, N is less than or equal to zero, and either SCLWINDOW is called with the X-values or the Y-values being equal, or is not called at all, then when SCLPRINT is called a message will be printed: 'EMPTY GRAPH'. Normally, when calling SCLPRINT, the OUTPUT file is used. See the section on Typical Procedure Usage. However, a different external file could just as well be used provided that it is properly declared in the program heading. Also, to obtain extra copies of a graph, call SCLPRINT repetitively. In reference to SCLPLOT, as long as N agrees with the number of X and Y values and also if N is not less than or equal to zero, everything will work properly. It should go without saying that any N passed to SCLPLOT should lie within the range of INTEGER numbers as defined by Pascal-6000. PRNTPLT.41 1 PRNTPLT - Pascal-6000 Printer Plotter 27 May 86 Notes ----- The external routines described herein require approximately 2300 octal words of central memory. The scaling algorithm was obtained from: Dixon, W, J. and R. A. Kronmal, 'The Choice of Origin and Scale for Graphs,' JOURNAL OF THE ACM, 12,2 (April, 1965) pages 259-261. This reference gives an excellent method for choosing graph scales which centers the information in the graphical frame and provides divisions which are simple numbers. A few changes have been made to handle special cases (e.g., when all values are on a single X or Y line) and to re-scale to fit Pascal field specifications. The plot image of numerically rounded points is built up in the scratch array and is then printed. J5 MINN SCLPLOT, by M. Frisch, revised February 1971, describing a FORTRAN printer plotting routine, was also used as a reference. PRNTPLT.42 1 PRNTPLT - Pascal-6000 Printer Plotter 27 May 86 Example 7 --------- PROGRAM SINGLEPLOT(OUTPUT); (*$I'PRNTPLT' INCLUDE PRNTPLT DECLARATIONS *) CONST MAX = 200 (* MAX NO. OF POINTS *); TYPE ARDATA = ARRAY[1..MAX] OF REAL; CH50 = PACKED ARRAY[1..50] OF CHAR; VAR X : ARDATA; Y : ARDATA; I : INTEGER; N : REAL; IMAGE : SCRATCH; TITLE,XLEG,YLEG : CH50; BEGIN (* MAIN PROGRAM *) TITLE := ' THIS PLOT SHOWS EXTREMES. '; XLEG := ' X SCALE FACTOR MESSAGE IS TO THE LEFT. '; YLEG := ' Y SCALE FACTOR MESSAGE IS STRAIGHT UP. '; N := 1000.0; FOR I := 1 TO 100 DO BEGIN (* GENERATE 100 DATA POINTS *) X[I] := N; Y[I] := LN(X[I]) / X[I]; N := N + 1000.0 END; SCLINITIAL(IMAGE); SCLPLOT(IMAGE,100,X,Y,'Q'); SCLPRINT(IMAGE,OUTPUT,TITLE,XLEG,YLEG) END (* MAIN PROGRAM *). PRNTPLT.43 1 PRNTPLT - Pascal-6000 Printer Plotter 27 May 86 Example 8 --------- PROGRAM MULTIPLOTTING(OUTPUT); (*$I'PRNTPLT' INCLUDE PRNTPLT DECLARATIONS *) CONST MAX = 400 (* MAX NO. OF POINTS *); TYPE ARDATA = ARRAY[1..MAX] OF REAL; VAR X : ARDATA; Y : ARRAY[1..4] OF ARDATA; I : INTEGER; IMAGE : SCRATCH; BEGIN (* MAIN PROGRAM *) FOR I := 1 TO MAX DO BEGIN (* GENERATE DATA POINTS *) X[I] := 0.005 * I * 3.14159258367; Y[1,I] := SIN(X[I]); Y[2,I] := COS(X[I]); Y[3,I] := (X[I] / 4.0) - 0.8; Y[4,I] := 0.5 END; SCLINITIAL(IMAGE); FOR I := 1 TO 4 DO SCLPLOT(IMAGE,MAX,X,Y[I],CHR(I)); SCLPRINT(IMAGE,OUTPUT, 'A: Y=SIN(X); B: Y=COS(X); C: Y=X/0.4-0.8; D: Y=0.5 ', ' > > > X INCREASING > > > ', ' ^ ^ ^ Y INCREASING ^ ^ ^ ') END (* MAIN PROGRAM *) . PRNTPLT.44 1 PRNTPLT - Pascal-6000 Printer Plotter 27 May 86 Example 9 --------- PROGRAM USINGSCLWINDOW(OUTPUT); (*$I'PRNTPLT' INCLUDE PRNTPLT DECLARATIONS *) CONST MAX = 400; (* MAX NO. OF POINTS *) TYPE ARDATA = ARRAY[1..MAX] OF REAL; VAR X : ARDATA; Y : ARRAY[1..4] OF ARDATA; I : INTEGER; IMAGE : SCRATCH; BEGIN (* MAIN PROGRAM *) FOR I := 1 TO MAX DO BEGIN (* GENERATE DATA POINTS *) X[I] := 0.005 * I * 3.14159258367; Y[1,I] := SIN(X[I]); Y[2,I] := COS(X[I]); Y[3,I] := (X[I] / 4.0) - 0.8; Y[4,I] := 0.5 END; SCLINITIAL(IMAGE); SCLWINDOW(IMAGE,5.5,4.5,0.4,0.6); FOR I := 1 TO 4 DO SCLPLOT(IMAGE,MAX,X,Y[I],CHR(I)); SCLPRINT(IMAGE,OUTPUT, 'A: Y=SIN(X); B: Y=COS(X); C: Y=X/0.4-0.8; D: Y=0.5 ', ' > > > X INCREASING > > > ', ' ^ ^ ^ Y INCREASING ^ ^ ^ ') END (* MAIN PROGRAM *). PRNTPLT.45 1 QSORT - Quicksort of Real or Integer Array 27 May 86 Quicksort of Real or Integer Array ================================== QSORT performs a modified Quicksort of an arbitrary length array of real or integer into non-decreasing order. The modified Quicksort algorithm, designed by Richard C. Singleton, is believed to be the most efficient non-stable sorting algorithm. It was rewritten for Pascal by Steve Legenhausen and later modified by Daniel LaLiberte for inclusion in the Pascal library at the University of Minnesota. To use QSORT, include the following procedure declaration in your program with the X compiler option set to at least X2. Because the default is 'X4', you do not need to worry about this unless you have changed the option setting within your program. PROCEDURE QSORT(VAR V: ARRAY [LO .. HI:INTEGER] OF ELEMENT; N: INTEGER); EXTERN; where ELEMENT is the type of the array to be sorted (INTEGER or REAL). Arrays with differing lengths can be sorted because the first parameter is declared as a conformant array parameter. QSORT will perform an in-place sort of the first N members of the array V. For example, to sort all 100 elements of the integer array A, you might do the following: CONST LEN = 100; TYPE ELEMENT = INTEGER; VAR A: ARRAY [1 .. LEN] OF ELEMENT; PROCEDURE QSORT(VAR V: ARRAY [LO .. HI:INTEGER] OF ELEMENT; N: INTEGER); EXTERN; . . . QSORT(A,LEN); QSORT.46 1 QSORT - Quicksort of Real or Integer Array 27 May 86 You can also sort real numbers simply by declaring ELEMENT as a Real instead of Integer. However, to use QSORT with both reals and integers in the same program, the following method is suggested: TYPE REALVECTOR = ARRAY[1 .. 100] OF REAL; INTEGERVECTOR = ARRAY[1 .. 500] OF INTEGER; VAR A: REALVECTOR; B: INTEGERVECTOR; PROCEDURE SORTREAL(VAR V: ARRAY [LO .. HI:INTEGER] OF REAL; N: INTEGER); PROCEDURE QSORT(VAR V: ARRAY [LOW .. HIGH:INTEGER] OF REAL; N: INTEGER); EXTERN; BEGIN QSORT(V,N) END; PROCEDURE SORTINTEGER( VAR V: ARRAY [LO .. HI : INTEGER] OF INTEGER; N: INTEGER); PROCEDURE QSORT( VAR V: ARRAY [LOW .. HIGH:INTEGER] OF INTEGER; N: INTEGER); EXTERN; BEGIN QSORT(V,N) END; . . . SORTREAL(A,100); SORTINTEGER(B,500); References ---------- Legenhausen, Steve. Quicksort: A Tutorial. University Computer Center Technical Report 73006, University of Minnesota, (July 1973). Singleton, Richard C. Algorithm 347. Comm. ACM 12,3 (March 1969), 185-187. QSORT.47 1 RADIXIO - Alternative Radix Input-Output Procedures 27 May 86 Alternative Radix Input-Output Procedures ========================================= This writeup describes RADIXIO, a package of procedures that allow you to write integers in either octal or hexadecimal representation. A word in memory has sixty bits. These bit patterns can be represented by twenty octal digits or fifteen hexadecimal digits. These procedures write the textual representation of those digits. If you use field widths of twenty and fifteen for WRITEOCT and WRITEHEX, respectively, leading digits are written (for non-negative numbers, the digits are zeroes). To use these procedures in your program, you must enter the following INCLUDE directive after the program heading. (*$I'RADIXIO' RADIX INPUT-OUTPUT ROUTINES. *) This INCLUDE directive declares two procedures. Each description below includes the procedure heading that is defined by the RADIXIO include package. PROCEDURE WRITEOCT(VAR F: TEXT; N,W: INTEGER); This procedure writes an integer N in octal representation on text file F with a field width of W. A field width of twenty (20) writes the integer with no leading blanks. Any field width larger than twenty has W-20 leading blanks. A field width less than twenty prints out a truncated representation consisting of the W lowest-order digits. PROCEDURE WRITEHEX(VAR F: TEXT; N,W: INTEGER); This procedure writes an integer N in hexadecimal representation on text file F with a field width of W. A field width of fifteen (15) is sufficient to print the whole integer. A field width larger than fifteen prints W-15 leading blanks. A field width less than fifteen yields only the W lowest-order digits. If a field width of less than one is passed to WRITEOCT or WRITEHEX, the error message "ZERO OR NEGATIVE FIELD WIDTH" is written and the program aborts. RADIXIO.48 1 RADIXIO - Alternative Radix Input-Output Procedures 27 May 86 Example: The following program illustrates the use of the procedures WRITEOCT and WRITEHEX. PROGRAM CONVERT(OUTPUT); (*$I'RADIXIO' INCLUDE RADIX I/O ROUTINES *) VAR I, N : INTEGER; BEGIN (* CONVERT *) FOR I := 1 TO 10 DO BEGIN N := SQR(I*5); WRITE(OUTPUT,' ',N:5); WRITEOCT(OUTPUT,N,25); WRITEHEX(OUTPUT,N,20); WRITELN(OUTPUT); WRITE(OUTPUT,' ',-N:5); WRITEOCT(OUTPUT,-N,25); WRITEHEX(OUTPUT,-N,20); WRITELN(OUTPUT) END END (* CONVERT *). The above program produces the following output. 25 00000000000000000031 000000000000019 -25 77777777777777777746 FFFFFFFFFFFFFE6 100 00000000000000000144 000000000000064 -100 77777777777777777633 FFFFFFFFFFFFF9B 225 00000000000000000341 0000000000000E1 -225 77777777777777777436 FFFFFFFFFFFFF1E 400 00000000000000000620 000000000000190 -400 77777777777777777157 FFFFFFFFFFFFE6F 625 00000000000000001161 000000000000271 -625 77777777777777776616 FFFFFFFFFFFFD8E 900 00000000000000001604 000000000000384 -900 77777777777777776173 FFFFFFFFFFFFC7B 1225 00000000000000002311 0000000000004C9 -1225 77777777777777775466 FFFFFFFFFFFFB36 1600 00000000000000003100 000000000000640 -1600 77777777777777774677 FFFFFFFFFFFF9BF 2025 00000000000000003751 0000000000007E9 -2025 77777777777777774026 FFFFFFFFFFFF816 2500 00000000000000004704 0000000000009C4 -2500 77777777777777773073 FFFFFFFFFFFF63B RADIXIO.49 1 RANDOM - Pascal-6000 Random Number Generators. 27 May 86 Random Number Generators ======================== Two pseudo-random number generators are available in Pascal-6000. Both produce real numbers between 0.0 and 1.0. Both may be 'seeded' to produce different random sequences, and the seed may be retrieved from both to allow re-initializing the random sequence at a later time. Thus each random number generator consists of three routines: the generator itself, the routine to set the seed, and the routine to get the seed. To use one or both of these generators in your program, you should insert the following compiler directive after your main program heading. (*$I'RANDOM' RANDOM NUMBER GENERATOR DECLARATIONS. *) This directs the compiler to declare the six routines needed for using the two random number generators. RANDOM ------ RANDOM is a feedback shift-register pseudo-random number generator. The algorithm which is used is described in the article 'Generalized Feedback Shift-register Pseudorandom Number Generator' T. G. Lewis and W. H. Payne JACM Vol. 20, No. 3, July 1973, pp. 456-468. Random produces multidimensional pseudo-random numbers equally distributed in the half-open interval [0.0,1.0) and has a period of 2**98-1. The three routines which make up the RANDOM system are described below. FUNCTION RANDOM : REAL; Returns a new pseudo-random number each time it is referenced in a Pascal program. For example X := RANDOM * 10.0 sets the real variable X to a new random number in the half open interval [0.0,10.0), and I := TRUNC(RANDOM * 10.0) + 1 sets the integer variable I to a new random number in the closed interval [1,10]. The default sequence is the one which is selected by SETRANDOM(0,0). RANDOM.50 1 RANDOM - Pascal-6000 Random Number Generators. 27 May 86 PROCEDURE SETRANDOM(SEED1, SEED2 : INTEGER); Seeds the random number generator. The lower 49 bits of each seed are combined to make a 98-bit seed. Each seed sets the generator to producea different sequence by selecting a unique starting point in the 2**98-1 number sequence generated by RANDOM. If both SEED1 and SEED2 are zero, the default sequence is selected. Setting both to zero will, however, produce the same sequence as setting them both to 2**49-1. PROCEDURE GETRANDOM(VAR SEED1, SEED2 : INTEGER); Returns a seed which may later be used to re-initialize RANDOM to the current point in the sequence using SETRANDOM. Only the lower 49 bits of SEED1 and SEED2 will be set. The upper 11 bits of each will always be zero. After doing SETRANDOM(0,0), GETRANDOM will return 2**49-1 for both SEED1 and SEED2. RAN --- RAN is a 48-bit multiplicative congruential pseudo-random number generator. RAN takes advantage of the fact that the CDC-6000 double precision multiply hardware automatically provides a modulus 2**48 operation on overflow. RAN returns pseudo-random numbers in the open interval (0.0,1.0) and has a period of 2**45. The three routines which make up the RAN system are described below. FUNCTION RAN : REAL; Returns a new pseudo-random number each time it is evaluated in a Pascal program. The default sequence can be reproduced by SETRAN(0). PROCEDURE SETRAN(SEED : INTEGER); Seeds the random number generator. The seed should be a positive odd integer, but if it is not, SETRAN adjusts it by taking the absolute value and adding one if necessary. Only the lower 48 bits of the seed are significant. Thus -3, -2, 2, and 3 are all considered to be the same seed. Each different seed sets the generator to produce a different sequence by selecting a unique starting point in the 2**45 number sequence generated by RAN. If the seed is zero, SETRAN uses the default seed. PROCEDURE GETRAN(VAR SEED : INTEGER); Returns a 48-bit seed which may later be used to re-initialize to the current point in the sequence using SETRAN. RANDOM.51 1 LFM - Pascal-6000 Local File Manager 27 May 86 Local File Manager ================== NOTE: This package is available only at sites running the NOS 1 or NOS 2 operating systems. LFM is a package that allows the use of system local file routines from within a Pascal program. The package contains several type, function and procedure definitions. To use these routines, insert the following compiler directive immediately after your program heading. It must be on a line by itself. (*$I'LFM' LOCAL FILE MANAGER DECLARATIONS. *) These routines do not communicate with Pascal. If you attempt Pascal file operations on a file which has been manipulated by these routines, or vice-versa, the results are unpredictable. Information about local file manipulation under NOS 1 can be found in the NOS 1 Reference Manual, Volume 2, Sections 3 and 4. Example: Print the names of all assigned files. | | PROGRAM FILES(OUTPUT); | (*$I'LFM' INCLUDE LFM DECLARATIONS *) | VAR ENTRY : FNTENTRY; | BEGIN (* FILES *) | WHILE FNTGET(ENTRY) DO | WRITELN(OUTPUT,ENTRY.FNAME) | END (* FILES *). | LFM.52 1 LFM - Pascal-6000 Local File Manager 27 May 86 LFM defines the following types: TYPE For NOS 1 only: FILETYPE = (MSFILE, TTFILE, LOFILE, INFILE, PRFILE, PUFILE, DAFILE, REFILE, PTFILE, LIFILE); For NOS 2 only: FILETYPE = (U0FILE, U1FILE, U2FILE, U3FILE, U4FILE, U5FILE, U7FILE, ROFILE, LIFILE, PTFILE, PMFILE, FAFILE, SYFILE, LOFILE, U16FILE, INFILE, QFFILE); The local file type. For NOS 1 only: FILEACCESS = (READMODE, WRITEMODE, APPENDMODE, MODIFYMODE, READMODIFYMODE, READAPPENDMODE, EXECUTEMODE); For NOS 2 only: FILEACCESS = (READMODE, WRITEMODE, MODIFYMODE, APPENDMODE, EXECUTEMODE, READMODIFYMODE, READAPPENDMODE); The access permission of a local file. FILEPOSITION = (EORPOS, BOIPOS, EOFPOS, EOIPOS); The current position of a local file. For NOS 1 only: FILEIDTYPE = 0 .. 77B; The ID type of the local file. For NOS 2 only: FILESTATUS = 0 .. 77; The status of the local file. For NOS 1 only: | FNTENTRY = PACKED RECORD A record describing the FNT entry of a local file: FNAME : ALFA; | The name of the local file. UNUSED0 : 0..77777777777777B; Not used. UNUSED1 : BOOLEAN; Not used. EXTENDONLY : BOOLEAN; A BOOLEAN variable which is TRUE if the local file is accessible only in APPEND (extend) mode. MODIFYONLY : BOOLEAN; A BOOLEAN variable which is TRUE if the local file is accessible only in MODIFY mode. EXECUTEONLY : BOOLEAN; A BOOLEAN variable which is TRUE if the local file is accessible only in EXECUTE mode. LFM.53 1 LFM - Pascal-6000 Local File Manager 27 May 86 UNUSED2 : BOOLEAN; Not used. WRITELOCKOUT : BOOLEAN; A BOOLEAN variable which is TRUE if the local file has WRITE LOCKOUT set. FTYPE : 0 .. 77B; The file type of the local file. SSCONTROLINFO : BOOLEAN; A BOOLEAN variable which is TRUE if the System Sector contains control information for the local file. CONTROLPOINT : 0 .. 37B; The control point at which the local file is attached. ID : FILEIDTYPE; The ID type of the local file. EQNO : 0 .. 77B; The number of the equipment on which the local file resides. FIRSTTRACK : 0 .. 7777B; The address of the first track of the file. CURTRACK : 0 .. 7777B; The address of the current track of the file. CURSECTOR : 0 .. 7777B; The current sector of the local file. UNUSED3 : 0 .. 3B; Not used. TRACKINTERLOCK : BOOLEAN; A BOOLEAN variable which is TRUE if the local file has TRACK INTERLOCK set. OPENED : BOOLEAN; A BOOLEAN variable which is TRUE if the local file has been opened. WRSLASTOPEN : BOOLEAN; A BOOLEAN variable which is TRUE if the local file has been written on since it was last opened. WRITTEN : BOOLEAN; A BOOLEAN variable which is TRUE if the local file has been written on. UNUSED4 : 0 .. 3B; Not used. LFM.54 1 LFM - Pascal-6000 Local File Manager 27 May 86 READSTATUS : 0 .. 3B; The current read status of the local file (0 = incomplete, 1 = EOR, 2 = EOF, 3 = EOI). LASTOPWRITE : BOOLEAN; A BOOLEAN variable which is TRUE if the last operation on the local file was a WRITE. NOTBUSY : BOOLEAN A BOOLEAN variable which is TRUE if the local file is not busy. END; For NOS 2 only: | FNTENTRY = | PACKED RECORD | A record describing the FNT entry of a local file: | | FNAME : ALFA; | The name of the local file. | | UNUSED0 : 0..77777777777777B; | Not used. | | ACCESSLEVEL : 0..7B; | Access level of the local file. | | RESIDENCE : 0..3B; | Residence of the local file. | | WRITELOCKOUT : BOOLEAN; | A BOOLEAN variable that is TRUE if the local file has WRITE | LOCKOUT set. | | FTYPE : 0..77B; | The file type of the local file. | | STATUS : 0..77B; | File status. | | LENGTH : 0..77777777B; | Length of file in sectors (zero for non-mass storage | files). | | POSITION : 0..77777777B; | Random index (mass storage), block count (tape), or zero | (others). | | UNUSED1 : 0..17B; | Not used. | | MODE : 0..17B; | Allowed operations on file. | | LFM.55 1 LFM - Pascal-6000 Local File Manager 27 May 86 READSTATUS : 0..7B; | Result of last read (0=incomplete, 1=EOR, 2=EOF, 3=EOI, | 4=BOI). | | LASTOPWRITE : BOOLEAN | True if last operation was a write, otherwise false. | | END; | The following functions are declared by LFM: FUNCTION COMPLETE(FN : ALFA) : BOOLEAN; | A BOOLEAN function which returns TRUE if the last operation on the local file FN was complete. FUNCTION FILEID(FN : ALFA) : FILEIDTYPE; | A function which returns the ID type of the local file FN. Only | has effect on NOS 1 system. | FUNCTION FILESC(FN : ALFA) : FILESTATUS; | A function which returns the status code of the local file FN. | Only has effect on NOS 2 system. | FUNCTION FNTGET(VAR E : FNTENTRY) : BOOLEAN; | Return one FNTENTRY at a time (with a function value of TRUE), | until there are no more entries, at which time it returns an | empty FNTENTRY (and a function value of FALSE). Once FNTGET | returns FALSE, it will start over at the beginning of the FNT | table next time it is called. | FUNCTION LFMODE(FN : ALFA; PERM : FILEACCESS) : BOOLEAN; | A BOOLEAN function which returns TRUE if the local file FN has a file access permission of PERM. FUNCTION LFPOS(FN : ALFA; POS : FILEPOSITION) : BOOLEAN; | A BOOLEAN function which returns TRUE if the local file FN is positioned at POS. FUNCTION LFSIZE(FN : ALFA) : INTEGER; | A function which returns the size of the local file FN. FUNCTION LFTYPE(FN : ALFA; FT : FILETYPE) : BOOLEAN; | A BOOLEAN function which returns TRUE if the local file FN is of the type FT. FUNCTION LOCAL(FN : ALFA) : BOOLEAN; | A BOOLEAN function which returns TRUE if the file FN is a local file. FUNCTION OPENED(FN : ALFA) : BOOLEAN; | A BOOLEAN function which returns TRUE if the local file FN has been opened. LFM.56 1 LFM - Pascal-6000 Local File Manager 27 May 86 LFM defines the following procedures: PROCEDURE BKSP(FN : ALFA; COUNT : INTEGER); | Backspace COUNT logical records on local file FN. PROCEDURE BKSPRU(FN : ALFA; COUNT : INTEGER); | Backspace COUNT PRUs on local file FN. PROCEDURE DEVICE(FN : ALFA; VAR D : ALFA); | Returns the device type on which the local file FN resides. PROCEDURE ENCSF(FN : ALFA); | Enter control statement file on local file FN. PROCEDURE EVICT(FN : ALFA); | Evict local file FN. * PROCEDURE LOCK(FN : ALFA); | Lock local file FN. PROCEDURE NODROP(FN : ALFA); | Nodrop local file FN (set no-auto-drop status). Only has effect | on NOS 2 system. | PROCEDURE PRIMARY(FN : ALFA); | Select local file FN to be the primary file. PROCEDURE PROTECT(ONSWITCH : BOOLEAN); Select or deselect user file privacy. PROCEDURE RENAME(NEWNAME, OLDNAME : ALFA); | Rename local file OLDNAME to NEWNAME. For U of MINN only: PROCEDURE RETPF; Return program file. Returns the executing program file if the file PROCFIL is local, USERPRG is ON, and the executing program file is not set for NODROP (NO-AUTO-DROP). PROCEDURE RETURN(FN : ALFA); | Return local file FN. PROCEDURE REWIND(FN : ALFA); | Rewind local file FN. * For NOS 1 only: PROCEDURE SETID(FN : ALFA; ID : FILEIDTYPE); | Set file ID on local file FN. | For NOS 2 only: PROCEDURE SETFS(FN : ALFA; FS : FILESTATUS); | Set file status on local file FN. | LFM.57 1 LFM - Pascal-6000 Local File Manager 27 May 86 PROCEDURE SKIPEI(FN : ALFA); | Skip to end of information on file FN. PROCEDURE SKIPF(FN : ALFA; COUNT : INTEGER); | Skip COUNT files on local file FN. If COUNT > 0, the files are skipped forwards. If COUNT < 0, the files are skipped backwards. If COUNT = 0, the file is not repositioned. PROCEDURE SKIPR(FN : ALFA; COUNT : INTEGER); | Skip COUNT NOS logical records (segments) on local file FN. If COUNT > 0, the records are skipped forwards. If COUNT < 0, the records are skipped backwards. If COUNT = 0, the file is not repositioned. PROCEDURE UNLOAD(FN : ALFA); | Unload local file FN. PROCEDURE UNLOCK(FN : ALFA); | Unlock local file FN. LFM.58 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 Permanent File Manager ====================== NOTE: This package is available only at sites running the NOS 1 or NOS 2 operating systems. This writeup describes PFM, a set of routines which perform NOS permanent-file operations within a Pascal program. PFM is designed for use by Pascal programmers who wish to access permanent files within their programs, but who do not want to hassle with COMPASS routines or a FORTRAN-oriented package (such as PROCPAC). This writeup is divided into six sections: PF (permanent-file commands), ERROR (error processing), PACKNAME (manipulating pack names), CATLIST (obtaining information about your permanent files), EXAMPLE (an example using PF), and MESSAGES (list of PF syntax error messages). To use the PFM routines, insert the following compiler directive immediately after your program heading. It must be on a line by itself. (*$I'PFM' PERMANENT FILE MANAGER. *) Example: PROGRAM SAMPLE(OUTPUT, RANDATA); (* THIS PROGRAM GENERATES 100 RANDOM INTEGERS BETWEEN 1 AND 365 AND SAVES THEM ON A PERMANENT FILE *) (*$I'RANDOM' RANDOM NUMBER ROUTINES *) (*$I'PFM' PERMANENT FILE MANAGER *) VAR RANDATA : FILE OF INTEGER; I : INTEGER; BEGIN (* SAMPLE *) FOR I := 1 TO 100 DO BEGIN RANDATA^ := TRUNC(365 * RANDOM) + 1; PUT(RANDATA) END; PF('SAVE,RANDATA') END (* SAMPLE *). PFM.59 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 PF : Permanent-File Commands ---------------------------- The main procedure, PF, emulates an operating system permanent-file command. With a few exceptions, one need only know how to use permanent files in general. The inclusion of PFM declares the following: PROCEDURE PF(CMD: PACKED ARRAY [LO..HI:INTEGER] OF CHAR); The procedure PF will take as its argument a string of arbitrary length which contains a permanent-file control statement. PF will then check the string for correct syntax and issue the control statement to the operating system. For example: PF('GET,FILE/UN=ABC0001') The general permanent-file command under NOS takes the form: command,lfn1=pfn1,lfn2=pfn2,...,lfnn=pfnn/options. where lfni and pfni are the names of NOS local and permanent files and 1 <= i <= 20. If only one name is given (=pfni is missing), lfni is assumed to be the same as pfni. Both local and permanent file names must be valid NOS file names ( <= 7 characters and containing only letters and digits). The NOS permanent-file command requires a terminating character, either a period ('.') or closing parenthesis (')'). PF does not require a terminator, but can process one. PF also allows an open parenthesis ('(') instead of a comma (',') for the first delimiter, just as NOS does. A local file name (lfn) in a PF command string refers to a Pascal external file variable having the same name, if there is one, or else it refers to a NOS local file having that name. A Pascal file variable is called "external" if its name appears in the program-heading parameter list. When lfn refers to an external file variable, the PFM operation will be performed on the NOS local file that has been bound to the Pascal file variable. For example, if the source program PROGRAM SAVE(F); (*$I'PFM' PERMANENT FILE MANAGER *) VAR F : TEXT; BEGIN PF('SAVE,F') END. is compiled onto file LGO, then the two NOS command statements LGO,FILEA. LGO,FILEB. will attempt first to save any NOS local file FILEA, and then to save any NOS local file FILEB. PFM.60 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 If the local file name is not associated with a Pascal file, PF will process a system local file. Pascal will not be able to communicate directly with that file, and the programmer will have to use the procedures OPEN and CLOSE to manipulate the file. See chapter OPECLO in this writeup for a description of OPEN and CLOSE. The commands implemented for PF are: APPEND - append local file to an indirect-access permanent file. ATTACH - attach a direct-access permanent file. CHANGE - change attributes of a permanent file. DEFINE - define a direct-access permanent file. GET - get an indirect-access permanent file. OLD - get an indirect-access permanent file as primary file. PERMIT - Change file access permission on a permanent file. PURGE - purge a permanent file. REPLACE - replace an indirect-access permanent file. SAVE - save a local file as an indirect-access permanent file. At the University of Minnesota, one additional function is available. ACQUIRE - get or attach a permanent file. The above permanent-file operations are implemented using NOS operating system primitives. The APPEND and PERMIT commands in PF are syntactically different from the normal control-statement forms of APPEND and PERMIT. System form: APPEND,pfn,lfn1,lfn2,...,lfnn/options. PERMIT,pfn,un1=m1/options. PFM form: APPEND,lfn1=pfn,lfn2=pfn,...,lfnn=pfn/options. PERMIT,pfn1,pfn2,...,pfnn/UN=un1,M=m1,options. The syntax was changed to allow uniform parsing for all PF commands. You can now append two local files to two different permanent files in one PF call, and permit several permanent files to a user number in a certain mode. You cannot permit one permanent file to several user numbers in one PF call. The CHANGE and PURGE commands don't require an associated local file. The PFM format of the commands are: PURGE,pfn1,pfn2,...,pfnn/options. and CHANGE,nfn1=ofn1,nfn2=ofn2,...,nfnn=ofnn/options. where: nfni - new file name ofni - old file name (must be permanent file) PFM.61 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 Pascal handles file maintenance automatically, including closing and opening, resetting and rewriting, and returning local files. Using PF, you may change files without letting Pascal know. If the local file name is associated with a Pascal file, some of this maintenance is done by PF: SAVE, REPLACE, APPEND - closes the file before executing the command. DEFINE - closes and returns the file before executing the command and rewrites the file afterward. GET, OLD, ATTACH, ACQUIRE - resets the file after executing the command. The options that PF processes are: UN=un alternate user number PW=pw password of permanent file PN=pn pack name on which permanent file resides CT=ct category (P, S, PU) M=m mode (W, R, A, E, N, M, RM, RA) SS=ss subsystem (NUL, BAS, FOR, FTN, EXE, BAT, ACC) at U of MINN: (NUL, BAS, FOR, M77, EXE, BAT, MNF, SNO, COB, PAS, ACC, TRA) BR=br backup requirement (N, Y, MD) PR=pr preferred residence (L, D, M, N) R=dt device type SR=sr special request (FA, DN, CE, NF, MR, IE, SY) S=sp file space WB wait if file busy RT real-time attach IP ignore packname DF use system default family NA no abort parameter For NOS 2 sites: AC=ac visible to alternative user (Y, N) | XD=xd password expiration date (yymmdd) XT=xt password expiration time (0..7777B) * The NA option allows the user to process errors within the program, using the function PFERROR, and the procedure PFMESSAGE. Options specified and their related settings must be exactly as shown above; the routines do not recognize other identifiers. PFM.62 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 ERROR : Error Processing ------------------------ If a syntax error is found, PF will HALT without processing the request, and the program will abort with an error message of the form: PFM : specific error message. For an explanation of PF syntax errors, see the MESSAGES section of this writeup. If an error occurs while the system is processing the request, PF will stop your program with a HALT unless the NA parameter is present in the command string. In the event that the NA parameter is present, the procedure will return control to the calling routine. To check whether or not an error has been found, the following function is included in the package: FUNCTION PFERROR : INTEGER; This function returns a number indicating one of two possible situations: 1) PFERROR = 0 No error occurred. 2) PFERROR > 0 A system permanent-file error occurred. In the second case, the number returned will be the ordinal of the error issued by the system (see the NOS Reference Manual, Volume 2, Section 5). In that case, the programmer can access the error message by means of the following included type and procedure: TYPE CH30 = PACKED ARRAY [1..30] OF CHAR; PROCEDURE PFMESSAGE(VAR MESSAGE : CH30); If there is no error, the procedure returns a blank message. PFM.63 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 PACKNAME : Manipulating Pack Names ---------------------------------- PFM includes two procedures for manipulating the current pack name associated with user permanent files. GETPACK returns the current pack name, and SETPACK sets the pack name. These routines are declared by PFM as: PROCEDURE GETPACK(VAR PN : ALFA); PROCEDURE SETPACK(PN : ALFA); The current pack name is returned to ALFA variable PN for GETPACK, and SETPACK sets the desired pack name found in ALFA variable PN. A valid NOS pack name has at most seven characters, so the ALFA variable PN will contain at least three trailing blanks. SETPACK effectively executes the NOS command: PACKNAM,pn. Example: PROGRAM SHA(OUTPUT); (*$I'PFM' PERMANENT FILE MANAGER *) BEGIN SETPACK('SHA ') END. This program will set the default pack name to SHA. GETPACK and SETPACK will not cause any system errors, but if the pack name is invalid, errors may occur when trying to execute a subsequent PF request. PFM.64 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 CATLIST : Obtaining Catalog Information --------------------------------------- Two routines allow you to obtain permanent-file catalog information. Two TYPE definitions are used in conjunction with these routines. They are defined by PFM as: TYPE PACKEDDATE = PACKED RECORD A record describing the packed date used by catalog entries. YEAR : 0..77B; Year minus 1970 [1982 = 12]. MONTH : 0..77B; Month [1..12]. DAY : 0..77B; Day [1..31]. HOUR : 0..77B; Hour [0..23]. MINUTE : 0..77B; Minute [0..59]. SECOND : 0..77B; Second [0..60]. END; CATENTRY = PACKED RECORD A record describing a permanent-file catalog entry. PFN : PACKED ARRAY [1..7] OF CHAR; Permanent file name. UI : 0..777777B; User Index. LEN : 0..77777777B; Permanent-file length (in PRUs). PAD1 : 0..7777B; Unused. TRACK : 0..7777B; First track address. DIRECT : BOOLEAN; Direct-access permanent-file flag. PFM.65 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 SECTOR : 0..3777B; First sector address. RANINX : 0..77777777B; Random index for Permit sectors. CREATE : PACKEDDATE; Creation date, time (packed). ACCESS : 0..77777777B; Access counts. LASTMOD : PACKEDDATE; Last modification date, time (packed). CAT : 0..77B; File catalog type. MODE : 0..77B; File mode. EF : 0..7B; Error flag. EC : 0..7B; Permanent-file error code. DN : 0..77B; Device number. LASTACC : PACKEDDATE; Last access date, time (packed). PAD2 : 0..77777777B; Unused. CNTLMOD : PACKEDDATE; Control modification date, time (packed). PR : 0..7B; Preferred residency. BR : 0 .. 7B; Backup requirement. SS : 0..77B; Subsystem code. PAD3 : 0..7777B; Unused. UTLCNTL : PACKEDDATE; Utility control date, time (packed). PW : PACKED ARRAY [1..7] OF CHAR; File password. PFM.66 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 PWEXP : PACKED RECORD YEAR, MONTH, DAY : 0..77B END; Password expiration date. AF : 0..7777B; Alternate storage flags. PAD4 : 0..77B; Not used. AT : 0..77B; Alternate storage type. ASA : 0..777777777777B; Alternate storage address. PAD5 : 0..7777777B; Not used. AL : 0..7; Not used. PAD6 : 0..17B; Not used. CATEGOR : 0..37777777777B; Not used. PAD7 : ARRAY [10..13] OF ALFA; Unused. * UCW : INTEGER; User control word. * INW : INTEGER; Installation word. * END; The CATSTART procedure initiates the catlist function. It is declared as: PROCEDURE CATSTART(FN, UN, PN : ALFA); CATSTART has three parameters: FN - The name of the permanent-file for which information is to be obtained. If this parameter is blank, information is PFM.67 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 returned for all files. UN - The user number which owns the permanent file. If this parameter is blank, the current user number is used. PN - The pack name of the device on which the permanent-file resides. If this parameter is blank, the current pack name is used. The function CATGET is used to return permanent-file catalog entries, one at a time. CATGET is declared by PFM as: FUNCTION CATGET(VAR CE : CATENTRY) : BOOLEAN; CATGET returns a CATENTRY to the parameter CE. CATGET returns TRUE each time it is called if it completes a catlist request. If a specific file name is requested, CATGET should return TRUE if the file is permanent and FALSE if it is not. CATGET returns FALSE after it runs out of requested catlist entries. Example: PROGRAM CATLIST(OUTPUT); (*$I'PFM' PERMANENT FILE MANAGER *) CONST BLANKS = ' '; VAR CE : CATENTRY; BEGIN CATSTART(BLANKS, BLANKS, BLANKS); WHILE CATGET(CE) DO WRITELN(OUTPUT, CE.PFN) END. Executing the above program will print the file names of all permanent files on the current user number and pack name. Both CATSTART and CATGET inhibit error processing by the operating system; the no-abort parameter is implicit. PFERROR should be used to determine whether or not there are system errors. PFM.68 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 EXAMPLE : Retain a Data File ---------------------------- Suppose you want to write data to a file and retain it. Since RETAIN is not a function which is implemented, one must simulate the function. PROGRAM RETAINDATA(INPUT, OUTPUT, FILE1, FILE2); (*$I'PFM' PERMANENT FILE ROUTINES *) VAR FILE1, FILE2: TEXT; MESS: CH30 (* ERROR MESSAGE, IF ERROR *); PROCEDURE COPYTEXT(VAR F1, F2: TEXT); BEGIN RESET(F1); REWRITE(F2); WHILE NOT EOF(F1) DO BEGIN WHILE NOT EOLN(F1) DO BEGIN F2^ := F1^; GET(F1); PUT(F2) END; READLN(F1); WRITELN(F2) END END (* COPYTEXT *); BEGIN (* RETAINDATA *) COPYTEXT(INPUT,FILE1); (* PURGE THE OLD COPY, TRY TO SAVE THE FILE *) PF('PURGE,DATAFIL/PN=SHA,NA'); PF('SAVE,FILE1=DATAFIL/PN=SHA,NA'); IF PFERROR <> 0 THEN IF PFERROR = 12B THEN (* FILE TOO LONG *) BEGIN (* DEFINE AND COPY *) PF('DEFINE,FILE2=DATAFIL/PN=SHA'); COPYTEXT(FILE1,FILE2) END ELSE BEGIN (* PRINT SYSTEM ERROR *) PFMESSAGE(MESS); HALT(MESS) END END (* RETAINDATA *). Note: The file DATAFIL may be attached to the job in WRITE mode after running this program (if the DEFINE command was executed). PFM.69 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 MESSAGES : Syntax Error Messages for PF --------------------------------------- This is a list of all syntax error messages which might be produced by PF, and an explanation of the reason an error has occurred. PFM : EMPTY COMMAND STRING. The command string parameter to PF contains only blanks. PFM : EMPTY FILE LIST. No file names were specified in the command string. PFM : INVALID COMMAND NAME. The command string contains a command name that PFM did not recognize. The command is either misspelled or is a NOS permanent-file command not processed by PFM. PFM : INVALID COMMAND TERMINATOR. The command string does not end in a valid terminator (blank, period, or right parenthesis). PFM : INVALID EXPIRATION DATE. The XD parameter of the command string has an equivalence that does not match the format "yymmdd". PFM : INVALID FILE NAME. A file name in the command string contains characters that are not normally valid in a NOS file name. PFM : INVALID KEYWORD OPTION SETTING. A keyword parameter of the command string has an equivalence that does not match one of the allowed keywords. PFM : INVALID NUMERIC OPTION SETTING. A numeric parameter of the command string has an equivalence that is too large or contains invalid characters. PFM : INVALID OPTION NAME. There is an option parameter in the command string that PFM does not process. The option could also be misspelled. PFM : INVALID RESIDENCY. The R parameter of the command string has an equivalence that contains characters which are invalid in a NOS device name. PFM : MISSING FILE NAME. The command string contains no file name. PFM : MISSING OPTION SETTING. The command string contains an option that is missing its equivalence. PFM : NAME TOO LONG. A command string contains a command name or file name that is PFM.70 1 PFM - Pascal-6000 Permanent File Manager 27 May 86 longer than seven (7) characters. PFM : OPTION INCOMPATIBLE WITH COMMAND. The command string contains an option that is not allowed with the particular command. PFM : TOO MANY FILE NAMES. The command string contains more file name pairs than it can process (twenty file pairs). * PFM.71 1 ROUTE - Pascal-6000 Route Routines 27 May 86 Route Routines | ============== | | | NOTE: This package is available only at sites running the NOS 1 or | NOS 2 operating systems. | | | | | | | | | ROUTE is an include package that allows a user to perform the | functions of the NOS Dispose Processor (DSP) from within a Pascal | program. Essentially, these are the functions of the ROUTE control | statement. | | This package defines two parameter block record types (DSPBLOCK and | FUNBLOCK), the procedure ROUTE, and three initializaton procedures | (INITDSP, INITFUN, and FUNLOC). | | Complete information about the ROUTE macro and the DSP parameter block | can be found in the NOS 1 Reference Manual Volume 2, Section 8, or the | NOS 2 Reference Manual, Volume 4, Section 7. As noted below, you | might need to refer to one of these to make use of ROUTE. | | | Usage | ----- | | To use these routines, insert the following compiler directive | immediately after your program heading. It must be on a line by | itself. | | (*$I'ROUTE' ROUTE ROUTINES. *) | | Then declare a variable of type DSPBLOCK and initialize it by calling | INITDSP. This variable will serve as your DSP parameter block. Set | up the parameter block according to the DSP function you desire. | Ordinarily this involves assigning values to fields that correspond to | parameters on the ROUTE control statement (FORMS, DISP, EX, IC, TID, | RC) and setting flags in the FLAGS field (see below). Once the block | is set up, all that remains is to call ROUTE. ROUTE passes the block | on to the system ROUTE macro, which in turn calls DSP. See part three | of this writeup for an example of a program using the ROUTE package. | | The FLAGS field is a boolean array of parameter flags indexed by the | type NOSFLAG. Most of the flags in this array have a corresponding | field defined elsewhere in the DSP block. Whenever a value is | assigned to such a field as a parameter for the DSP call, the | corresponding flag must be assigned the value TRUE to indicate that | the field contains information that affects DSP processing. For | example, if you want to route a file to the print queue, you place the | display code characters 'PR' in the DISP field and assign | ROUTE.72 1 ROUTE - Pascal-6000 Route Routines 27 May 86 FLAGS[NOSFDISP] the value TRUE. See the NOS 1 Reference Manual, | Volume 2, Section 8, or the NOS 2 Reference Manual, Volume 4, Section | 7, for a complete description of parameter flags. | | You must do some extra work in instances when, if you were using the | ROUTE control statement to route your file, you would use a | non-default value for the FM or UN parameter. When using the ROUTE | package in such cases, in addition to declaring a DSP block, you must | also declare a variable of type FUNBLOCK, initialize it by calling | INITFUN, and assign the desired values to the FAMILY and USERNUM | fields in this block. Then you must insert the COMPLEMENT of the | FUNBLOCK address in the TID field of the DSP block. Since INITDSP | initializes the TID field to 77777777B, this rather odd requirement | can be satisfied by simply subtracting from TID the address returned | by the function FUNLOC described below, like this: | | YOURDSPBLK.TID := YOURDSPBLK.TID - FUNLOC(YOURFUNBLK); | | Finally, don't forget to assign TRUE to FLAGS[NOSFTID]. | | WARNING: All string-type fields in the DSP parameter block must be | ZERO-FILLED before calling ROUTE. INITDSP zeroes all string-type | fields. The nonstandard, predeclared constant COL (or CHR(0)) may | also be used for this purpose. | | WARNING: When routing local files created by your Pascal program, | make sure that output is complete and the output buffer has been | flushed before calling ROUTE routines. This can be accomplished by | calling PUTSEG (segmented files only), PUTFILE, RESET, or CLOSE (see | WRITEUP,PASCLIB=OPECLO and WRITEUP,PASCAL=FILES+SEGFILE for more | information about Pascal-6000 file manipulation facilities). | ROUTE.73 1 ROUTE - Pascal-6000 Route Routines 27 May 86 Declarations | ------------ | | In what follows, note the following: (1) the NOS 1 DSP parameter block | and parameter flags are somewhat different from those of NOS 2, and | local installations may also have introduced modifications to these | ROUTE declarations; (2) all "PAD" fields are unused. | | | ROUTE defines the following types: | | TYPE | | DSPBLOCK = | PACKED RECORD | This is the DSP parameter block defined for NOS 1 only. | | LFN : PACKED ARRAY [1..7] OF CHAR; | ERR : 0..77B; | PAD1 : 0..3777B; | C : BOOLEAN; | | PAD2 : 0..7777B; | FORMS : 0..7777B; | DISP : PACKED ARRAY [1..2] OF CHAR; | EX : 0..7B; | PAD3 : BOOLEAN; | IC : 0..3B; | FLAGS : PACKED ARRAY [NOSFLAG] OF BOOLEAN; | | OID : PACKED ARRAY [1..3] OF CHAR; | DID : PACKED ARRAY [1..3] OF CHAR; | TID : 0..77777777B; | | PAD4 : 0..77777777777777B; | PAD5 : 0..77B; | PRIOR : 0..7777B; | | SPACE : 0..7777B; | PAD6 : 0..7777B; | ABORT : 0..7777B; | PAD7 : 0..37B; | PAD8 : 0..3; | RC : 0..37B; | PAD9 : 0..7777B; | | PAD10 : INTEGER; | | PAD11 : INTEGER; | | U : BOOLEAN; | PAD12 : 0..377777777777B; | RA : 0..77777777B; | | ROUTE.74 1 ROUTE - Pascal-6000 Route Routines 27 May 86 SSWRDS : ARRAY [10B..13B] OF INTEGER; | | PAD13 : ARRAY [14B..16B] OF INTEGER; | | INST : ARRAY [17B..21B] OF INTEGER | END; | | Description of fields: | | LFN | The local file name of the file to be routed. | | ERR | Error code returned by the system when FLAGS[NOSFERR] is | set to TRUE. Zero indicates normal termination of the DSP | call. For the meaning of other error codes, see the NOS 1 | Reference Manual Volume 2, Section 8, or the NOS 2 | Reference Manual, Volume 4, Section 7. | | C | Completion bit, which must be zero when DSP is called, and | which is set when the operation is complete. | | FORMS | Forms code, expressed as two display code characters (FC | parameter on the ROUTE control statement). In case of a | route to the input queue, this field is used for input | flags. | | DISP | Disposition code, expressed as two alphanumeric characters | (DC parameter on the ROUTE control statement). | | EX | External characteristics code (EC parameter on the ROUTE | control statement). | | IC | Internal characteristics code (IC parameter on the ROUTE | control statement). | | FLAGS | Each flag set to TRUE indicates that the corresponding DSP | block field is a parameter for the DSP call. | | OID | Origin identifier of the host mainframe from which file LFN | was sent. | | DID | Destination identifier of the host to which file LFN is to | be sent. | | TID | If the file is to be routed with the default family and | user number, this field should be equal to 77777777B. | ROUTE.75 1 ROUTE - Pascal-6000 Route Routines 27 May 86 Otherwise, this field should contain the complement of the | FUNBLOCK address, which is returned by the function FUNLOC. | | PRIOR | Priority. | | SPACE | Spacing code for output files (580 PFC printers only). | | ABORT | Value of this field determines which message is sent to the | dayfile in case of a forced abort. | | RC | Repeat count (REP on the ROUTE control statement). | | U | If set, the system uses words +10B thru +13B of the DSP | block to update the system sector. | | RA | Random address of a routing directive. See the description | of the MFQUEUE control statement in the NOS 1 Reference | Manual, Volume 1. | | SSWRDS | System sector words. | | INST | Reserved for installations. | | NOSFLAG = | Parameter flags for NOS 1 systems only. For each field used in | the DSP parameter block, the corresponding flag should be set | to TRUE. | | (NOSFRJN,NOSFRES1,NOSFSPACE,NOSFRC,NOSFRES2,NOSFERR, | NOSFRES3,NOSFFORMS,NOSFPRIOR,NOSFIC,NOSFEX,NOSFEBLK, | NOSFRES4,NOSFDISP,NOSFDOID,NOSFTID,NOSFCENT,NOSFDEF); | | Description of flags: | | NOSFRJN | Return job name in LFN. | | NOSFRES1 | Reserved. | | NOSFSPACE | 580 PFC Spacing code. | | NOSFRC | Repeat count. | | ROUTE.76 1 ROUTE - Pascal-6000 Route Routines 27 May 86 NOSFRES2 | Reserved. | | NOSFERR | No dayfile message, return error to ERR. | | NOSFRES3 | Reserved. | | NOSFFORMS | Forms code. | | NOSFPRIOR | Priority. | | NOSFIC | Internal characteristics. | | NOSFEX | External characteristics. | | NOSFEBLK | Extended block (file is queued with local file name). | | NOSFRES4 | Reserved for installations. | | NOSFDISP | Disposition code. | | NOSFDOID | Origin id and destination id. | | NOSFTID | TID. | | NOSFCENT | Route to central site. | | NOSFDEF | Deferred route. | | | FUNBLOCK = | RECORD | This record is a parameter block used when routing to the | remote batch queue with a family or user number other than that | of the calling job (the default). Fields should be | left-jusified and blank-filled. | | FAMILY : PACKED ARRAY [1..7] OF CHAR; | USERNUM : PACKED ARRAY [1..7] OF CHAR | END; | | | ROUTE defines the following procedures and functions: | ROUTE.77 1 ROUTE - Pascal-6000 Route Routines 27 May 86 | PROCEDURE ROUTE(VAR D : DSPBLOCK); | This procedure calls the system ROUTE macro which in turn makes | the call to DSP, using D as the parameter block of the call. | | PROCEDURE INITDSP(VAR D : DSPBLOCK); | This procedure initializes a DSP parameter block, and should be | called before the block is set up by the user. All fields except | TID are zeroed; TID is set to 77777777B. | | PROCEDURE INITFUN(VAR F : FUNBLOCK); | This procedure initializes the family/user number block F, and | should be called before any use of F. | | FUNCTION FUNLOC(F : FUNBLOCK) : ADDRESS; | This function returns the address of the family/user number block | F. | | | ROUTE defines the following types for NOS 2 systems only: | | TYPE | | DSPBLOCK = | PACKED RECORD | LFN : PACKED ARRAY [1..7] OF CHAR; | ERR : 0..77B; | PAD1 : 0..3777B; | C : BOOLEAN; | | PAD2 : 0..7777B; | FORMS : 0..7777B; | DISP : PACKED ARRAY [1..2] OF CHAR; | EX : 0..7B; | S : BOOLEAN; | IC : 0..3B; | FLAGS : PACKED ARRAY [NOSFLAG] OF BOOLEAN; | | SLID : PACKED ARRAY[1..3] OF CHAR; | DLID : PACKED ARRAY[1..3] OF CHAR; | TID : 0..77777777B; | | UJN : PACKED ARRAY[1..7] OF CHAR; | PAD3 : 0..77B; | PRIOR : 0..7777B; | | SPACE : 0..7777B; | SVC : PACKED ARRAY[1..2] OF CHAR; | ABORT : 0..7777B; | PAD4 : 0..177B; | RC : 0..37B; | PAD5 : 0..7777B; | | PAD6 : INTEGER; | | ROUTE.78 1 ROUTE - Pascal-6000 Route Routines 27 May 86 PAD7 : INTEGER; | | DD : PACKED ARRAY[1..2] OF CHAR; | PAD8 : 0..7777777777B; | EFLAGS : 0..777777B; | | PAD9 : PACKED ARRAY[1..7] OF CHAR; | PAD10 : 0..777777B; | | PAD11 : PACKED ARRAY[1..7] OF CHAR; | ERTADD : 0..777777B; | | PAD12 : ARRAY[12B..15B] OF INTEGER; | | INST : INTEGER | END; | | Description of fields not described above: | | S | Forced service class flag. | | SLID | Three character alphanumeric logical identifier of the | source mainframe for file LFN. | | DLID | Three character alphanumeric logical identifier of the | destination mainframe for file LFN. | | UJN | The user job name to be used instead of the job's default | user job name. | | SVC | Forced service class code. | | DD | Data declaration in display code which defines the data | type of a file destined to a remote mainframe. | | EFLAGS | Extended parameter block flags. | | ERTADD | First word address of the block containing the explicit | remote text string for the file. | | NOSFLAG = | Parameter flags for NOS 2. | | (NOSFRJN,NOSFRES1,NOSFSPACE,NOSFRC,NOSFUJN,NOSFERR, | NOSFRES2,NOSFFORMS,NOSFPRIOR,NOSFIC,NOSFEX,NOSFEBLK, | NOSFRES3,NOSFDISP,NOSFLID,NOSFTID,NOSFCENT,NOSFDEF); | | ROUTE.79 1 ROUTE - Pascal-6000 Route Routines 27 May 86 Description of flags not described above: | | NOSFUJN | User job name. | | NOSFLID | Source logical id and destination logical id. | | | | | | Example | ------- | | Here is a program that uses the ROUTE include package to route a small | file to the print queue. It uses the DSPBLOCK type and the procedure | ROUTE: | | PROGRAM TESTDSP(F,OUTPUT); | (*$I'ROUTE' ROUTE ROUTINES. *) | VAR | F : SEGMENTED TEXT; | DBLK : DSPBLOCK; | FBLK : FUNBLOCK; | BEGIN | REWRITE(F); | WRITELN(F,'1TEST DATA.'); | PUTSEG(F); (* ENSURE OUTPUT BUFFER IS FLUSHED *) | INITDSP(DBLK); INITFUN(FBLK); | WITH DBLK DO | BEGIN LFN[1] := 'F'; | DISP := 'PR'; EX := 6; TID := TID - FUNLOC(FBLK); | FLAGS[NOSFDISP] := TRUE; FLAGS[NOSFEX] := TRUE; | FLAGS[NOSFTID] := TRUE; FLAGS[NOSFERR] := TRUE | END; | WITH FBLK DO | BEGIN USERNUM[1] := 'E'; USERNUM[2] := 'A' END; | ROUTE(DBLK); | IF DBLK.ERR = 0 THEN WRITELN(' FILE ROUTED.') | ELSE WRITELN(' ERROR IN ROUTE:', DBLK.ERR:3) | END. | ROUTE.80 1 SBCOPY - Single-buffer File Copy 27 May 86 Single-buffer File Copy ======================= NOTE: This package is available only at sites running the NOS 1 or NOS 2 operating systems. SBCOPY is a procedure that copies one file to another using a single-buffer copy. The copy does not position the files before copying, and copies to the end-of-information. To use SBCOPY, you need to insert the following line after the program heading. (*$I'SBCOPY' SBCOPY DECLARATION. *) The procedure SBCOPY is declared by the INCLUDE package in the following way: PROCEDURE SBCOPY(FN1, FN2 : ALFA); The file names passed to SBCOPY need not be associated with the Pascal program as file variables, and problems may arise if they are associated, and a RESET or REWRITE is not done after the copy and before any reading or writing on the file is done. SBCOPY uses an 'X' compiler option setting of 'X2'. The INCLUDE package provides the correct setting for the declaration. SBCOPY.81 1 SYSPROC - Pascal-6000 System Communication Procedures 27 May 86 System Communication Procedures =============================== NOTE: This package is available only at sites running the NOS 1 or NOS 2 operating systems. SYSPROC is a package of external procedures that allow you to invoke operating-system functions. To use these procedures in your program, you must enter the following INCLUDE directive after the program heading. (*$I'SYSPROC' SYSPROC ROUTINES. *) This INCLUDE directive declares two functions and thirteen procedures. | A summary of the functions and procedures follows. Functions: JOBORIGIN - Return origin type of current job. USERINDEX - Return current user index. Procedures: ABORT - Abort the program (similar to HALT). | CLEARBDISPLAY - Clear Console B display. | ENDRUN - End the program. EXCST - End program, execute control statement. FAMILY - Return current FAMILY name. GETJCR - Return contents of Job Control Registers. JOBNAME - Return name of current job. MACHINEID - Return Machine ID. PACKNAME - Return current pack name. PROGNAME - Return program name. ROLLOUT - Roll out job for specified time period. SETJCR - Set contents of Job Control Registers. USERNUMBER - Return current user number. SYSPROC.82 1 SYSPROC - Pascal-6000 System Communication Procedures 27 May 86 Each description below specifies the procedure or function heading that is declared by the SYSPROC include package. Functions: ---------- FUNCTION JOBORIGIN : INTEGER; | This function returns as its value, the job origin type of the | current job. | FUNCTION USERINDEX : INTEGER; This function returns as its value, the user index of the current job. This is an integer between 0 and 131071 (377777B). Procedures: ----------- PROCEDURE ABORT; | This procedure aborts the program. Internally-declared Pascal | files might not be returned. | PROCEDURE CLEARBDISPLAY; | This procedure clears the console B display. Same as using | MESSAGE(' ',1). | PROCEDURE ENDRUN; Calling this procedure causes an immediate termination of the program. Internally-declared Pascal files might not be returned. PROCEDURE EXCST(CS : PACKED ARRAY [LO .. HI : INTEGER] OF CHAR); This procedure ends the program, places the command string CS in the control statement stream, and transfers control to the system. This procedure, like ENDRUN, immediately terminates the Pascal program. Internal files might not be returned. PROCEDURE FAMILY(VAR FM : ALFA); This procedure returns the current family name to the ALFA variable FM. PROCEDURE GETJCR(REG : INTEGER; VAR N : INTEGER); This procedure returns the contents of Job Control Register REG (where REG is 1, 2, or 3) to the integer variable N. If REG is not 1, 2, or 3, then 0 is returned to N. SYSPROC.83 1 SYSPROC - Pascal-6000 System Communication Procedures 27 May 86 PROCEDURE JOBNAME(VAR JN : ALFA); This procedure returns the name of the current job to the ALFA variable JN. Jobnames are seven characters long, so the last three characters of JN will always be blank. PROCEDURE MACHINEID(VAR MID : ALFA); This procedure returns the current machine ID to the ALFA variable MID. The machine ID is two characters long, so the remaining eight characters are blanks. At the University of Minnesota, this routine returns a machine ID which can be one of the following: __ _______ + ID Machine CA Cyber A (Cyber 845) ME MERITSS (Cyber 174) MD MERITSS D (Cyber 825) PROCEDURE PACKNAME(VAR PN : ALFA); This procedure returns the current pack name to the ALFA variable PN. The last three characters of the pack name are blanks, because a pack name must be seven characters or less. PROCEDURE PROGNAME(VAR PRG : ALFA); This procedure returns the name of the executing program (stored in RA+PGNR). The name is space-filled and returned to the ALFA variable PRG. PROCEDURE ROLLOUT(SECONDS : INTEGER); This procedure rolls out the current program (in WAIT mode) for approximately the number of seconds specified as SECONDS. The parameter should be a number between 0 and 262080 (777700B). If the parameter is negative, or larger than 262080, then a rollout of one is assumed. PROCEDURE SETJCR(REG : INTEGER; N : INTEGER); This procedure sets the contents of the Job Control Register REG to the integer value N. REG must be 1, 2, or 3. N must be between 0 and 131071 (377777B). If these conditions are not met, the procedure returns without changing anything. PROCEDURE USERNUMBER(VAR UN : ALFA); This procedure returns the current user number to the ALFA variable UN. This parameter is space-filled. SYSPROC.84 1 TSAIDS - Pascal 6000 Interactive Computing Aids 27 May 86 Interactive Computing Aids ========================== NOTE: This package is available only at sites running the NOS 1 or NOS 2 operating systems. TSAIDS is a package of routines that allows interactive users to interrogate terminal status and to set various aspects of interactive terminal control. TSAIDS includes several TYPE declarations, five procedures, and one function. The declarations for TSAIDS may be included in your program by inserting the following compiler directive immediately after your program heading. (*$I'TSAIDS' INTERACTIVE COMPUTING AIDS DECLARATIONS. *) TSAIDS defines the following symbols: TYPE CSETMODE = (CSETNORMAL,CSETEXTENDED,CSETRESTORE); The type of the terminal mode character set. PARITYMODE = (EVENPARITY,ODDPARITY); The type of terminal parity. DUPLEXMODE = (HALFDUPLEX,FULLDUPLEX); The type of terminal transmission duplex mode. TERMINALMODE = (LINEMODE,SCREENMODE); Mode of the terminal. TERMINALMODEL = (TMNONE,TMUSER,TM721,TM722,TMVT100,TMZ19); Terminal model. TERMSTATUS = PACKED RECORD A record describing the current terminal status: NAME: ALFA; | The name of the current character set (i.e. TTY, TTYD, etc.). PAD1 : 0..77777777777777B; | Not used. | SUBSYSTEM: 0..77B; The ordinal of the current TELEX subsystem. NUMBER: 0..7777B; The port number of the terminal. PAD2: 0..77B; | Not used. | | TSAIDS.85 1 TSAIDS - Pascal 6000 Interactive Computing Aids 27 May 86 CONNECTSTAT: 0..77B; | Connection status. Not used under NOS 1. | | PAD3: 0..17B; | Not used. | TERMCLASS: 0..377B; | Terminal class. INTERRUPT: 0..777777B; Interrupt address. TRANSCODE: 0..77B; Transmission code. PAD4: 0..177B; | Not used. TAPEMODE: BOOLEAN; A BOOLEAN variable which is TRUE if the terminal is in TAPE mode. DUPLEX: DUPLEXMODE; The current transmission mode of the terminal. CURRENTCSET: CSETNORMAL..CSETEXTENDED; | The current character set mode of the terminal. INITIALCSET: CSETNORMAL..CSETEXTENDED; | The initial character set mode of the terminal. PARITY: PARITYMODE; Describes the current parity of the terminal. END; PROCEDURE CSET(C: CSETMODE; SETINIT : BOOLEAN); Sets the current character set for the terminal. If SETINIT is true, then the initial character set is also set. CSET may not be called with CSET(CSETRESTORE,TRUE). Has no effect if called from a non-interactive job. PROCEDURE DISABLE(VAR INTERRUPT: BOOLEAN); Disables terminal interrupt control and sets the variable INTERRUPT to FALSE. INTERRUPT will be set to TRUE if an interrupt is attempted from the terminal. Note that the variable INTERRUPT should be declared in the main program, or if it is declared at a higher level, the ENABLE procedure should be called before the program returns from that level. If called from a non-interactive job, the variable INTERRUPT will never be set to TRUE. For U of MINN only: PROCEDURE DUPLEX(DPLX : DUPLEXMODE); Sets the current terminal duplex. Has no effect if called from a TSAIDS.86 1 TSAIDS - Pascal 6000 Interactive Computing Aids 27 May 86 non-interactive job. PROCEDURE ENABLE; Re-enables terminal interrupts. Has no effect if called from a non-interactive job. FUNCTION TTYFILE(VAR F: TEXT): BOOLEAN; A BOOLEAN function that returns TRUE if the specified file is assigned to an interactive terminal. PROCEDURE PARITY(P: PARITYMODE); Sets the current terminal parity. Has no effect if called from a non-interactive job. PROCEDURE PROMPT(ON: BOOLEAN); Enter (TRUE) or exit (FALSE) terminal prompt mode. Has no effect if called from a non-interactive job. PROCEDURE GETTM(VAR TMD: TERMINALMODE; VAR TMDL: TERMINALMODEL); | Get terminal mode and model. Only has effect at sites that have | the SETSLM macro. | PROCEDURE SETTM(TMODE: TERMINALMODE; TMODEL: TERMINALMODEL); | Set terminal mode and model. Only has effect at sites that have | the SETSLM macro. | PROCEDURE TSTATUS(VAR S: TERMSTATUS); Sets the various fields in S that describe the current status of an interactive terminal (see above). If called from a non-interactive job the NAME will be all blanks, the subsystem, number and rubouts will be zero, DISABLED, BRIEFMODE and TAPEMODE will be FALSE, DUPLEX and PARITY will be HALFDUPLEX and NORMAL (respectively) and CURRENTCSET and INITIALCSET will both be NORMAL. PROCEDURE WRITECB(VAR F: TEXT; CB: INTEGER); | Write control byte to a textfile. A control byte is a 12-bit | (0..4095) quantity that can control the positioning of prompt | characters and can define alternate input and output modes. | Normally, control bytes are written to OUTPUT, since OUTPUT is | usually connected to the terminal. For more information on | control bytes, refer to chapter 12 of the NOS 1 Reference Manual, | Volume 2 (or NOS 2 Reference Manual, Volume 4). | TSAIDS.87