18 SOFTWARE SUPPORT MANUAL
40 This document file was created by scanning the
41 original document and then editing the scanned
42 text. As much as possible, the original text
43 format was restored. Some format changes were
44 made to insure this document would print on
45 current laser printers using 60 lines per page,
46 which changed the page numbering. The original
47 spelling and grammar have been preserved.
75 SOFTWARE SUPPORT MANUAL
102 ----------------------------------------------------------
103 | For additional copies, order No. DEC-S8-LFSSA-A-D |
104 | from Software Distribution Center, Digital Equipment |
105 | Corporation, Maynard, Mass. |
106 ----------------------------------------------------------
109 digital equipment corporation - maynard, massachusetts
130 Copyright (c) 1973 by Digital Equipment Corporation
146 The following are trademarks of Digital Equipment Corporation,
147 Maynard, Massachusetts:
149 CDP DIGITAL KA10 PS/8
150 COMPUTER LAB DNC LAB-8 QUICKPOINT
151 COMTEX EDGRIN LAB-8/e RAD-8
152 COMSYST EDUSYSTEM LAB-K RSTS
153 DDT FLIP CHIP OMNIBUS RSX
155 DECCOMM GLC-8 PDP SABR
156 DECTAPE IDAC PHA TYPESET 8
177 CHAPTER 1 THE F4 COMPILER 1-1
179 CHAPTER 2 THE RALF ASSEMBLER 2-1
181 CHAPTER 3 THE FORTRAN IV LOADER 3-1
183 CHAPTER 4 THE FORTRAN IV RUN-TIME SYSTEM 4-1
185 CHAPTER 5 LIBRA AND FORLIB 5-1
187 APPENDIX A RALF Assembler Permanent Symbol Table A-1
189 APPENDIX B Assembly Instructions B-1
236 The OS/8 F4 compiler runs in 8K on either a PDP-8 or a PDP-12. It
237 operates in three passes to transform FORTRAN IV source programs into
238 RALF assembly language. The function of each of the three passes is:
240 1. Analyze statements, check syntax and convert to a polish
243 2. Convert output of PASS1 to RALF assembly language making
244 extensive use of code skeleton tables.
246 3. Produce a listing of the FORTRAN source program and/or chain
249 The following is a more complete description of each of the three
256 After opening the source language input file(s) and an intermediate
257 output file, PASS1 processes statements in the following fashion:
259 1. Assemble a statement into the statement buffer by reading
260 characters from the OS/8 input file. This section eliminates
261 comments and handles continuations so that the statement
262 buffer contains the entire statement as if it had been
263 written on one long line.
265 2. The statement is first assumed to be an arithmetic assignment
266 and an attempt is made to compile it as such. This is done
267 with a special switch (NOCODE) set so that in the event the
268 statement is not arithmetic, no erroneous output is produced.
269 Thus, with this switch set, the expression analyzer
270 subroutine is used merely as a syntax checker.
272 3. If the statement is indeed an arithmetic assignment statement
273 (or arithmetic statement function) the switch is set off and
274 the statement is then recompiled, this time producing output.
276 4. If not an arithmetic assignment, the statement might be one
277 of the keyword defined statements. The compiler now checks
278 the first symbol on the line to see of it is a legal keyword
279 (REAL, GOTO, etc.) and jumps to the appropriate subroutine if
280 so. Any statement that is not now classified is considered
283 5. The compilation of each statement takes place. Some state-
284 ments produce only symbol table entries (e.g., DIMENSION)
290 which will be processed by PASS2. Others use the arithmetic
291 expression analyzer (EXPR) and also output special purpose
292 operators which will tell PASS2 what to do with the value
293 represented by the arithmetic expression (e.g., IF, DO).
295 6. After the statement has been processed, control passes to the
296 end-of-statement routine which handles DO-loop terminations
297 and then outputs the end-of-statement code.
299 7. Statements containing some kind of error cause a special
300 error code to be output.
302 8. The entire process is now repeated for the next statement.
304 9. When the END statement is encountered, PASS1 chains to PASS2.
310 A significant portion of the PASS1 processing involves the production
311 of symbol table entries. These entries contain all storage related
312 information, i.e., variable name, type, dimensions, etc.
314 The symbol table is organized as a set of linked lists. The first 26
315 such lists are for variables, with the first letter of the variable
316 name corresponding to the ordinal number of the list. There are also
317 separate lists for statement numbers and literals (integer, real,
318 complex, double, and Hollerith). In addition to list elements, there
319 are special entries for holding DIMENSION and EQUIVALENCE information.
321 A detailed description of each type of entry follows. (NOTE: All
322 symbol table entries are in Field 1.)
324 1. VARIABLE - The first word of each entry is a pointer to the
325 next entry, with a zero pointer signaling end of list. The
326 second word contains type information. The third word points
327 to the dimension and/or equivalence information blocks. The
328 next one to three words contain the remainder of the name
329 (the first character is implied by which list the entry is
330 in) in stripped six-bit ASCII terminated by a zero character.
331 Thus, shorter variables take less symbol table space. The
332 entries are (as for all lists in the symbol table) arranged
333 in order of increasing magnitude, or alphabetically.
354 DIMENSION/EQUIVALENCE | ------> |
366 0 1 2 3 4 5 6 7 8 9 10 11
367 ----------------------------------------------------------------------
368 | C | D | E | A | E | E || L | A | T || Y | P | E |
369 | O | I | X | S | Q | X || I | R | || | | |
370 | M | M | T | F | U | P || T | G | || | | |
371 | | | | | I | L || | | || | | |
372 | | | | | V | I || | | || | | |
373 | | | | | | C || | | || | | |
374 ----------------------------------------------------------------------
378 0 - Variable is in common.
379 1 - Variable is dimensioned.
380 2 - External symbol or subroutine/function name.
381 3 - Symbol is the name of an arithmetic statement function.
382 4 - Variable is an equivalence slave.
383 5 - Variable is explicitly typed.
384 6 - Entry is a literal.
385 7 - Variable is a formal parameter.
393 - 9 common section name
395 2. STATEMENT NUMBER - The first two words are the standard
396 pointer/type. The next three words are the statement number,
397 with leading zeros deleted, in stripped six-bit ASCII, filled
398 to the right with blanks.
419 3. INTEGER OR REAL LITERALS - The first two words are the
420 pointer and type. The next three words are the value in
421 standard floating-point format (12-bit exponent, 24-bit
422 signed 2's complement mantissa). Since the type of the
423 literal must be preserved, there are two lists; hence use of
424 1 and 1.0 in the same program will cause one entry in each of
425 the integer and real literal lists.
439 4. COMPLEX LITERALS - The first two words are standard. The
440 next three are the real part in standard floating-point
441 format. The next three are the imaginary part.
450 REAL MANTISSA 0-11 | A |
452 REAL MANTISSA 12-23 | |
454 IMAGINARY EXPONENT | IM |
456 IMAGINARY MANTISSA 0-11 | GIN |
458 IMAGINARY MANTISSA 12-23 | RY |
467 5. DOUBLE PRECISION LITERALS - The first two words are standard.
468 The next six are the literal in FPP extended format (12-bit
469 exponent, 60-bit mantissa).
489 6. HOLLERITH (quoted) LITERALS - The first two words are stan-
490 dard. The next N words are the characters of the literal in
491 stripped six-bit ASCII, ending in a zero character.
503 7. DIMENSION INFORMATION BLOCK - If a variable is DIMENSIONed,
504 the third word of its symbol table entry will point to its
505 dimension information block (may be indirectly, see section
506 8 below). The first word of this block is the number of
507 dimensions. The second word is the total size of the array
508 in elements; thus the size in PDP-8 words may be 3 or 6 times
509 this number. The third word contains the "magic number"
510 which is computed as follows:
516 where d(j) is the jth dimension and n is the number of
526 For a 3-dimensional variable this number becomes:
530 The magic number must be subtracted from any computed index,
531 since indexing starts at one and not zero. The fourth word
532 will (in PASS2) contain the displacement from #LIT of a
533 literal which will contain either the magic number in
534 un-normalized form (for dimensioned variables which are
535 subroutine arguments) or the address of the variable minus
536 the magic number (for local or COMMON dimensioned variables).
537 This literal is necessary for calling subroutines where a
538 subscripted variable is an argument. The next N words are
539 the dimensions of the variable. If the variable is a formal
540 parameter of the subroutine, it may have one or more dimen-
541 sions which are also formal parameters. In this case, the
542 magic number is zero, and the dimension(s) is a pointer to
543 the symbol table entry for the variable(s) used as a dimen-
547 NUMBER OF DIMENSIONS | # |
549 TOTAL NUMBER OF ELEMENTS | SIZE |
564 8. EQUIVALENCE INFORMATION BLOCK - If a variable is an
565 EQUIVALENCE slave variable, the third word of its symbol
566 table entry points to the equivalence information block.
567 The first word of this block points to the dimension infor-
568 mation (if any) of the variable. The second word points to
569 the symbol table entry of the EQUIVALENCE master variable.
570 The third word is the linearized subscript of the master
571 variable from the EQUIVALENCE statement. The fourth word is
572 the linearized subscript of the slave variable.
586 POINTER TO DIMENSIONS | ------> |
588 POINTER TO MASTER | ------> |
590 MASTER SUBSCRIPT | SSM |
592 SLAVE SUBSCRIPT | SSM |
595 9. COMMON INFORMATION BLOCK - If a symbol is defined as the name
596 of a COMMON section, the third word of its symbol table entry
597 points to a list of common information blocks. The first
598 word of each such block points to the next block. The second
599 word is the number of entries in the list that follows. The
600 rest of the block is a set of pointers to the symbol table
601 entries of the variables in the COMMON section.
604 POINTER TO NEXT CIB | ------> |
606 NUMBER OF ENTRIES | # |
610 POINTER TO VARIABLES < | ------> |
611 IN THIS COMMON | |-------------|
619 The output of PASS1 is a stream of polish with many special operators.
620 Whenever an operand is to be output, the address of its symbol table
621 entry is used. The following is a list of the output codes (in their
622 mnemonic form, obtain numeric values from listing of PASS1) and the
623 operation they are conveying to PASS2:
625 PUSH The next word in the output file is an operand
626 (symbol table pointer) to be put onto the stack.
628 ADD Add the operands represented by the top two stack
629 entries (actually this causes PASS2 to generate
630 the RALF coding which will do the desired add).
632 SUB Subtract top from next-to-top.
634 MUL Multiply top two.
636 DIV Divide top into next-to-top.
638 EXP Raise next-to-top to power of top.
644 NOT Logical .NOT. of top of stack.
646 NEG Negate top of stack.
648 GE Compare top two for greater than or equal to, this
649 has TRUE value if the next-to-top is .GE. the top.
651 GT Compare for greater than.
653 LE Compare for less than or equal.
655 LT Compare for less than.
657 AND Logical AND of top two entries.
659 OR Logical inclusive OR of top two.
661 EQ Compare top two for equality.
663 NE Compare top two for inequality.
665 XOR Exclusive OR of top two.
667 EQV EQUIVALENCE of top two.
669 PAUSOP Use top of stack as PAUSE number.
671 DPUSH The next two words are a symbol table pointer and
672 a displacement; put them onto the stack (used for
675 BINRD1 Take the top of stack as the unit number and com-
676 pile an unformatted READ-open.
678 FMTRD1 The top two stack elements are the unit and
679 format, take them and compile a formatted READ-
682 RCLOSE Compile a READ-close.
684 DARD1 Take the top two stack elements as a unit number
685 and a block number and compile a direct access
686 unformatted READ-open.
688 FMTWRI |> Same as for the corresponding READ case, except
689 WCLOSE | substitute the word "WRITE".
692 DEFFIL Take the top four stack entries as the unit,
693 number of records, record size, and index
694 variable and compile a DEFINE FILE call.
696 ASFDEF Set the PASS2 switch which says that the following
697 statement is an arithmetic statement function.
703 ARGSOP The next word is a count, call it n; take the
704 previous n stack entries as subscripts (or
705 arguments) and the N+1st entry from the top as
706 the array (or function) name; now compile this
707 as an array reference (or function/subroutine
710 EOLCOD The current statement is completed, reset stacks
711 and do other housekeeping.
713 ERRCOD The following word contains an error code, write
714 it on the TTY together with the current line
715 number, and put the error code and line number
716 into the error list for possible PASS3.
718 RETOPR Compile a subroutine RETURN.
720 REWOPR Take the top of stack as a unit and compile a
723 STOROP Compile a store of the top of stack into the
726 ENDOPR Compile a RETURN if a function or subroutine or
727 a CALL EXIT if a main program.
729 DEFLBL The following word is a symbol table pointer to
730 a statement number, compile this as the tag for
731 the current RALF line.
733 DOFINI The following word is a symbol table pointer for
734 the DO-loop index, compile the corresponding
737 ARTHIF The following one, two, or three words are symbol
738 table pointers to statement numbers for the less
739 than zero, zero, and greater than zero conditions
740 with the comparison to be made on the top of
743 LIFBGN The top of stack is taken as a logical expression
744 PASS 2 should compile a jump-around-on-false; this
745 implies that some statement is to follow.
747 DOBEGN The top two stack entries represent the final
748 value and increment of the DO-loop, process them
749 in hopes of finding a matching DOFINI.
751 ENDFOP The top of stack is a unit, compile an END FILE.
753 STOPOP Compile a CALL EXIT.
762 ASNOPR The next word is the address of the symbol table
763 entry for a statement number; compile an ASSIGN
764 of this statement number to the variable
765 represented by the top of stack.
767 BAKOPR Take the top of stack as the unit and compile
770 FMTOPR The following word is a count N; the next N words
771 after that are the image of the FORMAT statement.
773 GO2OPR The following word is the symbol table entry for
774 the statement number which is to be executed next.
776 CGO2OP The following word is a count N; the next N words
777 are symbol table pointers for the statement
778 numbers of a computed GO TO list; use the value
779 represented by the top of stack to compile a
780 computed GO TO into this list.
782 AGO2OP Compile an assigned GO TO with the top of stack.
784 IOLMNT Take the top of stack as a list element for an
785 I/O statement and compile read or write; PASS2
786 knows if it is a READ or WRITE by remembering
787 previous FMTRD1, FMTWR1, etc.
789 DATELM The next word is a count N; the next N words are
792 DREPTC The next word is a repetition count for the set
793 of DATELMs up until the next ENDELM.
795 ENDELM Signals the end of a data element group.
797 PRGSTK Tells PASS2 to purge the top stack entry.
799 DOSTOR Performs the same function as STOROP after
800 checking the top two stack elements for legal
801 DO-parameter type (integer or real).
807 The following is a brief description of the function of each of the
808 major PASS1 subroutines:
810 RDWR Compiles everything in a READ or WRITE statement
811 starting at the first left parenthesis.
813 RESTCP Restore character pointer and count for the
814 statement buffer from the stack.
821 OUTWRD Output a word (the AC on entering) to the PASS1
824 COMARP Test for comma or right parenthesis, skip one
825 instruction if a comma, two if a right
826 parenthesis, and none if neither.
828 BACK1 Backup the statement buffer character pointer.
830 GETSS Scans a variable reference, or subscripted
831 variable reference with numeric subscripts and
832 returns the linearized subscript.
834 MUL12 Perform a 12-bit unsigned integer multiply.
836 DOSTUF Handles compilation of DO-loop setup.
838 TYPLST Process a type declaration, DIMENSION, or
839 COMMON statement; sets up type bits and/or
840 dimension information.
842 LOOKUP Perform a symbol table search for variables and
845 LUKUP2 Perform a symbol table search for integer, real,
846 complex, and double precision literals or
849 EXPR Analyze and process an arithmetic expression.
851 LETTER Get next character from the statement buffer and
852 skip if it is a letter, otherwise put the
853 character back and don't skip.
855 CHECKC The first word after the JMS is the negative of
856 the ASCII character to test for; if this is the
857 next character, skip.
859 GETCWB Get the next character from the statement buffer
862 SAVECP Save the character pointer and count on the stack.
864 GETC Get the next character ignoring blanks.
866 ERMSG Output an error code to PASS1 output file.
868 POP Pop the stack into the AC.
870 PUSH Push the AC onto the stack.
872 LEXPR Analyze and process an arithmetic expression,
873 legal to the left of the equal sign in an
874 assignment statement.
879 GET2C Get the next two character into one word.
881 STMNUM Scan off a statement number and do the symbol
884 DIGIT Same as letter, except checks for a digit.
886 NUMBER Scans off an integer, real, or double precision
889 GETNAM Scan off a variable name.
891 ICHAR Get the next character from the input file.
897 The first part of PASS2 generates the storage for variables,
898 arguments, arrays, literals and temporaries by processing the symbol
899 table built by PASS1, which is kept in core. The next step is to
900 generate the code for subroutine entry and exit including argument
901 pickup and restore. After all such prolog code is generated, PASS2O
902 is loaded into core, overlaying most of the prolog-generating
903 functions. The main loop of the compiler is now entered. This
904 consists simply of reading a PASS1 output code from the intermediate
905 file and using this number as an index into a jump table. The
906 sections of code entered in this way then perform the correct
907 generation of RALF code.
911 The statement: A=B+C*D
912 would produce the following PASS1 output:
913 (assuming A,B,C,D are REAL)
916 ->A (symbol table address of A)
939 The corresponding operations performed by PASS2 are:
941 1) Make a 3-word entry on the stack corresponding to the
942 variable A consisting of a pointer to the symbol table
943 entry, a word containing the type, and one reserved word.
945 2) Repeat above for B.
947 3) Repeat above for C.
949 4) Repeat above for D.
951 5) The multiply operator is handled like any of the binary
952 operators by the subroutine CODE. This routine is called
953 with the address of the multiply skeleton table. The
954 top two stack entries are taken as the operands, with
955 their types used to index into the skeleton tables.
956 (See description of binary operator skeleton tables below.)
957 The correct skeleton for this combination is chosen based on
958 the where-abouts of each of the operands (AC or memory)
959 at the corresponding point in the code which is being
960 compiled. There are three possible cases: Memory,AC;
961 Memory,Memory; AC,Memory. In this example, both operands
962 are in memory so the code generated would be:
968 The CODE subroutine then makes a new stack entry to replace
969 the entries for C and D. This entry has a 0 in place of
970 the symbol table pointer, signifying that the operand is in
971 the AC. Other special case operand codes are:
973 0 - AC ( Already mentioned)
977 52 - 60 Array reference, the subscript of which is in
978 an index register (1-7).
980 61 - A variable, the address of which is in base
983 62 - A variable, the address of which is in base
986 63-6777 - Symbol table entry (can be variable or
989 7000 - Special temporary
998 6) The add operator is handled in the same way as for multiply,
999 except that in this case the add skeleton table is used.
1000 When the correct row is found, the memory,AC case is chosen
1001 since the result of C*D is now in the AC. This skeleton
1006 The new top of stack entry is a 0, since the result is in
1009 7) The store operation works in a similar manner using a special
1010 skeleton table to determine whether the value to be stored is
1011 already in the AC and whether it must be converted from one
1012 type to another. In this case, no conversion need be
1013 performed and the code generated is:
1017 8) The end of statement has been reached and any necessary
1018 bookkeeping is performed.
1024 PASS2 modifies the symbol table entries corresponding to variables
1025 by replacing the first word of the entry with the first character of
1026 the name, this character being derived from the list in which the name
1033 PASS2 creates a list (in field 1) of error codes and line numbers
1034 corresponding to the errors printed on the Teletype during PASS2.
1035 This list works downward starting just below the skeleton table area,
1036 working towards the symbol table area. PASS3 uses this list to
1037 write out extended error messages on the listing.
1041 PASS2 SKELETON TABLES
1043 All binary operators have associated with them a skeleton table
1044 having 24 entries arranged in 8 rows and 3 columns. The rows
1045 correspond to the following eight possibilities:
1047 1) Both operands integer or real.
1048 2) Both operands complex.
1049 3) Both operands double precision.
1050 4) First operand integer or real, second complex.
1051 5) First operand integer or real, second double precision.
1057 6) First operand complex, second integer or real.
1058 7) First operand double precision, second integer or real.
1059 8) Both operands logical.
1061 The columns correspond to the following three possibilities:
1063 1) First operand in memory, second in AC.
1064 2) Both operands in memory.
1065 3) First operand in the AC, second in memory.
1067 Each entry of the skeleton tables is either zero (illegal operator-
1068 type combination) or points to a code skeleton (minus one). Code
1069 skeletons are composed of combinations of the following types of
1072 1) OPCODES - If an element has a non-negative value, it is taken
1073 as the address of a text string for the desired opcode. This
1074 works since all such text strings are stored below location
1075 4000 (in field 0). In this case, the next word of the
1076 skeleton is taken as a designator for the address field, the
1079 a. A non-negative values means the address field is a
1080 literal text string, with the value being the address of
1081 the string. (Same restriction as for opcode text
1084 b. A zero indicates that this instruction should have no
1087 c. A minus one indicates that the address field is the
1088 operand defined by the three variables ARG1, TYPE1, and
1091 d. A minus two indicates that the address field is the
1092 operand defined by the three variables ARG2, TYPE2, and
1095 2) MODE CHANGE - An element value of minus one means generate a
1096 STARTF if currently in extended mode. A value of minus two
1097 means generate a STARTE if currently in single mode.
1099 3) MACRO - Any other negative value is taken as the address
1100 (minus 3) of a sub-skeleton. This sub-skeleton may contain
1101 anything except another sub-skeleton reference. When the
1102 end of the sub-skeleton is encountered, the main skeleton is
1105 4) END-OF-SKELETON - A zero indicates the end of the skeleton.
1118 The following is a list of the major PASS 2 subroutines together with
1119 a brief functional description.
1121 ERMSG Output a 2-character error code together with the
1122 line number on the Teletypes; also put the code and
1123 line number into the error list for PASS3.
1125 UCODE Generate the code for unary operators, given the
1126 skeleton table address.
1128 CODE Generate code for binary operators, given the
1129 skeleton table address.
1131 INWORD Read a word from the PASS1 output file.
1133 FATAL Output a fatal error message and exit to OS/8.
1135 ONUMBER Output the AC as a 4-digit octal number.
1137 SAVEAC Generate an FSTA #TMP+XXXX if necessary.
1139 GENCOD Generate the code specified by the given code
1142 OPCOD Output a TAB followed by the specified opcode
1145 OPCODE Same as OPCOD, except output a second TAB after
1148 OADDR Generate the address field specified by the
1151 GENSTF Generate STARTF if in E mode.
1153 GENSTE Generate STARTE if in F mode.
1155 OSNUM Output a statement number preceded by a "#".
1157 CRLF Output a carriage return/line feed.
1161 OUTSYM Output a text string.
1163 GARG Pop the top entry of the stack into ARG1, TYPE1,
1166 GARGS Pop the top two stack entries into ARG1, TYPE1,
1167 BASE1 and ARG2, TYPE2, BASE2.
1169 OUTNAM Output a variable name.
1175 OLABEL Output a generated label.
1177 GETSS Find the address of the dimension information
1178 block given the symbol table address.
1180 SKPIRL Skip if integer, real, or logical.
1182 GENCAL Generate the code for a subroutine call from
1183 the information contained on the stack.
1185 MUL12 Do a 12-bit unsigned multiply.
1187 OINS Output a literal opcode and address field.
1189 OCHAR Output a character
1191 NUMBRO Output a 5-digit octal number.
1197 PASS3 first initializes the listing header line with the version
1198 number, date, and page number. It then processes lines, much like
1199 PASS1, handling continuations and comments and outputs their image
1200 to the listing file together with the line number. A constant check
1201 is made on the error message list for line numbers that correspond
1202 to the current line number, When such a correspondence occurs, the
1203 error code is used to find the associated detailed error message,
1204 which is then printed out.
1239 RALF and FLAP are essentially the same program, with differences con-
1240 trolled by the conditional assembly parameter RALF, which must be
1241 nonzero to assemble RALF, or zero to assemble FLAP. The source may be
1242 assembled by either PAL8 or FLAP; although FLAP flags one error (a US
1243 on a FIELD statement), this may safely be ignored. The remainder of
1244 this chapter applies to RALF only. The following definitions are pre-
1245 requisite to discussion of the operation of this assembler.
1247 MODULE The relocatable binary output of an assembly. A module
1248 is physically an OS/8 file or sub-file in a library,
1249 and is made up of an external symbol dictionary and
1250 related text. Logically, it consists of one or more
1251 program sections and COMMON sections.
1253 LIBRARY An OS/8 file on a directory device containing a catalog
1254 and one or more modules as sub-files. Used solely by
1255 the loader, as a source of modules with which to
1256 satisfy unresolved symbols in a program being loaded.
1258 CATALOG A list of entry points defined in modules contained in
1259 a library, with an indication of the locations of the
1260 modules which define them.
1262 EXTERNAL A list of the global symbols defined in and/or used by
1263 SYMBOL a module. Usually called ESD table.
1266 TEXT That part of the assembler's binary output which
1267 contains the binary data to be loaded into memory,
1268 along with sufficient information for the loader to
1269 associate the output with specific memory locations
1270 through references to the ESD table.
1272 SECTION A unit of binary data output by the assembler as part
1273 of a module to be loaded into a contiguous area of
1274 memory. COMMON sections are a special case in that
1275 they may be defined with the same name in each of many
1276 modules. In this case, all the definitions are combined
1277 to create a single section in memory whose size is that
1278 of the largest COMMON section with the given name.
1279 Program sections, the only other type of section, must
1280 have unique names. Sections are listed in the ESD
1281 table by name, type and size.
1283 ENTRY POINT An address within a section which is named and defined
1284 to be global, so that it may be used for the resolution
1285 of external references in other sections. Entry points
1286 are listed in the ESD table by name, type and address
1287 within the section in which they occur.
1293 EXTERNAL A symbol which is specified at assembly time to be
1294 SYMBOL defined in another module as an entry point. External
1295 symbols are listed in the ESD table by name and type.
1296 A complete program must include entry point names
1297 equivalent to every external symbol defined in every
1298 module in the program. There need not, however, be an
1299 external symbol for every entry point, nor is there any
1300 limit on the number of modules which may contain
1301 external symbols referencing one entry point. From a
1302 functional viewpoint, entry points correspond to tags
1303 within a program and external symbols correspond to
1304 references to those tags. Every section is considered
1305 to have an entry point at location zero of the section.
1306 The name of this entry point is the section name.
1308 When RALF is called from the monitor, execution begins at the tag
1309 BEGIN. Unless entry is via CHAIN, the OS/8 command decoder is called
1310 to obtain input and output file designations. If entry is by way of
1311 CHAIN, it is assumed that the command decoder area has already been
1312 set up by the caller. In either case, it is always assumed that the
1313 USR is already in core. A check is made to determine that the first
1314 output file is a directory device file and, if no first output file
1315 was specified, the default file SYS:FORTRN.RL is set up.
1317 Default output file extensions are defined if none were specified to
1318 the command decoder, using .RL for the first output file and .LS for
1319 the second output file. The first output file is then opened, and the
1320 handler for the first input file is FETCHed. If /L or /G was
1321 specified, the loader is looked up on SYS so that chaining will be
1322 possible. The symbol table, which is loaded above 12000 in order to
1323 preserve the USR, is now moved down to 10000. Finally, the system
1324 date word is converted to character form and stored in the title
1325 buffer. This completes the initialization procedure, and control is
1326 passed to NEWLIN to collect the first line in the buffer.
1328 At NEXTST, teats are made to determine whether the line just assembled
1329 needs to be listed, and whether there are any remaining significant
1330 characters in the line which have not been assembled. If a semicolon
1331 terminated the statement, the character pointers are bumped to skip
1332 over it, and control passes to ASMBL to process the next statement on
1333 the line. If the assembler is currently in a REPEAT line and the
1334 count is not exhausted, the current line is re-assembled. Otherwise,
1335 a new line is obtained in the line buffer by collecting input
1336 characters until a carriage return is found. If the line is longer
1337 than 128 characters, all characters after the 128th are ignored and
1338 the LT message is printed. The line length is calculated and saved.
1340 At ASMBL, ASMOF is tested to determine whether the assembly is
1341 currently inside a conditional. If so, the line is scanned for angle
1342 brackets but not assembled. If not, and the first character is not a
1343 slash, leading blanks are thrown away and control passes to LUNAME.
1344 If there is a name, it is collected. If it is followed by a comma,
1345 the symbol is looked up in the user symbol table. If the symbol is
1346 undefined, it is defined as a label. If it was already defined, the
1352 current location counter is compared with it to check for a possible
1353 MD error. Control then returns to ASMBL.
1355 If the symbol found by LUNAME was followed by an equal sign, it is
1356 looked up and defined according to the expression to the right of the
1357 equal sign. If it was followed by a space, either of the characters
1358 ' or #, or the character % and then a space, it is looked up in the
1359 op-code table. If it is found, control passes to the appropriate
1360 op-code handler. Otherwise, control is dispatched to GETEXP which
1361 restores the character pointers saved by LUNAME, processes the rest of
1362 the line as a single-word expression, and returns to NEXTST for the
1365 Expressions are processed on a strict left-to-right basis by the
1366 routine EXPR. A symbol is looked up, and its value is stored in WORD1
1367 and WORD2. It is then combined with the accumulated expressions in
1368 EXPVAL according to the operator in LASTOP. A new operator (if any)
1369 is then located, and the loop begins again. When no operator is found
1370 after some symbol, the expression is considered complete and control
1371 returns to the calling routine. Undefined symbols appearing in an
1372 expression cause output of a US message, and the value zero is used
1373 in their place. COMMON and section names in the symbol table have
1374 special values (namely their lengths), but they always refer to the
1375 starting location of the sections they define, and their values are
1376 taken to be zero of the section so named. If GETNAM is not able to
1377 find a symbol in the expression, three possibilities are checked
1378 before flagging the expression as invalid:
1380 1. It may be a number, rather than a symbol.
1382 2. It may be one of the characters period (representing the
1383 current value of the location counter) or double quote
1384 (representing the binary value of the next ASCII character).
1386 3. The last operator may have been a plus sign in an indexed FPP
1389 At the end of expression evaluation, the console keyboard flag is
1390 checked to ensure that the user has not typed CTRL/C to stop the
1393 There are six expression operator routines, one each for the
1394 operations add, subtract, AND, OR, multiply and divide. Except for
1395 add and subtract, these routines must operate on absolute addresses
1396 because the loader does not have facilities for non-additive
1397 resolution of address constants.
1399 The symbol table is the sole occupant of field 1, except for the OS/8
1400 field 1 resident. The symbol table is loaded at location 12000 to
1401 prevent an unnecessary swap of the USR, but moved down, to start at
1402 location 10000, during initialization. Subsequent calls to the USR do
1403 require a swap. The symbol table is a set of linked lists, or, more
1404 properly, two sets; one for user-defined symbols and one for op-codes
1405 and pseudo-ops. Each set contains a list corresponding to every
1411 letter of the alphabet, and each list consists of the symbols which
1412 start with that same letter. Every time a symbol is encountered in
1413 the source, the list corresponding to its first letter is searched
1414 until a match is found, or until the end of the list or a symbol of
1415 higher alphabetical order is found. In the latter cases, the new
1416 symbol is inserted into the user symbol table by changing the list
1417 pointers so that the new symbol appears in the list in correct
1418 alphabetical order. The pre-defined symbol table is never changed,
1419 because the user is not permitted to define op-codes or pseudo-ops.
1421 A RALF output file of relocatable binary data consists of two parts;
1422 the ESD table and the text. The ESD table contains all information
1423 required by LIBRA or the loader, and is generated between the first
1424 and second passes of assembly. It serves as a partial symbol table
1425 for the loader (the full symbol table is built up from the ESD tables
1426 of all the modules in a program) and provides the name, attributes,
1427 and value of every global symbol used by any module, as well as an ESD
1428 code by which the symbol may be referred to within the text. Every
1429 entry in the ESD table is six words long. The first three words are
1430 the symbol itself, packed in stripped ASCII, with two characters per
1431 word. The next word contains type information in the following
1434 A VALUE OF INDICATES
1436 0 Last entry in the ESD table.
1438 1 The symbol is defined as external to this module. The
1439 value of the symbol must be resolved by a symbol of the
1440 same name appearing in the ESD table of another module.
1441 The ESD code which follows the type code is the code by
1442 which references to this symbol will be identified in the
1445 2 The symbol is defined as an entry point in this module.
1446 It is therefore suitable for the resolution of external
1447 references in other modules. The ESD code which follows
1448 the type word identifies the program section in which
1449 this entry point appears, and the value of the symbol is
1450 relative to that section.
1452 3 The symbol is defined as a COMMON section whose size is
1453 at least as large as specified by the value of the
1454 symbol. If several modules contain ESD entries referring
1455 to COMMON sections with the same name, a single COMMON
1456 block having the size of the largest symbol is allocated
1457 for all of them. A name consisting of blanks is treated
1458 in the same manner as any other name.
1460 4 The symbol is defined as a section of location
1461 independent (that is, fully word-relocatable) code of a
1462 size equal to the value of the symbol. The ESD code for
1463 this section allows text from the module to be included
1464 in this section, and relocated with respect to it.
1472 The text portion of a relocatable binary file consists of the binary
1473 data to be loaded into memory, along with information directing the
1474 loader on how to modify that data to correct the addresses for program
1475 relocation. The first word of text is a control word, which is made
1476 up of a 4-bit type code and an 8-bit indicator. Following the control
1477 word, and depending on the type code, are a number of data words to be
1478 loaded as directed by the type code and the indicator. The control
1479 word type codes are:
1483 0 End of text, if the indicator is zero, or no operation
1486 1 Copy the number of words given by the indicator from text
1487 directly into memory without modification.
1489 2 Re-origin to the section identified by the indicator,
1490 with a relative location defined by bits 9-23 of the
1491 following doubleword. Thus, the next two words define a
1492 new origin for the following text, in the program section
1493 identified by the indicator.
1495 3 Relocate the following doubleword bits 9-23 by the value
1496 of the symbol whose ESD code is identified by the
1497 indicator. The following doubleword is usually a two-
1498 word FPP instruction, the low-order 15 bits of which are
1499 to be relocated by the value of the symbol identified by
1504 WRITING PDP-8 CODE UNDER OS/8 FORTRAN IV
1507 RALF contains the normal set of PDP-8 instructions (TAD, DCA, CDF,
1508 KSF, etc.), however RALF does not allow literals, the PAGE pseudo-op,
1509 or the use of I to specify indirect addressing. PDP-8 code generated
1510 by RALF is not relocatable; therefore, operations such as the
1511 following are illegal:
1513 EXTERN SWAP /Illegal
1517 The character % appended to the end of a memory reference instruction
1518 indicates indirect addressing, and the character Z indicates a page 0
1529 CURRENT PAGE PAGE ZERO
1530 DIRECT INDIRECT DIRECT INDIRECT
1532 TAD A TAD% A TADZ A TADZ% A
1533 DCA B DCA% B DCAZ B DCAZ% B
1535 Spaces are not allowed between memory reference instructions and
1536 either the Z or the % characters. The Z must precede the % when both
1537 are used. I.e., do not write "DCA%Z".
1539 Three pseudo-ops have been added to RALF: SECT8, COMMZ, and FIELD1.
1540 All three define sections of code and are handled in the same manner
1541 as SECT; however, these new sections have special meaning for the
1542 loader. The address pseudo-op (ADDR) which generates a two word re-
1543 locatable 15 bit address (i.e., JA TAG without use of JA) might prove
1544 useful in 8-mode routines. The following example demonstrates a way
1545 in which an 8-mode routine in one RALF module calls an 8-mode routine
1551 RIF /Set DF to current
1552 TAD ACDF /IF for return
1555 TAD KSUB /Make a CIF from
1564 KSUB, ADDR SUB /Psuedo-op to
1571 In general the address pseudo-op can be used to supply an 8-mode
1572 section with an argument or pointer external to the section.
1574 FPP and 8-mode code may be intermixed in any RALF section. PDP-8 mode
1575 routines must be called in FPP mode by either:
1581 A TRAP3 SUB causes FRTS to generate a JMP SUB with interrupts on and
1582 the FPP hardware (if any) halted. TRAP4 generates a JMS SUB under the
1588 same conditions. The return from TRAP4 is:
1593 The return from TRAP3 is:
1601 Communication between FPP and 8-mode routines is best done at the FPP
1602 level because of greater flexibility in both addressing and relocation
1603 in FPP mode. The following routine demonstrates how to pass an argu-
1604 ment to, and retrieve an argument from, an 8-mode routine:
1615 FLDA SUBOUT /Get result
1618 If the 8-mode routine SUB were in the same module as the FPP routine,
1619 the externs would not be necessary. In practice it is common for FPP
1620 and 8-mode routines that communicate with one another to be in the
1621 same section. A number of techniques can be used to pass arguments.
1622 For example, an FPP routine could move the index registers to an
1623 8-mode section and pass single precision arguments via ATX.
1625 Because 8-mode routines are commonly used in conjunction with FPP code
1626 (generated by the compiler), the 8-mode programmer should be familiar
1627 with OS/8 FORTRAN IV subroutine calling conventions. The general code
1628 for a subroutine call is a JSR, followed by a JA around a list of
1629 arguments, followed by a list of pointers to the arguments. The FPP
1630 code for the statement:
1652 The general format of every subroutine obeys the following scheme:
1655 JA #ST /Jump to start of
1657 TEXT +SUB+ /Needed for
1659 RTN, SETX XSUB /Reset SUB's index
1660 SETB BSUB /And base page
1661 BSUB, FNOP /Start of base page
1665 ORG BSUB+30 /Restart for SUB
1667 GOBAK, FNOP:JA . /Return to
1670 Location 00000 of the calling routine's base page points to the list
1671 of arguments, if any, and may be used by the called subroutine
1672 provided that it is not modified. Location 0003 of the calling
1673 routine's base page is free for use by the called subroutine.
1675 Location 0030 of the calling routine's base page contains the address
1676 where execution is to continue upon exit from the subroutine, so that
1677 a subroutine should not return from a JSR call via location 0 of the
1685 The "non-standard" return allows the calling routine to reset its own
1686 index registers and base page before continuing in-line execution.
1687 General initialization code for a subroutine would be:
1696 #ST, STARTD /So only 2 words
1698 FLDA 30 /Get return JA
1700 FLDA 0 /Get pointer to list
1706 SETX XSUB /Set SUB's XR
1707 SETB BSUB /Set SUB's Base
1710 FSTA BSUBX /Store pointer
1715 STARTF /Set F mode before
1718 The above code can be optimized for routines that do not require full
1719 generality. The JA #ST around the base page code is a convenience
1720 which may be omitted. The three words of text are necessary only for
1721 error traceback and may also be omitted. If the subroutine is not
1722 going to call any general subroutines, the SETX and SETB instructions
1723 at location RTN and the JA RTN at location 0030 are not necessary. If
1724 the subroutine does not require a base page, the SETB instruction is
1725 not necessary in subroutine initialization; similar remarks apply to
1726 index registers. If neither base page nor index registers are
1727 modified by the subroutine, the return sequence:
1732 is also legal. In a subroutine call, the JA around the list of argu-
1733 ments is unnecessary when there are no arguments. A RALF listing of
1734 a FORTRAN source will provide a good reference of general FPP coding
1737 In order to generate good 8-mode code, one must be aware of the manner
1738 in which the loader links and relocates RALF code. The loader handles
1739 three 8-mode section types: COMMZ, FIELD1, and SECT8. All three
1740 types of section are forced to begin and end on page boundaries and to
1741 be a part of level MAIN; 8-mode sections never reside in overlays.
1742 COMMZ and FIELD1 sections are forced to reside in field 1; SECT
1743 sections may be in any field. The first COMMZ section encountered is
1744 forced to begin at location 10000, thus enabling a page 0 in field 1.
1745 COMMZ sections of the same name are handled like COMMON sections of
1746 the same name (i.e., they are combined into one common section). This
1747 feature allows 8-mode code in different modules to share page 0, pro-
1748 vided that the modules do not destroy each other's page 0 allocations.
1749 Suppose two modules were to share page 0, with the first using
1750 location 0-17 and the second using locations 20-37:
1765 . /Should not go over
1766 LASTA, -1 /20 locations
1776 ORG .+20 /ORG past module A's
1791 The two COMMZ sections will be put on top of one another, however,
1792 because of the ORG .+20 in module B, they will effectively reside back
1793 to back. When the image is loaded, the COMMZ sections will look as
1814 If module A is to reference module B's page 0, the procedure is:
1824 Alternately, a duplicate of the source code for COMMZ SHARE may be
1825 included in module B. Modules that are using the same COMMZ section
1826 must be aware of how it is divided up. Although COMMZ SHARE takes only
1827 40 locations, the loader allocates a full 200 locations to it. All
1828 8-mode section core allocations are always rounded up so that they
1829 terminate on a page boundary. If COMMZ sections of different names
1830 exist, they are accepted by the loader and inserted into field 1, but
1831 only one COMMZ is the real page 0. In general, it is unwise to have
1832 more than 1 COMMZ section name.
1834 FIELD1 sections are identical to COMMZ sections in most respects.
1835 Memory allocation for FIELD1 sections is assigned after COMMZ sections,
1836 however, and FIELD1 sections are combined with FORTRAN COMMON sections
1837 of the same name as well as other FIELD1 sections of the same name.
1838 The first difference ensures that COMMZ will be allocated page 0
1839 storage even in the presence of FIELD1 sections. The second allows
1840 PDP-8 code to be loaded into COMMON, making it possible to load
1841 initialization code into data buffers. Two FIELD1 sections with the
1842 same name may be combined in the same manner as two COMMZ, sections.
1844 The primary purpose of COMMZ is to provide a PDP-8 page 0; the primary
1845 purpose of FIELD1 is to ensure that 8-mode code will be loaded into
1846 field 1 and that generating CIF CDF instructions in-line is not neces-
1847 sary. SECT8 sections may not be combined in the manner of a COMMON
1848 and are not ensured of being placed into field 1.
1850 An 8-mode section does not have to be less than a page in length;
1851 however, the programmer should be aware that a SECT8 section which
1852 exceeds one page may be loaded across a field boundary and could
1853 thereby produce disastrous results at execution time. For this
1854 reason, it is generally unwise to cross pages in SECT8 code. This
1855 situation will never occur on an 8K configuration. If the total
1856 amount of COMMZ and FIELD1 code exceeds 4K, the loader generates an
1857 OVER CORE message. The loader generates an MS error for any of the
1860 1. A COMMZ section name is identical to some entry point or some
1861 non-COMMZ section name.
1863 2. A FIELD1 section name is identical to some entry point or a
1864 SECT, SECT8 or COMMZ section name.
1866 3. A SECT8 section name is identical to an entry point or some
1869 COMMZ sections, like FORTRAN COMMONS, are never entered in the library
1872 For users who intend to write 8-mode code that will execute in
1873 conjunction with certain 8-mode library routines, the layout of PDP-8
1885 0-1 Temps for any non-interrupt time routine.
1886 2-13 User locations.
1887 14-157 System locations.
1888 160-177 User locations.
1890 1. Do not define any COMMZ sections other than the system COMMZ
1893 2. If the system page 0 is desired, it will be pulled in from
1894 the library if EXTERN #DISP appears in the code.
1896 3. Do not use any part of page 0 reserved for the system.
1898 Special purpose PDP-8 mode subroutines may be written to perform idle
1899 jobs (refreshing a scope, checking sense lines) or to handle specific
1900 interrupts not serviced by FRTS.
1902 The run-time system enters idle loops while waiting for the FPP to
1903 complete a task or for an I/O job to complete. It is possible to
1904 effect a JMS to a user routine during the idle loop.
1906 RTS contains a set of instructions such as:
1913 This sequence of instructions must be revised if an IDLE routine is to
1916 The location #IDLE must be changed to a SKP (7410). #IDLE+1 must be
1917 set to the address of the routine to be called. #IDLE+2 must be set
1918 to a CDF CIF to the field of the routine. This setup can be done in a
1919 routine that is called at the beginning of MAIN. For example:
1923 where SETIDL is a routine such as:
1925 SECT8 SETIDL /Must be an 8-mode section
1927 TEXT +SETIDL+ /Traceback information
1943 FNOP /For trace back
1947 RET, JA . /Return address
1951 #RET, STARTD /Set up
1952 FLDA 10*3 /Return address
1954 SETB BP /Just for traceback
1955 TRAP4 SET8 /Go to the 8 mode
1958 JA RET /Return to main
1960 TAD IDLAD /Field of idle
1964 TAD SCDF /CDF to #IDLE
1966 TAD IDLAD+1 /Address of #IDLE
1970 DCA% IDPTR /Store at #IDLE
1971 TAD JOB+1 /Address of IDLE top routine
1973 DCA IDPTR /Store a #IDLE+1
1974 TAD JOB /Field of routine
1979 DCA% IDPTR /Store at #IDLE+2
1980 CDF CIF /Set to field 0
1981 JMP% SET8 /Return to instruction
1982 /Following "TRAP4 SET8"
1984 IDLAD, ADDR #IDLE /15 bit address of IDLE
1985 JOB, ADDR DOIT /15 bit address of IDLE
1988 SFIEL, 6203 /CDF CIF
1992 /The following routine performs the
1994 /Executed during IDLE loops
2006 CDF CIF 0 /Back to field 0
2009 If the subroutine is checking for an illegal argument, an argument
2010 error message with traceback can be included in the subroutine by
2011 adding two lines somewhere on the base pages
2014 EXAMER, TRAP4 #ARGER
2016 When the error is detected in the program, effect a jump to the TRAP4
2017 instruction. For example,
2020 JEQ EXAMER /A value of 0 is illegal
2026 JLT EXAMER /The value in EXTMP1 must be
2027 /greater than that in EXTMP2
2029 Some points to note in the above example
2031 1. Using a # as the first character in the name of the start of the
2032 program assumes that the name is not called from the FORTRAN level.
2033 This is because # is an illegal FORTRAN keyboard character.
2035 2. If index registers 3-5 are not used by the subroutine, the space
2036 from XR3 to the ORG statement can be used for temporary storage,
2039 3. The arguments passed from the FORTRAN level do not have to be
2040 picked up all at once at the start of the calculation (3-word)
2041 portion of the program. They can be picked up as required during
2042 the program, can be saved in temporary space, or accessed
2043 indirectly each time required, as best suits the subroutine.
2045 If a call to this routine such as Z=EXAMPL(A,B,C,D) were encountered
2046 by the compiler, it would generate the following call to the routine:
2048 JSR EXAMPL /go to the routine
2049 JA .+10 /jump around arguments
2050 JA A /pointer to lst argument
2051 JA B /pointer to 2nd argument
2052 JA C /pointer to 3rd argument
2053 JA D /pointer to 4th argument
2060 The AMOD routine is listed below to illustrate an application of the
2061 formal calling sequence. It also includes an error condition check
2062 and picks up two arguments. When called from FORTRAN, the code is
2071 /SUBROUTINE AMOD(X,Y)
2072 SECT AMOD /SECTION NAME(REAL NUMBERS)
2073 ENTRY MOD /ENTRY POINT NAME(INTEGERS)
2074 JA #AMOD /JUMP TO START OF ROUTINE
2075 TEXT +AMOD + /FOR ERROR TRACE BACK
2076 AMODXR, SETX XRAMOD /SET INDEX REGISTERS
2077 SETB BPAMOD /ASSIGN BASE PAGE
2078 BPAMOD, F 0.0 /BASE PAGE
2079 XRAMOD, F 0.0 /INDEX REGS.
2080 AMODX, F 0.0 /TEMP STORAGE
2081 ORG 10*3+BPAMOD /RETURN SEQUENCE
2087 AMODER, TRAP4 #ARGER /PRINT AN ERROR MESSAGE
2088 FCLA /EXIT WITH FAC=0
2090 BASE 0 /STAY ON CALLER'S BASE PG
2091 /LONG ENOUGH TO GET RETURN ADDRESS
2092 MOD, /START OF INTEGER ROUTINE SAME AS
2093 #AMOD, STARTD /START OF REAL NUM. ROUTINE
2094 FLDA 10*3 /GET RETURN JUMP
2095 FSTA AMDRTN /SAVE IN THIS PROGRAM
2096 FLDA 0 /GET POINTER TO PASSED ARG
2097 SETX XRAMOD /ASSIGN MOD'S INDEX REGS
2098 SETB BPAMOD /AND ITS BASE PAGE
2102 FLDA% BPAMOD,1 /ADDR OF X
2104 FLDA% BPAMOD,1+ /ADDR OF Y
2108 JEQ AMODER /Y=0 IS ERROR
2121 FSTA AMODX /SAVE IN A TEMPORARY
2122 FDIV BPAMOD /DIVIDE BY Y
2123 JAL AMODER /TOO BIG.
2124 ALN 0 /FIX IT UP NOW.
2126 FMUL BPAMOD /MULTIPLY IT.
2128 FADD AMODX /AND ADD IN X.
2129 JXN AM,1 /CHECK SIGN
2133 RTS has its own interrupt skip chain in which all on-line device flags
2134 are checked and serviced. This chain may be extended to handle
2135 special interrupts. The external tag #INT marks the first of three
2136 locations on RTS which have to be modified to effect a JMS to the
2137 user's special interrupt handler. The three locations must be set up
2138 in exactly the same manner as that used to set up #IDLE, #IDLE1,
2139 #IDLE2 as described above. All the same conventions hold. Refer also
2140 to the library subroutines ONQI and ONQB.
2142 Three pseudo-ops have been added to RALF to help the loader determine
2143 core allocation. Each is a more definitive case of the SECT pseudo-op
2144 and defines a chunk of code, thereby providing more control for the
2147 SECT8 - section starts at a page boundary
2148 FIELD1 - section starts at a page boundary and is in field 1
2149 COMMZ - section starts at page 0 of field 1
2151 If there is more than one SECT8 section in a module, those sections
2152 are not necessarily loaded in contiguous core. The loader considers
2153 core to be in two chunks - one block in field 0, and all of field 1
2156 If there is more than one COMMZ pseudo-op in a module, they are
2157 stacked one behind the other, but there is no way of specifying which
2158 one starts at absolute location 0 of field 1. COMMZ sections are
2159 allocated by the loader before FIELD1 sections.
2161 Modules can share a COMMZ section in the same way that FORTRAN COMMON
2162 sections can be shared. FIELD1 sections can also be shared by using
2163 the same FIELD1 section name in each module.
2165 The first occurrence of a section name defines that section. For
2183 The second mention of PARTA in the same module continues the source
2184 where the first mention of PARTA ended at execution time. (There is
2185 a location counter for each section.)
2187 To save core, a RALF FIELD1 section and FORTRAN COMMON section of the
2188 same name are mapped on top of each other, being allocated the length
2189 of the longer and the same absolute address by the loader. This
2190 feature is useful for initialization (once-only) code, which can
2191 later be overlayed by a data area. Thus, the occurrence of FIELD1
2192 AREA1 in the RALF module and COMMON AREA1 in the FORTRAN program
2193 causes AREA1 to start the same location (in field 1) and have a length
2194 of at least 200 locations (depending on the length of the RALF FIELD1
2195 section or of the COMMON section in the FORTRAN).
2197 If the subroutine is longer than one page and values are to be passed
2198 across page boundaries, the address pseudo-op, ADDR, is required.
2203 This generates a two-word reference to the proper location on another
2204 page, here VAR1. For example, to pass a value to VAR1, possible code
2207 00124 1244 TAD VAR2 /Value on this page
2208 00125 3757 DCA% AVAR1+1 /Pass through 12-bit
2210 00156 0000 AVAR1,ADDR VAR1 /Field and
2211 00157 0322 /location of VAR1
2213 Any reference to an absolute address can be effected by the ADDR
2216 If it is doubtful that the effective address is in the current data
2217 field, it is necessary to create a CDF instruction to the proper field.
2218 In the above example, suitable code to add to specify the data field
2221 TAD AVAR1 /Get field bits
2222 RTL /Rotate to bits 6-8
2224 TAD (6201 /Add a CDF
2225 DCA .+1 /Deposit in line
2228 If the subroutine includes an off-page reference to another RALF
2229 module (e.g., in FORLIB), it can be addressed by using an EXTERN
2230 with an ADDR pseudo-op. For example, in the display program, a ref-
2231 erence to the non-interrupt task subroutine ONQB is coded as
2244 The next instruction in the program is ADDR DISPLY so that DISPLY will
2245 be added to the background list. Execution from ONQB returns after
2248 It may be desirable to salvage the first (field) word allocated by
2249 ADDR pseudo-ops. If the address requires only twelve bite for proper
2250 execution, code such as
2253 ARG,ADDR X or ARG= .-1
2255 permits TMP to be used for temporary storage because ARG+1 in the left
2256 hand example or just ARG in the right hand example defines the 12-bit
2259 RALF does not recognize LINC instruction or PDP-8 laboratory device
2260 instructions. Such instructions can be included in the subroutine by
2261 defining them by equate statements in the program.
2263 For example, adding the statements:
2269 takes care of all instructions for coding the PDP-12 display
2272 When writing a routine that is going to be longer than a page, it can
2273 be useful to have a non-fixed origin in order not to waste core and to
2274 facilitate modification of the code. A statement such as
2276 IFPOS .-SECNAM&177-K<ORG .-SECNAM&7600+200+SECNAM>
2278 will start a new page only if the value [current location less section
2279 name] is greater than some K (start of section has a relative value of
2280 0) where K<=177 and is the relative location on the current page
2281 before which a new page should be started. The ORG statement includes
2282 an AND mask of 7600 to preserve the current page. When added to 200
2283 for the next page and the section name, the new origin is set.
2285 When calculating directly in a module, the following rules apply to
2286 relative and absolute values.
2296 relative - relative = absolute
2297 absolute + relative = relative
2298 OR (!), AND (&) and ADD (+) of relative symbols
2299 generate the RALF error message RE.
2301 When passing arguments (single precision) from FPP code to PDP code,
2302 using the index registers is very efficient. For example,
2307 FLDA% ARG1 /Get argument in FPP mode
2308 SETX MODE8 /Change index registers so XR0 is
2310 ATX MODE8 /Save argument
2314 TRAP4 SUB8 /Go to PDP-8 routine
2318 SUB8, 0 /PDP-8 routine
2322 TAD MODE8 /Get argument
2326 MODE8, 0 /Index registers set here
2357 THE FORTRAN IV LOADER
2360 The FORTRAN IV loader accepts a set of (up to 128) RALF modules as
2361 input, and links the modules, along with any necessary library
2362 components, to form a loader image file that may be read into memory
2363 and executed by the run-time system. The main task accomplished by the
2364 loader is program relocation, achieved by replacing the relative
2365 starting address of every section with an absolute core address.
2366 Absolute addresses are also assigned to all entry points, all
2367 relocatable binary text, and the externs.
2369 The loader executes in three passes. Pass 0 begins by determining how
2370 much memory is available on the running hardware configuration, and
2371 then constructs tables from the OS/8 command decoder input for use by
2374 Pass 1 reads the relocatable binary input and creates the loader
2375 symbol table. The length of each input module is computed and stored,
2376 along with the relative values of entry points defined within the
2377 input modules. When an undefined symbol is encountered, pass 1
2378 searches the catalog of the FORTRAN IV library specified to pass 0,
2379 or FORLIB.RL if no other library was explicitly specified, and loads
2380 the library routine corresponding to the undefined symbol.
2382 Pass 1 also allocates absolute core addresses to all modules and,
2383 through them, to all symbols. Pass 1 execution concludes by computing
2384 the lengths of all overlay levels defined for the current FORTRAN IV
2385 job. Trap vectors are also set up at this time, and the tables
2386 required for pass 2 loading are initialized.
2388 Pass 2 concludes loader execution by creating a loader image file from
2389 the relocated binary input and symbol values processed by pass 1.
2390 Pass 2 also produces the loader symbol map, if requested, and chains
2391 to the run-time system if /G was specified.
2393 Pass 0 contains very few subroutines. The routine CORDSW checks for
2394 the presence of /U, /C or /O option specifications, as supplied to the
2395 command decoder, and processes these options if necessary. A routine
2396 called UPDMOD is called when input to each overlay has been concluded,
2397 to update the module counts in the module count table.
2399 CORMOV is a general core-moving subroutine, called by the instruction
2414 LOADER PASS 0 (FILE COLLECTION)
2415 ------------------------------
2416 00000 | OS/8 Command Decoder | FIELD 0
2419 |----------------------------|
2420 02000 | Loader Pass 1 and |
2423 |----------------------------|
2424 04600 | Core measuring routine |
2425 | and scratch area to |
2426 | save 00000-02000 |
2428 |----------------------------|
2432 |----------------------------|
2433 07600 | OS/8 Field 0 resident |
2434 |----------------------------|
2435 10000 | OS/8 User Service Routine | FIELD 1
2438 |----------------------------|
2439 12000 | Symbol table, loader map |
2442 |----------------------------|
2443 13200 | Pass 0 code |
2444 |----------------------------|
2445 14000 | Pass 1 initialization |
2448 |----------------------------|
2449 16000 | Module count and |
2451 |----------------------------|
2452 17000 | Library catalog header |
2453 | read into this block |
2454 |----------------------------|
2455 17600 | OS/8 Field 1 resident |
2456 ------------------------------
2458 while ERROR is the local error processing routine, called with a
2459 pointer to the appropriate error message in the accumulator.
2461 The major pass 1 and pass 2 subroutines, described below, operate on
2462 the loader internal tables, whose format is presented later in this
2463 chapter. The subroutines are presented in approximately the order
2464 that they occur in the source listing.
2473 LOADER PASS 1 (SYMBOL RESOLUTION)
2474 ------------------------------
2475 00000 | Pass 1 and Pass 2 | FIELD 0
2476 | utility routines |
2477 |----------------------------|
2478 01400 | Symbol map printer |
2479 |----------------------------|
2481 |----------------------------|
2482 03200 | Pass 1 symbol collection |
2483 |----------------------------|
2484 04000 | Inter-pass code allocates |
2485 | storage, builds and writes |
2486 | Loader Image Header Block. |
2487 |----------------------------|
2488 04600 | Library catalog loads |
2489 | here in 8K. Unused in |
2491 |----------------------------|
2492 07200 | Input device handlers |
2493 |----------------------------|
2494 07600 | OS/8 Field 0 resident |
2495 |----------------------------|
2496 10000 | ESD table | FIELD 1
2499 |----------------------------|
2500 12000 | Symbol table |
2501 |----------------------------|
2502 15400 | Overlay length table |
2503 |----------------------------|
2504 16000 | Module count and module |
2505 | tables (MCTTBL, MODTBL) |
2506 |----------------------------|
2507 17200 | Loader header |
2508 |----------------------------|
2509 17400 | ESD reference page |
2510 |----------------------------|
2511 17600 | OS/8 Field 1 resident |
2512 |----------------------------|
2513 20000 | Library catalog loads here | FIELD 2
2515 |----------------------------|
2516 25000 | OS/8 BATCH processor if |
2517 | 12K or more and BATCH |
2519 ------------------------------
2532 LOADER PASS 2 (LOADER IMAGE BUILDER)
2533 -----------------------------------
2534 00000 | Utility routines: Symbol table | FIELD 0
2535 | look-up, TTY message handler, |
2536 | OS/8 block I/O, MCTTBL |
2538 |---------------------------------|
2539 01400 | Routine to print symbol map. |
2540 |---------------------------------|
2542 |---------------------------------|
2543 03200 | Binary buffer #1 |
2545 |---------------------------------|
2546 05200 | Binary buffer #2 |
2548 |---------------------------------|
2549 07200 | I/O device handlers |
2550 |---------------------------------|
2551 07600 | OS/8 Field 0 resident |
2552 |---------------------------------|
2553 10000 | RALF module text loads | FIELD 1
2555 |---------------------------------|
2556 12000 | Symbol table |
2558 |---------------------------------|
2559 15400 | Overlay length table |
2560 |---------------------------------|
2561 16000 | MCTTBL and MODTBL | -
2562 |---------------------------------| |
2563 17200 | Binary section table and | > symbol map
2564 | binary buffer (LDBUFS) table | | output buffer
2565 |---------------------------------| |
2566 17400 | ESD reference page | -
2567 |---------------------------------|
2568 17600 | OS/8 Field 1 resident |
2569 |---------------------------------|
2570 20000 | Binary buffer #3, if >8K | FIELD 2
2571 |---------------------------------|
2572 22000 | Binary buffer #4, if >8K |
2573 |---------------------------------|
2574 24000 | Binary buffer #5, if >12K |
2575 |---------------------------------|
2577 |---------------------------------|
2578 30000 | RALF module text loads | FIELD 3
2580 -----------------------------------
2591 SETBPT Sets words BPTR and BPT2 to contain AC and AC+1,
2594 TTYHAN Subroutine to unpack and print a TEXT message on the
2595 console terminal. TTYHAN is called by:
2603 RTNOS8 Prints a fatal error message and then returns to the
2604 OS/8 monitor. A pointer to the message must follow
2607 IOHAN Used to execute all I/O under OS/8. The calling
2610 TAD (ACARG /Optional
2619 where ARG1, ARG2 and ARG3 are standard OS/8 device
2620 handler arguments and ADDR points to a three-word block
2621 in field 1 which contains the OS/8 unit number in word
2622 1, the file length in word 2, and the starting block
2625 If ACARG is zero, the indicated I/O operation is
2626 executed after the handler has been FETCHed, if
2627 necessary. If ACARG=n (greater than zero), the handler
2628 for OS/8 unit n is FETCHed, no I/O is done, and the
2629 four arguments that conclude the calling sequence are
2632 ADVOVR Called to initialize the loader to accept a new input
2633 module. ADVOVR determines whether a new overlay or
2634 level is being started by accessing the module count
2635 table. If so, it sets various pointers and internal
2636 counters accordingly, rounds the previous overlay to
2637 terminate on a 200 word boundary, and updates the
2638 length of the previous level, if necessary, as the
2639 maximum of its constituent overlay lengths.
2641 NXTOVR Called by ADVOVR when the next input module will be the
2642 first module in a new overlay.
2650 SETCNT Initializes the pointers and counters used by ADVOVR.
2651 SETCNT is called once at the beginning of each pass.
2653 LOOK Executes a symbol look-up in the loader symbol table.
2656 TAD (Pointer to symbol name in
2659 RETURN here if not found
2660 RETURN here if found
2661 GPTR points to word following entry name
2663 If the symbol is not found, it is inserted into the
2664 loader symbol table and GPTR is set to point to the
2665 word following the symbol name.
2667 SYMMAP Produces the symbol map.
2669 PUTSYM Enters an ESD symbol in the loader symbol table. PUTSYM
2670 calls LOOK to determine whether the symbol is already
2671 present in the symbol table and, if so, verifies that
2672 the symbol is not multiply defined. Otherwise, it
2673 copies the ESD data words into the symbol table entry,
2674 updates the length of the current overlay by the length
2675 associated with the symbol, and links the symbol to its
2676 parent symbol, if any.
2678 FIT Fits a section into core by subtracting its length from
2679 the amount of core still available and substituting its
2680 load address for its length in the symbol table.
2682 DO8S, FIT8S Fits an 8-mode section into core by calling FIT and
2683 then checking for field 1 overflow.
2685 SETREF Extracts data from the ESD table of the current module
2686 and initializes the ESD reference page at 17400.
2688 BLDTV Builds the transfer vector. A transfer vector entry
2689 is created for each subroutine in an overlay. This
2690 entry provides the information that the run-time system
2691 will require in order to load the overlay containing
2692 the referenced subroutine.
2694 NEWORG Called whenever an origin is found in an input module,
2695 to map the location referenced by the origin into a
2696 block of the loader image file and an address within
2699 NEWBB Called whenever a new binary buffer is needed during
2700 loader image file construction. NEWBB scans a list of
2701 available buffers and dumps the content of the least
2702 recently accessed buffer to free up space for new data.
2709 MERGE Relocates an input word pair and outputs it to the
2712 GETCTL Gets a control byte from the input module and incre-
2713 ments its return address by the content of the control
2716 PUTBIN Inserts words, sequentially, into the current binary
2717 buffer. When the buffer is full, PUTBIN calls NEWBB to
2718 execute output to the loader image file and supply a
2721 TXTSCN Called once for each input module. TXTSCN reads and
2722 relocates an entire input module, executing calls to
2723 MERGE, PUTBIN and NEWORG as needed.
2731 The loader symbol table begins at location 12000 and contains room for
2732 26 (decimal) permanent system symbol entries and 218 (decimal) user
2733 entries. Each entry is 7 words long, and provides the name and
2734 definition of a symbol. The table is organized in buckets according
2735 to the first character of the symbol, which must be A to Z, #, or
2736 blank (for blank COMMON). The table of bucket pointers begins at
2737 location 12000 with the pointer to bucket A, and consists of one word
2738 per bucket. This word contains a value of zero, if there are no
2739 symbols in the corresponding bucket, or else the address of the first
2740 symbol in the bucket.
2742 Symbols within a bucket are arranged in alphabetical order, with each
2743 symbol entry pointing to the following entry, and the last entry
2744 pointing to zero. Thus, the symbol table appears as a set of threaded
2745 lists in core. The format of a symbol table entry is:
2767 ------------------------------
2768 | Pointer to next symbol in |
2769 | bucket (zero if none). | WORD 1
2770 |----------------------------|
2772 |----------------------------|
2774 |----------------------------|
2776 |----------------------------|
2777 | | 3-bit | 4-bit | |
2778 | * | level | overlay | ** |
2780 |----------------------------|
2781 | 9-bit pointer to | |
2784 | (zero if none). | Field |
2785 | Trap vector | bits |
2787 | during pass 2. | |
2788 |----------------------------|
2790 | (Length during pass 1) |
2791 ------------------------------
2794 * 1-bit trap vector flag during pass 1. Error flag during pass 2.
2802 5- multiple entry point
2809 Several special symbols are created by the loader. The symbol #YLVLn,
2810 where n is an octal digit, describes overlay level n. This symbol
2811 table entry contains the length of level n during pass 1 and the
2812 starting address of level n during pass 2.
2814 The symbol #YTRAP describes the trap vector, a method by which the
2815 run-time system controls automatic overlaying of user subroutines.
2816 Four words are allocated in the trap vector for each entry point in
2817 every overlay except overlay #MAIN. The symbol table entry for #YTRAP
2818 contains the accumulated length of the trap vector during pass 1 and
2819 the trap vector starting address during pass 2.
2827 ESD CORRESPONDENCE TABLE (ESDPG)
2831 The ESD correspondence table begins at location 17400 and contains 128
2832 (decimal) 1-word entries. This table establishes the correspondence
2833 between the local ESD reference numbers used to reference a symbol
2834 inside a RALF module, and the address of that symbol in the loader
2835 symbol table. The nth entry in the ESD correspondence table points to
2836 the address of ESD symbol n.
2840 BINARY BUFFER TABLE (LDBUFS)
2844 The binary buffer table begins at location 17247 and contains from two
2845 to ten entries, depending upon the amount of memory available. Each
2846 entry is 4 words in length. The binary buffers function as windows
2847 into the loader image file, through which the loaded program is
2848 written onto mass storage. Each binary buffer is 8 pages (4 OS/8
2849 blocks) in length. The loader tries to minimize the amount of "window
2850 turning" necessary to buffer the binary data by keeping a record of
2851 the last time each buffer was referenced. In this way, when the
2852 content of a binary buffer must be dumped to make room for new data,
2853 the loader empties that buffer which was least recently used.
2855 In addition, program loading is overlay oriented such that only one
2856 overlay is loaded at a time and while any specific overlay is being
2857 loaded, only origins inside that overlay are legal.
2859 The format of a binary buffer table entry is:
2861 ------------------------------------
2862 | Pointer to the binary buffer of |
2863 | "next earliest reference", i.e., |
2864 | the youngest buffer older than | WORD 1
2865 | this buffer. Contains zero if |
2866 | this buffer is oldest. |
2867 |----------------------------------|
2868 | Loader image block #. Contains |
2869 | zero if buffer has not been used.| WORD 2
2870 |----------------------------------|
2871 | Blocks left in current overlay |
2872 | If <4, only part of buffer will | WORD 3
2874 |----------------------------------|
2875 | Page address | Buffer | |
2876 | of buffer. | field | Unused | WORD 4
2878 ------------------------------------
2886 The number of binary buffers used varies with the amount of memory
2887 available as follows:
2889 -------------------------------------------
2892 -------------------|-----------------------
2900 -------------------------------------------
2904 BINARY SECTION TABLE
2908 The binary section table overlays the loader image header block
2909 (described under FRTS) after the latter has been written into the
2910 loader image file at the beginning of pass 2. Thus, the binary
2911 section table begins at location 17200 and contains eight 4-word
2912 entries. Each entry relates the core origin of one of the eight
2913 overlay levels to that level's position in the loader image file.
2914 The format of a binary section table entry is:
2916 -----------------------------------
2918 | Unused | of | WORD 1
2920 |---------------------------------|
2921 | Address of level | WORD 2
2922 |---------------------------------|
2923 | Relative block # | WORD 3
2924 |---------------------------------|
2925 | Length (in blocks) | WORD 4
2926 -----------------------------------
2929 OVERLAY TABLE (OVLTBL)
2932 The overlay table begins at location 15435 and contains room for 113
2933 (decimal) 2-word entries. There is one entry for each overlay
2934 defined, including overlay MAIN, with each entry designating the
2935 length in words, of the corresponding overlay. The format of an
2936 overlay table entry is:
2946 -----------------------
2948 |---------------------| Negated to indicate
2949 | LEVEL 1 OVERLAY 1 | last table entry
2950 |--------/\/----------| /
2952 . | ------------------- /
2953 . | | HIGH-order bits |/
2954 |--------/\/----------| | | of length | WORD 1
2955 | LEVEL m OVERLAY n-1 |>----< |-----------------|
2956 |---------------------| | | LOW-order bits |
2957 | LEVEL m OVERLAY n | | | of length | WORD 2
2958 |---------------------| | -------------------
2959 | OVLTBL format | - individual entry (2 words)
2960 -----------------------
2964 MODULE DESCRIPTOR TABLE (MODTBL)
2968 The module descriptor table begins at location 16172 and contains
2969 room for 172 (decimal) 3-word entries. Each entry provides the
2970 information needed to locate an input module. The first MODTBL entry
2971 corresponds to the library file to be used in building the current
2972 loader image. Successive entries correspond to input modules and
2973 appear in the order that the modules were specified by the user,
2974 (i.e., in ascending order by level, and ascending by overlay within
2975 any given level.) At the end of pass 1, entries corresponding to
2976 individual library modules are appended to the end of the table, even
2977 though the library modules load into level MAIN. The table format is:
2981 --------------------------------
2982 | FORLIB.RL or user- |
2983 | specified library | -
2984 |------------------------------| | --------------------------
2985 | Level MAIN module #1 | | | OS/8 I/O unit # |
2986 |------------------------------| | |------------------------|
2987 | Level MAIN module #2 | < | File length (positive) |
2988 |------------------------------| | |------------------------|
2989 | Level MAIN module #3 | | | Starting block # |
2990 |----/\/----------------\/\----| | --------------------------
2992 |----/\/----------------\/\----|
2993 | Level MAIN module n | MODTBL format of
2994 |------------------------------| individual entry (3 words)
2995 | Level 1 Overlay 1 module #1 |
2996 |------------------------------|
2997 | Level 1 Overlay 1 module #2 |
2998 |----/\/----------------\/\----|
3004 |----/\/----------------\/\----|
3005 | Level 1 Overlay 1 module #n |
3006 |------------------------------|
3007 | Level 1 Overlay 2 module #1 |
3008 |----/\/----------------\/\----|
3012 |----/\/----------------\/\----|
3013 | Level m Overlay n module #p |
3014 |------------------------------|
3015 | Library module #1 |
3016 |------------------------------|
3017 | Library module #2 |
3018 |----/\/----------------\/\----|
3024 MODULE COUNT TABLE (MCTTBL)
3028 The module count table begins at location 16000 and contains room for
3029 122 (decimal) 1-word entries that give the (two's complement) module
3030 count for each overlay level. The table format is:
3034 -------------------------
3035 | LEVEL MAIN | 1-word ENTRIES
3036 |-----------------------|
3038 |-----------------------|
3039 | LEVEL 1 OVERLAY 1 |
3040 |-----------------------|
3041 | LEVEL 1 OVERLAY 2 |
3042 |-----------------------|
3043 | LEVEL 1 OVERLAY 3 |
3044 |----/\/---------\/\----|
3046 |----/\/---------\/\----|
3047 | LEVEL 1 OVERLAY n |
3048 |-----------------------|
3050 |-----------------------|
3051 | LEVEL 2 OVERLAY 1 |
3052 |-----------------------|
3053 | LEVEL 2 OVERLAY 2 |
3054 |----/\/---------\/\----|
3064 |----/\/---------\/\----|
3065 | LEVEL 2 OVERLAY n |
3066 |-----------------------|
3068 |-----------------------|
3069 | LEVEL 3 OVERLAY 1 |
3070 |----/\/---------\/\----|
3074 |----/\/---------\/\----|
3075 | LEVEL m OVERLAY n |
3076 |-----------------------|
3078 |-----------------------|
3080 -------------------------
3082 If an overlay or level is not defined for a specific program, there is
3083 no module count table entry corresponding to that overlay or level.
3085 The loader image file, produced by the loader and read as input by the
3086 run-time system, consists of a header block followed by a binary image
3087 of each level defined in the FORTRAN IV job.
3089 ----------------------------------- -----------
3090 | HEADER | LEVEL | LEVEL / / LEVEL |
3091 | BLOCK | MAIN | 1 \ \ n |
3093 ---------------------------------- ------------
3096 The loader image file header block contains information in the
3100 0 2 -- Identifies the file as a loader image file.
3101 1-2 Initial SWAP arguments to load level MAIN.
3102 3-4 Highest address used by core load, including overlays
3103 but not including OS/8 device handlers.
3104 5 Loader version number.
3105 6 Double-precision flag.
3106 7-46 User overlay information table containing one 4-word
3107 entry per overlay level (the level MAIN entry is
3108 ignored) in the following format:
3122 ---------------------------------------
3123 | Unused until SWAP time. Must | WORD 1
3124 | be positive or zero. |
3125 |-------------------------------------|
3126 Load | Page | Bits 4-5 | Field | Bits 9-11 | WORD 2
3127 address ---> | bits | unused | bits | unused |
3128 |-------------------------------------|
3129 | Block number of this level, | WORD 3
3130 | relative to header block. |
3131 |-------------------------------------|
3132 | Length of overlays in this level, | WORD 4
3134 ---------------------------------------
3183 THE FORTRAN IV RUN-TIME SYSTEM
3186 The FORTRAN IV run-time system supervises execution of a FORTRAN job
3187 and provides an I/O interface between the running program and the OS/8
3188 operating system. FRTS includes its own loader, which should not be
3189 confused with LOAD, the system loader. It executes with only one
3190 overlay, used to restore the resident monitor and effect program
3191 termination. The run-time system was designed to permit convenient
3192 modification or enhancement, and it is well documented in the assembly
3193 language source, available from the Software Distribution Center,
3194 which includes extensive comments.
3196 One of the most valuable modifications to FRTS provides for the
3197 inclusion of background (or idle) jobs. When FORTRAN is waiting for
3198 I/O operations or the FPP to complete execution, the PDP-8 or PDP-12
3199 processor is sitting in an idle loop. An idle job may be executed by
3200 the PDP-8 or PDP-12 CPU during this time, perhaps for the purpose of
3201 refreshing a CRT display, for example, or monitoring a controlled
3202 process. To indicate such a job, the idle wait loop must be modified
3203 to include a reference to the user's PDP-8 routine. The routine #IDLE
3204 in FRTS must be changed as part of the user's subroutine from
3206 #IDLE, JMP .+4 to #IDLE, SKP
3211 Devices issuing interrupts may be added to the interrupt skip chain so
3212 that FORTRAN checks the user's device as well as system devices. The
3221 and must be changed, as above, to:
3228 In both cases, ADDUSR should be the address of the user's routine, and
3229 FLDUSR should be the memory field of the user's routine.
3231 The idle job is initiated by the subroutine HANG in the run-time
3232 system. Hang should only be called when the FORTRAN program must wait
3233 for an I/O device flag. The calling sequence is:
3242 CDF n /Where n is current field.
3246 /Return here with interrupts OFF
3247 /When device flag is raised.
3251 The word ADDRSS must point to a location in page 400 of the run-time
3252 system which must normally contain a JMP DISMIS. Three such locations
3253 have been provided for the user at #DISMS, #DISMS+1, and #DISMS+2. The
3254 selected location must be the location via which the interrupt caused
3255 by the desired flag is dismissed. No two flag routines should use the
3256 same dismiss location. The following program example illustrates
3257 these calling conventions. This routine may be used to drive a
3258 Teletype terminal via the PT08 option.
3262 FIELD1 GETCH /JMS GETCH GETS A CHAR
3263 0 /GETCH RUNS IN FIELD I ONLY
3269 TAD DISMIS+1 /SET UP TO CALL HANG
3276 JMS% HANG+1 /NO CHAR READY: HANG
3278 /HANG RETURNS W/ IOF
3285 /INTERRUPT ROUTINE -
3286 KSFSUB, 0 /CALLED AS SUBROUTINE
3290 JMP% DISMIS+1 /RETURN TO SYSTEM LOCATION
3291 /CONTAINING "JMP DISMIS"
3303 In most cases, it is easier to include references to the FORLIB module
3304 ONQI for adding a handler to the interrupt skip chain and ONQB for
3305 adding a job to the idle chain, instead of trying to modify #IDLE and
3306 #INT. ONQB provides slots for up to 9 idle jobs to be executed
3307 round-robin, and ONQI provides for up to 9 user flags to be tested on
3310 FRTS entry points are listed, along with the core map, on the
3311 following pages. The FRTS calling sequence must be observed in any
3312 user subroutine. The formal calling sequence is illustrated below. In
3313 general, it can be used exactly as illustrated, changing only the
3314 section, entry, base page, index register and return location names.
3318 FRTS CALLING SEQUENCE
3322 SECT EXAMPL /Section name. Your module may
3323 /require another section pseudo-op
3324 /such as FIELD1 or SECT8.
3325 JA #EXSRT /Jump to start of subroutine
3326 /Use # for first character
3327 TEXT +EXAMPL+ /6 character section name for
3328 /error traceback (optional)
3329 EXAMXR, SETX XREXAM /Set up index registers
3330 /for this subroutine
3331 SETB BPEXAM /and its base page.
3332 BPEXAM, F 0.0 /Base page
3333 XREXAM, F 0.0 /Index registers 0-2
3334 F 0.0 /Index registers 3-5 (optional)
3335 EXTMP1, F 0.0 /Space between index registers
3336 EXTMP2, F 0.0 /and the ORG for temporary
3337 EXTMP3, F 0.0 /storage (optional)
3338 ORG 10*3+BPEXAM /Location 30 of base page
3339 FNOP /Force a two-word instruction
3340 JA EXAMXR /Jump to base page for
3341 /return to calling program
3342 0 /Force a two-word instruction
3343 EXMRTN, JA . /Will be replaced by return jump
3344 BASE 0 /Caller's base page
3345 #EXSRT, STARTD /Start of subroutine
3346 FLDA 10*3 /Get return jump from caller's
3348 FSTA EXMRTN /Save in return location for
3350 FLDA 0 /Location 0 of caller's routine
3351 /is a pointer to the argument list
3352 SETX XREXAM /Change to EXAMPL's index registers
3358 SETB BPEXAM /Change to EXAMPL's base page
3360 FSTA BPEXAM /Save the pointer
3361 LDX 1,1 /Set up index register 1
3362 FLDA% BPEXAM, 1 /Get address of argument list
3363 FSTA EXTMP1 /Save the addresses
3364 FLDA% BPEXAM, 1+ /of all passed arguments
3367 FSTA EXTMP3 /Continue for all arguments
3371 STARTF /Start three-word instructions
3379 . /Continue to get arguments
3380 . /as required in routine
3381 JA EXMRTN /Exit when done
3385 RTS ENTRY POINT USEAGE AND COMMENTS
3387 #UE TRAP3 #UE /Produces USER ERROR error message.
3389 #ARGER or TRAP4 #ARGER /Produces BAD ARG error message.
3392 #READO TRAP3 #READO /Initializes
3393 JA UNITNO /formatted
3394 JA FORMAT /read operation.
3396 #WRITO TRAP3 #WRITO /Initializes
3397 JA UNITNO /formatted
3398 JA FORMAT /write operation.
3400 #RUO TRAP3 #RUO /Initializes unformatted
3401 JA UNITNO /read operation.
3403 #WUO TRAP3 #WUO /Initializes unformatted
3404 JA UNITNO /write operation.
3406 #RDAO TRAP3 #RDAO /Initializes
3407 JA UNITNO /direct access
3408 JA RECNO /read operation.
3417 #WDAO TRAP3 #WDAO /Initializes
3418 JA UNITNO /direct access
3419 JA RECNO /write operation.
3421 #RFSV TRAP3 #RFSV /Passes a variable to or from the read/
3422 /write processors via the floating AC.
3424 #RENDO TRAP3 #RENDO /Terminates a read/write operation.
3426 #ENDF FLDA UNITNO /Executes an
3427 TRAP3 #ENDF /end file,
3428 #REW or TRAP3 #REW /rewind,
3429 #BAK or TRAP3 #BAK /backspace (depending upon the entry used)
3430 /on the referenced I/O unit.
3432 #DEF TRAP3 #DEF /Opens a file
3433 JA UNITNO /for direct access I/O.
3435 JA FPNPR /(FPP numbers per record)
3436 JA VARIABLE /Refer to DEFINE FILE statement
3438 #EXIT JSR #EXIT /Terminates current FORTRAN IV job.
3440 #SWAP TRAP3 #SWAP /Reads overlay OVLY into level LVL and
3441 ADDR /jumps to ADR. ADDR is given by:
3442 /ADDR=4000000*OVLY+100000*LVL+ADR
3444 #8OR12 /=00000001 if the CPU is a PDP-12.
3446 #IDLE Address of background job, used by ONQB. Contains:
3448 JMP I (NULJOB /Replace by SKP
3449 0 /Replace by addr of background job
3450 CDF CIF 0 /Replace by field of background job
3458 NON-FPP FPP (Same as non-FPP
3460 -----------------------------------
3461 0000 | Page zero (0120-0134 free) |
3462 |---------------------------------|
3463 0200 | Most entry points, character |
3464 | I/O handlers, interrupt |
3465 | service, and HANG routine |
3466 |---------------------------------|
3467 0600 | Format decoder; A, H, and ' |
3468 | format processors, and EXIT |
3469 |------\/\---------------/\/------|
3476 |------\/\---------------/\/------|
3477 1400 | REWIND, ENDFILE, BACKSPACE and |
3478 | general unit initialization |
3479 | DATABL table (3wds/unit) |
3480 |---------------------------------|
3481 2000 | I, E, F and G output |
3482 |---------------------------------|
3483 2400 | I, E, F and G input |
3484 |---------------------------------|
3485 2600 | X, L and T formats and |
3487 |---------------------------------|
3488 3000 | Char in and char out routines |
3489 | including OS/8 packing, editing |
3490 | and forms control |
3491 |---------------------------------|
3492 3400 | Binary and D. A. I/O, and |
3493 | DEFINE FILE processor |
3494 |---------------------------------|
3495 3600 | Overlay loader |
3496 |---------------------------------|
3497 4000 | Input line buffer, overlay |
3498 | and DSRN tables, FORMAT |
3499 | parenth pushdown list, /P |
3500 | processor and init flag clear |
3501 |---------------------------------|
3502 4400 | Floating-point utilities (shift,|
3503 | add, etc.) used even w/FPP |
3504 |---------------------------------|
3505 4600 | Error routine and messages |
3506 |---------------------------------|
3507 5200 | OS/8 handler area and part of |
3508 | FRTS loader initialization |
3509 |---------------------------------|-----------------------------
3510 5600 | FPP simulator | FPP start-up and trap |
3512 | |----------------------------|
3513 6000 | | B and D format I/O |
3514 |---------------------------------|----------------------------|
3515 6600 | Floating-point package and | Floating-point package |
3516 | part of LPT ring buffer | (never used) and part of |
3517 | | LPT ring buffer |
3518 |---------------------------------|-----------------------------
3519 7400 | Most of LPT ring buffer |
3520 |---------------------------------|
3521 7600 | OS/8 handler and field |
3523 |---------------------------------|
3524 10000 | OS/8 User Service Routine |
3525 |---------------------------------|
3526 12000 | FRTS loader tables, IONTBL | Locations 12000 to 17400 are
3527 | | overlayed at execution time
3528 |------\/\---------------/\/------|
3535 |------\/\---------------/\/------|
3536 12200 | FRTS loader: main flow |
3537 |---------------------------------|
3538 12400 | program start-up (1) |
3539 |---------------------------------|
3540 12600 | initialize and |
3541 | configure system |
3542 |---------------------------------|
3543 13000 | Load OS/8 handlers and assign |
3544 | unit numbers to OS/8 files |
3545 |---------------------------------|
3546 13400 | Utility and error routines, |
3549 |---------------------------------|
3550 15600 | FPP start-up and trap routines | Locations 14000 to 16777 are
3551 |---------------------------------| used to save lower field 0
3552 16000 | B and D format I/O | during loading of device
3553 |---------------------------------| handlers and file
3554 16600 | EAE Floating-point package | specifications
3555 |---------------------------------|
3556 17400 | Termination routine | Locations 17400 to 17777 are
3557 |---------------------------------| written on SYS block 37
3558 17600 | OS/8 field 1 resident | before program load and
3559 |---------------------------------| restored on termination
3565 #INT /Address of user interrupt location, used by ONQI:
3567 JMP .+4 /Replace with SKP
3568 0 /Replace with address of interrupt
3570 CDF CIF 0 /Replace with field of interrupt
3574 #DISMS /Addresses first of three JMP DISMIS instructions
3575 for use by specialized I/O routines.
3577 #HANG /Addresses I/O dismiss routine.
3579 #RETRN /Provides return from TRAP3.
3584 ------------------------
3585 (1) Program start-up moves OS/8 handler to top of core, writes field
3586 1 resident onto SYS, and termination routine goes to FRTS to load
3598 The DSRN table controls files and I/O devices used under OS/8 FORTRAN
3599 IV ASCII, binary and direct access I/O operations, including
3600 BACKSPACE, REWIND, and END FILE operations. The exact meaning of the
3601 initials DSRN is one of the great, unanswered questions of FORTRAN IV
3602 development and, as such, has considerable historical interest. The
3603 DSRN table provides room for 9 entries; each entry is 9 words in
3604 length, and contains the following data:
3606 WORD 1: (HAND) Handler entry point. If this value is positive, the
3607 I/O device handler is a FORTRAN internal (character-oriented)
3608 handler, and the remainder of the DSRN table entry is
3609 ignored. If the value is negative, the handler is an OS/8
3610 device handler whose entry point is the two's complement of
3611 the value. Entry points always fall in the range [7607,
3612 7777] for resident handlers or [5200, 5377] for non-resident
3613 handlers. Space for non-resident handlers is allocated
3614 downward from the top of memory, and the handlers are moved
3615 into locations 5200 to 5577 before being called.
3617 WORD 2: (HCODEW) Handler code word. Bits 0-4 of this word specify
3618 the page into which the device handler was loaded, while bits
3619 6-8 specify the memory field. If all of bits 0-8 are zero,
3620 the handler is permanently resident. When any of these bits
3621 are non-zero, the data is used to determine which handler, if
3622 any, currently occupies locations 5200-5577. This eliminates
3623 unnecessarily moving the content of memory. Bit 10 is set if
3624 forms control has been inhibited on the I/O unit. Bit 11 is
3625 set if the device handler can execute with the interrupt
3626 system enabled. The data in bits 10 and 11 is obtained from
3627 the IOWTBL table in the FRTS loader.
3629 WORD 3: (BADFLD) Buffer address and field. Bits 0-4 address the
3630 memory page at which the I/O buffer for this unit begins,
3631 while bits 6-8 specify the memory field. Unlike the FORTRAN
3632 internal I/O unit buffers, OS/8 device handler buffers always
3633 occupy two full pages of memory. Buffer space is allocated
3634 upward from the top of the FORTRAN program.
3636 WORD 4: (CHRPTR) Character pointer.
3638 WORD 5: (CHRCTR) Character counter. Words 4 and 5 of each DSRN table
3639 entry define the current character/position in the I/O buffer
3653 Value of Character Next value Next value Special
3654 CHRCTR position of CHRCTR of CHRPTR Conditions
3655 ----------------------------------------------------------------------
3656 | Bits 4-11 of word | | | Refresh buffer if
3657 -3 | addressed by | -2 | CHRPTR + 1 | input operation and
3658 | CHRPTR | | | CHRPTR mod 256=0
3660 -2 | " | -1 | " | none
3662 -1 | Bits 0-3 of words | | |
3663 | addressed by | | | Dump buffer if
3664 | CHRPTR-2 and | -3 | CHRPTR | output operation
3665 | CHRPTR-1 | | | and CHRPTR mod
3668 ----------------------------------------------------------------------
3671 WORD 6: (STBLK) Starting block of file.
3673 WORD 7: (RELBLIC) Current relative block of file. That is, block to
3676 WORD 8: (TOTBLK) Length of file in blocks.
3678 WORD 9: (FFLAGS) Status flags:
3680 Bit 0 - Has been written flag. Set to 1 if unit has
3681 received output since last REWIND.
3683 Bit 1 - Formatted I/O flag. Set to 1 if an ASCII I/O
3684 operation has occurred since last REWIND.
3686 Bit 2 - Unformatted I/O flag. Set to 1 if a binary or
3687 direct access I/O operation has occurred since last
3688 REWIND. Bits 1 and 2 are never set simultaneously.
3690 Bit 11- END FILEd flag. Set to 1 if unit has been END
3691 FILEd. Bit 11 is not cleared by a REWIND.
3693 When any active unit is selected for an I/O operation, the DSRN table
3694 entry for that unit is moved into 9 words on page 0. These 9 words
3695 are tagged with the labels cited above. Upon completion of the I/O
3696 operation, the 9 words are moved from page 0 back into the DSRN table.
3712 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 3
3714 /PAGE ZERO FOR FORTRAN IV RTS
3716 0000 *0 /INTERRUPT STUFF
3718 00001 5402 JMP I .+1
3720 00003 5165 LPGET, LPBUFR /LINE PRINTER RING BUFFER FETCH
3721 00004 0000 TOCHR, 0 /TELETYPE STATUS WORD
3722 00005 0000 KBDCHR, 0 /KEYBOARD INPUT CHARACTER
3723 00006 0000 POCHR, 0 /P.T. PUNCH COMPLETION FLAG
3724 00007 0000 RDRCHR, 0 /P.T. READER STATUS
3725 00010 0000 FMTPXR, 0 /XR USED TO INDEX FORMAT PARENTH
3726 00011 3777 INXR, INBUFR-1 /XR USED TO GET CHARS FROM INPUT
3731 00016 0000 VEOFSW, 0 /USED BY "EOFCHK" TO STORE VARIABLE ADDRESS
3732 00017 0000 0 /*K* MUST BE IN AUTO - XR
3733 00020 0000 T, 0 /TEMPORARY
3734 00021 0000 DFLG, 0 /0 = F.P., 1 = D.P.
3735 00022 0000 INST, 0 /CURRENT INSTRUCTION WORD
3737 /IOH PAGE ZERO LOCATIONS
3739 00023 0000 RWFLAG, 0 /READ/WRITE FLAG
3740 00024 0000 FMTTYP, 0 /TYPE OF CONVERSION BEING DONE
3741 00025 0000 EOLSW, 0 /EOL SW ON INPUT - CHAR POS ON OUT
3742 00026 0000 N, 0 /REPEAT FACTOR
3743 00027 0000 W, 0 /FIELD WIDTH
3744 00030 0000 D, 0 /NUMBER OF PLACES AFTER DECIMAL
3745 00031 0300 DATCDF, 0 /SUBROUTINE TO CHANGE DATA FIELD
3746 00032 0000 DATAF, 0 /CONTAINS VARIOUS CDF'S
3747 00033 5431 JMP I DATCDF /RETURN
3748 00034 5013 ERR, ERROR /POINTER TO ERROR ROUTINE
3749 00035 0000 FATAL, 0 /FATAL ERROR FLAG - 0=FATAL
3750 00036 5000 MCDF, MAKCDF
3752 /FPP PARAMETER TABLE LOCATIONS:
3754 00037 0000 APT, 0 /VARIOUS FIELD BITS FOR FPP
3755 00040 5313 PC, DPTEST /FPP PROGRAM COUNTER
3756 00041 0000 XRBASE, 0 /FPP INDEX REGISTER ARRAY ADDRESS
3757 00042 0000 BASADR, 0 /FPP BASE PAGE ADDRESS
3758 00043 0000 ADR, 0 /ADDRESS TEMPORARY
3760 00045 0000 ACH, 0 /*** FLOATING ACCUMULATOR ***
3763 00050 0000 EAC2, 0 /** FOR EXTENDED PRECISION OPTION **
3771 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 4
3773 /FLOATING POINT PACKAGE LOCATIONS
3776 00053 0000 AC1, 0 /FLOATING AC OVERFLOW WORD
3777 00054 0000 AC2, 0 /OPERAND OVFLOW WORD
3779 00056 0000 OPH, 0 /*** FLOATING OPERAND REGISTER ***
3782 /RTS I/O SYSTEM LOCATIONS
3784 00060 0000 FMTBYT, 0 /FORMAT BYTE POINTER
3785 00061 0000 IFLG, 0 /I FORMAT FLAG
3786 00062 0000 GFLG, 0 /G FORMAT FLAG
3787 00063 0000 EFLG, 0 /E FORMAT FLAG - SOMETIMES ON FOR
3790 00066 0000 PFACT, 0 /P-SCALE FACTOR
3791 00067 0000 PFACTX, 0 /TEMP FOR PFACT
3792 00070 0000 INESW, 0 /EXPONENT SWITCH
3794 00072 0000 FMTNUM, 0 /CONTAINS ACCUMULATED NUMERIC VALUE
3795 00073 0000 CTCINH, 0 /^C INHIBIT FLAG
3796 00074 0320 PTTY, TTY /POINTER TO TTY HANDLER - USED BY
3797 00075 0000 0 / SO FORMS CONTROL WILL WORK ON
3798 00076 6001 FPNXT, ICYCLE /USED AS INTERPRETER ADDRESS IF
3802 00077 0000 HAND, 0 /HANDLER ENTRY POINT
3803 00100 0000 HCODEW, 0 /HANDLER LOAD ADDR & FIELD + IOFFL
3804 00101 0000 BADFLD, 0 /BUFFER ADDRESS AND FIELD
3805 00102 0000 CHRPTR, 0 /ACTUALLY A WORD POINTER
3806 00103 0000 CHRCTR, 0 /COUNTER - RANGES FROM -3 TO -1
3807 00104 0000 STBLK, 0 /STARTING BLOCK OF FILE
3808 00105 0000 RELBLK, 0 /CURRENT RELATIVE BLOCK NUMBER
3809 00106 0000 TOTBLK, 0 /LENGTH OF FILE
3810 00107 0000 FFLAGS, 0 /FILE FLAGS:
3811 /BIT 0 - "HAS BEEN WRITTEN" FLAG
3812 /BITS 1-2 - FORMATTED/UNFORMATTED
3813 /BIT 11 - "END-FILED" FLAG
3814 00110 0000 BUFFLD, 0 /ROUTINE TO SET DF TO BUFFER FIELD
3815 00111 7402 BUFCDF, HLT
3816 00112 5510 JMP I BUFFLD
3817 00113 0000 FGPBF, 0 /THESE THREE WORDS ARE USED
3818 00114 0000 BIOPTR, 0 /TO FETCH AND STORE FLOATING POINT
3819 00115 0000 FEXIT /FROM RANDOM MEMORY
3830 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 5
3834 00200 2203 FTEMP2, ISZ .+3 /ALSO USED AS I/O F.P. TEMPORARY
3835 00201 6213 CDF CIF 10
3836 00202 5603 JMP I .+1
3837 00203 2200 VDATE, RTSLDR /USED TO STORE OS/8 DATE
3839 /RTS ENTRY POINTS - "VERSION INDEPENDENT"
3841 00204 5777 VUERR, JMP I (USRERR /USER ERROR
3842 /** LOADER MUST DEFINE #ARGER AS
3843 00205 4434 VARGER, JMS I ERR /LIBRARY ARGUMENT ERROR
3844 00206 2023 VRENDO, ISZ RWFLAG /END OF I/O LIST
3845 00207 5634 VRFSV, JMP I GETLMN /I/O LIST ARG ENTRY - COROUTINE
3846 00210 5776 VBAK, JMP I (BKSPC /"BACKSPACE" ROUTINE
3847 00211 5775 VENDF, JMP I (ENDFL /"END FILE" ROUTINE
3848 00212 5774 VREW, JMP I (RWIND /"REWIND" ROUTINE
3849 00213 5773 VDEF, JMP I (DFINE /"DEFINE FILE" ROUTINE
3850 00214 7330 VWUO, AC4000 /UNFORMATTED WRITE
3851 00215 5772 VRUO, JMP I (RWUNF /UNFORMATTED READ
3852 00216 7330 VWDAO, AC4000 /DIRECT ACCESS WRITE
3853 00217 5771 VRDAO, JMP I (RWDACC /DIRECT ACCESS READ
3854 00220 7330 VWRITO, AC4000 /FORMATTED (ASCII) WRITE
3855 00221 5770 VREADO, JMP I (RWASCI /FORMATTED (ASCII) READ
3856 00222 5767 VSWAP, JMP I (SWAP /OVERLAY PROCESSOR
3857 00223 3000 VEXIT, TRAP3; CALXIT /"STOP" ROUTINE - ENTERED IN FPP
3859 00225 0000 V8OR12, 0;0 /0;1 IF CPU IS A PDP-12
3861 00227 5766 VBACKG, JMP I (NULLJB /BACKGROUND JOB DISPATCHER
3863 00231 6203 CDF CIF 0 /USED BY ROUTINE "ONQB" IN LIBRARY
3864 00232 4630 JMS I .-2
3865 00233 5227 JMP VBACKG
3867 /IOH GET VARIABLE ROUTINE.
3868 /THIS ROUTINE MAKES THE FORMATTED I/O PROCESSOR AND THE
3869 /PROGRAM CO-ROUTINES (DEF(COROUTINE): 2 ROUTINES EACH
3870 / IS A SUBROUTINE). ON ENTRY FAC=INPUT NUMBER
3871 /IF I/O IS A READ, ON RETURN FAC=OUTPUT NUMBER IF I/O
3873 00234 0000 GETLMN, 0
3874 00235 5577 VRETRN, JMP I [RETURN
3889 All FORTRAN IV mass storage I/O is performed in terms of OS/8 blocks,
3890 including direct access I/O. Hence, all FORTRAN IV files conform to
3891 OS/8 standard ASCII file format. When a formatted READ or WRITE is
3892 requested, the data is converted to or from 8-bit binary representa-
3893 tion according to the FORMAT statement associated with the READ or
3894 WRITE. Standard OS/8 file format packs three 8-bit characters into
3895 two 12-bit words as follows:
3898 ----------------------------- ------------------
3899 | WORD 3 | | | WORD 1 |
3900 | bits 0-3 | WORD 1 | |----------------|
3901 |---------------------------- | WORD 2 |
3902 | WORD 3 | | |----------------|
3903 | bits 4-7 | WORD 2 | | WORD 3 |
3904 ----------------------------- ------------------
3906 Unformatted (i.e. direct access) READ and WRITE operations also
3907 operate on standard OS/8 format files, with each statement causing one
3908 FORTRAN IV record to be read or written. A FORTRAN IV record must
3909 contain at least one OS/8 block, and always contains an integral
3910 number of blocks. The number of variables contained in a 1-block
3911 record depends upon the content and format of the I/O list, as
3914 Number of 12-bit Number of
3915 Format type Words/Variable Variables/Block
3916 ___________ ________________ _______________
3920 Double precision 6 42 1/2
3923 It is possible to mix any types of data in an I/O list; however, no
3924 more than 85 variables may be stored in one OS/8 block. The number of
3925 blocks required for a FORTRAN IV record depends, therefore, upon the
3926 number of variables in the I/O list, and may be minimized by supplying
3927 every direct access WRITE with sufficient data to nearly fill an
3928 integral number of blocks without overflowing the last block.
3930 The last word in every file block contains a block count sequence
3931 number and is not available for data storage. FRTS assigns block
3932 count numbers sequentially, beginning with 1, whenever a file is
3933 written. Block count numbers must be maintained by the user when
3934 FORTRAN IV files are created outside of an OS/8 FORTRAN IV
3935 environment. While reading a binary file, FRTS checks the block count
3936 sequence numbers on input blocks and ignores any block whose sequence
3937 number is larger than expected. Sequence number checking is disabled
3938 during direct access READ operations.
3940 When FRTS is loaded and started, the initialization routines deter-
3941 mine what optional hardware, such as FPP-12 Floating Point Processor
3942 or KE8E Extended Arithmetic Element, is present in the running
3943 hardware configuration. The initialization routines then modify FRTS
3949 to use the optional hardware, if available. When an FPP is present in
3950 the system and it becomes desirable to disable the FPP under FRTS,
3951 this may be accomplished by changing the content of location 12621
3952 from 6555 to 7200. The extended arithmetic element may be disabled in
3953 the same manner by changing the content of FRTS location 12623 from
3954 7413 to 7200. These changes must be made before FRTS is started. The
3955 OS/8 monitor GET and ODT commands provide an excellent mechanism for
3956 changes of this type.
3958 The FRTS internal line printer handler uses a linked ring buffer for
3959 maximum I/O buffering efficiency. The buffer consists of several
3960 contiguous sections of memory, linked together by pointers. All of
3961 these buffer segments are located above 04000, so that the pointers
3962 are readily distinguishable from buffered characters. The entire
3963 07400 page is included in the line printer ring buffer. If it becomes
3964 desirable to modify FRTS by patching or reassembly, most of the 07400
3965 page may be reclaimed from the buffer by changing the content of
3966 location 07402 from 7577 to 5164. This frees up locations 07403 to
3967 07577 for new code and still leaves about eighty character positions
3968 in the LPT ring buffer.
3970 Because FRTS executes with the processor interrupt system enabled, it
3971 may hang up on hardware configurations that include equipment capable
3972 of generating spurious program interrupts. In addition, any OS/8 I/O
3973 device handler that exits without clearing all device flags may cause
3974 troublesome interrupts when it is assigned as a FORTRAN I/O unit under
3975 FRTS. To counteract these potential problems, FRTS provides certain
3976 areas that are reserved for inclusion of user-generated code designed
3977 to clear device flags and/or inhibit spurious interrupts.
3979 A string of NOP instructions beginning at location 04020 is executed
3980 during FRTS initialization, just before the interrupt system is
3981 enabled. When the /H option is specified to FRTS, the system halts
3982 after these NOPs have been executed and the interrupt system has been
3983 enabled. Another string of NOPs occupying the eight locations from
3984 03746 to 03755 is executed after every call to an OS/8 device handler.
3985 Any of these NOP instructions may be replaced by flag-handling or
3986 interrupt-servicing code. If additional memory locations are
3987 required, they may be obtained by replacing some of the code from
3988 locations 04007 to 04017 with flag-handling code. Locations 04007-17
3989 are used to clear flags associated with LAB-8/E peripheral devices.
3991 Due to memory limitations, it is not possible to add internal I/O
3992 device handlers to the four internal handlers supplied with the
3993 system. However, FORTRAN I/O unit 0, which is not defined by the ANSI
3994 standard, may be specified for terminal I/O via the internal console
3995 terminal handler. I/O unit 0 is not re-assignable.
3997 The FRTS /P option provides a mechanism whereby the core image gener-
3998 ated from a FORTRAN program may be punched onto paper tape in binary
3999 loader format. This permits the loader image to be executed on a
4000 hardware configuration that does not include mass-storage devices. To
4001 use the /P option, specify /P to FRTS and assign a device or file as
4002 FORTRAN I/O unit 9. Assigning the paper tape punch as unit 9 causes
4008 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 6
4010 /INTERRUPT DRIVEN I/O HANDLERS
4012 00236 0000 LPT, 0 /RING-BUFFERED - LP08 OR LS8E
4013 00237 0176 AND [377 /JUST IN CASE
4014 00240 7450 LPTSNA, SNA
4015 00241 5765 JMP I (IOERR /CANNOT BE USED FOR INPUT
4017 00243 3667 DCA I LPPUT
4018 00244 1003 TAD LPGET
4020 00246 1267 TAD LPPUT
4021 00247 7640 SZA CLA /IS LPT QUIET?
4022 00250 5253 JMP .+3 /NO
4023 00251 1667 TAD I LPPUT
4024 00252 6666 LLS /YES - START 'ER UP
4026 00254 6665 LIE /ENABLE LPT INTERRUPTS
4027 00255 1267 TAD LPPUT /1 IN AC, REMEMBER?
4028 00256 3267 DCA LPPUT
4029 00257 1667 TAD I LPPUT
4031 00261 5256 JMP .-3 /NEGATIVE NUMBERS ARE BUFFER LINKS
4032 00262 7640 SZA CLA /ANY ROOM LEFT IN BUFFER?
4033 00263 4764 JMS I (HANG
4034 00264 0436 LPUHNG /WAIT FOR LINE PRINTER
4035 00265 6001 ION /TURN INTERRUPTS BACK ON
4036 00266 5636 JMP I LPT /RETURN
4038 00267 5165 LPPUT, LPBUFR
4040 00270 0000 PTP, 0 /PAPER TAPE PUNCH HANDLER
4042 00272 5765 JMP I (IOERR /INPUT IS ERROR
4043 00273 3236 DCA LPT /SAVE CHAR
4045 00275 1006 TAD POCHR /IF PUNCH IS NOT IDLE,
4046 00276 7640 SZA CLA /WE DISMISS JOB
4047 00277 4764 JMS I (HANG
4048 00300 0502 PPUHNG /WAIT FOR PUNCH INTERRUPT
4050 00302 6026 PLS /OUTPUT CHAR
4051 00303 3006 DCA POCHR /SET FLAG NON-ZERO
4053 00305 5670 JMP I PTP
4055 /*K* THE FOLLOWING ADDRESSES GET FALLEN INTO & MUST BE SMALL
4057 IFNZRO PPUHNG&7000 <--ERROR-->
4058 IFNZRO TTUHNG&7000 <--ERROR-->
4059 IFNZRO KBUHNG&7000 <--ERROR-->
4060 IFNZRO RDUHNG&7000 <--ERROR-->
4061 IFNZRO LPUHNG&7000 <--ERROR-->
4067 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 7
4069 /INTERRUPT-DRIVEN PTR AND TELETYPE HANDLER
4071 00306 0000 PTR, 0 /CRUDE READER HANDLER
4073 00310 5765 JMP I (IOERR /OUTPUT ILLEGAL TO PTR
4075 00312 6014 RFC /START READER
4076 00313 4764 JMS I (HANG
4077 00314 0510 RDUHNG /HANG UNTIL COMPLETE
4078 00315 1007 TAD RDRCHR /GET CHARACTER
4080 00317 5706 JMP I PTR /RETURN
4081 00320 0000 TTY, 0 /BUFFERS 2 CHARS ON OUTPUT, 1 ON
4082 00321 6002 IOF /DELICATE CODE AHEAD
4083 00322 7450 SNA /INPUT OR OUTPUT?
4084 00323 5342 JMP KBD /INPUT
4085 00324 3236 DCA LPT /OUTPUT - SAVE CHAR
4086 00325 1004 TAD TOCHR /GET TTY STATUS
4087 00326 7740 SMA SZA CLA /G.T. 0 MEANS A CHAR IS BACKED UP
4088 00327 4764 JMS I (HANG
4089 00330 0451 TTUHNG /WAIT FOR LOG JAM TO CLEAR
4090 00331 1004 TAD TOCHR /NO CHAR BACKED UP - SEE IF TTY
4091 00332 7104 CLL RAL /"BUSY" FLAG IN LINK - INTERRUPTS
4092 00333 7230 CLA CML RAR /COMPLEMENT OF BUSY IN SIGN
4093 00334 1236 TAD LPT /GET CHAR
4094 00335 7510 SPA /IF TTY NOT BUSY,
4095 00336 6046 TLS /OUTPUT CHAR
4096 00337 3004 DCA TOCHR /STORE POS OR NEG, BACKED UP
4097 00340 6001 TTYRET, ION /TURN INTERRUPTS BACK ON
4098 00341 5720 JMP I TTY /AND LEAVE
4101 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 8
4103 00342 1005 KBD, TAD KBDCHR /HAS A CHARACTER BEEN INPUT?
4105 00344 4764 JMS I (HANG
4106 00345 0465 KBUHNG /NO - RUN BACKGROUND UNTIL ONE IS
4107 00346 1005 TAD KBDCHR /GET CHARACTER
4109 00350 3005 DCA KBDCHR /CHEAR CHARACTER BUFFER
4111 00352 5340 JMP TTYRET /RETURN WITH INTERRUPTS ON
4113 00353 6554 KILFPP, FPHLT /BRING FPP TO A SCREECHING HALT
4115 00355 5354 JMP .-1 /WAIT FOR IT TO STOP
4116 00356 6552 FPICL /CLEAN UP MESS HALT HAS MADE IN FPP
4117 00357 7430 SZL /^C OR ^B?
4118 00360 5763 JMP I (7600 /^C - HIYO SILVER, AWAY!
4119 00361 6032 KCC /CLEAR KBD FLAG ON ^B
4120 00362 4434 CTLBER, JMS I ERR /*** THIS MAY BE DANGEROUS! **
4126 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 9
4128 /INTERRUPT SERVICE ROUTINES
4130 00400 3322 INTRPT, DCA INTAC
4132 00402 3323 DCA INTLNK
4133 00403 5207 VINT, JMP .+4 /** MUST BE AT 403 **
4134 IFNZRO VINT-403 <--- CHANGE LOADER!!!>
4136 00405 6203 CDF CIF 0 /USER INTERRUPT ROUTINE GOES HERE
4137 00406 4604 JMS I .-2
4139 00407 6551 FPINT /CHECK FOR FPP DONE
4140 00410 5215 JMP LPTEST
4141 00411 5314 FPUHNG, JMP DISMIS /ALWAYS GOES TO RESTRT
4143 00412 5314 VDISMS, JMP DISMIS /FOR USE BY USERS
4144 00413 5314 JMP DISMIS
4145 00414 5314 JMP DISMIS
4146 00415 6661 LPTEST, LSF
4147 00416 5240 JMP NOTLPT
4148 00417 6662 LPTLCF, LCF /CLEAR FLAG
4149 00420 1403 TAD I LPGET
4150 00421 7650 SNA CLA /CHECK FOR SPURIOUS INTERRUPT
4151 00422 5314 JMPDIS, JMP DISMIS /GO AWAY IF SO
4152 00423 3403 DCA I LPGET /ZERO CHAR JUST OUTPUT
4153 00424 2003 ISZ LPGET
4154 00425 1403 TAD I LPGET
4156 00427 3003 DCA LPGET /TAKE CARE OF BUFFER LINKS
4158 00431 1403 TAD I LPGET /HAKE SURE CHAR IS IN AC
4159 00432 7440 SZA /IS THERE A CHARACTER?
4160 00433 6666 LLS /YES - PRINT IT
4162 00435 6661 LSF /CHECK FOR IMMEDIATE FLAG
4163 00436 5314 LPUHNG, JMP DISMIS /NO - MAYBE RESTART PROGRAM
4164 00437 5217 JMP LPTLCF /YES - LOOP
4166 00440 6041 NOTLPT, TSF /CHECK TTY
4167 00441 5252 JMP NOTTTY
4168 00442 6042 TCF /CLEAR FLAG
4169 00443 1004 TAD TOCHR /GET TTY STATUS
4170 00444 7540 SMA SZA /IF THERE IS A CHARACTER WAITING,
4171 00445 6046 TLS /OUTPUT IT.
4172 00446 7740 SMA SZA CLA /CHANGE "WAITING" TO "BUSY",
4173 00447 7130 STL RAR /"BUSY" TO "IDLE".
4174 00450 3004 DCA TOCHR
4175 00451 5314 TTUHNG, JMP DISMIS
4185 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 10
4187 /KBD AND PTP INTERRUPTS
4189 00452 6031 NOTTTY, KSF
4190 00453 5276 JMP NOTKBD
4192 00455 6034 KRS /USE KRS TO FORCE PARITY BIT
4193 00456 3005 DCA KBDCHR /AND ALSO SO THAT ^C WILL STILL
4194 00457 1005 TAD KBDCHR
4195 03460 1377 TAD (-202 /CHECK FOR ^C OR ^B
4198 00463 5266 JMP CTCCTB /YUP - TAKE SOME DRASTIC ACTION
4199 00464 6032 KCC /DATA CHARACTER - CLEAR FLAG
4200 00465 5314 KBUHNG, JMP DISMIS
4202 00466 1073 CTCCTB, TAD CTCINH
4203 00467 7650 SNA CLA /ARE WE IN A HANDLER?
4204 00470 5366 JMP NOTINH /NO
4205 00471 1323 TAD INTLNK
4206 00472 7104 CLL RAL /YES - RETURN WITH INTERRUPTS OFF
4207 00473 1322 TAD INTAC /TRUST IN GOD AND RTS
4211 00476 6021 NOTKBD, PSF
4212 00477 5303 JMP NOTPTP
4213 00500 6022 PCF /P.T. PUNCH INTERRUPT - CLEAR FLAG
4214 00501 3006 DCA POCHR /CLEAR SOFTWARE FLAG
4215 00502 5314 PPUHNG, JMP DISMIS
4217 00503 6011 NOTPTP, RSF
4218 00504 5311 JMP LPTERR
4220 00506 6012 RRB /GET RDR CHAR
4221 00507 3007 DCA RDRCHR
4222 00510 5314 RDUHNG, JMP DISMIS
4224 00511 6663 LPTERR, LSE /TEST FOR LP08 ERROR FLAG
4226 00513 6667 LIF /DISABLE LP08 INTERRUPTS IF ERROR
4227 00514 1323 DISMIS, TAD INTLNK
4229 00516 1322 TAD INTAC /RESTORE AC AND LINK
4232 00521 5400 JMP I 0 /RETURN FROM THE INTERRUPT
4235 00523 0000 INTLNK, 0
4244 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 11
4246 /BACKGROUND INITIATE/TERMINATE ROUTINE
4248 00524 0000 HANG, 0 /ALWAYS CALLED WITH INTERRUPTS OFF!
4249 00525 1724 TAD I HANG /GET POINTER TO UNHANGING LOCATION
4250 00526 3371 DCA UNHANG
4251 00527 6214 RDF /GET FIELD CALLED FROM
4252 00530 1332 TAD HCIDF0
4253 00531 3364 DCA HNGCDF /SAVE FOR RETURN
4254 00532 6203 HCIDF0, CDF CIF 0
4255 00533 1376 TAD (JMP RESTRT /CHANGE THE "JMP DISMIS"
4256 00534 3771 DCA I UNHANG /TO A "JMP RESTRT"
4257 00535 1373 TAD BACKLK
4259 00537 1372 TAD BACKAC /SET UP BACKGROUND AC AND LINK
4260 00540 6202 BAKCIF, CIF 0
4261 00541 6201 BAKCDF, CDF 0
4263 00543 5774 JMP I BACKPC /INITIATE BACKGROUND
4265 / COME HERE WHEN THE HANG CONDITION HAS GONE AWAY
4267 00544 1222 RESTRT, TAD JMPDIS /RESTORE THE UNHANG LOCATION
4268 00545 3771 DCA I UNHANG
4269 00546 1322 TAD INTAC /SUSPEND THE BACKGROUND
4270 00547 3372 DCA BACKAC
4271 00550 1323 TAD INTLNK
4272 00551 3373 DCA BACKLK
4274 00553 3374 DCA BACKPC
4277 00556 1332 TAD HCIDF0
4278 00557 3340 DCA BAKCIF
4280 00561 4436 JMS I MCDF /*K* OK SINCE BACKGROUND DOESN'T
4281 00562 3341 DCA BAKCDF
4283 00564 7402 HNGCDF, HLT
4284 00565 5724 JMP I HANG /INTERRUPTS ARE OFF - RETURN
4285 00566 1222 NOTINH, TAD JMPDIS /IN CASE WE WERE HUNG, WE DON'T
4286 00567 3771 DCA I UNHANG /TO GET "UNHUNG" OUT OF THE ERROR
4287 00570 5775 JMP I (KILFPP /KILL FPP AND GO TO EXIT OR ERROR
4289 00571 0000 UNHANG, 0
4290 00572 0000 BACKAC, 0
4291 00573 0000 BACKLK, 0
4292 00574 0227 BACKPC, VBACKG
4294 IFNZRO VHANG-0524 <--CHANGE LOADER!>
4303 the image to be punched out directly; however, it may be desirable to
4304 direct the binary output to an intermediate file for later transfer to
4305 paper tape via OS/8 PIP. In any event, FRTS returns to the monitor
4306 once the core image has been transferred.
4308 The output file is a binary image of memory locations 00000 to 07577
4309 and 10000 up to the highest location used by the FORTRAN load. The
4310 content of each field is punched separately with its own checksum and
4313 With the BIN loader resident in field 0, load the binary tape produced
4314 under the /P option by reading each segment separately and verifying
4315 the checksum as each memory field is loaded. When all segments have
4316 been read into memory, start execution at location 00200. The
4317 following restrictions apply:
4319 1. OS/8 device handlers which have been assigned FORTRAN I/O
4320 unit numbers are not necessarily punched out. For this
4321 reason, I/O unit assignments other than in the form /n=m
4324 2. With respect to the presence of an FPP and/or EAE, the con-
4325 figuration on which the image is punched must be identical to
4326 the configuration on which it is to be run. If the punching
4327 configuration contains hardware that is absent from the
4328 target configuration, this hardware must be disabled under
4329 FRTS. If the target configuration contains hardware that is
4330 absent from the punching configuration, the extraneous
4331 hardware will not be used.
4333 3. The statements STOP and CALL EXIT cause a core load produced
4334 under the /P option to halt. Any fatal error flagged during
4335 punching or execution causes error traceback followed by a
4336 halt. Do not press CONTinue in response to either of these
4339 A FORTRAN IV program is terminated in one of three ways:
4341 1. A fatal error condition is flagged (CTRL/B) is processed as a
4344 2. CTRL/C is recognized, or the CPU is halted and re-started in
4347 3. A STOP, CALL EXIT, or (under RALF) JSR #EXIT statement is
4350 The sequence of events that results in program termination proceeds as
4363 (1) (CTRL/B) (2) CTRL/C CALL EXIT (3)
4365 ------------- --------------- ---------------
4366 | BRANCH TO | | | | SIMULATE |
4367 | ERROR | | EXECUTE IOF | | END FILE ON |
4368 | ROUTINE | | | | ANY OPEN |
4369 ------------- --------------- | FILES |
4372 ------------- --------------- / \ |
4373 | | | LET I/O DE- | / TTY, \ |
4374 | PRINT | | VICE HANDLER| /LPT BUFFERS\_|
4375 | TRACEBACK | | PROCESS ^C | \ CLEAR / NO
4376 ------------- --------------- \ ? /
4380 | ------------- | ---------------
4381 | | | | | SET NORMAL |
4382 ----->| JMP 07605 |<------ | TERMINATION |
4384 ------------- ---------------
4386 | Location 07605 traps back to FRTS |
4387 -------------------------------------|
4392 At point A, FRTS executes the following operations.
4394 1. Read termination routine into memory.
4396 2. Read OS/8 field 0 resident from block 37 of SYS.
4398 3. Jump into termination routine at location 17400.
4400 4. restore normal content of locations 07600 and 07605 (in OS/8
4403 5. If configuration is an in-core TD8E DECtape system, restore
4404 second part of TD8E handler from n7600 to 27600.
4406 6. Wait for TTY to finish all pending I/O. If BATCH is running,
4407 print LF on TTY and LPT.
4409 7. If normal termination flag is set, close any output files
4410 that were opened by the FRTS loader.
4412 8. Return to OS/8 monitor via location 07605.
4421 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 78
4423 6600 FPPKG= . /FOR EAE OVERLAY
4425 /23-BIT FLOATING PT INTERPRETER
4426 /W.J. CLOGHER, MODIFIED BY R.LARY FOR FORTRAN
4428 06600 0000 LPBUF2, ZBLOCK 16
4431 06617 0000 AL1BMP, 0 /*K* UTILITY SUBROUTINE
4435 06623 4542 JMS I [AL1
4436 06624 5617 JMP I AL1BMP
4438 /FLOATING MULTIPLY-DOES 2 24X12 BIT MULTIPLIES
4439 06625 4777 DDMPY, JMS I (DARGET
4441 06627 4776 FFMPY, JMS I (ARGET /GET OPERAND
4442 06630 4304 JMS MDSET /SET UP FOR MPY-OPX IN AC ON RETN.
4443 06631 1044 TAD ACX /DO EXPONENT ADDITION
4444 06632 3044 DCA ACX /STORE FINAL EXPONENT
4445 06633 3304 DCA MDSET /ZERO TEM STORAGE FOR MPY ROUTINE
4447 06635 1045 TAD ACH /IS FAC=0?
4449 06637 3044 DCA ACX /YES-ZERO EXPONENT
4450 06640 4334 JMS MP24 /NO-MULTIPLY FAC BY LOW ORDER OPR.
4451 06641 1056 TAD OPH /NOW MULTIPLY FAC BY HI ORDER MULT
4454 06644 1054 TAD AC2 /STORE RESULT BACK IN FAC
4455 06645 3046 DCA ACL /LOW ORDER
4456 06646 1304 TAD MDSET /HIGH ORDER
4458 06650 1045 TAD ACH /DO WE NEED TO NORMALIZE?
4461 06653 4217 JMS AL1BMP /YES-DO IT FAST
4463 06655 7710 SPA CLA /CHECK OVERFLOW WORD
4464 06656 2046 ISZ ACL /HIGH BIT ON - ROUND RESULT
4465 06657 5265 JMP MDONE
4466 06660 2045 ISZ ACH /LOW ORDER OVERFLOWED - INCREMENT
4468 06662 7510 SPA /CHECK FOR OVERFLOW TO 4000 0000
4469 06663 5775 JMP I (SHR1 /WE HANDLE A SIMILIAR CASE IN
4480 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 79
4482 06665 3053 MDONE, DCA AC1 /ZERO OVERFLOW WD(DO I NEED THIS???
4483 06666 2333 ISZ MSIGN /SHOULD RESULT BE NEGATIVE?
4485 06670 4543 JMS I [FFNEG /YES-NEGATE IT
4487 06672 7650 SNA CLA /A ZERO AC MEANS A ZERO EXPONENT
4490 06675 7740 SMA SZA CLA /D.P. INTEGER MODE?
4491 06676 1044 TAD ACX /WITH ACX LESS THAN 0?
4493 06700 5476 JMP I FPNXT /NO - RETURN
4495 06702 4541 JMS I [ACSR /UN-NORMALIZE RESULT
4496 06703 5476 JMP I FPNXT /RETURN
4501 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 80
4503 /MDSET-SETS UP SIGNS FOR MULTIPLY AND DIVIDE
4504 /ALSO SHIFTS OPERAND ONE BIT TO THE LEFT.
4505 /EXIT WITH EXPONENT OF OPERAND IN AC FOR EXPONENT
4506 /CALCULATION-CALLED WITH ADDRESS OF OPERAND IN AC AND
4507 /DATA FIELD SET PROPERLY FOR OPERAND.
4510 06705 7344 CLA CLL CMA RAL /SET SIGN CHECK TO -2
4511 06706 3333 DCA MSIGN
4512 06707 1056 TAD OPH /IS OPERAND NEGATIVE?
4514 06711 5314 JMP .+3 /NO
4515 06712 4774 JMS I (OPNEG /YES-NEGATE IT
4516 06713 2333 ISZ MSIGN /BUMP SIGN CHECK
4517 06714 1057 TAD OPL /AND SHIFT OPERAND LEFT ONE BIT
4523 06722 3053 DCA AC1 /CLR. OVERFLOW WORD OF FAC
4524 06723 1045 TAD ACH /IS FAC NEGATIVE
4526 06725 5331 JMP LEV /NO-GO ON
4527 06726 4543 JMS I [FFNEG /YES-NEGATE IT
4528 06727 2333 ISZ MSIGN /BUMP SIGN CHECK
4529 06730 7000 NOP /MAY SKIP
4530 06731 1055 LEV, TAD OPX /EXIT WITH OPERAND EXPONENT IN AC
4531 06732 5704 JMP I MDSET
4539 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 81
4541 /24 BIT BY 12 BIT MULTIPLY. MULTIPLIER IS IN OPL
4542 /MULTIPLICAND IS IN ACH AND ACL
4543 /RESULT LEFT IN MDSET,AC2, AND AC1
4546 06735 1373 TAD (-14 /SET UP 12 BIT COUNTER
4548 06737 1057 TAD OPL /IS MULTIPLIER=0?
4550 06741 5345 JMP MPLP1 /NO-GO ON
4551 06742 3053 DCA AC1 /YES-INSURE RESULT=0
4552 06743 5734 JMP I MP24 /RETURN
4553 06744 1057 MPLP, TAD OPL /SHIFT A BIT OUT OF LOW ORDER
4554 06745 7010 MPLP1, RAR /OF MULTIPLIER AND INTO LINK
4556 06747 7420 SNL /WAS IT A 1?
4557 06750 5356 JMP MPLP2 /NO - 0 - JUST SHIFT PARTIAL PROD
4558 06751 1054 TAD AC2 /YES-ADD MULTIPLICAND TO PARTIAL
4559 06752 1046 TAD ACL /LOW ORDER
4561 06754 7024 CML RAL /*K* NOTE THE "SNL" 5 WORDS BACK!
4562 06755 1045 TAD ACH /HI ORDER
4563 06756 1304 MPLP2, TAD MDSET
4564 06757 7010 RAR /NOW SHIFT PARTIAL PROD. RIGHT 1
4565 06760 3304 DCA MDSET
4570 06765 7010 RAR /OVERFLOW TO AC1
4572 06767 2055 ISZ OPX /DONE ALL 12 MULTIPLIER BITS?
4573 06770 5344 JMP MPLP /NO-GO ON
4574 06771 5734 JMP I MP24 /YES-RETURN
4583 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 82
4585 /DIVIDE-BY-ZERO ROUTINE - MUST BE AT BEGINNING Of PAGE
4587 07000 2035 DBAD, ISZ FATAL /DIVIDE BY 0 NON-FATAL
4588 07001 4434 JMS I ERR /GIVE ERROR MSG
4590 07003 3044 DCA ACX /RETURN A VERY LARGE POSITIVE NUM
4598 /FLOATING DIVIDE - USES DIVIDE-AND-CORRECT METHOD
4600 07006 4777 DDDIV, JMS I (DARGET
4602 07010 4776 FFDIV, JMS I (ARGET /GET OPERAND
4603 07011 4775 JMS I (MDSET /GO SET UP FOR DIVIDE-OPX IN AC
4604 07012 7041 CMA IAC /NEGATE EXP. OF OPERAND
4605 07013 1044 TAD ACX /ADD EXP OF FAC
4606 07014 3044 DCA ACX /STORE AS FINAL EXPONENT
4607 07015 1056 TAD OPH /NEGATE HI ORDER OP. FOR USE
4608 07016 7141 CLL CMA IAC /AS DIVISOR
4610 07020 4231 JMS DV24 /CALL DIV.--(ACH+ACL)/OPH
4611 07021 1046 TAD ACL /SAVE QUOT. FOR LATER
4615 07025 5327 JMP DVL2 /AVOID MULTIPLYING BY 0
4616 07026 1374 TAD (-15 /SET COUNTER FOR 12 BIT MULTIPLY
4617 07027 3231 DCA DV24 /TO MULTIPLY QUOT. OF DIV. BY
4618 07030 5267 JMP DVLP1 /LOW ORDER OF OPERAND (OPL)
4620 /DIVIDE ROUTINE - (ACH,ACL)/OPH = ACL REMAINDER REM
4623 07032 1045 TAD ACH /CHECK THAI DIVISOR IS .GT.
4624 07033 1056 TAD OPH /DIVISOR IN OPH (NEGATIVE)
4625 07034 7630 SZL CLA /IS IT?
4626 07035 5200 JMP DBAD /NO-DIVIDE OVERFLOW
4627 07036 1374 TAD (-15 /YES-SET UP 12 BIT LOOP
4629 07040 5251 JMP DV1 /GO BEGIN DIVIDE
4630 07041 1045 DV2, TAD ACH /CONTINUE SHIFT OF FAC LEFT
4632 07043 3045 DCA ACH /RESTORE HI ORDER
4633 07044 1045 TAD ACH /NOW SUBTRACT DIVISOR FROM HI ORDER
4634 07045 1056 TAD OPH /DIVIDEND
4635 07046 7430 SZL /GOOD SUBTRACT?
4636 07047 3045 DCA ACH /YES-RESTORE HI DIVIDEND
4637 07050 7200 CLA /NO-DON'T RESTORE--OPH.GT.ACH
4638 07051 1046 DV1, TAD ACL /SHIFT FAC LEFT 1 BIT-ALSO SHIFT
4639 07052 7004 RAL /1 BIT OF QUOT. INTO LOW ORD OF ACL
4641 07054 2054 ISZ AC2 /DONE 12 BITS OF QUOT?
4642 07055 5241 JMP DV2 /NO-GO ON
4643 07056 5631 JMP I DV24 /YES-RETN W/AC2=0
4657 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 83
4659 /DIVIDE ROUTINE CONTINUED
4661 07057 3057 MP12L, DCA OPL /STORE BACK MULTIPLIET
4662 07060 1054 TAD AC2 /GET PRODUCT SO FAR
4663 07061 7420 SNL /WAS MULTIPLIER BIT A 1?
4664 07062 5265 JMP .+3 /NO-JUST SHIFT THE PARTIAL PRODUCT
4665 07063 7100 CLL /YES-CLEAR LINK AND ADD MULTIPLICAND
4666 07064 1046 TAD ACL /TO PARTIAL PRODUCT
4667 07065 7010 RAR /SHIFT PARTIAL PRODUCT-THIS IS HI
4668 07066 3054 DCA AC2 /RESULT-STORE BACK
4669 07067 1057 DVLP1, TAD OPL /SHIFT A BIT OUT OF MULTIPLIER
4670 07070 7010 RAR /AND A BIT OR RESLT. INTO IT (LO
4671 07071 2231 ISZ DV24 /DONE ALL BITS?
4672 07072 5257 JMP MP12L /NO-LOOP BACK
4673 07073 7141 CLL CIA /YES-LOW ORDER PROD. OF QUOT. X
4674 07074 3046 DCA ACL /NEGATE AND STORE
4675 07075 7024 CML RAL /PROPAGATE CARRY
4676 07076 1054 TAD AC2 /NEGATE HI ORDER PRODUCT
4678 07100 1045 TAD ACH /COMPARE WITH REMAINDER OF FIRST
4679 07101 7430 SZL /WELL?
4680 07102 5331 JMP DVOPS /GREATER THAN REM. - ADJUST QUOT OF
4681 07103 3045 DCA ACH /OK - DO (REM - (Q*OPL)) / OPH
4682 07104 4231 DVL3, JMS DV24 /DIVIDE BY OPH (HI ORDER OPERAND)
4683 07105 1053 DVL1, TAD AC1 /GET QUOT. OF FIRST DIV.
4684 07106 7500 SMA /IF HI ORDER BIT SET-MUST SHIFT 1
4685 07107 5325 JMP FD /NO-ITS NORMALIZED-DONE
4686 07110 7100 SHR1, CLL
4687 07111 2046 ISZ ACL /ROUND AND SHIFT RIGHT ONE
4689 07113 7001 IAC /DOUBLE PRECISION INCREMENT
4691 07115 3045 DCA ACH /STORE IN FAC
4692 07116 1046 TAD ACL /SHIFT LOW ORDER RIGHT
4694 07120 3046 DCA ACL /STORE BACK
4695 07121 2044 ISZ ACX /BUMP EXPONENT
4698 07124 5306 JMP DVL1+1 /IF FRACT WAS 77777777 WE MUST
4699 07125 3045 FD, DCA ACH /STORE HIGH ORDER RESULT
4700 07126 5773 JMP I (MDONE /GO LEAVE DIVIDE
4702 07127 3046 DVL2, DCA ACL /COME HERE IF LOW-ORDER QUO=0
4703 07130 5304 JMP DVL3 /SAVE SOME TIME
4716 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 84
4718 /ROUTINE TO ADJUST QUOTIENT OF FIRST DIVIDE (MAYBE) WHEN
4719 /REMAINDER OF THE FIRST DIVIDE IS LESS THAN QUOT*OPL
4721 07131 7041 DVOPS, CMA IAC /NEGATE AND STORE REVISED REMAINDER
4725 07135 1045 TAD ACH /WATCH FOR OVERFLOW
4727 07137 5344 JMP DVOP1 /OVERFLOW-DON'T ADJUST QUOT. OF 1
4728 07140 3045 DCA ACH /NO OVERFLOW-STORE NEW REM.
4729 07141 7040 CMA /SUBTRACT 1 FROM QUOT OF
4730 07142 1053 TAD AC1 /FIRST DIVIDE
4732 07144 7300 DVOP1, CLA CLL
4733 07145 1045 TAD ACH /GET HI ORD OF REMAINDER
4734 07146 7450 SNA /IS IT ZERO?
4735 07147 3046 DVOP2, DCA ACL /YES-MAKE WHOLE THING ZERO
4737 07151 4231 JMS DV24 /DIVIDE EXTENDED REM. BY HI DIVISOR
4738 07152 1046 TAD ACL /NEGATE THE RESULT
4739 07153 7141 CLL CMA IAC
4741 07155 7420 SNL /IF QUOT. IS NON-ZERO, SUBTRACT
4742 07156 7040 CMA /ONE FROM HIGH ORDER QUOT.
4743 07157 5305 JMP DVL1 /GO TO IT
4745 07160 0000 LPBUF3, ZBLOCK 12
4775 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 85
4777 /"NRMFAC" AND "OPNEG" MUST BE AT 0 AND 3 ON PAGE
4779 07200 3053 NRMFAC, DCA AC1 /KILL OVERFLOW BIT
4780 07201 4271 JMS FFNOR
4781 07202 5476 JMP I FPNXT
4783 07203 0000 OPNEG, 0 /ROUTINE TO NEGATE OPERAND
4784 07204 1057 TAD OPL /GET LOW ORDER
4785 07205 7141 CLL CMA IAC /NEGATE AND STORE BACK
4787 07207 7024 CML RAL /PROPAGATE CARRY
4788 07210 1056 TAD OPH /GET HI ORDER
4789 07211 7141 CLL CMA IAC /NEGATE AND STORE BACK
4791 07213 5603 JMP I OPNEG
4793 /FLOATING SUBTRACT AND ADD
4795 07214 4777 FFSUB, JMS I (ARGET /PICK UP THE OP.
4796 07215 4203 JMS OPNEG /NEGATE OPERAND
4798 07217 4777 FFADD, JMS I (ARGET /PICK UP OPERAND
4799 07220 1056 TAD OPH /IS OPERAND = 0
4801 07222 5476 JMP I FPNXT /YES-DONE
4802 07223 1045 TAD ACH /NO-IS FAC=0?
4804 07225 5236 JMP DOADD /YES-DO ADD
4805 07226 1044 TAD ACX /NO-DO EXPONENT CALCULATION
4806 07227 7141 CLL CMA IAC
4808 07231 7540 SMA SZA /WHICH EXP. GREATER?
4809 07232 5243 JMP FACR /OPERANDS-SHIFT FAC
4810 07233 7041 CMA IAC /FAC'S-SHIFT OPERAND=DIFFRNCE+1
4812 07235 4541 JMS I [ACSR /SHIFT FAC ONE PLACE RIGHT
4813 07236 1055 DOADD, TAD OPX /SET EXPONENT OF RESULT
4815 07240 4537 JMS I [OADD /DO THE ADDITION
4816 07241 4271 JMS FFNOR /NORMALIZE RESULT
4817 07242 5476 JMP I FPNXT /RETURN
4818 07243 4541 FACR, JMS I [ACSR /SHIFT FAC = DIFF.+1
4819 07244 4246 JMS OPSR /SHIFT OPR. 1 PLACE
4820 07245 5236 JMP DOADD /DO ADDITION
4834 /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 86
4836 /OPERAND SHIFT RIGHT-ENTER WITH POSITIVE COUNT-1 IN AC
4839 07247 7040 CMA /- (COUNT+1) TO SHIFT COUNTER
4841 07251 1056 LOP2, TAD OPH /GET SIGN BIT
4842 07252 7100 CLL /TO LINK
4844 07254 7020 CML /WITH HI MANTISSA IN AC
4845 07255 7010 RAR /SHIFT IT RIGHT, PROPAGATING SIGN
4846 07256 3056 DCA OPH /STORE BACK
4849 07261 3057 DCA OPL /STORE LO ORDER BACK
4850 07262 2055 ISZ OPX /INCREMENT EXPONENT
4852 07264 2052 ISZ AC0 /DONE ALL SHIFTS?
4853 07265 5251 JMP LOP2 /NO-LOOP
4854 07266 7010 RAR /SAVE 1 BIT OF OVERFLOW
4855 07267 3054 DCA AC2 /IN AC2
4856 07270 5646 JMP I OPSR /YES-RETN.
4858 07271 0000 FFNOR, 0 /ROUTINE TO NORMALIZE THE FAC
4859 07272 1045 TAD ACH /GET THE HI ORDER MANTISSA
4860 07273 7450 SNA /ZERO?
4861 07274 1046 TAD ACL /YES-HOW ABOUT LOW?
4863 07276 1053 TAD AC1 /LOW=0, IS OVRFLO BIT ON?
4865 07300 5313 JMP ZEXP /#=0-ZERO EXPONENT
4866 07301 7332 NORMLP, CLA CLL CML RTR /NOT 0-MAKE A 2000 IN AC
4867 07302 1045 TAD ACH /ADD HI ORDER MANTISSA
4868 07303 7440 SZA /HI ORDER = 6000
4869 07304 5307 JMP .+3 /NO-CHECK LEFT MOST DIGIT
4870 07305 1046 TAD ACL /YES-6000 OK IF LOW=O
4872 07307 7710 SPA CLA /2,3,4,5,ARE LEGAL LEFT MOST DIGS.
4873 07310 5314 JMP FFNORR /FOR NORMALIZED #-(+2000=4,5,6,7)
4874 07311 4534 JMS I (AL1BMP /SHIFT AC LEFT AND BUMP ACX DOWN
4875 07312 5301 JMP NORMLP /GO BACK AND SEE IF NORMALIZED
4876 07313 3044 ZEXP, DCA ACX
4877 07314 3053 FFNORR, DCA AC1 /DONE W/NORMALIZE - CLEAR AC1
4878 07315 5671 JMP I FFNOR /RETURN
4880 07316 0000 LPBUF4, ZBLOCK 60
4898 The binary output of an assembly under RALF is called a RALF module.
4899 Every RALF module consists of an External Symbol Dictionary (or ESD)
4900 and associated text. The ESD lists all global symbols defined in the
4901 assembly, while the text contains the actual binary output along with
4904 There are three major classes of global symbols. Entry points are
4905 global symbols defined in a module and referenced by code in other
4906 modules. Thus, entry points include the names of all modules and the
4907 names of all globally callable subroutines within modules. Externs are
4908 global symbols that are referenced in a module but not defined in that
4909 module. For example, the entry point of module A would appear as an
4910 extern if referenced in module B. The COMMON area comprises a third
4911 class of global symbols including all global symbols which define
4914 A FORTRAN IV library is a specially formatted file, created with
4915 LIBRA, consisting of a library catalog (which lists section names and
4916 entry points of library modules) and a set of RALF modules, perhaps
4917 interspersed with empty subfiles. The loader uses one such library,
4918 specified by the user, to resolve externs while building a loader
4919 image file. The general structure of a FORTRAN IV library is:
4921 ----------------------------------------------------------------
4922 | CATALOG | MODULE | FREE | MODULE | MODULE | \
4923 | | | AREA | | | etc. /
4925 -----------------------------------------------------------------
4927 LIBRA is a very simple program, basically a file-to-file copy inside
4928 several nested loops. The outer loop begins at START, and calls the
4929 command decoder for specification of the library and input files. If
4930 no library is specified, the previous library name is used (initially
4931 this is SYS:FORLIB.RL). If a new name is given, but no extension is
4932 specified, .RL is forced. A check is made to verify that the
4933 specified library is on a file-structured device, and the handler is
4936 At ZTEST, the /Z switch is tested. If it was set, control passes to
4937 NEWLIB to create a new library. Otherwise, an attempt is made to find
4938 an old library of the specified name on the device. If it fails,
4939 control passes to NEWLIB. Otherwise, the catalog of the old library
4940 is read and scanned to determine the starting block of available
4941 space. This is stored at LAVAIL. Control then passes to GETINF to
4942 begin reading input files.
4944 If /Z was set, or the specified library isn't found, a new library is
4945 entered at NEWLIB, and an empty catalog is written. Control passes to
4946 GETINF. There, a check is made to determine whether input is
4952 presently coming from another library. If it is, control passes to
4953 INLIB to obtain the next module from the library. Otherwise, the next
4954 input file is obtained from the command decoder area in field 1, and
4955 if one exists, control passes to FTCHIN to load the handler. If there
4956 is none, the /C switch is tested. If it is not set, control is passed
4957 to LCLOSE to close the library. If it is set, however, the command
4958 decoder is recalled to obtain a continuation of the preceding input
4959 line, and control returns to NXTINF to look in the command decoder
4962 At FTCHIN, the unit, starting block, and length of the next input file
4963 are obtained from the command decoder area, the appropriate device
4964 handler is fetched, and at LUKMOD, the input file is read to ensure
4965 that it is either a module or a library. If a library, control passes
4966 to GOTLIB, which sets INLSW and goes to INLIB to obtain the first
4967 module from the library. Otherwise, the length is checked against the
4968 available length in the library, to ensure that this module can be fit
4969 in, and control goes to NXTEBK to read the ESD.
4971 At INLIB, the catalog of the library being input is read, and scanned
4972 until a module is found with a starting block greater than the
4973 starting block of the last input module (in the case of the first
4974 module in a library, MODBLK, which normally contains the starting
4975 block of a module, contains the starting block of the library, so this
4976 scan yields the starting block of the first module in the library).
4977 When the next module has been found, control returns to LUKMOD to
4978 check the length of the module against the available length in the
4981 At NXTEBK, the end of the input module is scanned for entry point and
4982 section names. Whenever one is found, the catalog of the output
4983 library is scanned for a matching name. If a match is found, control
4984 passes to GOTMAT, which prints the duplicated name, and if the /I
4985 switch is set, asks the operator which name to keep. If he types N,
4986 for new, control passes to DLETO to delete the old name. Otherwise,
4987 control is passed to ESDLND to find the next entry point or section
4988 name in the input. If /I is not set, /R is tested. If it is not set,
4989 control is passed to ESDLND. If it is, control flows into DELTO,
4990 where the old name is cleared, and the rest of the catalog is scanned
4991 to find the first available name slot. Control then passes to INSERT.
4993 If no match was found, the /I switch is tested. If it was set, the
4994 operator is asked whether to include the name. If he types, N, for
4995 no, control is passed to ESDLND. Otherwise, or if /I was not set, a
4996 pointer is set up for the new name, and control passes to INSERT,
4997 where the new name is added to the catalog.
4999 When the entire ESD has been scanned, INCLUD is tested to determine
5000 whether any name has been included in the catalog, and assuming at
5001 least one has, the module is copied into the library, and LAVAIL is
5002 updated to indicate the next available block in the library. Control
5003 returns to GETINF for another module.
5011 LCLOSE receives control whenever the end of the input file string is
5012 reached and /C is not set. Here, any remaining changes in the library
5013 catalog are written, and if a new library was entered, it is closed.
5014 Control passes to CATLST, to create a catalog listing. The second
5015 output file, if any was specified, is opened, a title is output to it,
5016 and at PRCAT, the entire contents of the catalog are listed. When
5017 this process is complete, the output file is closed, and control
5018 returns to start for more command decoder input.
5020 User-coded modules may be added to the system library or incorporated
5021 in a new library provided that entry points, variable storage
5022 allocations, calling sequences, error conditions and the like are
5025 Every library module must have a unique section (and entry) name(s).
5026 The library supplied by DEC uses the character # before names where
5027 duplication in the FORTRAN program may be possible. Note that this
5028 character is acceptable to RALF, but is illegal in a FORTRAN source.
5029 If more than one entry is required to the routine, they should be
5030 listed as such using the pseudo-op ENTRY before they are encountered
5031 as tags in the code. Thus, if a double precision tangent routine is
5032 being written, it may be helpful to have an entry for a double
5033 precision co-tangent calculation also. Appropriate code would be:
5048 When routines will handle double precision or complex values, allocate
5049 six words for their storage. Such routines can switch between the
5050 STARTF (3 word format) and STARTE (6 word format) pseudo-ops as
5051 required, being careful to define variables of the proper length to
5052 keep track of temporary locations.
5054 All user-written library routines are called by a JSR in STARTF mode.
5055 Depending on the type of function, the routine must be coded to exit
5056 as follows in order to return the result to the program:
5058 Single precision Answer in AC in STARTF mode
5059 (integer, real and logical)
5061 FLDA ANSWER /In STARTF mode
5062 JA RETURN /3 word result
5070 Double precision: Answer in AC in STARTE mode
5072 FLDA ANSWER /In STARTE mode
5073 JA RETURN /6 word result
5075 Complex: Answer in location #CAC in
5078 EXTERN #CAC /Real part in first 3 words
5079 STARTE /Imaginary in last 3 words
5080 FLDA ANSWER /Exit in STARTE mode
5081 FSTA #CAC /6 word result
5084 Routines should conform to the FPP FORTRAN calling sequence. An
5085 example of that sequence follows:
5087 SECT DTAN /Sector name
5088 JA #DTAN /Jump to Start of Function
5089 TEXT +DTAN + /6 characters for trace
5090 /back feature must be
5091 /immediately before index
5092 /register assignment.
5093 DTANXR, SETX XRDTAN /This tag referenced when
5094 /returning to reset base
5095 /page and index registers
5096 SETB BPDTAN /if this routine called.
5098 BPDTAN, F 0.0 /3 words each
5099 XRDTAN, F 0.0 /These locations may be
5100 /used for temporary storage or
5101 ORG 10*3+BPDTAN /If this routine is called,
5102 /will set up return to it.
5106 DTNRTN, JA . /Return to calling program
5107 BASE 0 /Still on caller's base page
5108 #DTAN, STARTD /Start of subroutine
5109 FLDA 10*3 /Get jump to caller's return jump
5110 FSTA DTNRTN /Save for return from this routine
5111 FLDA 0 /Get next location in caller's
5112 /routine (pointer to argument list)
5113 SETX XRDTAN /Change index registers to this
5115 SETB BPDTAN /Change base page to this routine's
5116 BASE BPDTAN /Change base page to this routine's
5117 FSTA TEMP /Save pointer
5119 FLDA% TEMP,1 /Get address of argument list
5121 STARTE /A double precision routine
5122 FLDA% TEMP /Get variable
5123 FSTA TEMP /Save variable
5135 FLDA ANSWER /Load answer
5138 The following conventions must be observed to return to the calling
5139 program at the correct location, to permit the error trace back
5140 feature to function properly, and to preserve index registers and base
5143 Locations 0 and 30 of the called (user-coded) program are determined
5144 by a statement in the form ORG 10*3+BPAGE which must be followed by a
5145 two-word jump to the index register and base page assignment
5146 instructions JA BPXR. In the above example, the code is:
5152 By saving the contents of location 30 of the calling program (FLDA
5153 10*3,FSTA RETURN) for the return exit, the called program executes
5154 (when control is returned to it) a JA BPXR to its base page and index
5155 register assignment statement. In the calling program this resets the
5156 index registers and base page and then returns to execute the
5157 instruction in the calling program. In the tangent example above, the
5163 which creates the instruction
5167 at the tag DTNRTN, where xxx is the location in the calling routine
5168 whose function corresponds to DTANXR in DTAN.
5170 When called, the routine must assign its own base page and index
5171 registers (SETX XROWN, SETB BPOWN). If arguments are to be passed to
5172 the called routine, a scheme such as illustrated above permits any
5173 number of arguments to be passed from the calling program and saved on
5174 the base page of the called program, in this case just two arguments.
5176 The corresponding code for the calling program (as created by the
5190 JA .+4 /Jump past all arguments
5195 FSTA Q /Save result in some variable
5197 The FORTRAN for such code is:
5201 The calling sequence is also discussed in Chapter 2.
5203 To permit the error trace back feature to function properly, a TEXT
5204 statement followed by a six alphanumeric character name is required
5205 immediately before the index register and base page assignment
5206 statements. Thus, if the cotangent routine includes a JSR TAN and an
5207 unacceptable argument is passed to the tangent function, the trace
5208 back indicates the location of the problem by a sequence such as:
5217 (Line numbers are not relevant in RALF modules such as TAN and SIN:
5218 they are meaningful only in FORTRAN source programs.)
5220 A new library routine may call other new or existing library routines
5221 as part of its function, as well as the error handling function of the
5222 run-time system. To invoke the error message program, code such as
5223 the following is required:
5226 MERROR, TRAP4 #ARGER
5228 Then any condition encountered in the program that is an error should
5229 jump to MERROR. For example, if an argument of <=0 is illegal, it
5230 could be examined and handled as follows:
5233 JLE MERROR /<0 error
5234 FSTA NEXT / Save non-zero value
5236 In this case, the TRAP4 #ARGER at MERROR will produce the message BAD
5237 ARG DTAN nnnn followed by traceback and program termination. If a new
5238 library routine would like to use an existing library routine, a JSR
5239 to that routine is required. The sequence for passing arguments is:
5249 JA .+6 /Execute upon exit from
5252 FSTA ANSWER /Save answer
5254 The arguments must be referenced in the order expected by the called
5255 routine and must agree in number and type. The following routines can
5256 can be used in this manner:
5258 ROUTINE ARGUMENTS PASSED
_______ ________________
5260 AMOD Address of X then Y
5273 ATAN2 Address of X then Y
5277 DMOD Address of X then Y
5278 DSIGN Address of X then Y
5284 DATAN2 Address of X then Y
5298 For real and double precision routines, the result is returned via the
5299 FAC (3 or 6 words, respectively). For complex routines, the result is
5300 returned in #CAC (6 words).
5306 The TAN function from FORLIB is included here as an example of the
5307 requirements just discussed. The TAN function calls two external
5308 functions, has the standard calling sequence, and contains an error
5315 SECT TAN /SECTION NAME
5316 JA #TAN /JUMP AROUND BASE PAGE
5319 TANER, TRAP4 #ARGER /EXIT TO ERROR MESSAGE HANDLER
5320 TEXT +TAN + /FOR ERROR TRACE BACK
5321 TANXR, SETX XRTAN /START OF FORMAL CALLING SEQUENCE
5323 BTAN, FNOP /START OF BASE PAGE
5326 XRTAN, F 0.0 /INDEX REGISTERS
5327 TAN1, F 0.0 /LOCATIONS 21-42 OCTAL AVAILABLE
5330 ORG 10*3+BPTAN /SET UP FOR A RETURN
5333 JA TANXR /JUMP TO XR + RP ASSIGNMENT
5338 FLDA 10*3 /SAVE RETURN JUMP
5340 FLDA 0 /GET NEXT LOCATION
5342 SETX XRTAN /SET UP FOR TAN'S INDEX REGS
5343 SETB BPTAN /SET UP FOR TAN'S BP
5347 FLDA% BPTAN,1 /GET ADDRESS OF X
5351 JEQ TANRTN /IF 0 RETURN NOW
5352 FSTA TAN1 /SAVE FOR A SECOND
5354 JSR COS /TAKE COS(X)
5355 JA .+4 /JUMP AROUND ARGUMENT LIST
5356 JA TAN1 /REFERENCE TO PASSED ARGUMENT
5357 JEQ TANER /COS=0. A NO-NO
5365 JSR SIN /NOW TAKE SIN(X)
5366 JA .+4 /JUMP AROUND ARGUMENT LIST
5367 JA TAN1 /REFERENCE TO ARGUMENT
5368 FDIV TAN2 /DIV BY COS(X)
5371 The library routine ONQI illustrates many of the same conventions.
5372 This listing may also prove valuable as a guide to interfacing with
5373 the run-time system.
5375 FIELD1 ONQI /ROUTINE TO ADD A
5376 /HANDLER TO INTERRUPT SKIP CHAIN
5377 /PUT THIS CODE IN FIELD 1
5379 JMP SETINT /SET UP INT INITIALLY
5380 ISZ ONQI /BUMP ARGUMENT POINTER
5381 ISZ INTQ+1 /BUMP INTERRUPT Q POINTER
5382 DCA% INTQ+1 /STICK IOT ONTO INT Q
5383 TAD XSKP /FOLLOWED BY A SKIP
5385 DCA% INTQ+1 /ONTO INT Q
5386 ISZ ONQI /SKIP FIRST WORD OF ADDR
5388 ONQISW, TAD% ONQI /GET INT HANDLER ADDRESS
5390 DCA% INTADR+1 /ONTO ADDRESS STACK
5391 TAD INTADR+1 /NOW MAKE JMS%
5394 DCA% INTQ+1 /ONTO INT Q
5396 ISZ IQSIZE /ROOM FOR MORE?
5398 TAD .-1 /NO, CLOSE OUT THE SUBR
5401 SETINT, TAD ONQISW /DO THIS PART ONLY ONCE
5404 TAD XSKP /FIX UP #INT
5405 DCA% XINT+1 /PUT SKIP INST. FIRST
5408 DCA% XINT+1 /GET ADDR. OF USER'S ROUTINE
5409 ISZ XINT+1 /ADD TO INTERRUPT CALL
5410 TAD CIFCDF /GET FIELD INSTRUCTION
5411 /FIELD1 SECTION INSURES ITS IN FIELD 1
5414 JMP ONQI+1 /BACK TO ONQI
5416 XINT, ADDR #INT /POINTS TO INT RTN IN COMMON
5417 INTQ, ADDR IHANDL /MUST USE 15 BIT ADDRESS
5424 INTADR, ADDR IHADRS / "
5435 IHADRS, 0;0;0;0;0 /CAN SET UP 1-5 DEVICES
5438 ENTRY ONQB /USE "ENTRY" TO PERMIT
5439 /ACCESS FROM OUTSIDE OF SECTION
5440 /ROUTINE TO SET UP AN IDLE JOB
5442 JMP SETBAK /SETUP #IDLE
5443 TAD% ONQB /GET ADDRESS OF IDLE JOB
5445 DCA% BAKADR+1 /STORE ONTO BACKGROUND JOB Q
5446 TAD BAKADR+1 /MAKE A JMS%
5452 ISZ BQSIZE /MORE ROOM?
5454 TAD .-1 /NO, CLOSE THE DOOR
5457 SETBAK, TAD ONQBSW /CLOSE OFF #IDLE INITIALIZATION
5460 TAD XSKP /FIX UP #IDLE
5461 DCA% XIDLE+1 /ADD SKIP TO IDLE CALL
5462 TAD BAKQ+1 /GET ADDRESS OF ROUTINE
5466 TAD CIFCDF /GET FIELD INSTR.
5470 EXTERN #IDLE /EXTERNAL REFERENCE
5489 BHADRS, 0;0;0;0;0 /1-5 JOBS
5544 RALF Assembler Permanent Symbol Table
5548 Mnemonic Code Mnemonic Code
________ ____ ________ ____
5550 FPP Memory Reference Instructions FPP Special Format Instructions
5557 FMULM 7000 FNEG 0003
5559 FSUB 2000 FNORM 0004
5571 8-Mode Memory Reference Instructions JSR 1130
5575 ISZ 2000 STARTD 0006
5576 DCA 3000 STARTE 0050
5577 JMS 4000 STARTF 0005
5663 ASSEMBLY INSTRUCTIONS for OS/8
5666 The following sequence of commands may be used to assemble the OS/8
5667 FORTRAN IV system programs. It is assumed that all PAL language
5668 sources reside on DSK. In this example, DTA1 is shown as the target
5669 device, however any other device could be used via the appropriate
5670 ASSIGN command. Note that PASS2O.SV is produced by conditional
5671 assembly of PASS2.PA and that the "O" in PASS2O is an oh, not a zero.
5672 The initial dot and asterisk characters on every command line shown
5673 are printed by the monitor. All other characters (except carriage
5674 return, in some cases) are typed by the user. Type CTRL/Z after each
5675 of the three system pauses at point (1), to continue assembly of
5676 PASS2O. Type ALT MODE to produce the "$" character.
5683 .SAVE DEV F4=0;12200$
5685 *PASS2.BN,LIST.LS<PASS2$
5688 .SAVE DEV PASS2=0;5000$
5690 *PASS2O.BN,LIST.LS<TTY:,DSK:PASS2$OVERLY=1 (1)
5693 .SAVE DEV PASS2O=0;7605$
5695 *PASS3.BN,LIST.LS<PASS3$
5698 .SAVE DEV PASS3=0;400$
5700 *RALF.BN,LIST.LS<RALF$
5703 .SAVE DEV RALF=0;200$
5705 *LOAD.BN,LIST.LS<LOAD$
5708 .SAVE DEV LOAD=0;200$
5710 *FRTS.BN,LIST.LS<RTS,RTL$
5713 .SAVE DEV FRTS=0;200$
5720 *LIBRA.BN,LIST.LS<LIBRA$
5723 .SAVE DEV LIBRA=0;200$
5728 ASSEMBLY INSTRUCTIONS for OS/278 and OS/78
5731 The following BATCH file lists the sequence of commands that may be
5732 used to assemble the OS/278 FORTRAN IV system programs. All the PAL
5733 language sources reside on the device assigned to SRCE, and all output
5734 files go to the device assigned to TARG. The SYS device is used to
5735 store the binary files until the programs are SAved. Note that
5736 PASS2O.SV is produced by conditional assembly of PASS2.PA and that the
5737 "O" in PASS2O is an oh, not a zero.
5739 If these commands are typed in, the initial "}" and asterisk (*)
5740 characters on every command line shown are printed by the monitor.
5741 All other characters (except carriage return, in some cases) are typed
5744 To use these commands with OS/78, replace the "}" with a ".".
5747 $JOB (FORGEN.BI) ASSEMBLE FORTRAN IV FOR OS278
5749 /}ASSIGN XXX SRCE where XXX is the device containing the source files
5750 /}ASSIGN YYY TARG where YYY is the output device for the .SV files
5754 }SAVE TARG:F4.SV;12200=100
5757 }PAL PASS2<SRCE:PASS2
5759 }SAVE TARG:PASS2.SV;5000=100
5762 }PAL PASS2O<SRCE:PASS2O,PASS2
5764 }SAVE TARG:PASS2O.SV;7605=100
5767 }PAL PASS3<SRCE:PASS3
5769 }SAVE TARG:PASS3.SV;400=100
5780 }SAVE TARG:LOAD.SV;200=100
5783 }PAL FRTS<SRCE:RTS,RTL /W/K
5785 }SAVE TARG:FRTS.SV;200=100
5788 }PAL RALF<SRCE:RALF /W
5790 }SAVE TARG:RALF.SV;200=100
5793 }PAL LIBRA<SRCE:LIBRA
5795 }SAVE TARG:LIBRA.SV;200=100
5842 Argument passing, 2-7 Idle jobs, 4-1
5843 Arithmetic expression Indirect addressing, 2-5
5844 analyzer, 1-1 Interrupts,
5845 Servicing, 4-1, 4-14
5847 Background Jobs, 4-1
5848 Binary buffer table, 3-9
5849 Binary section table, 3-10 Keyword, 1-1
5850 Block count sequence number, 4-13
5853 COMMON information block, 1-7 Library, 2-1
5854 Communication, 2-7 Format, 5-1
5855 COMMZ sections, 2-10 Line printer handler, 4-13
5856 Compilation, 1-1 Literals, 1-4, 1-5
5857 Compiler symbol table, 1-2 Loader, 3-1
5858 Core maps, 3-2 to 3-4
5860 Device handlers, 4-14 Subroutines,
5861 Device flag handlers, 4-2 Loader symbol table, 3-1, 3-7
5862 Dimension information block, 1-5
5867 Entry point, 2-1 Module count table, 3-12
5868 EQUIVALENCE information table, Module descriptor table, 3-11
5871 ESD correspondence table, 3-9 Off-page references, 2-17
5872 External symbol, 2-2 Optimized code, 2-9
5873 External symbol dictionary, 2-1, Output codes, 1-7
5874 2-2, 2-4 Overlay table, 3-10
5877 FIELD1 sections, 2-11 /P option, 4-20
5878 Files, 4-9 Page boundaries, 2-11
5879 Formatted I/O, 4-9 PASS1, 1-1
5881 Calling sequence, 4-3 Subroutines, 1-10
5882 Core maps, 4-5 to 4-7 PASS2, 1-12
5883 Entry points, 4-4 Error list, 1-14
5884 Initialization, 4-13 Skeleton tables, 1-14
5885 Page zero, 4-10 Symbol table, 1-14
5887 Header block, 3-13 Pass3, 1-17
5897 Program loading, 3-9
5898 Program termination, 4-21
5899 Pseudo-ops, 2-3 to 2-6,
5906 RALF output file, 2-4
5911 Statement number, 1-3
5912 Subroutine calls, 2-7
5913 Subroutine return sequence, 2-8
5920 Termination, program, 4-21
5922 TRAP3 and TRAP4, 2-6
5925 Variable type word, 1-2
5928 8-mode sections, 2-11
5957 SOFTWARE SUPPORT MANUAL
5963 Digital Equipment Corporation maintains a continuous effort to improve
5964 the quality and usefulness of its publications. To do this effectively
5965 we need user feedback--your critical evaluation of this document.
5968 Did you find errors in this document? If so, please specify by page.
5970 ______________________________________________________________________
5971 ______________________________________________________________________
5972 ______________________________________________________________________
5973 ______________________________________________________________________
5974 ______________________________________________________________________
5977 How can this document be improved?
5979 ______________________________________________________________________
5980 ______________________________________________________________________
5981 ______________________________________________________________________
5982 ______________________________________________________________________
5983 ______________________________________________________________________
5986 How does this document compare with other technical documents you
5989 ______________________________________________________________________
5990 ______________________________________________________________________
5991 ______________________________________________________________________
5992 ______________________________________________________________________
5993 ______________________________________________________________________
5997 Job Title_________________________________ Date:______________________
5999 Name:__________________________ Organization:_________________________
6001 Street:________________________ Department:___________________________
6003 City:_________________ State:___________ Zip or Country_______________
6031 -------------------------------Fold Here------------------------------
6049 -----------------Do Not Tear - Fold Here and Staple-------------------
6056 BUSINESS REPLY MAIL ========
6057 NO POSTAGE STAMP NECESSARY IF MAILED IN THE UNITED STATES ========
6058 ======================================================================
6059 Postage will be paid by: ========
6061 +-+-+-+-+-+-+-+ ========
6062 |d|i|g|i|t|a|l| ========
6063 +-+-+-+-+-+-+-+ ========
6064 Digital Equipment Corporation ========
6065 Software Information Service ========
6066 Software Engineering and Services ========
6067 Maynard, Massachusetts 01754 ========