diff --git a/Makefile b/Makefile index ddd6a61c..3142ac8a 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,8 @@ SRC = system syseng sysen1 sysen2 sysen3 sysnet kshack dragon channa \ spcwar rwg libmax rat z emaxim rz maxtul aljabr cffk das ell ellen \ jim jm jpg macrak maxdoc maxsrc mrg munfas paulw reh rlb rlb% share \ tensor transl wgd zz graphs lmlib pratt quux scheme gsb ejs mudsys -DOC = info _info_ sysdoc sysnet syshst kshack _teco_ emacs emacs1 c kcc chprog +DOC = info _info_ sysdoc sysnet syshst kshack _teco_ emacs emacs1 c kcc \ + chprog sail BIN = sys2 emacs _teco_ lisp liblsp alan inquir sail comlap c decsys moon graphs SUBMODULES = dasm itstar klh10 mldev simh sims supdup tapeutils diff --git a/doc/sail/fail.-read- b/doc/sail/fail.-read- new file mode 100644 index 00000000..34a7cb0b --- /dev/null +++ b/doc/sail/fail.-read- @@ -0,0 +1,20 @@ +This is the procedure for creating a new FAIL under ITS: + +1) Assemble: do FAIL^K then SAIL;FAIL NREL_SAIL;FAIL. + +2) Load: rename FAIL REL to FAIL OREL, then do +STINK^K and MSAIL;FAIL LOADER@, making sure first that you do +not have a job named FAIL. +This will complete and return to DDT quietly, so type a rubout +(whereby you will see by DDT's response when STINK is finished). + +3) Set up for simulation by DECUUO: +Then do ..STAR/ and deposit the RH of the contents in 120 (leave +the LH of 120 zero). Then merge in a bootstrap by means of +1L DECSYS;DECBOT BIN +and deposit 1000 in location 56 to set the simulation switches. + +4) Finally, dump with Y as SAIL;FAIL BIN (make sure to rename the old +FAIL BIN!) or anything else. + + \ No newline at end of file diff --git a/doc/sail/fail.manual b/doc/sail/fail.manual new file mode 100644 index 00000000..0ca89f37 --- /dev/null +++ b/doc/sail/fail.manual @@ -0,0 +1,3910 @@ + FAIL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sponsored by + Advanced Research Projects Agency + ARPA Order No. 2494 + Stanford Artificial Intelligence Laboratory May 1974 +Memo AIM-226 + +Computer Science Department +Report STAN-CS-74-407 + + + + + FAIL + + by + + F. H. G. Wright II + R. E. Gorin + + + + COMPUTER SCIENCE DEPARTMENT + STANFORD UNIVERSITY + + + +Abstract + +This is a reference manual for FAIL, a fast, one-pass assembler for +PDP-10 and PDP-6 machine language. FAIL statements, pseudo- +operations, macros, and conditional assembly features are described. +Although FAIL uses substantially more main memory than MACRO-10, it +assembles typical programs about five times faster. FAIL assembles +the entire Stanford time-sharing operating system (two million +characters) in less than four minutes of CPU time on a KA-10 +processor. FAIL permits an ALGOL-style block structure which +provides a way of localizing the usage of some symbols to certain +parts of the program, such that the same symbol name can be used to +mean different things in different blocks. + + + +This manual was supported by the Advanced Research Projects Agency of +the Department of Defense under Contract No. DAHC15-73-C-0435. The +views and conclusions contained in this document should not be +interpreted as necessarily representing the official policies, either +expressed or implied, of the Advanced Research Projects Agency or the +U.S. Government. + +This manual supersedes SAILON-26. + +Available from the National Technical Information Service, +Springfield, Virginia 22151. + + + + + + + + + + + + + + + + + + + + + + + + +Acknowledgments + + +The original version of FAIL and the original manual (SAILON-26) were +written by Phil Petit in 1967. Various additions and modifications +were subsequently contributed by William Weiher, Fred Wright, Ralph +Gorin, and others. This manual was prepared using PUB, the document +compiler created by Larry Tesler. Brian McCune and Les Earnest +reviewed the manuscript and made helpful suggestions. + FAIL i + + + Table of Contents + + +Section Page + +1. Introduction 1 + +2. Basic Syntax 2 + + 2.1 Statements 2 + 2.1.1 Instruction Statement . . . . . . . . . 3 + 2.1.1.1 Opcode Field . . . . . . . . . 3 + 2.1.1.2 Accumulator (AC) Field . . . . . . 4 + 2.1.1.3 Indirect (@) Field . . . . . . . 4 + 2.1.1.4 Address Field . . . . . . . . . 4 + 2.1.1.5 Index Field . . . . . . . . . . 5 + 2.1.2 Halfword Statement . . . . . . . . . . 5 + 2.1.3 Full-Word Expression . . . . . . . . . . 5 + 2.1.4 Truncated Expression . . . . . . . . . . 6 + 2.1.5 Input-Output Instruction Statement . . . . . 6 + 2.1.5.1 Device Selection Field . . . . . . 6 + 2.1.6 Comment Field . . . . . . . . . . . . 7 + 2.1.7 Statement Termination . . . . . . . . . 7 + + 2.2 Expressions 7 + + 2.3 Atoms 9 + 2.3.1 Identifiers . . . . . . . . . . . . . 9 + 2.3.2 Values . . . . . . . . . . . . . 10 + 2.3.3 Constants . . . . . . . . . . . . 11 + 2.3.3.1 Simple Numbers . . . . . . . . 11 + 2.3.3.2 Decimal Numbers . . . . . . . 12 + 2.3.3.3 Floating-Point Numbers . . . . . 12 + 2.3.3.4 Ascii Constants . . . . . . . 13 + 2.3.3.5 Sixbit Constants . . . . . . . 13 + 2.3.4 Symbols . . . . . . . . . . . . . 14 + 2.3.4.1 Labels . . . . . . . . . . 15 + 2.3.4.2 Parameters (Assignment + Statements) . . . . . . . . . . . . 16 + 2.3.4.3 Variables . . . . . . . . . 17 + 2.3.4.4 Predefined Symbols . . . . . . 17 + 2.3.4.5 Half-Killed Symbols . . . . . . 18 + 2.3.4.6 Block Structure . . . . . . . 19 + 2.3.4.7 Linkage with Separately + Assembled Programs . . . . . . . . . 22 + 2.3.4.8 Symbols and Arrows . . . . . . 23 + 2.3.5 Complex Atoms . . . . . . . . . . . 24 + 2.3.5.1 Atomic Statements . . . . . . . 24 + 2.3.5.2 Literals . . . . . . . . . . 25 + ii Table of Contents FAIL + + +3. Pseudo-Ops 27 + + 3.1 Destination of Assembled Code 27 + 3.1.1 LOC, RELOC, and ORG . . . . . . . . . 27 + 3.1.2 SET and USE . . . . . . . . . . . . 28 + 3.1.3 PHASE and DEPHASE . . . . . . . . . . 29 + 3.1.4 HISEG . . . . . . . . . . . . . . 29 + 3.1.5 TWOSEG . . . . . . . . . . . . . 29 + 3.1.6 LIT . . . . . . . . . . . . . . 31 + 3.1.7 VAR . . . . . . . . . . . . . . 31 + + 3.2 Symbol Modifiers 32 + 3.2.1 OPDEF . . . . . . . . . . . . . . 32 + 3.2.2 BEGIN and BEND . . . . . . . . . . . 32 + 3.2.3 GLOBAL . . . . . . . . . . . . . 33 + 3.2.4 INTERNAL and ENTRY . . . . . . . . . 33 + 3.2.5 EXTERNAL . . . . . . . . . . . . . 33 + 3.2.6 LINK and LINKEND . . . . . . . . . . 34 + 3.2.7 .LOAD and .LIBRARY . . . . . . . . . 34 + 3.2.8 PURGE . . . . . . . . . . . . . . 35 + 3.2.9 XPUNGE . . . . . . . . . . . . . 35 + 3.2.10 SUPPRESS and ASUPPRESS . . . . . . . . 35 + 3.2.11 UNIVERSAL and SEARCH . . . . . . . . . 36 + + 3.3 Entering Data 37 + 3.3.1 DEC and OCT . . . . . . . . . . . . 37 + 3.3.2 BYTE . . . . . . . . . . . . . . 37 + 3.3.3 POINT . . . . . . . . . . . . . . 38 + 3.3.4 XWD . . . . . . . . . . . . . . 38 + 3.3.5 IOWD . . . . . . . . . . . . . . 38 + 3.3.6 ASCII, ASCIZ, ASCID, and SIXBIT . . . . . 39 + 3.3.7 RADIX50 . . . . . . . . . . . . . 39 + + 3.4 Reserving Space for Data 40 + 3.4.1 BLOCK . . . . . . . . . . . . . . 40 + 3.4.2 INTEGER and ARRAY . . . . . . . . . . 40 + + 3.5 Assembler Control Statements 41 + 3.5.1 TITLE . . . . . . . . . . . . . . 41 + 3.5.2 END and PRGEND . . . . . . . . . . . 41 + 3.5.3 COMMENT . . . . . . . . . . . . . 42 + 3.5.4 RADIX . . . . . . . . . . . . . . 42 + 3.5.5 .INSERT . . . . . . . . . . . . . 42 + + 3.6 Listing Control Statements 43 + 3.6.1 TITLE and SUBTTL . . . . . . . . . . 43 + 3.6.2 LIST, XLIST, and XLIST1 . . . . . . . . 43 + 3.6.3 LALL and XALL . . . . . . . . . . . 43 + 3.6.4 NOLIT . . . . . . . . . . . . . . 44 + 3.6.5 NOSYM . . . . . . . . . . . . . . 44 + FAIL Table of Contents iii + + + 3.6.6 CREF and XCREF . . . . . . . . . . . 44 + 3.6.7 PAGE . . . . . . . . . . . . . . 44 + 3.6.8 PRINTX . . . . . . . . . . . . . 44 + 3.6.9 PRINTS . . . . . . . . . . . . . 44 + +4. Macro Operations 45 + + 4.1 Macros 45 + 4.1.1 Macro Bodies . . . . . . . . . . . 46 + 4.1.2 Concatenation . . . . . . . . . . . 46 + 4.1.3 Arguments in Macro Definitions . . . . . 46 + 4.1.4 Macro Calls . . . . . . . . . . . . 47 + 4.1.5 Arguments in Macro Calls . . . . . . . 48 + 4.1.6 How Much is Eaten by a Macro Call . . . . 49 + 4.1.7 Complex Example . . . . . . . . . . 50 + + 4.2 FOR 51 + 4.2.1 String FOR . . . . . . . . . . . . 51 + 4.2.2 Character FOR . . . . . . . . . . . 52 + 4.2.3 Arithmetic FOR . . . . . . . . . . . 53 + + 4.3 REPEAT 54 + + 4.4 Conditional Assembly 54 + 4.4.1 Numeric IFs . . . . . . . . . . . . 54 + 4.4.2 Text IFs . . . . . . . . . . . . . 55 + 4.4.3 Symbol IFs . . . . . . . . . . . . 55 + +Appendices 56 + + A Command Language 56 + + B Relocatable and Undefined Values 59 + + C Predefined Opcodes 60 + + D Stanford Character Set 69 + + E Summary of Character Interpretations 70 + +Index 73 + FAIL Introduction 1 + + +1. Introduction + + +FAIL is an assembly program for PDP-6 and PDP-10 machine language. +FAIL operates in one pass, which means that it reads the input file +only once; the linking loader program (LOADER or LINK-10) completes +any aspects of the assembly which could not be done by FAIL. The +efficiencies which have been employed in its coding make FAIL five +times faster than MACRO-10, the DEC assembler. + +FAIL processes source program statements by translating mnemonic +operation codes into the binary codes needed in machine instructions, +relating symbols to numeric values, and assigning relocatable or +absolute core addresses for program instructions and data. The +assembler can prepare a listing of the program which includes a +representation of the assembled code. Also, the assembler notifies +the user of any errors detected during the assembly. + +FAIL has a powerful macro processor which allows the programmer to +create new language elements to perform special functions for each +programming job. + +FAIL permits an ALGOL-style block structure which provides a way of +localizing the usage of symbols to particular parts of the program, +called blocks. Block structure allows the same symbol name to be +given different meanings in different blocks. + +The reader of this manual should be familiar with the PDP-10 +instruction set, which is described in both DECsystem-10 System +Reference Manual and PDP-10 and PDP-6 Instruction Sets (SAILON-71). + +Other documents of interest: + +Frost, M. UUO Manual, SAILON-55.3, December 1973 +Petit, P. RAID, SAILON-58, September 1969 +Harvey, B. Monitor Command Manual, SAILON-54.3, December 1973 + +The following are available in the DECsystem-10 Software Notebooks: + + Cross-Reference Listing: CREF, June 1973 + DDT-10 Programmer's Reference Manual, June 1973 + Linking Loader Programmer's Reference Manual, August 1971 + LINK-10 Programmer's Reference Manual, May 1973 + MACRO-10 Assembler Programmer's Reference Manual, June 1972 + DECsystem-10 Operating System Commands, February 1974 + DECsystem-10 Monitor Calls, June 1973 + 2 Basic Syntax FAIL + + +2. Basic Syntax + + +This section describes the basic components of a typical FAIL source +program. It covers the normal mode of turning each source statement +into a binary word. Pseudo-operations and macro features are +explained in later sections. + +This section is organized in a top-down manner: the complex +constructs, statements, are described first, followed by a +description of the language elements from which statements are built, +etc. + +Statements are the elements of the language that generate machine +code and other binary data. A statement is generally free format, +consisting of several fields, each of which is an expression. +Expressions are composed of atoms and operators. The operators +signify typical arithmetic and boolean operations, such as addition +or logical OR. Atoms are either constants, symbols, or complex +atoms. + + + + + 2.1 Statements + + +Statements are the syntactic units which actually produce code. The +statements that are described in this section usually generate one +word of code. A null statement, which consists of no expressions, +generates no code. A typical statement consists of one or more +expressions separated by spaces, commas, or parentheses. + +There are five kinds of statements: instruction statements, full-word +expressions, truncated expressions, halfword statements, and input- +output statements. The most common of these is the instruction +statement. Also, there are pseudo-operations (called pseudo-ops), +which are described in section 3, page 27. A pseudo-op may +direct FAIL to perform an assembler control function or to assemble +data in a particular format. + +The examples that are given below are intended to be as general as +possible. In most cases, many of the indicated fields may be +omitted. + FAIL Basic Syntax 3 + + + 2.1.1 Instruction Statement + + OPCODE AC,@ADDRESS(INDEX) ;COMMENT + +An instruction statement is used to assemble one machine instruction. +The typical format is shown above; the parts will be explained later. +Any portion of the instruction statement may be omitted. The comment +field is not really part of the instruction statement, but may be +included on the same line for clarity and conciseness. The parts may +appear in any order, except that the opcode field, if present, must +be the first expression. Also, each part must be syntactically +identifiable. The form above is hallowed by years of use; departure +from it will render a program less intelligible to other readers. + +If the opcode field is omitted, all other fields will be recognized +and handled normally, unless the address expression is the first +field seen, in which case the statement is treated as a full-word +expression. + + + 2.1.1.1 Opcode Field + + +If the first atom appearing in the statement (excluding labels and +assignment statements) is an identifier, it will be looked up in the +opcode table to see if it is an opcode, in which case the opcode +alone will be returned as the first expression, overriding any +significance it may have as a symbol. An opcode (short for operation +code) may be a machine instruction mnemonic, a UUO mnemonic, a +pseudo-op, or a user-defined opcode (see OPDEF in section 3.2.1, +page 32). An opcode, if it appears, must be the first thing in the +statement (except for labels or assignment statements). + +If an opcode is a pseudo-op mnemonic, FAIL will process that +particular pseudo-op as appropriate. The syntax of pseudo-ops +differs from that of normal statements. + +If an opcode is a machine instruction, UUO mnemonic, or user opcode, +its value is placed in the binary word being assembled. These +opcodes are treated as having full-word values, but in most cases +only the opcode field (bits 0-8) is non-zero. A few machine +instructions, and many UUO mnemonics, specify values for other fields +as well. The values of the other fields (except the address field, +if non-zero) can be modified by subsequent operands. + +Whenever an opcode is recognized, it is immediately processed without +regard for any arithmetic operator that might follow. Although FAIL +tries to allow a symbol and opcode with the same name to co-exist, it +cannot resolve the ambiguity in all circumstances; it is a good idea + 4 Basic Syntax FAIL + + +to avoid conflicts as much as possible. FAIL will not recognize an +identifier as an opcode if the identifier is followed by any one of +the characters colon (:), left-arrow (_), up-arrow (^), tilde (), or +number sign (#). + + + 2.1.1.2 Accumulator (AC) Field + + +If an expression appears in a statement followed by exactly one +comma, its value will be placed in the accumulator field of the +current word (bits 9-12), possibly replacing the accumulator field +indicated by an opcode. This expression must be defined, available, +and absolute (some of these terms are defined in section 2.3.2, +page 10). For the sake of brevity, "accumulator" is often written as +"AC". + + + 2.1.1.3 Indirect (@) Field + + +If one or more at-sign characters (@) appear as part of a statement, +the indirect bit (bit 13) will be turned on in the word being +assembled. The at-sign may appear anywhere in the statement as long +as it is not embedded inside symbols or expressions. The character +open single quote (`) may be used as an alternative to at-sign. + + + 2.1.1.4 Address Field + + +If in a statement an expression appears which is neither enclosed in +parentheses nor followed by a comma, it is considered to be an +address expression unless it is the first expression (including the +opcode) in the statement. Address expressions are truncated to 18 +bits and placed in the address field (bits 18-35) of the word being +assembled. + +Only one address field may be assembled per statement; an attempt to +assemble more than one is an error. This error sometimes occurs +because an undefined opcode is used, which is treated as an +expression in case it is really an undefined symbol. This error can +also occur when an opcode includes an address field and the user +attempts to supply another address field. + FAIL Basic Syntax 5 + + + 2.1.1.5 Index Field + + +If an expression is enclosed in parentheses in a statement, the right +half of its value will be ORed into the left half of the current +word. Also, if no address field has appeared yet, the left half of +its value will be ORed into the right half of the current word. The +expression must be defined, available, and absolute. This construct +is most commonly used for specifying the index field (bits 14-17). + +Sometimes, this construct is used for putting left-half quantities in +address fields, or as a general halfword-swapping operation. Often +when this is done, the expression in parentheses must be enclosed in +brokets (< and >) to force its evaluation as an atomic statement; see +section 2.3.5.1, page 24. If the left half of the expression is non- +zero, the word will be flagged as containing an address field, making +another address field illegal. + + Examples: + +MOVEI 2,-1(6) ;assembles 201106 777777 +MOVSI 1,() ;assembles 205040 254000 + + + + 2.1.2 Halfword Statement + + EXPR,,@ADDRESS(INDEX) ;COMMENT + +If an expression is followed by comma-comma (,,), it will be placed +in the left halfword of the current location, and FAIL will continue +to process an address field, index field, and indirect field. This +is more convenient than the XWD pseudo-op for assembling halfwords +since it allows the entire effective address to be specified in the +usual way. The only restriction is to beware of possible +interpretation of the first symbol as an opcode. If the expression +followed by the comma-comma is not the first thing assembled in the +word, the warning message Illegal ,, will be printed, although the +statement will assemble correctly. This prevents confusion if an +extra comma is typed after an accumulator field. + + + 2.1.3 Full-Word Expression + + EXPR ;COMMENT + +When the first expression in a statement is not preceded by a comma +and is not an opcode, FAIL assumes that the expression is a full-word +expression. The entire 36-bit value of the expression is placed in + 6 Basic Syntax FAIL + + +the current word. The full-word expression is the only ordinary +statement (i.e., not a pseudo-op) that assembles a single expression +with a full 36-bit value. Full-word expressions are treated as +address fields for purposes of the multiple address field error. + +If a full-word expression contains any undefined symbols, unavailable +symbols, or strange relocation constants, the entire word will be +updated with the value of the expression when it becomes known. This +will obliterate any index, indirect, or accumulator field appearing +after the expression on the line. If the expression actually has +only an 18-bit value, this can be fixed by prefixing the expression +with a comma (i.e., by using a truncated expression). If a full-word +value is actually needed and the problem is not just one of +availability (curable by the use of GLOBAL or down-arrow (); see +section 2.3.4.6, page 20), it may be necessary to use an explicit +expression to set the accumulator, index, and indirect fields. + + + 2.1.4 Truncated Expression + + ,EXPR ;COMMENT + +If a comma appears before any expression in a statement, it flags the +current word as containing data in order to force a subsequent +expression to be treated as an address field even when it is the only +expression in the statement. This can be used to form an 18-bit +truncated expression. Note that a statement consisting of a single +comma will assemble a zero word. + + + 2.1.5 Input-Output Instruction Statement + + OPCODE DEV,@ADDRESS(INDEX) ;COMMENT + +An input-output instruction statement is used to assemble one +hardware I/O instruction. Most parts are the same as in an +instruction statement, except that a device selection field appears +instead of an accumulator field. Also, the opcode portion must be +one of the PDP-10 hardware input-output instructions (e.g., DATAO). +Note that hardware I/O instructions are not related to operating +system UUOs. + + + 2.1.5.1 Device Selection Field + + +The same syntax and restrictions that apply to an accumulator field +apply also to the device selection field. The value of the device +selection field is placed in bits 3-9 of the current word. This +value is often called the device code. + FAIL Basic Syntax 7 + + + 2.1.6 Comment Field + + +When FAIL's statement processor encounters a carriage return or +semicolon (;), all characters up to the next line feed or form feed +are completely ignored except for listing and certain macro processor +functions (see section 4.1, page 45). Upon reaching the line +feed or form feed, the comment is terminated. Usually, this is used +to insert a relevant comment at the end of a line of code. + + + 2.1.7 Statement Termination + + +A statement is terminated by a comment or by any of the characters +line feed, double-arrow (), right bracket (]), or right broket (>) +when not processing a comment. When a statement is terminated, the +value of the current word (if any) is returned. A statement returns +no value at all if no expressions appear in it or if it is a pseudo- +op which assembles no code. Terminating a statement with one of the +bracket characters often has special significance, as in atomic +statements or literals. Double-arrow can be used for assembling more +than one statement on a line, but will not terminate a comment. + + + + + 2.2 Expressions + + +Expressions are built from atoms connected by operators which allow +the specification of values based upon arithmetic and logical +functions of several values. These expressions follow essentially +the same rules as conventional programming languages. Each operand +in an expression may be an atom, an atomic statement, or an +expression in parentheses, preceded by any number of unary operators. +If parentheses are used, the expression inside the parentheses is +evaluated before performing any operations using that operand. If a +unary operator appears, its function will be evaluated before any +operations using that operand (but after the expression in +parentheses, if parentheses are used). Multiple unary operators are +evaluated from right to left, so -1 is processed as -(1). Finally, +these operands can be connected with binary infix operators whose +order of evaluation is determined by their assigned precedence levels +(highest first) and is left-to-right for operators of the same level. +An expression may, of course, consist of a single operand (i.e., +atom) with no operators at all. + +Surrounding an entire expression with parentheses sometimes signifies + 8 Basic Syntax FAIL + + +an index field (see section 2.1.1.5, page 5). All arithmetic is +integer or boolean; no type conversion is done for floating-point +operands. + +The following is a list of the available operators and their +precedence levels: + + Symbol Meaning Precedence Level + + binary operators + + + Addition 1 + - Subtraction 1 + * Multiplication 2 + / Division 2 + & Logical AND 3 +  Logical AND 3 + ! Logical OR 3 +  Logical OR 3 +  Exclusive OR 3 +  Exclusive OR 3 +  Logical Left-Shift 4 + + unary operators + + - Negation (two's complement) 5 +  Logical NOT (one's complement) 5 + + +If an expression contains any undefined values, its own value is +undefined. If an expression is used in a context where undefined +values are legal, FAIL retains a structure describing the evaluation +needed, called a Polish fixup for its similarity to Polish arithmetic +notation, in order to complete the evaluation when the unknowns +become defined. As soon as all values in the expression are defined, +a fixup will be output (to the loader) to correct the value (or the +value will be corrected directly in the case of a literal). If the +expression is not completely defined by the end of the assembly (due +to external references or errors), the Polish structure is sent to +the loader for evaluation at load time. In other words, the right +thing usually happens with a partially undefined expression as long +as it is legal in the context where it is used. + +Expressions may also begin with any number of labels or assignment +statements, which have no effect on the value of the expression. + FAIL Basic Syntax 9 + + + + Examples + + FOO2 ;value of FOO shifted left 2 bits + (BAR-1)-2 ;value of BAR-1 shifted right 2 bits + (A+2)*B + -(A+2)*-B ;same value as above + *B ;another way (The symbol A must + ;be defined and available. See + ;Atomic Statements, section 2.3.5.1, page 24) + =60*=60 + "A"-40 + [0]-1 ;even literals can appear in expressions + FOO:BAR_1 105 ;the value of this expression is 105 + ;(labels and assignment statements have no + ;effect on the value of the expression) + + + + + + 2.3 Atoms + + +An atom is the most basic syntactic element. An atom is either a +symbol or a constant. There are also complex atoms which are not +really atoms at all, but which can be used in the same way as atoms +in forming expressions. Every atom represents a value. + + + 2.3.1 Identifiers + + +Identifiers are very basic syntactic elements. They have many +different uses, all of which involve referring to something by a +convenient symbolic name. The uses of identifiers will be covered as +the various applications arise. Identifiers may be defined either by +the programmer or by FAIL. + +The characters legal in an identifier are letters, digits, and the +four characters dollar sign ($), percent sign (%), point (.), and +underbar (). An identifier is any non-null string of characters +from this set, delimited by characters not from this set, except that +the first character of an identifier must not be a digit. Only the +first six characters of an identifier are significant, and upper and +lower case letters are treated as equivalent. Thus "FOOBAR" and +"foobarbletch" are equivalent identifiers. Also, "" is considered +equivalent to ".", so, for example, "A7" and "A.7" are equivalent +identifiers. + 10 Basic Syntax FAIL + + +Certain identifiers have special meaning in FAIL, and cannot be used +except with their own special meanings. Some of these reserved +identifiers are IFAVL, IFDEF, IFDIF, IFE, IFG, IFGE, IFIDN, IFL, +IFLE, IFMAC, IFN, IFNAVL, IFNDEF, IFNMAC, IFNOP, IFOP, IOWD, .FNAM1, +.FNAM2, ".", and "$.". + + + 2.3.2 Values + + +Most of the normal assembly process consists of translating text +strings into their corresponding binary values. The main +transformation happens when the atomic elements are converted to +their binary representations; these are combined by binary +operations into more complex constructs. + +Often the final 36-bit value of an atom depends upon information not +available at the time the atom is seen. This value may become known +when a later part of the program is assembled, or it may not be known +until the program is actually loaded. Consequently, up until the +final loading of a program into a core image, its representation must +be a slightly expanded form of simple binary so that the steps +necessary to complete the calculation of all binary values can be +adequately described. Partially defined values are commonly used in +writing FAIL programs; several mechanisms exist to enable FAIL (and +the loader) to handle such values correctly. The full impact of +forward references and relocatable values is discussed in appendix +B, page 59. + +Some of the different kinds of values that often occur in FAIL are +distinguished by particular names: relocatable, absolute, defined, +undefined, available, and unavailable. The definitions that follow +involve symbols and block structure to some extent. Refer to section +2.3.4, page 14, and section 2.3.4.6, page 19, for further +elucidation. + +A value that depends on where the program is when it is loaded in +core is called relocatable. Relocatable values occur most frequently +when some location in the program or in the data is referred to. +Values that do not depend on where the program is located are called +absolute or unrelocatable. An example of an absolute value is a +constant. Another example of an unrelocatable value is the length of +a table (that is, the difference between two relocatable values). + +A symbol is an identifier that has a value. A symbol is defined when +a value is assigned to it. A symbol can be referenced before it is +defined, that is, when the value of the symbol is undefined. FAIL +makes sure that the right thing happens when the value becomes +defined as long as an undefined value is legal in the particular +context where it is used. + FAIL Basic Syntax 11 + + +A symbol that is defined is said to be available (after the point of +definition) in the block where it is defined. When another (lower) +block is entered, such a symbol becomes unavailable unless the +programmer has taken steps to force the availability of that symbol +in lower blocks. + + + 2.3.3 Constants + + +Constants are the simplest forms of atoms; their values do not +depend on context or previous operations (with the exception of the +radix for interpretation of numbers). Constants are absolute, i.e., +independent of where the program is loaded. A constant may be one of +several types of numerical or text constants. In addition to the +atomic constants described here, there are various data entry pseudo- +ops described in section 3.3, page 37. + + + 2.3.3.1 Simple Numbers + + +A simple number consists of a string of digits, optionally followed +by the letter "B" and one or two additional digits which represent a +scale factor. The digit string is interpreted as a number in the +current radix. Since the radix is initialized to 8, simple numbers +are usually interpreted as octal by default. In this case, the +accumulation is done by logical shifting, so the number is considered +unsigned. If the radix is anything other than 8, the accumulation is +done by multiplication, and the sign bit cannot be set (but a +negative number can be entered as an expression). The current radix +can be set with the RADIX pseudo-op (see section 3.5.4, page 42). + +The one- or two-digit argument following the "B", interpreted in +decimal, specifies the low-order bit position of the number in the +word. The number is shifted left logically a number of bit positions +equal to 35 (decimal) minus the argument. + + Examples: + + 1743 + 2 + 254B8 + 1B33 ;equivalent to 4 + 22B18 + 10B37 ;equivalent to 2 + 12 Basic Syntax FAIL + + + 2.3.3.2 Decimal Numbers + + +Decimal numbers provide a way of entering decimal information +regardless of the current radix. A decimal number is a simple number +preceded by an equal sign (=). Since decimal numbers are handled +identically to simple numbers except for the radix, the "B" shifting +operation may also be used with decimal numbers. + + Examples: + + =100 + =69 + =10B27 + + + 2.3.3.3 Floating-Point Numbers + + +Numbers may also be entered in standard floating-point notation, in +which case they will be converted to PDP-10 single-precision +floating-point format. Floating-point numbers are always interpreted +in decimal regardless of the current radix. Note that any arithmetic +performed by FAIL on numbers is always integer arithmetic, even if +the operands are floating-point numbers. + +A floating-point number consists of two strings of digits, separated +by a decimal point and followed by an optional scale factor. The +digit strings before and after the decimal point represent the +integer and fraction parts of the floating-point number, +respectively. The scale factor is the letter "E", an optional minus +sign, and one or two digits. The number following the "E" specifies +a power of ten by which the number will be multiplied. + +Although the fraction part of the number may be omitted, it is +probably better to include the redundant 0 to avoid a possible future +conflict that could arise if FAIL were modified to allow a decimal +point following a digit string to signify a decimal number. + + Examples: + + 10.7E1 ;equivalent to 107.0 + 9.973 + 0.13 + 10. ;better to write this as 10.0 + 1.86E05 + 31.4159E-1 + 69E1 ;presently equivalent to 690.0 + FAIL Basic Syntax 13 + + + 2.3.3.4 Ascii Constants + + +Constants may also be specified as the ascii value of a character or +string of characters. The ascii value of a character is its 7-bit +code in the Stanford Character Set, a modified form of the USASCII +code (see appendix D, page 69). An ascii constant is written as a +string of characters not containing a double quote ("), enclosed with +double quotes, e.g, "Foo". If the string is null, i.e., "", the +resulting value will be zero. If the string contains exactly one +character the resulting value will be the ascii value of that +character. If the string contains more than one character, each +additional character will shift the total left 7 bits and add its own +value, much as an octal number is accumulated. This results in +packing characters into right-justified 7-bit bytes. Only the low- +order 36 bits of the total are used, so if more than 5 characters +appear in the string, only the last 5 characters and the low-order +bit of the sixth-from-last character will affect the value. + +This right-justified form is not the standard way of packing text for +addressing with byte instructions, but is intended mainly for small +immediate operands, etc. Text pseudo-ops (described in section +3.3.6, page 39) are used to store text in the usual left-justified +format in multiple words. + + Examples: + + "A" ;101 octal + "^C" ;27503 + "foobar" ;337576130362 + + + 2.3.3.5 Sixbit Constants + + +Another character code that is frequently used is sixbit. It is a +modified version of ascii code which uses only 6, instead of 7, bits +in order to pack 6 characters into a word rather than 5. + +The basic ascii to sixbit transformation consists of subtracting 40 +(octal) from the ascii code, which maps ascii 40-137 (all the +printing characters of 64-character ASCII) into the desired 0-77. +Since the 140-177 range consists mostly of lower-case versions of the +100-137 characters, a better transformation also maps this range to +40-77. The method used by FAIL is to copy the 100 bit into the 40 +bit and set the 100 bit to 0. The inverse transformation is +accomplished by adding 40 to each sixbit character. + +Sixbit constants can be specified in FAIL in the same way as ascii + 14 Basic Syntax FAIL + + +constants, except that close single quotes (apostrophes) (') should +be used instead of double quotes. Naturally, if more than one +character appears in the string, the shifting will be 6 bits at a +time instead of 7, and the last 6 characters of the string will +always be completely significant. Again, a pseudo-op is available +(see section 3.3.6, page 39) to pack longer strings into multiple +words. + + Examples: + + 'a' ;41 + 'DSK ' ;446353000000 + 'gronker' ;625756534562 + + + 2.3.4 Symbols + + +Symbols are one of the most important features provided by an +assembler. One capability provided by symbols is the ability to +abbreviate a complex expression with a single identifier. Another is +to represent an assembly parameter, so that its value can be changed +at the symbol definition only, without having to modify the places +where the parameter is used. A third use is to represent values +which are difficult for the programmer to calculate, such as values +dependent upon exactly where certain parts of the program are stored. + +A symbol is an identifier which at some point in the program (or +possibly in an external program) is assigned a value which will be +associated with that identifier whenever it is used in a context +where symbols are recognized (see section 2.1.1.1, page 3, and +section 4.1.4, page 47, for discussion of possible conflicts with +opcodes or macros). The point at which a value is assigned to a +symbol is said to be the point where it is defined. + +In most circumstances, a symbol may be used to stand for a value +either before or after it is defined. A symbol is said to be +referenced when it is used to stand for a value. If this reference +occurs earlier in the source file(s) than the definition, it is said +to be a forward reference; if the reference follows the definition, +it is said to be a backward reference. Backward references can be +handled fairly easily, by merely replacing the symbol by its known +value. However, forward references create some complication since +FAIL does not know the value of the symbol until later in the file. + +Two-pass assemblers avoid the forward reference problem by assembling +the program twice. On the first pass the assembler calculates the +value for each symbol; on the second pass these known values are +used when the corresponding symbols are referenced. This method + FAIL Basic Syntax 15 + + +probably has the smaller storage requirements, but it requires more +cpu time since the entire source file is scanned twice. + +FAIL uses the one-pass approach to save execution time (at the +expense of increasing the storage requirements). In this method, +each forward reference assembles an incomplete word, but sufficient +information is included in the binary file to enable the loader to +complete the assembly. Part of the necessary mechanism exists in the +loader anyway in order to handle externally defined symbols, which +must be treated as forward references even by a two-pass assembler. +Information placed in the binary file to update the value of an +incompletely assembled word is referred to as a fixup. + +Because of the problem of forward references in a one-pass assembler, +the meaning of "defined" as used in this manual is not "defined +somewhere within the program", but rather "defined in the program +before the place being considered". In this sense a symbol is not +considered to be "defined" at the time of a forward reference, even +if it is defined later in the program. + +A symbol may be defined in one of four ways. It may be defined as a +label, as a parameter, or as a variable, or it may be a predefined +symbol. These types of symbols are discussed in the following +subsections. + + + 2.3.4.1 Labels + + +Labels are the most common type of symbol. They are used as symbolic +references to locations in the program. Labels help to keep such +references independent of the exact placement of those parts of the +program in the core image. The value of a label is calculated +automatically by FAIL, so that the programmer need not keep careful +account of the exact numeric locations of all parts of his program. + +A label is defined by simply writing an identifier followed by a +colon (:) at the beginning of any expression being scanned. This +will normally define the symbol as equal to the location counter, +i.e., the location where the next word will be assembled. However, +in some circumstances involving the use of literals (section 2.3.5.2, +page 25) or the PHASE pseudo-op (section 3.1.3, page 29), the value +of the label may differ from the location counter. The value +assigned to a label is usually relocatable because the location +counter is initialized to relocatable zero, but it may be absolute. + +Although labels may occur at the beginning of any expression, they +almost always occur at the beginning of a line. This convention +improves the readability of programs by keeping labels in a place +where they are easily recognized. + 16 Basic Syntax FAIL + + +In order to detect possible conflicts in label usage, FAIL does not +allow any label to be defined more than once. (However, FAIL block +structure allows a label to be redefined in different blocks; see +section 2.3.4.6, page 19.) Once a symbol has been defined as a label, +it cannot be redefined; a symbol cannot be defined as a label if it +has any previous definition. An attempt to do either of these things +will result in a multiple definition error message, and the new +definition will not take effect. + + Examples: + +LOOP: JRST LOOP ;points to itself +FOO: ;labels the location of the next instruction + + + 2.3.4.2 Parameters (Assignment Statements) + + +A parameter is a symbol that is given an arbitrary 38-bit value by an +assignment statement. Actually, the final value is 36 bits, but +since either 18-bit halfword may be relocatable two more bits are +included in the representation of the value. The basic format of an +assignment statement is an identifier followed by a left-arrow (_) +followed by an expression. The 38-bit value of the expression, which +must be defined, will be given to the specified symbol. An equal sign +(=) may also be used as an alternative to left-arrow to allow partial +compatibility with other assemblers, but if the first atom after the += begins with another = to indicate a decimal number, at least one +space should separate the two to distinguish them from ==, which has +a different function (see section 2.3.4.5, page 18). + +As with labels, any number of assignment statements may appear at the +beginning of any expression, but they are normally written as +separate statements for improved readability. In its full +generality, an assignment statement may define more than one symbol +by beginning with several symbol names, each followed by a left- +arrow, and finally followed by the expression, whose value will be +given to all symbols mentioned. + +Unlike labels, parameters may be redefined as often as desired. Once +a parameter has been defined, each reference to it will use the value +in effect at the time of that reference (i.e., as of the last +assignment). The value appearing in the symbol table in the binary +output file will be the last value assigned. The value used for +forward references (i.e., before the first definition) will be that +of the first assignment. Note that this is an incompatibility with +two-pass assemblers, which would instead use the last value assigned +during pass one. + FAIL Basic Syntax 17 + + + + Examples: + + FOO_105 + BAR_=69 + BLETCH_BARF_LOSS_FOO+BAR*3 + garp= =97 ;note space between = is necessary + + + 2.3.4.3 Variables + + +Variables are symbols whose values are the addresses of cells +automatically allocated by FAIL for data storage. A variable is +usually created by immediately following a symbol reference with a +number sign (#). The symbol, which must not be previously defined, +is declared to be a variable and will have its location assigned when +the location of the variables area is known (see section 3.1.7, +page 31). The symbol is not defined at this point; it cannot be +used in contexts which do not allow forward references. However, it +can be used as any other forward-referenced symbol; the number sign +need not be used with more than one occurrence of the symbol. +Similar effects can also be obtained with the INTEGER and ARRAY +pseudo-ops (see section 3.4.2, page 40). + + Examples: + + SETZM FOO# + MOVEI A,BAR#-1 + + + 2.3.4.4 Predefined Symbols + + +Predefined symbols are available for use in all circumstances where +symbols are recognized. + +Two predefined symbols, point (.) and dollar-point ($.) refer to the +location counter, which is the location where the next complete word +will be stored. In the absence of special circumstances, "." and "$." +have the same value; "." is the one usually used. These values are +usually relocatable but may be absolute; see section 3.1.1, page +27. + +The reason for having two of these symbols is that some features of +FAIL create complications affecting the location counter; see the +discussion of literals (section 2.3.5.2, page 25) and the PHASE +pseudo-op (section 3.1.3, page 29). + 18 Basic Syntax FAIL + + + + Examples: + + JRST .-1 + JUMPN T,$.+3 + +The predefined symbols, .FNAM1 and .FNAM2 refer to the name of the +current source file. The value of .FNAM1 is the 36-bit binary +representation of the source file name; .FNAM2 has the value of the +source file extension (or second file name). + + + 2.3.4.5 Half-Killed Symbols + + +Symbols are included in the binary output file to aid debugging and +to allow the loader to link several programs together. The debuggers +(RAID and DDT) have symbolic disassemblers which take binary words +and interpret their fields to display mnemonic opcodes, addresses, +accumulator names, etc. Sometimes, the user wants to prevent +particular symbol names from being displayed by the symbolic +disassembler. Symbols that have been marked to prevent their display +are called half-killed. Half-killing a symbol is useful for +parameters which might incorrectly be displayed as core addresses or +accumulator names. Half-killing is also handy for labels in code +that is relocated at runtime. The debuggers do recognize half-killed +symbols when they are input. + +FAIL treats half-killed symbols precisely the same as other symbols, +except, when the symbol is written in the binary output file, a bit +is set to inform the debugger that the symbol is half-killed. + +In FAIL, half-killing a symbol is accomplished by doubling the +defining character (e.g., ::, __, or ==). In the case of ==, the two +equal signs must not be separated by any spaces, because this is how +the ambiguity is resolved with respect to the other use of equal sign +to indicate decimal numbers. A parameter will be half-killed if any +one of its definitions specifies half-killing. + + Examples: + +ERRFLG__100 ;the usual way of writing it +IOFLG _ _ 2000 ;this can have spaces anywhere +BUFSIZ == 100 ;but this can't (100 is octal) +BUFSIZ = = 100 ;since this means decimal, not half-killed +BUFSIZ === 100 ;this is unambiguous (100 is decimal) +BUFSIZ == = 100 ;(100 is decimal) +LOOP:: SKIPN A,(B) ;a half-killed label + FAIL Basic Syntax 19 + + + 2.3.4.6 Block Structure + + +Block structure is very basic to the usage of symbols. This section +may be skipped if the reader does not plan to use block structure. +The one thing to remember is that in the absence of block structure +any symbol which is defined is also available. + +FAIL block structure provides a way of localizing the usage of +symbols to particular parts of the program, called blocks. Block +structure allows the same symbol name to be given different meanings +in different blocks. The block structure used in FAIL is similar to +that of ALGOL, but is somewhat less restrictive. + +A program is considered to be a block whose name is the same as the +program name (set by the TITLE statement; see section 3.5.1, page +41). Each block may contain any number of inner blocks, but the +depth of nesting may not exceed 17 (decimal). A definition of a +symbol, a user-defined opcode (see section 3.2.1, page 32), or a +macro (see section 4, page 45) applies only within the scope of +the outermost block in which it is defined. The scope of a block +includes the scope of each block it contains, unless the symbol +(etc.) in question is defined again in an inner block, in which case +the more local definition takes precedence within the scope of that +block. A block is delimited by a BEGIN statement and a BEND +statement (see section 3.2.2, page 32). + +Features exist in FAIL for controlling the block level of symbols. +If a symbol, when defined as a label or parameter, is preceded by an +up-arrow (^), it will be treated as if it were defined in the next- +outer block. If a double up-arrow (^^) is used, the symbol will be +treated as though it were defined in the outermost block of the +program. These features are most commonly used for such things as +making subroutine entry points available to outer blocks when the +subroutines themselves are contained in blocks. In simple cases, +this could be done by beginning the block after the entry label(s) or +even after some of the code, but this makes reading the routine more +difficult and hence the up-arrow construct is preferred. Tilde () +may be used instead of up-arrow. + +Here are some examples of symbol usage, with and without block +structure. Both examples generate the same code: + 20 Basic Syntax FAIL + + + + FOO1: JRST FOO1 FOO1: JRST FOO1 + JRST FOO2 JRST FOO2 + JRST FOO3 JRST FOO3 + JRST FOO5 JRST FOO5 + BEGIN + FOO2: JRST FOO1 FOO22: JRST FOO1 + ^FOO3: JRST FOO2 FOO3: JRST FOO22 + JRST FOO3 JRST FOO3 + BEGIN + JRST FOO1 JRST FOO13 + ^^FOO5: JRST FOO2 FOO5: JRST FOO22 + JRST FOO3 JRST FOO3 + FOO1: JRST FOO4 FOO13: JRST FOO4 + BEND + ^FOO4: JRST FOO4 FOO4: JRST FOO4 + BEND + FOO2: JRST FOO4 FOO2: JRST FOO4 + + +A complication arises with FAIL block structure due to the absence of +the ALGOL requirement that all identifiers be declared at block entry +time. FAIL allows forward references, yet does not require any +declaration of symbols other than their defining occurrences. Hence, +FAIL cannot decide whether to use an existing outer-block version of +a symbol or to make a forward reference to a more local definition +that may occur later. + +To resolve this ambiguity, FAIL always considers a symbol reference +to be a forward reference when the symbol has not been defined in the +current block, even if it has been defined in some outer block. If +no other definition is given by the time the block ends, then the +outer-block definition is used to resolve the forward reference. +While in the inner block in this situation, the outer-block symbol is +still said to be defined, but it is also said to be unavailable. +Thus block structure forces many references to be forward references, +even when they would not otherwise be such. + +Macros and user-defined opcodes cannot be forward-referenced. Such +symbols are always available; references to them will use their +outer-block definitions. + FAIL Basic Syntax 21 + + + + Examples: + +FOO: MOVSI 1,-62 ;FOO is defined as a label +BAR: CAME 2,ZOT(1) ;so is BAR + AOBJN 1,BAR ;BAR is referenced +BEGIN ;FOO and BAR are defined, but now unavailable +LOSS: MOVEI 1,0 ;LOSS is defined + JRST LOSS ;a backward reference to LOSS + JRST FOO ;this is treated as a forward reference +FOO: HRRM 6,LOSS ;so it can reference this definition +BAZ: JRST BAR ;this is treated as a forward reference + JRST FOO ;this refers to this block's FOO +BEND ;The outer-block definition of BAR becomes + ;available at this BEND. A fixup is emitted + ;to fix the reference to BAR at BAZ + + +Many contexts do not accept forward references (e.g., accumulator and +index fields). In these contexts unavailable symbols cannot be used, +even if they are defined. Therefore, FAIL provides two mechanisms +for forcing defined symbols to be available to lower blocks. One is +the down-arrow mechanism, which is used at the defining occurrence of +the symbol, and the other is the GLOBAL pseudo-op (see section +3.2.3, page 33), which is used in the referencing block. + +The down-arrow mechanism is the more commonly used method, since this +problem is most often associated with particular symbols (accumulator +names, assembly parameters, etc.). Preceding the symbol name in a +label or assignment statement with a down-arrow () causes that +symbol to remain available whenever inner blocks are entered. +Usually it is dangerous to redefine such symbols locally, since any +forward references will have incorrectly referred to the outer-block +definition. Consequently a warning message is printed in this case, +but if no forward references are made to the local version, it will +assemble correctly. However, if the redefinition of a down-arrowed +parameter is effective at its original block level (possibly via ^ or +^^), FAIL will change the original definition without complaint. +This allows redefinition of global parameters from inner blocks. A +question mark (?) may be used instead of down-arrow. + 22 Basic Syntax FAIL + + + + Examples: + +A_1 ;some accumulator (AC) definitions +B_2 +FOO__=69 ;and a parameter +BEGIN + ADD B,A ;this is illegal because AC + ;symbols must be available + MOVE A,B ;but this is legal since A is available + ;by  +A_5 ;this will produce a message and is too + ;late to affect the instruction above +B_6 ;this is legal and will fix up the MOVE + ;to be MOVE 1,6 + MOVE A,B ;whereas this will be MOVE 5,6 +^FOO__105 ;this is legal since it is "aimed" at the + ;FOO in the outer block +BEND + + +There are further details in section 3.2.2, page 32, and section +3.2.3, page 33, about the block structure pseudo-ops BEGIN, BEND, +and GLOBAL. + + + 2.3.4.7 Linkage with Separately Assembled Programs + + +It is sometimes desirable to have a program which is assembled in +several parts, either to save reassembling the entire program for +each change or because the program is written in a mixture of +languages. Even with a single assembly it is usually necessary to +use some of the job data area symbols, and sometimes symbols from the +debuggers (RAID or DDT), all of which are reached through the linking +loader. In this context, the word program refers to the result of +one assembly or compilation, and thus a core image may contain +several programs. + +To allow reasonable communication between these programs, the loader +allows symbol definitions to be passed between programs. For this +purpose, symbols are divided into two classes, local symbols and +global symbols. (There is no relation between the GLOBAL pseudo-op +and the global symbols discussed here.) + +Symbols are normally considered local, which means that they will not +be available outside their own program and may be defined in more +than one program without conflict. Global symbols, however, are +available to all programs and hence must not have conflicting + FAIL Basic Syntax 23 + + +definitions within the set of programs to be loaded. The easiest way +to declare a symbol to be global is to follow some occurrence of the +symbol by an up-arrow. This flags the symbol as a global without +specifying whether it is defined in this program or another program, +since FAIL will have figured that out by the end of the assembly. +Undefined globals (external symbols) will have appropriate fixup +information passed to the loader for resolution when the defining +programs are loaded. Globals may also be declared with the EXTERNAL +(section 3.2.5, page 33) and INTERNAL (section 3.2.4, page 33) +pseudo-ops. + +Declaring a symbol global forces its scope to the outermost block in +the same way as does a double up-arrow. Therefore, if a symbol is +defined and declared global in an inner block, there must not be a +conflicting definition in an outer block. + +One other related feature is the library mechanism. A library is a +file that contains a set of utility programs. Each program in the +library may be loaded independent of the others, depending on whether +it is required by the programs that have been loaded thus far. To +implement this, there is associated with each program in the library +(in one or more entry blocks) a list of certain global entry points +defined in that program. In most cases these are the names of the +routines contained in the program. When the loader is in library +search mode, it loads only those programs for which at least one of +the entry points corresponds to an existing unsatisfied global +request (external symbol). Only those programs actually needed are +loaded from the library; the rest are ignored. The ENTRY pseudo-op +(section 3.2.4, page 33) is used to declare symbols to be entry +points which will be available to a library search. + + + 2.3.4.8 Symbols and Arrows + + +This is a brief restatement of the ways that identifiers are used as +symbols in conjunction with arrows. + + Examples: + +^SYM: ;SYM is available at the next-outer block +^^BOL__10 ;BOL is half killed and available at the + ;outermost block +^^ZOT= =69 ;ZOT is available at the outermost block +A^_7 ;A is global and available to lower blocks +FOO^: ;FOO is global and defined here (internal), + ;available at the outermost block +PUSHJ P,BAZ^ ;BAZ is global, may be external, available at the + ;outermost block + 24 Basic Syntax FAIL + + + 2.3.5 Complex Atoms + + +Two constructs exist which assemble one or more statements in much +the same way as FAIL's normal top-level statement processor, but then +return as an atom the value associated with the statement(s) +assembled, rather than outputting the binary data. Both of these +constructs involve the use of opening and closing characters to +delimit the text. For an atomic statement, broken brackets, called +brokets (< and >), are the delimiters. For literals, the delimiters +are square brackets ([ and ]). + +When the opening character is recognized, FAIL saves its present +state and enters an auxiliary statement-assembly loop, continuing to +assemble statements until a statement is encountered which terminates +with the closing character. The closing character is located as a +statement delimiter, not by keeping a count of the opening and +closing characters. Thus if the delimiter character appears in a +text constant, it will not be counted toward the match; also, +attempting to use a comment (see section 2.1.6, page 7) in the final +statement of the sequence will prevent recognition of the closing +delimiter. Note that this method of counting brokets is different +from the macro processor, which counts brokets rigidly, independent +of context. Nesting of complex atoms is handled by the recursive +nature of FAIL's statement processor. + + + 2.3.5.1 Atomic Statements + + +When it is useful to have the value of an entire statement treated as +an atom, enclose that statement in brokets. Some number of +statements will be assembled as described above, and the value of the +first word assembled will be returned as the value of the atom, just +as if the corresponding number had been typed. The values of any +additional words assembled up to the closing broket will be ignored, +although their side effects (if certain pseudo-ops are used) may +remain. For example, if one of the multiple-word text pseudo-ops is +used inside brokets, only the first text word will be returned, and +the rest will be dispatched to the great bit bucket in the sky. This +type of atom is constrained by FAIL to be handled as a number, so all +symbols used in this context must be defined and available. + FAIL Basic Syntax 25 + + + + Examples: + + ;equivalent to 254000000000 + + > ;this broket will end it, not the one above + + + + 2.3.5.2 Literals + + +Although the PDP-10 instruction set allows a large percentage of +constants to be specified as immediate operands, it is still +frequently necessary to reference constants stored elsewhere in +memory. Instead of explicitly setting up these constants and +referencing them by labels, it is possible to reference these +constants as literals. The basic function of literals is to allow +the programmer to write the value of the desired constant directly +(i.e., literally), while the assembler automatically allocates a +memory location for it, stores the value in it, and supplies the +address of the cell for the reference. Also, an operation called +constants optimization occurs, which consists of comparing (the +binary value of) each literal with previous literals to see if the +required constant has already been allocated, in which case the +existing cell will be used rather than allocating another. This +avoids multiple copies of a given constant. + +To use a literal, put a statement of the desired value in square +brackets and use it as an atom. The value (of the literal) will be +the address of the literal in memory, which is treated like an +undefined symbol since the actual location will not be assigned until +later (usually the end of the program; also, see section 3.1.6, +page 31). Literals can be used only where forward references are +legal. + +Because of the constants optimization, it is often dangerous (and +considered poor form) to write a program which changes the contents +of a literal. Such a change affects all parts of the program +attempting to use that constant, which is not usually the desired +effect. + +A literal may contain more than one word if desired. The syntax of +literals is basically the same as that of atomic statements, except +that all words assembled are used. Multiple-word literals are most +commonly used to store long text strings, but may be used to store + 26 Basic Syntax FAIL + + +sequences of instructions. There is no rigid limit on the maximum +size of a literal, but large literals do consume assembler core +fairly rapidly. + +For purposes of assembling code in literals, it should be noted that +the predefined symbol "." retains its value during the assembly of a +literal, rather than referring to the current location within the +literal. Thus it refers to the location where the reference to the +outermost literal is being made. The current location within the +(current) literal can be referred to by using the symbol "$." (but +this may not do the right thing if the PHASE pseudo-op is in use). + +Naturally, labels may appear inside literals, but if they do they +will be assigned the value of the current location within the +literal, rather than the value outside. (Labels that appear inside +literals are called literal-labels.) This is the only time that FOO: +and FOO_. assign different values to FOO. The location of a literal +is unknown at the time it is processed; hence, labels that are +defined within literals (and "$." when used inside literals) are +undefined symbols. For example, it is illegal to say FOO_$. inside a +literal because assignment statements do not accept undefined values. +Note also that constants optimization will still occur with labeled +literals, and this may result in several labels having the same +value, if appropriate. + + Examples: + +PUSH P,[5] ;no PUSHI, so a literal is handy +OUTSTR [ASCIZ /FOOBAR/] ;a two-word text constant +JRST [ MOVEI C,12 ;some code in a literal + PUSHJ P,WRCH + SUB P,[1,,1] ;a nested literal + JRST .+1] ;returns to the next instruction + ;outside the literal + +PUSHJ P,[YTST: CAIE C,"Y" ;a subroutine in a literal + CAIN C,"y" ;(very rarely done actually) + AOS (P) + POPJ P,] + +PUSHJ P,YTST ;calling the above subroutine + FAIL Pseudo-Ops 27 + + +3. Pseudo-Ops + + +Most statements are translated into operations for the computer to +perform when the program is executed. Pseudo-ops (short for pseudo- +operations), on the other hand, signify operations to be performed at +assembly time. Some of these operations affect the behavior of the +assembler in particular ways; others serve as convenient methods of +entering data in commonly used formats. + + + + + 3.1 Destination of Assembled Code + + +The assembler uses a location counter to keep track of the location +where the code it is assembling will go. This counter is initialized +to relocatable 0 at the start of the assembly; it is incremented by 1 +for each instruction assembled. The value in the location counter is +the location where the next word assembled will go. + + + 3.1.1 LOC, RELOC, and ORG + + +The contents of the location counter can be changed with the LOC, +RELOC, and ORG statements. + +The LOC pseudo-op takes one argument, an expression, which must be +defined and available. The effect of LOC is to put the value of the +expression into the location counter and to set the relocation of the +counter to absolute, regardless of the relocation of the argument. + +The RELOC statement has the same effect as the LOC statement except +that the relocation is set to relocatable, regardless of the +relocation of the argument. + +The ORG statement has the same effect as the LOC and RELOC statements +except that the relocation is set to the relocation of the argument. + +Whenever LOC, RELOC or ORG is used, the current value (and +relocation) of the location counter is saved (there is only one such +saved location counter, not one for each pseudo-op). A LOC, RELOC, +or ORG statement with no argument will cause the saved value and +relocation to be swapped with the current value (and relocation) of +the location counter. + 28 Pseudo-Ops FAIL + + + 3.1.2 SET and USE + + +It is possible to have multiple location counters and to switch back +and forth among them. Only the currently active location counter is +incremented. Location counters may be given any names which fit the +syntax of identifiers. There is no relationship between location +counters and labels with the same name. + +The SET pseudo-op is used to initialize a location counter. It takes +two arguments separated by a comma. The first is the name of the +location counter; the second is the value to which the counter will +be set. SET has the same effect as ORG except that it changes the +indicated location counter and has no effect on the current location +counter unless it is the same as the indicated one. SET is usually +used to create a new location counter. + +The USE pseudo-op is used to change location counters. It takes one +argument, the name of the location counter to change to. USE causes +the current location counter value to be saved away and the value of +the indicated counter to be used. If a subsequent USE indicates the +location counter which was saved away, the value it had when it was +saved away will become the current value. If the indicated location +counter has not appeared in a SET before its appearance in a USE +(i.e., if it has no value), it will be given the value of the current +location counter. The location counter which the assembler starts +with has a blank name (i.e., a null argument indicates this first +one). + +In the example below, a close single quote (apostrophe) (') is used +to denote that the value it follows is relocatable. This is the +convention that FAIL uses when making a listing of the assembled +code. + + Example: + + Location Instructions + + 0' JRST FOO + 1' JRST BAZ + 2' SET GARP,37 + 2' USE GARP + 37 JRST FOO + 40 USE + 2' JRST FOO + FAIL Pseudo-Ops 29 + + + 3.1.3 PHASE and DEPHASE + + +It is sometimes desired to assemble code in one place which will +later be moved by the program itself to another place. In this case, +it is desired that labels be defined as referring to locations in the +place where the code will be moved, rather than where the assembler +will put it. To accomplish this, the PHASE pseudo-op is used. PHASE +has one argument, the location to which the next word assembled will +be moved by the program. For instance, if, while the location +counter is at 74, a PHASE 32 appears and a label appears on the next +line, the label will be given the value 32, but the code on that line +will be placed in location 74. Under these circumstances, the "." +symbol will have the value 32, but the "$." symbol will have the +value 74. The PHASE pseudo-op remains in effect until cancelled by a +DEPHASE pseudo-op (no argument). + +If a RELOC, LOC, or ORG pseudo-op (see section 3.1.1, page 27) +appears while PHASE is in effect, the following considerations apply. +If the relocation of the location counter remains unchanged by the +RELOC (or LOC or ORG), then the value of the phase will be offset by +the same amount as the location counter changes. That is, the value +of "." and "$." will be changed by the same amount. If the +relocation of the location counter changes and the relocation of the +phase was the same as the relocation of the (old) location counter, +then the relocation of the phase will be changed and the phase will +be offset by the same amount as the location counter changes. +Otherwise, the error message Indeterminate Phase due to RELOC will +occur and FAIL will dephase. + + + 3.1.4 HISEG + + +This statement outputs information directing the loader to load the +program into the high segment. It should appear before any code is +assembled. + + + 3.1.5 TWOSEG + + +This statement directs FAIL and the loader to assemble and load a +two-segment program. This complicates the relocation process because +the loader must maintain two relocation constants, one for each +segment. Since only one bit of relocation information is available +for each value in the relocatable binary file, a kludge is used to +decide which relocation to apply to each relocatable value. To do +this, the loader compares the unrelocated value to a quantity known + 30 Pseudo-Ops FAIL + + +as the high-segment origin, which is the first address used for the +high segment within that program. Any value greater than or equal to +this quantity will be considered a high-segment address, while any +value less than this quantity will be considered a low-segment +address. When the value in question is a location specifier, the +choice of relocation will determine which segment the code is +actually loaded into. + +Unfortunately, there is a possible bug in this relocation method. It +is possible to have an expression which evaluates, through normal +relocation arithmetic, to a relocatable quantity whose unrelocated +value does not correspond to the segment the relocation was +originally derived from. For example, if FOO is a label at high +segment location 120, it will probably have a value of relocatable +400120. The expression FOO-400000 would be calculated by FAIL to +have the value relocatable 120. This value would be passed directly +to the loader since Polish appears unnecessary. However, the loader +would apply the low-segment relocation to this value and probably +have incorrect results. At present, the best way to get around this +is to say FOO*1-400000, which will force the Polish to be passed to +the loader. + +The high-segment origin is specified by an optional argument to the +TWOSEG pseudo-op, or set to the default of 400000 in its absence. In +this case a RELOC 400000 followed by a RELOC 0 will initialize the +dual location counter to assemble into the low segment and to switch +segments whenever a RELOC statement with no argument is encountered +(see section 3.1.1, page 27). Like HISEG, TWOSEG should be used +before any code is assembled. + FAIL Pseudo-Ops 31 + + + + Example: + + TITLE EXAMPLE +PDLEN__100 +P_17 + TWOSEG 400000 ;initialize to two segments + RELOC 0 ;initialize dual location counters + RELOC 400000 ;now assemble code in the high segment +START: TDZA 1,1 + MOVNI 1,1 + MOVEM 1,RPGSW# + CALLI 0 + MOVE P,[IOWD PDLEN,PDLIST] + RELOC ;set the relocation to low segment +PDLIST: BLOCK PDLEN ;define space for data storage + RELOC ;set location counter to the high segment + PUSHJ P,CORINI ;code is assembled in the high segment + ;the rest of the program goes here + RELOC ;back to the low segment + VAR ;do variables in the low segment + RELOC ;to the high segment + LIT ;and literals here + END START + + + 3.1.6 LIT + + +The LIT statement causes all previously defined literals to be placed +where the LIT statement occurs. The LIT statement must not appear +inside a literal. If a two segment sharable program is being +assembled, LIT should appear in the upper segment. + + + 3.1.7 VAR + + +The VAR statement causes all variables which appeared with a # in +this block (or a sub-block of this one) to be placed where the VAR +appears. VAR must not appear inside a literal. If a two segment +sharable program is being assembled, VAR should appear in the lower +segment. + 32 Pseudo-Ops FAIL + + + 3.2 Symbol Modifiers + + +The pseudo-ops in this section perform several functions, all +relating to the definition or availability of symbols, or affecting +the linkage of this program to others. + + + 3.2.1 OPDEF + + +The OPDEF statement has the following form: + + OPDEF symbol [value] + +OPDEF inserts the symbol into FAIL's opcode table with the indicated +value. The symbol, which is a user-defined opcode, may then be used +as any other opcode. The value part of the OPDEF must be defined and +available. User-defined opcodes are sometimes called opdefs because +of the pseudo-op by which they are defined. + + + 3.2.2 BEGIN and BEND + + +The BEGIN statement is used to start a block. The block it starts +will end at the corresponding BEND statement. The BEGIN may be +followed by an identifier that will be used as the name of that +block. DDT and RAID recognize block names. If no identifier +appears, the assembler will create one of the form A.000, where the +000 will be replaced by the block number of this block in octal. +(The block number is initialized to zero and incremented for each +BEGIN.) There is no relationship between labels and blocks with the +same name. All text following the identifier is ignored until the +next line feed or double-arrow. + +BEND may be followed by an identifier which, if present, is compared +to the block name of the block being ended; if they don't match, +FAIL prints an error message. + +FAIL does not require block names to be unique; however, the loader +and the debuggers sometimes depend on unique block names, so the user +would be wise to avoid conflicts. + +For a discussion of block structure, see section 2.3.4.6, page 19. + FAIL Pseudo-Ops 33 + + + 3.2.3 GLOBAL + + +The GLOBAL pseudo-op should be followed by a list of symbols +separated by commas. Each symbol should be defined in an outer +block. The effect of GLOBAL is to find the nearest outer block in +which that symbol is defined and to make the definition in that block +immediately available in the block in which the GLOBAL appears. +GLOBAL does not affect the definition of the symbol in any +intervening blocks. + +If a symbol has been declared GLOBAL in a block and later is +redefined in that block, the redefinition affects the definition in +the outer block where GLOBAL found the original definition. Doing +this causes strange effects if the definition was not in the next- +outer block; it should not be done without some careful thought. + +The GLOBAL pseudo-op has no relation to the concept of global +symbols. + + + 3.2.4 INTERNAL and ENTRY + + +These statements declare certain locally defined symbols to be +internal symbols. Internal symbols are those which are made +available to other programs by the loader. INTERNAL (or ENTRY) +should be followed by a list of symbols separated by commas. These +symbols need not be defined before the INTERNAL (or ENTRY) statement +appears, but they must be defined by the end of the program. + +ENTRY emits special library entry blocks to the loader; see section +2.3.4.7, page 23. ENTRY statements must appear before any other +statements that emit code, except that it is specifically legal to +precede ENTRY statements by a TITLE statement. + + + 3.2.5 EXTERNAL + + +The EXTERNAL statement declares that certain symbols are external +symbols. An external symbol is a symbol that is declared internal in +some other program. EXTERNAL is followed by a list of symbols +separated by commas. The loader will fix up any references to an +external symbol when the program in which it is defined is loaded. + +Symbols must not be defined at the time they are declared with an +EXTERNAL statement. If an external symbol is subsequently defined, it +is automatically converted to an internal symbol. + 34 Pseudo-Ops FAIL + + +If any occurrence of a symbol is immediately followed by an up-arrow +(^), that symbol is made external if it is not yet defined, or +internal if it is defined. If an external symbol is subsequently +defined, it will be made internal. + + + 3.2.6 LINK and LINKEND + + +LINK and LINKEND are used to establish a single-linked list among +several separately assembled programs. Each linked list is +identified by a link number in the range 1-20 (octal). The formats +are + + LINK number,location + + LINKEND number,location + +The number is the link number; the location is the address where the +link information will be stored. The effect is to allow 20 lists to +be threaded through several separately assembled programs. + +The loader initializes each link (and linkend) to zero. LINK N,FOO +causes the loader to store in FOO the current value of link N. Then +link N is set to (point at) FOO. LINKEND N,BAZ causes the the loader +to store the address BAZ as the linkend for link N. When the loader +finishes loading all programs, the final value of each link will be +stored in the corresponding linkend address, only if that address is +non-zero. The LINKEND feature allows the head of the list to be in a +known place, rather than in the last place LINKed. + + + 3.2.7 .LOAD and .LIBRARY + + +The .LOAD pseudo-op causes the loader to load a specific REL file as +a consequence of loading the program in which this pseudo-op occurs. +The format is + + .LOAD DEV:FILE[PRJ,PRG] + +The DEV: field is optional (the default is DSK:); it specifies the +device where the REL file can be found. The [PRJ,PRG] field is +optional; it has the usual meaning. The file named must have the +extension REL (this is a loader restriction). + +In non-Stanford FAIL installations, the file name is scanned in +accordance with the convention that prevails at that site. + FAIL Pseudo-Ops 35 + + +The .LIBRARY pseudo-op is similar to .LOAD, except that instead of +loading the file, the loader will search the named file as a library. + + + 3.2.8 PURGE + + +The PURGE pseudo-op takes a list of symbols, separated by commas, as +its argument. Each of the symbols named will be purged, i.e., +removed from FAIL's symbol table. A purged symbol can be an opcode, +macro, label or other symbol. For PURGE to be legal, the symbol must +be defined and available when the PURGE occurs. Some symbols, such +as variable names literal-labels, and global symbols, cannot be +purged. Purged symbols are not passed to the loader or debugger. + +PURGE searches the symbol table for opcodes first, then macro names, +and finally labels (and parameters). This means that if a symbol has +a definition as both an opcode and a label, purging that symbol will +delete the opcode, and a second purge of that symbol will delete the +label definition. + +If the identifier name of some purged symbol is used after the purge, +FAIL makes a new and totally different symbol, which has no relation +to the purged symbol. The CREF program will also consider such a +symbol to be different from the purged symbol. + +Caution: if an opcode, pseudo-op, or other predefined symbol is +purged, it will remain unavailable to subsequent assemblies performed +by the FAIL core-image from which it was purged. Also, it is unwise +to purge a macro while it is being expanded. + + + 3.2.9 XPUNGE + + +XPUNGE is used to delete all local symbols from one block. XPUNGE +takes effect only at the next BEND (or END or PRGEND) statement +following the XPUNGE. At that BEND, most local symbols will not be +emitted to the loader. This decreases the size of the REL file and +makes loading it faster. Block names, internal and external symbols, +variables, and literal-labels will be passed to the loader. + + + 3.2.10 SUPPRESS and ASUPPRESS + + +When a parameter file (i.e., a file that contains assembly parameters +for use in several assemblies) is used in assemblies, many symbols +get defined but are never used. Unused defined symbols take up space + 36 Pseudo-Ops FAIL + + +in the binary file. Unused symbols may be removed from symbol tables +by means of the SUPPRESS or ASUPPRESS pseudo-ops. These pseudo-ops +control a suppress bit associated with each symbol; if the suppress +bit is on and the symbol is not referenced, the symbol will not be +output to the binary file. + +SUPPRESS takes a list of symbols, separated by commas, as its +argument. The suppress bit is turned on for each symbol named. A +symbol may be an opdef, a parameter, or a label. The symbol should +be defined before the SUPPRESS statement occurs. + +ASUPPRESS turns on the suppress bit for every user-defined symbol and +opcode that exists in the symbol table at the time the ASUPPRESS +occurs. + +Variables, literal-labels, internals, and entry point symbols are +never suppressed. Externals that are not referenced can be +suppressed. + +If ASUPPRESS appears in a universal program (see section 3.2.11, +page 36), then all symbols in the universal symbol table will have +the suppress bit set when they are used in a subsequent SEARCH. + + + 3.2.11 UNIVERSAL and SEARCH + + +The UNIVERSAL pseudo-op has the same syntax as TITLE (see section +3.5.1, page 41). In addition to the functions of TITLE, UNIVERSAL +declares the symbols defined in this program to be universal symbols. +Universal symbols are symbols which can be accessed by other programs +that are assembled after the universal symbols have defined. That +is, UNIVERSAL causes symbols to be retained by FAIL after it finishes +assembling the universal file. When subsequent files are assembled +(using this copy of FAIL, which has the universal symbols), the +universal symbols can be accessed as any other local symbols. The +program name set by UNIVERSAL is used to name the universal symbol +table created to contain the universal symbols defined by this +program. Only outer block symbols (and macros and opdefs) are +retained in the universal symbol table. Variables, literal-labels, +and internal symbols are not retained. + +Universal files are intended for making definitions, not for +assembling code. The usual use for a universal file is to define +opcodes, macros and parameters for subsequent assemblies. It is not +wise to include relocatable symbols in the universal file. The +exception is that a universal file may declare a symbol to be +external; that declaration can be used by subsequent assemblies that +search this universal symbol table. + FAIL Pseudo-Ops 37 + + +SEARCH controls access to the universal symbols. SEARCH takes a list +of arguments, each of which is the name of a universal symbol table. +For each universal table named, all the symbols in that table are +added to the end of the main symbol (or macro or opcode) table. +Then, when the symbol table is searched, if there is no other +definition of the symbol, the universal definition will be found. +Universal symbols are considered to be defined at the outer block. +If such symbols are to be made available to inner blocks, they must +be defined with a down-arrow, or declared GLOBAL. + + + + + 3.3 Entering Data + + + + 3.3.1 DEC and OCT + + +The DEC and OCT statements both take a string of arguments, each a +number, separated by commas. The radix is temporarily set for this +one statement to 10 for DEC or to 8 for OCT. The numbers are placed +in successive locations. + + Examples: + + DEC 5,9,4096 ;assembles three words + OCT 5,11,10000 ;assembles the same three words + + + 3.3.2 BYTE + + +The BYTE statement is used to enter bytes of data. Arguments in +parentheses indicate the byte size to be used until the next such +argument. The first argument of a BYTE statement must be a byte size +argument. Other arguments are the byte values. An argument may be +any expression that is defined, available, and absolute. Arguments +in parentheses (byte size) are interpreted in decimal (base 10) and +other arguments in the prevailing radix. Bytes are deposited with +the byte instructions, so if a byte will not fit in the current word, +it will be put in the left part of the next word. Unused parts of +words are filled with zeros. Byte size arguments are not surrounded +by commas, but other arguments are separated by commas. For +instance, the statement + + BYTE (7) 3,5(11)6 + 38 Pseudo-Ops FAIL + + +will put two 7-bit bytes (3 and 5) and an 11-bit byte (6) in a word, +left justified. + +Two successive delimiters, i.e., two commas or a comma and +parenthesis, indicate a null argument, which is the same as a zero. + + + 3.3.3 POINT + + +The POINT pseudo-op assembles a byte pointer in one word. The first +argument should be an expression and is interpreted in decimal. The +expression must be defined and available. It indicates the byte +size, and its value is placed in the size field of the assembled +word. The second argument should contain one or more of an index +field, an address field, and an at-sign. The third field, if +present, indicates the bit position of the low order bit of the byte, +i.e., its value is subtracted from 35 (decimal) and placed in the +position field. It is interpreted in decimal and must be available. +If the third argument is omitted (no comma should be present after +the second argument), the position field is set to 36 (decimal) so +that the first time the pointer is incremented, it will point to the +first byte of the word. + + + 3.3.4 XWD + + +The XWD statement takes two arguments, separated by a comma, and +assembles a single word with the value of the first argument in the +left half and the value of the second argument in the right half. +Both arguments must be present. + + + 3.3.5 IOWD + + +IOWD is a permanently defined macro (see section 4, page 45). +Its definition is + + DEFINE IOWD (A,B) + < XWD -(A),B-1 > + +IOWD takes two arguments and assembles a word in which the negative +of the first argument goes in the left halfword and one less than the +value of the second argument goes in the right halfword. This format +(i.e., negative word count, and memory address minus 1) is often used +in communicating with the operating system to specify the address and +length of a data block. Also, IOWD may be used to initialize an +accumulator for use as a push down pointer. + FAIL Pseudo-Ops 39 + + + 3.3.6 ASCII, ASCIZ, ASCID, and SIXBIT + + +There are four text statements: ASCII, ASCIZ, ASCID, and SIXBIT. +Each takes as its argument a string of characters starting and ending +with, and not otherwise containing, some non-blank character which +serves as a delimiter. This delimiter should not be any one of the +characters: left-arrow (_), colon (:), up-arrow (^), tilde (), or +number sign (#). + +ASCII puts the 7-bit representation of each successive character in +the string (excluding the delimiters) in successive words, 5 +characters per word, until the string is exhausted. The low order +bit of each word and the left-over part of the last word are filled +with zero. + +ASCIZ is the same as ASCII except that if the last character is the +5th of a word, a word of zero is added at the end. This is to ensure +that there is at least one 0 byte at the end. + +ASCID works as ASCII except that the low order bit of each word +generated is a 1. ASCID assembles data suitable for either the III +or Data Disc display systems at Stanford. Also, the ASCID format is +used for line numbers in the SOS editor. + +SIXBIT works as ASCII except that the characters are converted to the +sixbit representation and packed 6 to a word. The last word is +filled out with zeros if necessary. Ascii characters are converted +to sixbit by replacing the 40 bit with the 100 bit and removing the +100 bit. + + + 3.3.7 RADIX50 + + +This pseudo-op takes two arguments, separated by a comma. The first +argument is a number; the second argument is an identifier. The +value assembled by the RADIX50 statement is the radix50 +representation of the identifier, with the number ORed into the high- +order 6 bits. The 2 low-order bits of the number are cleared before +ORing. + +Radix50 is the representation used for symbol names in the loader, +DDT, and RAID. Radix50 is used to condense 6-character symbols into +32 bits. Legal characters are reduced to a value in the range 0-47 +octal. The radix50 value is obtained by accumulating a total +composed of each character value times a weight. The weight is the +power of 50 (octal) corresponding to the character position. The +weight of the rightmost non-blank character is 1; the second from + 40 Pseudo-Ops FAIL + + +the right has weight 50; the third has weight 50*50; etc. The +correspondence between characters and their radix50 value is given +below: + + Blank  0 + 0-9  1-12 + A-Z  13-44 + .  45 + $  46 + %  47 + + + + + 3.4 Reserving Space for Data + + + + 3.4.1 BLOCK + + +The BLOCK statement is used to reserve a storage area for data. The +value of the argument is added to the location counter, so subsequent +statements will be assembled beyond the area reserved by BLOCK. The +argument must be defined and available. A warning will be given if +the argument is negative. The loader will initialize each word +reserved by the BLOCK statement to zero; however, well-written +programs do their own initialization. Note that the BLOCK pseudo-op +has no relation to block structure. + +BLOCK N and ORG .+N are equivalent. + + + 3.4.2 INTEGER and ARRAY + + +INTEGER should be followed by a list of symbols, separated by commas. +Each of these symbols is then treated as a variable, i.e., as though +it had appeared in the block where the INTEGER appears, followed by a +number sign. + +The ARRAY statement takes a list of arguments separated by commas. +Each argument is a symbol followed by an expression in brackets. The +effect is similar to INTEGER, except that the expression (which ought +to be defined and available) denotes the number of locations to be +reserved (as in BLOCK), with the symbol being the address of the +first one. For example, + + ARRAY FOO[10],BAZ[20] + FAIL Pseudo-Ops 41 + + +will reserve 10 words for FOO and 20 words for BAZ. The symbols FOO +and BAZ are not defined by this statement; they can only be used +where forward references are legal. + + + + + 3.5 Assembler Control Statements + + + + 3.5.1 TITLE + + +TITLE names the program and sets the heading for the pages of the +listing. There should be precisely one TITLE statement per program; +it should appear before any statement that generates code. + +TITLE should be followed by a string of characters, the first part of +which should be an identifier. That identifier is used as the +program name which DDT and RAID will recognize. It is also used as +the name of the outermost block. + +The string of characters in the TITLE statement is printed as a part +of the heading on all pages subsequent to the one on which the TITLE +statement appears; if TITLE appears on the first line of a page, it +also affects the heading on that page. The string used in the +heading for TITLE is terminated by the first carriage return or +semicolon. + +If no TITLE statement appears before the first symbols are emitted +(generally, at the first BEND or END), then FAIL will generate a +title with program name ".MAIN". If a TITLE statement appears after +code has been emitted (except for entry blocks), the resulting binary +file may be unsuitable for use as part of a library file. + + + 3.5.2 END and PRGEND + + +The END statement is the last statement of a program. It signals the +assembler to stop assembling; no text following it will be +processed. If an argument is given, it is taken as the starting +address of the program. + +An END statement includes implicit VAR and LIT statements (see +section 3.1.7, page 31, and section 3.1.6, page 31). That is, all +outstanding variables and literals are placed starting at the current +value of the location counter when the END is seen. Variables are +put out first. + 42 Pseudo-Ops FAIL + + +PRGEND is used in place of END when it is desired to assemble more +than one program to and/or from a single file. It behaves exactly +like END, including taking an optional argument as the starting +address, and then restarts FAIL completely, except that I/O is +undisturbed. It therefore cannot appear in a macro expansion or +similar situation. PRGEND is particularly useful for directly +assembling a library which consists of many small programs. + + + 3.5.3 COMMENT + + +The first non-blank character following the COMMENT pseudo-op is +taken as the delimiter. All text from it to the line feed following +the next occurrence of this delimiter is ignored by the assembler, +except that it is passed to the listing file. The delimiter should +not be any one of the characters left-arrow (_), colon (:), up-arrow +(^), tilde (), or number sign (#). + + + 3.5.4 RADIX + + +The RADIX statement changes the prevailing radix until the next RADIX +statement is encountered. It has no effect on numbers preceded by an +equal sign. The one argument of RADIX is interpreted in the current +radix unless it is preceded by a equal sign. Thus, the statement +RADIX 10 will have no effect (since 10 in the current radix equals +the current radix). The radix may be set to almost anything, but for +radices above 10 (decimal) there are no digits to represent 10, 11, +etc. Zero is not permitted, and 1 should be avoided if one is going +to use either an arithmetic FOR macro or a macro argument with this +radix. + + + 3.5.5 .INSERT + + +The .INSERT pseudo-op causes FAIL to remember its position in the +current input file and then start reading (and assembling) another +file. When the end of the inserted file is reached, FAIL continues +processing the original file from the point where it left off. The +format is: + + .INSERT DEV:FILE.EXT[PRJ,PRG] + +The DEV: field is optional (the default is DSK:); it specifies the +device where the inserted file can be found. The [PRJ,PRG] field is +optional; it has the usual meaning. In non-Stanford FAIL + FAIL Pseudo-Ops 43 + + +installations, the file name is scanned in accordance with the +convention that prevails at that site. + +This pseudo-op will not work if it appears in the input stream from +any device other than DSK, since random access features are required +to accomplish the repositioning of the file. + + + + + 3.6 Listing Control Statements + + +These pseudo-ops affect the format of the assembly listing. Several +descriptions below refer to command line switches; appendix A, page +56, describes the command line format and the different switches. + + + 3.6.1 TITLE and SUBTTL + + +The TITLE statement can be used to set the heading that appears on +the pages of the listing. See section 3.5.1, page 41. + +SUBTTL is followed by a string of characters which is used as a +subheading on all subsequent pages until another SUBTTL appears. If +SUBTTL appears on the first line of a page, it will affect the +subheading of that page also. The string used in the heading for +SUBTTL is terminated by the first carriage return or semicolon. + + + 3.6.2 LIST, XLIST, and XLIST1 + + +The XLIST statement causes listing to stop until the next LIST +statement. LIST causes listing to resume if it has been stopped by +an XLIST or XLIST1 statement. Otherwise it is ignored. LIST is the +default. + +The XLIST1 statement has exactly the same effect as XLIST unless the +/I switch was used in the command string, in which case it is +ignored. + + + 3.6.3 LALL and XALL + + +XALL causes the listing of the body of macros, REPEATs, and FORs to +be suppressed during macro expansion. LALL causes it to start up +again. LALL is the default. + 44 Pseudo-Ops FAIL + + + 3.6.4 NOLIT + + +This statement causes the binary listing of code in literals to be +suppressed. This has the same effect as /L in the command string. + + + 3.6.5 NOSYM + + +This statement disables the listing of the symbol table, +counteracting /S in the command string. + + + 3.6.6 CREF and XCREF + + +These turn on and off the emission of information to CREF, the Cross- +Reference Listing program. These pseudo-ops have no effect unless /C +was used in the command string. CREF is the default. + + + 3.6.7 PAGE + + +This pseudo-op has the same function as a form feed; it is included +for compatibility with MACRO-10. A form feed is placed in the +listing immediately following PAGE. The effect is to skip to the top +of the next page of the listing. Use of this pseudo-op will destroy +the correspondence between listing pages and source file pages, so +its use is generally not recommended. + + + 3.6.8 PRINTX + + +This pseudo-op causes the line on which it appears to be printed on +the user's terminal. This is sometimes useful for giving a progress +report during long assemblies. + + + 3.6.9 PRINTS + + +The first non-blank character following the PRINTS pseudo-op is taken +as the delimiter. All text from it to the next occurrence of this +delimiter is printed on the user's terminal. The delimiter should +not be any one of the characters left-arrow (_), colon (:), up-arrow +(^), tilde (), or number sign (#). + FAIL Macro Operations 45 + + +4. Macro Operations + + +The FAIL macro processor provides features for modifying the input +text stream in many ways, such as the ability to abbreviate a +frequently occurring sequence with a single identifier or to iterate +the input of a stream of text a number of times. In both cases, +substitutions can be specified which allow each different occurrence +of the text to be somewhat modified. Provision for making the +assembly of a body of text conditional on any of a variety of +circumstances is also included. + + + + + 4.1 Macros + + +Macros are named text strings which may have substitutable arguments. +Macros may be used whenever the same or similar pieces of text (code) +occur in several places. A macro has a name and a macro body; also, +it may have a concatenation character and an argument list. The +several characteristics of a macro are specified by a DEFINE +statement. + +DEFINE and the macro name must appear on the same line. The macro +name is an identifier; it may be followed by an optional +concatenation character, which must also be on the same line as +DEFINE. The formal arguments, if any, are enclosed in parentheses +and separated by commas. The argument list may occur on a subsequent +line. The macro body, enclosed in braces ({ and }), appears after +the argument list in DEFINE. + +In the macro processor, braces and brokets are equivalent, i.e., "{" +and "<" are equivalent, as are "}" and ">". The equivalence between +brokets and braces applies at all times within the macro processor; +the text and examples that follow use braces, but brokets can be used +instead. The macro processor counts braces independent of context; +specifically, braces and brokets that appear in comments, text +constants, etc. are counted by the macro processor. In the +discussion that follows, "non-blank character" omits both blank and +tab characters. + +GDEFINE is similar to DEFINE except that the macro is defined at the +outermost block level. A macro defined by GDEFINE will remain +defined after exiting the block in which it was defined. + 46 Macro Operations FAIL + + + 4.1.1 Macro Bodies + + +The macro body may be any string of characters, subject to the +restriction that the right and left braces must be balanced. The +macro body itself is enclosed in braces and appears after the +argument list in a DEFINE statement. The macro body is stored in +FAIL's memory, associated with the macro name. At any point +following the DEFINE statement, the macro body will be substituted +for occurrences of the macro name. + + + 4.1.2 Concatenation + + +The concatenation character may be any non-blank character (excluding +also carriage return, line feed, and right brace) that appears in +DEFINE after the macro name and before the argument list and macro +body. This character may then be used to delimit identifiers so that +they will be recognized as arguments. Appearances of this character +will be deleted from the macro body whenever they appear. This +allows a macro argument to be part of an identifier, instead of an +entire identifier. See the example at the end of section 4.1.6, +page 50. + + + 4.1.3 Arguments in Macro Definitions + + +Arguments in macro definitions must be identifiers. A list of them, +enclosed in parentheses, may appear after the macro name in the +definition. If no list of arguments appears before the macro body, +it is assumed that there are no arguments. + +Each instance of an identifier in the macro body which is the same as +one of the arguments will be replaced with the string of text +corresponding to that argument when the macro is called. Thus, if +FUDLY is one of the arguments in the definition of a macro and the +following text appears in the body: + + A+FUDLY B + +then FUDLY will be recognized as an argument. But if the following +appears: + + A+FUDLYB + +then, since FUDLYB is an identifier and is different from FUDLY, it +will not be recognized as an argument. To concatenate the "B" above + FAIL Macro Operations 47 + + +with an actual argument, use a concatenation character. For example, +if the concatenation character is "$" and + + A+FUDLY$B + +appears in the macro body, then FUDLY will be recognized as an +argument, and the "$" will disappear when the macro is expanded. + +Here is a sample macro definition: + + DEFINE FOO (AC,ADDRS) + {MOVNI AC,3 + IMUL AC,ADDRS + ADDI AC,37 + MOVEM AC,ADDRS+1} + +If the text: + + FOO (A,FARB+7) + +appears in the program somewhere after the DEFINE above, it will +expand into: + + MOVNI A,3 + IMUL A,FARB+7 + ADDI A,37 + MOVEM A,FARB+7+1 + + + 4.1.4 Macro Calls + + +A macro name may appear anywhere and will be replaced by the macro +body, as long as the name appears as an identifier and is considered +to be an identifier by the assembler. A macro name may appear alone +on a line or in the accumulator, index, or address field. If the +macro name appears in a context where it is not considered to be an +identifier, the macro will not be expanded. For example, macro names +that appear in a comment or in the text argument of an ASCII +statement will not be expanded. Also, there are some other cases +where a macro name will not be expanded: + + the macro name in DEFINE, + the formal argument list in DEFINE and FOR, + the symbol name in OPDEF, PURGE, SUPPRESS and RADIX50, + the tested symbol in a symbol IF, + the block name in BEGIN and BEND, + the location counter name in USE and SET, + the universal symbol table name in SEARCH, and + the program name in TITLE and UNIVERSAL. + 48 Macro Operations FAIL + + +Macros may be used recursively. That is, a macro body may contain a +macro call or macro definition. However, if such macro calls are +nested too deep, the macro push-down list may overflow, resulting in +an error message and termination of the assembly. If this occurs, +the /P switch should be used in the command string. Every occurrence +of /P in the command string causes the assembler to allocate an extra +200 (octal) words of memory for the macro push-down list (see +appendix A, page 56). + + + 4.1.5 Arguments in Macro Calls + + +The list of arguments to a macro call may be enclosed in parentheses, +or not. The arguments themselves are separated by commas. For +example, if FOO is the name of a macro that requires two arguments, +FOO A,FARB+7 and FOO (A,FARB+7) have the same effect. + +If the argument list is enclosed in parentheses, then the first +argument begins with the first character after the "(", even if it is +blank. Subsequent arguments begin with the first character after the +comma that terminates the previous argument. Arguments do not +include the comma or ")" used to terminate them. Arguments are +scanned until the matching ")" is seen. + +If the argument list is not enclosed in parentheses, the first +argument begins with the first non-blank character after the macro +name. Subsequent arguments begin with the first character after the +comma that terminated the previous argument. Arguments do not +include the comma or other character used to terminate them. +Arguments are scanned until any one of right bracket, right broket, +right brace, semicolon, or carriage return is seen. + +Two commas in a row with nothing in between signify a null argument, +i.e., an argument that consists of no characters. If more arguments +are called for than are supplied, the last ones are considered to be +null. If more arguments are supplied than are called for, the extras +are ignored by the macro processor; see section 4.1.6, page 49. + +Unless the first character of an argument is "{", the argument +terminates at the first comma, right parenthesis, right brace (or +broket), right bracket, or carriage return. If the first character +of an argument is "{" (or "<"), then all characters included between +the matching braces are taken as the argument. This allows the +argument to contain commas, parentheses, etc. which would not be +legal otherwise, but the braces must be kept balanced. In addition, +all characters between the "}" that closes the argument and the next +argument terminator are ignored. This allows the continuation of a +list of arguments from one line to the next (i.e., enclose the last + FAIL Macro Operations 49 + + +argument on the line in braces and put the comma for it at the start +of the next line). + +If the first character of an argument is a backslash (\) or right- +arrow (), then the next thing after the backslash (or right-arrow) +is considered to be an expression (and it better be defined). The +expression is evaluated and the value is converted to a string of +ascii digits in the current radix (the radix ought not be 1). This +string of digits is taken as the argument. All characters from the +end of the expression to the next argument termination character +(comma, etc.) are ignored. + + + 4.1.6 How Much is Eaten by a Macro Call + + +When a macro call appears, some of the text following the macro name +is considered to be part of the call. Any text that is not part of +the macro call will be assembled as usual. For instance, if + + DEFINE FOO (A) {A + 7/6} + +has appeared, then when + + MOVEI A,FOO (3) (6) ;comment + +appears, it will be assembled as + + MOVEI A,3 + 7/6 (6) ;comment + +Thus, the text FOO (3) is considered to be part of the macro call and +is "eaten". + +The following rules govern how much text gets eaten in a macro call. +If the macro was defined as having no arguments, then only the macro +name and any following spaces (or tabs) are eaten. If the macro was +defined as having arguments and the first non-blank character after +the macro name is a left parenthesis, then everything from the macro +name to the right parenthesis which closes the argument list, +inclusive, is eaten. If the macro was defined as having arguments +and the first non-blank character is not a left parenthesis, then +everything from the macro name to the comma or carriage return which +terminates the last macro argument used is eaten. Thus, if +parentheses are not used and too few arguments are supplied, +everything from the macro name to the carriage return will be eaten. +If parentheses are not used and the macro was defined as having +arguments and enough or too many arguments are supplied, then +everything from the macro name to the comma (or carriage return) +which terminates the last argument used will be eaten. + 50 Macro Operations FAIL + + + Example: + + DEFINE FOO $ (A,B) {A$B} + MOVEI FOO 1,2, ,37(6) ;will expand to: + ;MOVEI 12 ,37(6) + ;"FOO 1,2," has been eaten + + + 4.1.7 Complex Example + + +This example is given without a full explanation. It shows an +example of an information carrying macro. The macro BAR is expanded +(by being redefined) every time that ADD1 is used. The \BAR in the +definition of ADD1 is necessary to cause the evaluation of BAR as an +expression (which causes a macro expansion to occur). + + Example: + + DEFINE BAR {0,} + DEFINE FOO (A,B,C) {DEFINE BAR {0,}} + DEFINE ADD1 (X) {FOO(\BAR,X)} + DEFINE SEC (A,B) {B} + + ;BAR = 0, + ADD1(X1) + ;BAR = 0,< + ; X1> + ADD1(X2) + ;BAR = 0,< + ; X1 + ; X2> + ADD1(X3) + ;BAR = 0,< + ; X1 + ; X2 + ; X3> + + SEC(\BAR) ;THIS GENERATES THE FOLLOWING: + ; X1 + ; X2 + ; X3 + FAIL Macro Operations 51 + + + 4.2 FOR + + +There are three types of FORs; all have the same general form. Each +consists of the word FOR, an optional concatenation character, a +range specifier, and a FOR-body. The FOR statement expands into the +text of its FOR-body, possibly with substitutions, repeated once for +each element in the range of the FOR. FOR replaces the IRP and IRPC +pseudo-ops found in MACRO-10. + +The optional concatenation character is specified by following the +word FOR with an at-sign followed immediately by the concatenation +character. If a FOR is used inside a macro and concatenation of FOR +arguments is desired, it is necessary to have a concatenation +character specified for the FOR which is different from the one for +the macro. + +The range specifier is different for each type of FOR and will be +explained below. The FOR statement may have one or two formal +arguments which are specified in the range specification. + +The FOR-body has the same form as a macro body; the text is enclosed +in braces, and braces must be balanced. + + + 4.2.1 String FOR + + +The range specification consists of one or two formal argument +identifiers, followed by either the identifier "IN" or the +containment character (), followed by an argument list. The +argument list has the same syntax as a macro call argument list (see +section 4.1.5, page 48), but the list must be in parentheses. The +effect is that the body of the FOR is assembled once for each element +in the argument list, and that element is substituted for the first +(or only) formal argument each time. The second formal argument, if +present, will have the remainder of the argument list (starting with +the element following the one currently substituted for the first +argument) substituted for it. + 52 Macro Operations FAIL + + + + Examples: + + Source Expansion + +FOR A IN (QRN,{()},STORP) MOVSI 13,QRN +{MOVSI 13,A PUSHJ P,GORP +PUSHJ P,GORP MOVSI 13,() +} PUSHJ P,GORP + MOVSI 13,STORP + PUSHJ P,GORP + + Source Expansion + +FOR ZOT,FUB  (A,B,C,D) MOVEI A,137 ; B,C,D LEFT +{MOVEI ZOT,137 ; FUB LEFT MOVEI B,137 ; C,D LEFT +} MOVEI C,137 ; D LEFT + MOVEI D,137 ; LEFT + + + 4.2.2 Character FOR + + +The range specifier consists of one or two formal arguments followed +by either the letter "E" or the character epsilon (), followed by a +string of characters enclosed in braces. The only restriction on the +string of characters is that the braces must balance. The body of +the FOR is assembled once for each character in the list, with that +character substituted for the first formal argument each time and the +rest of the string substituted for the second formal argument, if +any. + + Examples: + + Source Expansion + +FOR ZOT,FUB  {ABCD} MOVEI A,137 ; BCD LEFT +{MOVEI ZOT,137 ; FUB LEFT MOVEI B,137 ; CD LEFT +} MOVEI C,137 ; D LEFT + MOVEI D,137 ; LEFT + + Source Expansion + +FOR @$ QRN E {AZ1Q5} ZORPA_0 +{ZORP$QRN_0 ZORPZ_0 +} ZORP1_0 + ZORPQ_0 + ZORP5_0 + FAIL Macro Operations 53 + + + 4.2.3 Arithmetic FOR + + +This type of FOR is similar to the ALGOL FOR statement. The range +specifier consists of one or two formal arguments followed by a left- +arrow, followed by two or three expressions, separated by commas. +The expressions are like the two or three arguments of a FORTRAN DO +statement. The value of the first is the starting value, the value +of the second is the ending value, and the value of the third is the +increment. If the third expression is not present, 1 is used as the +increment. + +The body of the FOR is assembled repeatedly, first for the starting +value, then for the starting value plus the increment, etc. until it +has been assembled once for each such value which is less than or +equal to the ending value (greater than or equal if the increment is +negative). If the starting value is already greater than the ending +value (less than, for negative increment), the FOR body is not +assembled at all. For each repetition, the current value is +converted to ascii digits in the current radix, and that string is +substituted for the formal argument(s) (both arguments have the same +value). Note that all expressions must be defined, available, and +absolute. + + Examples (assume RADIX =8): + + Source Expansion + +FOR I_1+3, 25, 7 XWD FOO,4 +{XWD FOO,I XWD FOO,13 +} XWD FOO,22 + + Source Expansion + +FOR @$ ZOT_11,4,-1 ZOTQ11 : 11 +3 +{ZOTQ$ZOT : ZOT +3 ZOTQ10 : 10 +3 +} ZOTQ7 : 7 +3 + ZOTQ6 : 6 +3 + ZOTQ5 : 5 +3 + ZOTQ4 : 4 +3 + 54 Macro Operations FAIL + + + 4.3 REPEAT + + +The REPEAT statement is included for compatibility with MACRO-10. +The format is + + REPEAT exp,{text} + +The expression exp is evaluated, and the text is assembled that +number of times, with a carriage return and line feed inserted at its +end each time. The text is like a macro body: braces must balance. + +For example, the statement: + + REPEAT 3, {0} + +will expand to: + + 0 + 0 + 0 + + + + + 4.4 Conditional Assembly + + +The conditional assembly opcodes (the IFs) are like macros: they will +be recognized wherever they appear, as long as the assembler sees +them as identifiers. Thus, an IF need not be the first thing on a +line. Attempts to use IFs as symbols will produce erroneous results. + + + 4.4.1 Numeric IFs + + +There are six numeric IFs: + + IFE exp,{text} assembles text if exp=0 + IFN exp,{text} assembles text if exp0 + IFG exp,{text} assembles text if exp>0 + IFL exp,{text} assembles text if exp<0 + IFGE exp,{text} assembles text if exp0 + IFLE exp,{text} assembles text if exp0 + +The expression exp is evaluated. If its value bears the indicated +relation to zero, the text is assembled once; otherwise it is not +assembled. The text, which is called the IF-body, is like a macro +body: braces must balance. + FAIL Macro Operations 55 + + + +Examples: + + IFE 3, {ZOT} assembles nothing + IFGE 15, {JRST START} assembles JRST START + PUSHJ P,IFN PARM,{BAZ;}FOO assembles PUSHJ P,BAZ;FOO if PARM0 + PUSHJ P,IFN PARM,{BAZ;}FOO assembles PUSHJ P,FOO if PARM=0 + + + 4.4.2 Text IFs + + +There are two text IFs. They are IFIDN and IFDIF, which stand for +"if identical" and "if different", respectively. The format is + + IFIDN {text 1} {text 2} {text 3} + +The texts can be any string of characters in which the braces +balance. For IFIDN, if the two strings text 1 and text 2 are +identical in each and every character, the string text 3 will be +assembled, otherwise it will not. For IFDIF, if text 1 and text 2 +are different, text 3 will be assembled, otherwise it will not. + + + 4.4.3 Symbol IFs + + +There are eight symbol IFs. They are IFDEF, IFNDEF, IFAVL, IFNAVL, +IFOP, IFNOP, IFMAC, and IFNMAC. A typical example is + + IFDEF symbol,{text} + +If the indicated condition is true for the symbol, the text is +assembled; otherwise it is not. These conditionals come in pairs; +if one of a pair is true, the other is false. + +IFDEF is true if the symbol is defined in this block or in an outer +block. Defined symbols may be either opcodes, macro names, labels, +or parameters. IFDEF will be true if the symbol could be used on a +line by itself (ignoring possible future definitions). + +IFAVL is true if the symbol is available. That is, IFAVL is true if +the symbol is defined as an opcode or macro or if it has been defined +in this block, declared global in this block and defined in an outer +block, or defined in an outer block with a down-arrow. + +IFOP is true if the symbol is defined as an opcode. + +IFMAC is true if the symbol is defined as a macro (including the IFs, +IOWD, and the predefined symbols .FNAM1, .FNAM2, "$." and "."). + 56 Appendix A FAIL + + + Command Language + + +The basic format of a FAIL command is + + binary-file,listing-file_source-file-1, ... ,source-file-n + +File specifications consist of + + device:file + +If device: is missing, DSK: is assumed. Either (or both) output +file(s) may be omitted. If the listing-file is included, a comma +must precede it. Source-file names are separated by commas. The +device name for source files is sticky, so to change devices the +device name must be explicit, even if it is DSK:. Multiple source +files are concatenated as one assembly. If the last source-file name +on a line ends with a comma (and carriage return-line feed) then the +next line is taken as a continuation of this command. + +If no file extension is given for the binary and list files, REL and +LST are assumed, respectively (in the non-Stanford FAIL, CRF is the +default extension for the list file). If no extension is given for +the source file(s), FAI is tried first; failing that, a blank +extension is tried. + +Switches should follow file names and may be either of the slash type +or parentheses type (e.g., "/x" or "(x)"). + +Device switches (must follow the name of the affected file): + + nA advance magnetic tape n files + nB backspace magnetic tape n files + T skip to logical end of magnetic tape + W rewind magnetic tape + Z zero DECtape directory + +Assembler switches (may appear after any file name): + FAIL Appendix A 57 + + + + C make a cross-reference (CREF) listing + F don't pause after errors (inverse of R) + I ignore XLIST1 pseudo-op + J turn on cross-reference listing output + K turn off cross-reference listing output + L don't list literal values with text + N don't list assembly errors on TTY + R pause after each assembly error + S list symbol table + U underline macro expansions on listing + nV set the number of lines/page in listing to n + X don't list macro expansions + +The P switch is used to allocate extra space for the macro push-down +list (PDL), which is normally 200 (octal) locations long. If +recursive macros are used, more space may be needed. The macro PDL +will be expanded by 200 words for every occurrence of the P switch in +the command string. A numeric argument may given with the P switch +to specify a multiple of 200 words by which to expand the PDL. + +Sometimes, assembly parameters are specified from the user terminal, +rather than being included in the source program. Suppose the line +SEGSW__1 needs to be included in the assembly of the file BAZ. The +following command sequence would do that (and make a cross-reference +listing of BAZ): + +BAZ,BAZ/C_TTY:,DSK:BAZ +SEGSW__1 +^Z + +The text is typed to FAIL and terminated with control-Z (^Z) (at +Stanford displays, control-meta-line feed is used instead of control- +Z). Using RPG (known elsewhere as COMPIL), the command sequence +would be + +COMPILE/CREF TTY:F+DSK:BAZ +SEGSW__1 +^Z + +The file name F is needed to satisfy the RPG syntax; the device name +DSK: is needed to switch the default input device to DSK. + +If the command FILE@ is seen, the named file will be read and +interpreted as containing a series of commands of the usual form. + +The command FILE! causes FAIL to exit and run the named program. The +default device for this command is SYS:. + 58 Appendix A FAIL + + +To provide some compatability with RPG-style commands, FAIL accepts +"=" for "_" in the command line. Also, either "+" or ";" may be used +instead of "," to separate source-file names. + FAIL Appendix B 59 + + + Relocatable and Undefined Values + + +FAIL binary programs are usually required to be relocatable, i.e., +loadable anywhere in a core image. Many values depend upon the +absolute location of a program within its core image, e.g., the +target address of a branch instruction. The final determination of +these values must be made by the loader. + +The problem of relocation can usually be reduced to a question of +whether or not to augment a value by the relocation constant, which +is simply the location at which the loader decides to begin loading +this program. The mechanism for handling this involves associating +with each value a relocation factor, which is (at load time) to be +multiplied by the relocation constant and added to the value. For +the simple relocation mechanism to work, the relocation factor must +be a constant and either 0 or 1. Since 36 bits may contain two 18- +bit addresses, a relocation factor is provided for each halfword. +Thus, a value which is completely determined except for simple +relocation can be expressed in 38 bits. A value in which at least +one relocation factor is non-zero is said to be relocatable; one in +which both are zero is said to be unrelocatable or absolute. + +There is a more general, less efficient mechanism for delaying +calculations until load time. This is used in more complex cases +where the simple relocation scheme is inadequate. Whenever a value +cannot be calculated immediately and cannot be handled by the +relocation mechanism because it requires some other type of deferred +calculation, the value is said to be undefined. Undefined values are +represented by relatively complex structures which are retained in +FAIL for final evaluation or, if necessary, passed to the loader for +evaluation. Undefined values are illegal in those contexts which +require the value to be immediately known, including some situations +where the relocation factor mechanism is legal. The legality of +undefined or relocatable values is indicated in the discussion of +each possible usage. + 60 Appendix C FAIL + + + Predefined Opcodes + + +The standard machine instruction mnemonics of the PDP-10 (KA-10) are +defined in FAIL. + +When the Stanford version of FAIL is started, it obtains from the +system the definitions for all system UUOs and CALLIs that are +available at the time of the assembly. + +The table that follows includes all the pseudo-ops, machine +instruction mnemonics, special symbols, and UUO mnemonics currently +available at Stanford. The indication SAIL is used to indicate UUOs +and machine instructions available only at Stanford. The indication +UUO is used to mark system calls that are also available on a DEC +system. Hardware I/O instructions are indicated by I/O; these +instructions are not available to normal user programs. Machine +instruction mnemonics for the KI-10 processor are available as a +conditional assembly feature in FAIL; these are flagged with the +indication KI. The entry for each pseudo-op includes the page number +where that pseudo-op is explained. + +Note that there are sometimes subtle differences between DEC system +UUOs and Stanford UUOs; consult the appropriate reference manual. +Also note that some DEC mnemonics conflict with those used at +Stanford. + FAIL Appendix C 61 + + + +$. Predefined page 17 APRENB CALLI 16 UUO +. Predefined page 17 ARRAY Pseudo-Op page 40 +.FNAM1 Predefined page 18 ASCID Pseudo-Op page 39 +.FNAM2 Predefined page 18 ASCII Pseudo-Op page 39 +.INSERT Pseudo-Op page 42 ASCIZ Pseudo-Op page 39 +.LIBRARY Pseudo-Op page 34 ASH 240000,,0 +.LOAD Pseudo-Op page 34 ASHC 244000,,0 + ASUPPRESS Pseudo-Op page 35 +ACCTIM CALLI 400101 SAIL ATTSEG CALLI 400016 SAIL +ACTCHR CALLI 400105 SAIL +ADD 270000,,0 BEEP CALLI 400111 SAIL +ADDB 273000,,0 BEGIN Pseudo-Op page 32 +ADDI 271000,,0 BEND Pseudo-Op page 32 +ADDM 272000,,0 BLKI 700000,,0 I/O +ADSMAP CALLI 400110 SAIL BLKO 700100,,0 I/O +AND 404000,,0 BLOCK Pseudo-Op page 40 +ANDB 407000,,0 BLT 251000,,0 +ANDCA 410000,,0 BUFLEN CALLI 400042 SAIL +ANDCAB 413000,,0 BYTE Pseudo-Op page 37 +ANDCAI 411000,,0 +ANDCAM 412000,,0 CAI 300000,,0 +ANDCB 440000,,0 CAIA 304000,,0 +ANDCBB 443000,,0 CAIE 302000,,0 +ANDCBI 441000,,0 CAIG 307000,,0 +ANDCBM 442000,,0 CAIGE 305000,,0 +ANDCM 420000,,0 CAIL 301000,,0 +ANDCMB 423000,,0 CAILE 303000,,0 +ANDCMI 421000,,0 CAIN 306000,,0 +ANDCMM 422000,,0 CALL 040000,,0 UUO +ANDI 405000,,0 CALLI 047000,,0 UUO +ANDM 406000,,0 CALLIT CALLI 400074 SAIL +AOBJN 253000,,0 CAM 310000,,0 +AOBJP 252000,,0 CAMA 314000,,0 +AOJ 340000,,0 CAME 312000,,0 +AOJA 344000,,0 CAMG 317000,,0 +AOJE 342000,,0 CAMGE 315000,,0 +AOJG 347000,,0 CAML 311000,,0 +AOJGE 345000,,0 CAMLE 313000,,0 +AOJL 341000,,0 CAMN 316000,,0 +AOJLE 343000,,0 CHNSTS 716000,,0 SAIL +AOJN 346000,,0 CLKINT 717000,,0 SAIL +AOS 350000,,0 CLOSE 070000,,0 UUO +AOSA 354000,,0 CLRBFI 051440,,0 UUO +AOSE 352000,,0 CLRBFO 051500,,0 UUO +AOSG 357000,,0 COMMENT Pseudo-Op page 42 +AOSGE 355000,,0 CONI 700240,,0 I/O +AOSL 351000,,0 CONO 700200,,0 I/O +AOSLE 353000,,0 CONS 257000,,0 SAIL +AOSN 356000,,0 CONSO 700340,,0 I/O + 62 Appendix C FAIL + + + +CONSZ 700300,,0 I/O ENTER 077000,,0 UUO +CORE CALLI 11 UUO ENTRY Pseudo-Op page 33 +CORE2 CALLI 400015 SAIL EQV 444000,,0 +CREF Pseudo-Op page 44 EQVB 447000,,0 +CTLV CALLI 400001 SAIL EQVI 445000,,0 + EQVM 446000,,0 +DATAI 700040,,0 I/O EXCH 250000,,0 +DATAO 700140,,0 I/O EXIT CALLI 12 UUO +DATE CALLI 14 UUO EXTERNAL Pseudo-Op page 33 +DAYCNT CALLI 400100 SAIL +DDCHAN CALLI 400067 SAIL FAD 140000,,0 +DDTGT CALLI 5 UUO FADB 143000,,0 +DDTIN CALLI 1 UUO FADL 141000,,0 +DDTOUT CALLI 3 UUO FADM 142000,,0 +DDTRL CALLI 7 UUO FADR 144000,,0 +DDUPG 715140,,0 SAIL FADRB 147000,,0 +DEBREAK CALLI 400035 SAIL FADRI 145000,,0 +DEC Pseudo-Op page 37 FADRL 145000,,0 +DEFINE Pseudo-Op page 45 FADRM 146000,,0 +DEPHASE Pseudo-Op page 29 FBREAD 706000,,0 SAIL +DETSEG CALLI 400017 SAIL FBWAIT CALLI 400057 SAIL +DEVCHR CALLI 4 UUO FBWRT 707000,,0 SAIL +DEVNUM CALLI 400104 SAIL FDV 170000,,0 +DEVUSE CALLI 400051 SAIL FDVB 173000,,0 +DFAD 110000,,0 KI FDVL 171000,,0 +DFDV 113000,,0 KI FDVM 172000,,0 +DFMP 112000,,0 KI FDVR 174000,,0 +DFN 131000,,0 FDVRB 177000,,0 +DFSB 111000,,0 KI FDVRI 175000,,0 +DIAL CALLI 400117 SAIL FDVRL 175000,,0 +DISMISS CALLI 400024 SAIL FDVRM 176000,,0 +DIV 234000,,0 FIX 247000,,0 SAIL +DIVB 237000,,0 FIX 122000,,0 KI +DIVI 235000,,0 FIXR 126000,,0 KI +DIVM 236000,,0 FLTR 127000,,0 KI +DMOVE 120000,,0 KI FMP 160000,,0 +DMOVEM 124000,,0 KI FMPB 163000,,0 +DMOVN 121000,,0 KI FMPL 161000,,0 +DMOVNM 125000,,0 KI FMPM 162000,,0 +DPB 137000,,0 FMPR 164000,,0 +DPYCLR 701000,,0 SAIL FMPRB 167000,,0 +DPYOUT 703000,,0 SAIL FMPRI 165000,,0 +DPYPOS 702100,,0 SAIL FMPRL 165000,,0 +DPYSIZ 702140,,0 SAIL FMPRM 166000,,0 +DSKPPN CALLI 400071 SAIL FOR Pseudo-Op page 51 +DSKTIM CALLI 400072 SAIL FSB 150000,,0 + FSBB 153000,,0 +EIOTM CALLI 400005 SAIL FSBL 151000,,0 +END Pseudo-Op page 41 FSBM 152000,,0 + FAIL Appendix C 63 + + + +FSBR 154000,,0 HLROS 567000,,0 +FSBRB 157000,,0 HLRS 547000,,0 +FSBRI 155000,,0 HLRZ 554000,,0 +FSBRL 155000,,0 HLRZI 555000,,0 +FSBRM 156000,,0 HLRZM 556000,,0 +FSC 132000,,0 HLRZS 557000,,0 + HRL 504000,,0 +GDEFINE Pseudo-Op page 45 HRLE 534000,,0 +GDPTIM CALLI 400065 SAIL HRLEI 535000,,0 +GETCHR CALLI 6 UUO HRLEM 536000,,0 +GETLIN 051300,,0 SAIL HRLES 537000,,0 +GETLN CALLI 34 UUO HRLI 505000,,0 +GETNAM CALLI 400062 SAIL HRLM 506000,,0 +GETPPN CALLI 24 UUO HRLO 524000,,0 +GETPR2 CALLI 400053 SAIL HRLOI 525000,,0 +GETPRV CALLI 400115 SAIL HRLOM 526000,,0 +GETSEG CALLI 40 UUO HRLOS 527000,,0 +GETSTS 062000,,0 UUO HRLS 507000,,0 +GETTAB CALLI 41 UUO HRLZ 514000,,0 +GLOBAL Pseudo-Op page 33 HRLZI 515000,,0 + HRLZM 516000,,0 +HALT 254200,,0 HRLZS 517000,,0 +HISEG Pseudo-Op page 29 HRR 540000,,0 +HLL 500000,,0 HRRE 570000,,0 +HLLE 530000,,0 HRREI 571000,,0 +HLLEI 531000,,0 HRREM 572000,,0 +HLLEM 532000,,0 HRRES 573000,,0 +HLLES 533000,,0 HRRI 541000,,0 +HLLI 501000,,0 HRRM 542000,,0 +HLLM 502000,,0 HRRO 560000,,0 +HLLO 520000,,0 HRROI 561000,,0 +HLLOI 521000,,0 HRROM 562000,,0 +HLLOM 522000,,0 HRROS 563000,,0 +HLLOS 523000,,0 HRRS 543000,,0 +HLLS 503000,,0 HRRZ 550000,,0 +HLLZ 510000,,0 HRRZI 551000,,0 +HLLZI 511000,,0 HRRZM 552000,,0 +HLLZM 512000,,0 HRRZS 553000,,0 +HLLZS 513000,,0 +HLR 544000,,0 IBP 133000,,0 +HLRE 574000,,0 IDIV 230000,,0 +HLREI 575000,,0 IDIVB 233000,,0 +HLREM 576000,,0 IDIVI 231000,,0 +HLRES 577000,,0 IDIVM 232000,,0 +HLRI 545000,,0 IDPB 136000,,0 +HLRM 546000,,0 IENBW CALLI 400045 SAIL +HLRO 564000,,0 IFAVL Conditional page 55 +HLROI 565000,,0 IFDEF Conditional page 55 +HLROM 566000,,0 IFDIF Conditional page 55 + 64 Appendix C FAIL + + + +IFE Conditional page 54 IOPUSH 724000,,0 SAIL +IFG Conditional page 54 IOR 434000,,0 +IFGE Conditional page 54 IORB 437000,,0 +IFIDN Conditional page 55 IORI 435000,,0 +IFL Conditional page 54 IORM 436000,,0 +IFLE Conditional page 54 IOWD Pseudo-Op page 38 +IFMAC Conditional page 55 IWAIT CALLI 400040 SAIL +IFN Conditional page 54 IWKMSK 723100,,0 SAIL +IFNAVL Conditional page 55 +IFNDEF Conditional page 55 JBTSTS CALLI 400013 SAIL +IFNMAC Conditional page 55 JCRY 255300,,0 +IFNOP Conditional page 55 JCRY0 255200,,0 +IFOP Conditional page 55 JCRY1 255100,,0 +ILDB 134000,,0 JEN 254500,,0 +IMSKCL 722000,,0 SAIL JFCL 255000,,0 +IMSKCR 723240,,0 SAIL JFFO 243000,,0 +IMSKST 721000,,0 SAIL JFOV 255040,,0 +IMSTW 723040,,0 SAIL JOBRD CALLI 400050 SAIL +IMUL 220000,,0 JOV 255400,,0 +IMULB 223000,,0 JRA 267000,,0 +IMULI 221000,,0 JRST 254000,,0 +IMULM 222000,,0 JRSTF 254100,,0 +IN 056000,,0 UUO JSA 266000,,0 +INBUF 064000,,0 UUO JSP 265000,,0 +INCHRS 051100,,0 UUO JSR 264000,,0 +INCHRW 051000,,0 UUO JUMP 320000,,0 +INCHSL 051240,,0 UUO JUMPA 324000,,0 +INCHWL 051200,,0 UUO JUMPE 322000,,0 +INIT 041000,,0 UUO JUMPG 327000,,0 +INPUT 066000,,0 UUO JUMPGE 325000,,0 +INSKIP 051540,,0 SAIL JUMPL 321000,,0 +INTACM CALLI 400027 SAIL JUMPLE 323000,,0 +INTDEJ 723000,,0 SAIL JUMPN 326000,,0 +INTDMP 723140,,0 SAIL +INTEGER Pseudo-Op page 40 LALL Pseudo-Op page 43 +INTENB CALLI 400025 SAIL LDB 135000,,0 +INTENS CALLI 400030 SAIL LEYPOS 702300,,0 SAIL +INTERNAL Pseudo-Op page 33 LINK Pseudo-Op page 34 +INTGEN CALLI 400033 SAIL LINKEND Pseudo-Op page 34 +INTIIP CALLI 400031 SAIL LINKUP CALLI 400023 SAIL +INTIPI 723200,,0 SAIL LIOTM CALLI 400006 SAIL +INTIRQ CALLI 400032 SAIL LIST Pseudo-Op page 43 +INTJEN 723000,,0 SAIL LIT Pseudo-Op page 31 +INTMSK 720000,,0 SAIL LOC Pseudo-Op page 27 +INTORM CALLI 400026 SAIL LOCK CALLI 400076 SAIL +INTUUO 723000,,0 SAIL LOGIN CALLI 15 UUO +INWAIT 051600,,0 SAIL LOGOUT CALLI 17 UUO +IOPDL 726000,,0 SAIL LOOKUP 076000,,0 UUO +IOPOP 725000,,0 SAIL LSH 242000,,0 + FAIL Appendix C 65 + + + +LSHC 246000,,0 ORI 435000,,0 + ORM 436000,,0 +MAIL 710000,,0 SAIL OUT 057000,,0 UUO +MAP 257000,,0 KI OUTBUF 065000,,0 UUO +MOVE 200000,,0 OUTCHR 051040,,0 UUO +MOVEI 201000,,0 OUTFIV 051740,,0 SAIL +MOVEM 202000,,0 OUTPUT 067000,,0 UUO +MOVES 203000,,0 OUTSTR 051140,,0 UUO +MOVM 214000,,0 +MOVMI 215000,,0 PAGE Pseudo-Op page 44 +MOVMM 216000,,0 PEEK CALLI 33 UUO +MOVMS 217000,,0 PGACT 715040,,0 SAIL +MOVN 210000,,0 PGCLR 715100,,0 SAIL +MOVNI 211000,,0 PGINFO 715200,,0 SAIL +MOVNM 212000,,0 PGIOT 715000,,0 SAIL +MOVNS 213000,,0 PGSEL 715000,,0 SAIL +MOVS 204000,,0 PHASE Pseudo-Op page 29 +MOVSI 205000,,0 PJOB CALLI 30 UUO +MOVSM 206000,,0 PNAME CALLI 400007 SAIL +MOVSS 207000,,0 POINT Pseudo-Op page 38 +MSTIME CALLI 23 UUO POINTS 712000,,0 SAIL +MTAPE 072000,,0 UUO POP 262000,,0 +MUL 224000,,0 POPJ 263000,,0 +MULB 227000,,0 PORTAL 254040,,0 KI +MULI 225000,,0 PPACT 702040,,0 SAIL +MULM 226000,,0 PPHLD 702340,,0 SAIL + PPINFO 702240,,0 SAIL +NAMEIN CALLI 400043 SAIL PPIOT 702000,,0 SAIL +NOLIT Pseudo-Op page 44 PPREL 702200,,0 SAIL +NOSYM Pseudo-Op page 44 PPSEL 702000,,0 SAIL + PPSPY CALLI 400107 SAIL +OCT Pseudo-Op page 37 PRGEND Pseudo-Op page 41 +OPDEF Pseudo-Op page 32 PRINTS Pseudo-Op page 44 +OPEN 050000,,0 UUO PRINTX Pseudo-Op page 44 +OR 434000,,0 PTGETL 711540,,0 SAIL +ORB 437000,,0 PTIFRE 711100,,0 SAIL +ORCA 454000,,0 PTJOBX 711700,,0 SAIL +ORCAB 457000,,0 PTLOAD 711640,,0 SAIL +ORCAI 455000,,0 PTOCNT 711140,,0 SAIL +ORCAM 456000,,0 PTRD1S 711200,,0 SAIL +ORCB 470000,,0 PTRD1W 711240,,0 SAIL +ORCBB 473000,,0 PTRDS 711400,,0 SAIL +ORCBI 471000,,0 PTSETL 711600,,0 SAIL +ORCBM 472000,,0 PTWR1S 711300,,0 SAIL +ORCM 464000,,0 PTWR1W 711340,,0 SAIL +ORCMB 467000,,0 PTWRS7 711440,,0 SAIL +ORCMI 465000,,0 PTWRS9 711500,,0 SAIL +ORCMM 466000,,0 PTYGET 711000,,0 SAIL +ORG Pseudo-Op page 27 PTYREL 711040,,0 SAIL + 66 Appendix C FAIL + + + +PTYUUO 711000,,0 SAIL SETNAM CALLI 43 UUO +PURGE Pseudo-Op page 35 SETNM2 CALLI 400036 SAIL +PUSH 261000,,0 SETO 474000,,0 +PUSHJ 260000,,0 SETOB 477000,,0 +PZE 000000,,0 SETOI 475000,,0 + SETOM 476000,,0 +RADIX Pseudo-Op page 42 SETPOV CALLI 32 UUO +RADIX50 Pseudo-Op page 39 SETPR2 CALLI 400052 SAIL +REASSI CALLI 21 UUO SETPRO CALLI 400020 SAIL +RELEAS 071000,,0 UUO SETPRV CALLI 400066 SAIL +RELOC Pseudo-Op page 27 SETSTS 060000,,0 UUO +REMAP CALLI 37 UUO SETUWP CALLI 36 UUO +RENAME 055000,,0 UUO SETZ 400000,,0 +REPEAT Pseudo-Op page 54 SETZB 403000,,0 +RESCAN 051400,,0 UUO SETZI 401000,,0 +RESET CALLI 0 UUO SETZM 402000,,0 +RLEVEL CALLI 400054 SAIL SIXBIT Pseudo-Op page 39 +ROT 241000,,0 SKIP 330000,,0 +ROTC 245000,,0 SKIPA 334000,,0 +RUN CALLI 35 UUO SKIPE 332000,,0 +RUNMSK CALLI 400046 SAIL SKIPG 337000,,0 +RUNTIM CALLI 27 UUO SKIPGE 335000,,0 + SKIPL 331000,,0 +SEARCH Pseudo-Op page 36 SKIPLE 333000,,0 +SEGNAM CALLI 400037 SAIL SKIPN 336000,,0 +SEGNUM CALLI 400021 SAIL SKPHIM 710200,,0 SAIL +SEGSIZ CALLI 400022 SAIL SKPME 710140,,0 SAIL +SEND 710000,,0 SAIL SKPSEN 710240,,0 SAIL +SET Pseudo-Op page 28 SLEEP CALLI 31 UUO +SETA 424000,,0 SLEVEL CALLI 400044 SAIL +SETAB 427000,,0 SNEAKS CALLI 400064 SAIL +SETACT 051640,,0 SAIL SNEAKW CALLI 400063 SAIL +SETAI 425000,,0 SOJ 360000,,0 +SETAM 426000,,0 SOJA 364000,,0 +SETCA 450000,,0 SOJE 362000,,0 +SETCAB 453000,,0 SOJG 367000,,0 +SETCAI 451000,,0 SOJGE 365000,,0 +SETCAM 452000,,0 SOJL 361000,,0 +SETCM 460000,,0 SOJLE 363000,,0 +SETCMB 463000,,0 SOJN 366000,,0 +SETCMI 461000,,0 SOS 370000,,0 +SETCMM 462000,,0 SOSA 374000,,0 +SETCRD CALLI 400073 SAIL SOSE 372000,,0 +SETDDT CALLI 2 UUO SOSG 377000,,0 +SETLIN 051340,,0 SAIL SOSGE 375000,,0 +SETM 414000,,0 SOSL 371000,,0 +SETMB 417000,,0 SOSLE 373000,,0 +SETMI 415000,,0 SOSN 376000,,0 +SETMM 416000,,0 SPCWAR 043000,,0 SAIL + FAIL Appendix C 67 + + + +SPCWGO CALLI 400003 SAIL TMPCRD CALLI 400103 SAIL +SPWBUT CALLI 400000 SAIL TRC 640000,,0 +SRCV 710100,,0 SAIL TRCA 644000,,0 +STATO 061000,,0 UUO TRCE 642000,,0 +STATZ 063000,,0 UUO TRCN 646000,,0 +SUB 274000,,0 TRN 600000,,0 +SUBB 277000,,0 TRNA 604000,,0 +SUBI 275000,,0 TRNE 602000,,0 +SUBM 276000,,0 TRNN 606000,,0 +SUBTTL Pseudo-Op page 43 TRO 660000,,0 +SUPPRESS Pseudo-Op page 35 TROA 664000,,0 +SWAP CALLI 400004 SAIL TROE 662000,,0 +SWITCH CALLI 20 UUO TRON 666000,,0 + TRZ 620000,,0 +TDC 650000,,0 TRZA 624000,,0 +TDCA 654000,,0 TRZE 622000,,0 +TDCE 652000,,0 TRZN 626000,,0 +TDCN 656000,,0 TSC 651000,,0 +TDN 610000,,0 TSCA 655000,,0 +TDNA 614000,,0 TSCE 653000,,0 +TDNE 612000,,0 TSCN 657000,,0 +TDNN 616000,,0 TSN 611000,,0 +TDO 670000,,0 TSNA 615000,,0 +TDOA 674000,,0 TSNE 613000,,0 +TDOE 672000,,0 TSNN 617000,,0 +TDON 676000,,0 TSO 671000,,0 +TDZ 630000,,0 TSOA 675000,,0 +TDZA 634000,,0 TSOE 673000,,0 +TDZE 632000,,0 TSON 677000,,0 +TDZN 636000,,0 TSZ 631000,,0 +TIMER CALLI 22 UUO TSZA 635000,,0 +TITLE Pseudo-Op page 41 TSZE 633000,,0 +TLC 641000,,0 TSZN 637000,,0 +TLCA 645000,,0 TTCALL 051000,,0 UUO +TLCE 643000,,0 TTREAD 051700,,0 SAIL +TLCN 647000,,0 TTYIOS CALLI 400014 SAIL +TLN 601000,,0 TTYJOB CALLI 400113 SAIL +TLNA 605000,,0 TTYMES CALLI 400047 SAIL +TLNE 603000,,0 TTYSKP CALLI 400116 SAIL +TLNN 607000,,0 TTYUUO 051000,,0 UUO +TLO 661000,,0 TWOSEG Pseudo-Op page 29 +TLOA 665000,,0 +TLOE 663000,,0 UFA 130000,,0 +TLON 667000,,0 UFBCLR CALLI 400012 SAIL +TLZ 621000,,0 UFBERR CALLI 400060 SAIL +TLZA 625000,,0 UFBGET CALLI 400010 SAIL +TLZE 623000,,0 UFBGIV CALLI 400011 SAIL +TLZN 627000,,0 UFBPHY CALLI 400055 SAIL +TMPCOR CALLI 44 UUO UFBSKP CALLI 400056 SAIL + 68 Appendix C FAIL + + + +UGETF 073000,,0 UUO +UINBF 704000,,0 SAIL +UNIVERSAL Pseudo-Op page 36 +UNLOCK CALLI 400077 SAIL +UNPURE CALLI 400102 SAIL +UOUTBF 705000,,0 SAIL +UPGIOT 703000,,0 SAIL +UPGMVE 713000,,0 SAIL +UPGMVM 714000,,0 SAIL +USE Pseudo-Op page 28 +USETI 074000,,0 UUO +USETO 075000,,0 UUO +USKIP CALLI 400041 SAIL +UTPCLR CALLI 13 UUO +UUOSIM CALLI 400106 SAIL +UWAIT CALLI 400034 SAIL + +VAR Pseudo-Op page 31 +VDSMAP CALLI 400070 SAIL + +WAIT CALLI 10 UUO +WAKEME CALLI 400061 SAIL +WHO CALLI 400112 SAIL +WRCV 710040,,0 SAIL + +XALL Pseudo-Op page 43 +XCREF Pseudo-Op page 44 +XCT 256000,,0 +XGPUUO CALLI 400075 SAIL +XLIST Pseudo-Op page 43 +XLIST1 Pseudo-Op page 43 +XOR 430000,,0 +XORB 433000,,0 +XORI 431000,,0 +XORM 432000,,0 +XPUNGE Pseudo-Op page 35 +XWD Pseudo-Op page 38 + FAIL Appendix D 69 + + + Stanford Character Set + + +The Stanford Character Set is displayed in the following table. The +three-digit octal code for a character is composed of the number at +the left of its row plus the digit at the top of its column. For +example, the code for A is 100+1 or 101. + + 0 1 2 3 4 5 6 7 + 000 NUL        + 010  TAB LF VT FF CR   + 020         + 030         + 040 SP ! " # $ % & ' + 050 ( ) * + , - . / + 060 0 1 2 3 4 5 6 7 + 070 8 9 : ; < = > ? + 100 @ A B C D E F G + 110 H I J K L M N O + 120 P Q R S T U V W + 130 X Y Z [ \ ] ^ _ + 140 ` a b c d e f g + 150 h i j k l m n o + 160 p q r s t u v w + 170 x y z { | ALT } BS + + + NUL Null + TAB Horizontal Tab + LF Line Feed + VT Vertical Tab + FF Form Feed + CR Carriage Return + SP Space + ALT Altmode + BS Back Space + 70 Appendix E FAIL + + + Summary of Character Interpretations + + +The characters listed below have special meaning in the contexts +indicated. These interpretations do not apply when these characters +appear in text strings or in comments. + +000 NUL null ignored on input +001  down-arrow makes a symbol available in a lower + block +002  alpha +003  beta +004  logical and boolean AND +005  logical not boolean NOT +006  epsilon delimiter in FOR +007  pi +010  lambda +011 TAB tab same as space (040) +012 LF line feed line delimiter +013 VT vertical tab +014 FF form feed line delimiter; causes new listing + page +015 CR carriage return statement terminator +016  infinity +017  partial +020  containment delimiter in FOR +021  implication +022  set intersection +023  set union +024  for all +025  there exists +026  circle times arithmetic shift operator +027  double-arrow statement terminator; remainder of + line is interpreted as another + statement +030  underbar same as . (056) in identifiers +031  right-arrow same as backslash (134) +032  tilde same as up-arrow (136); illegal as + the delimiter in ASCIZ, COMMENT, etc. +033  not equal boolean XOR +034  less or equal +035  greater or equal same as not equal (033) +036  equivalence +037  logical or boolean OR +040 SP space general delimiter +041 ! exclamation same as logical or (037) +042 " double quote delimits ascii constants +043 # number sign declares a variable; illegal as the + delimiter in ASCIZ, COMMENT, etc. +044 $ dollar sign may be used in identifiers + FAIL Appendix E 71 + + +045 % percent may be used in identifiers +046 & ampersand same as logical and (004) +047 ' close single quote delimits sixbit constants +050 ( left parenthesis encloses macro arguments, + expressions, and index fields +051 ) right parenthesis see left parenthesis (050) +052 * asterisk integer multiply +053 + plus integer addition +054 , comma general argument separator +055 - minus integer subtraction or negation +056 . point may be used in identifiers, floating + point numbers, or predefined symbol +057 / slash integer division +060 0 digits used to form number, parts of + identifiers +... +071 9 +072 : colon used to define labels; illegal as the + delimiter in ASCIZ, COMMENT, etc. +073 ; semicolon forces remainder of line to be a + comment +074 < left broket delimits complex atoms; same as left + brace (173) to the macro processor +075 = equal denotes decimal number; alternate to + left-arrow (137) in assignment + statements +076 > right broket see left broket (074) +077 ? question mark same as down-arrow (001) +100 @ at-sign sets indirect bit in instructions; + precedes concatenation character in + FOR +101 A upper case letters used for identifiers; B and E are + special in numbers; E is special in + FOR +... +132 Z +133 [ left bracket delimits literals, value part of + OPDEF, size in ARRAY, PPN in .LOAD +134 \ backslash evaluate a macro argument and + converts the result to a digit string +135 ] right bracket see left bracket (133) +136 ^ up-arrow moves a symbol definition to an outer + block; makes a symbol INTERNAL or + EXTERNAL; illegal as the delimiter in + ASCIZ, COMMENT, etc. +137 _ left-arrow denotes assignment statement; + arithmetic FOR; illegal as the + delimiter in ASCIZ, COMMENT, etc. +140 ` open single quote same as at-sign (100) + 72 Appendix E FAIL + + +141 a lower case letters same as upper case letters, except in + text constants +... +172 z +173 { left brace delimits macro bodies, IF-bodies, + FOR-bodies, macro arguments +174 | vertical bar +175 ALT altmode same as right brace (176) +176 } right brace see left brace (173) +177 BS backspace illegal in input + FAIL 73 + + Index + +$. 17, 26, 29 Character FOR 52 + character interpretations 70 +. 17, 26, 29 close single quote 14, 28 +.FNAM1 18 colon 4, 15, 18, 39, 42, 44 +.FNAM2 18 comma 4, 6, 28, 33, 37, 38, 39, +.INSERT 42 40, 45, 48, 53, 56 +.LIBRARY 34 comma-comma 5 +.LOAD 34 Command Language 56 + comment 7 +absolute 10, 17, 59 COMMENT pseudo-op 42 +AC 4 COMPIL 57 +Accumulator Field 4 Complex Atoms 24 +Address Field 4 concatenation character 46, 51 +apostrophe 14, 28 Conditional Assembly 54 +Arguments in Macro Calls 48 Constants 11 +Arguments in Macro constants optimization 25 + Definitions 46 containment character 51 +Arithmetic FOR 53 control-meta-line feed 57 +ARRAY 40 control-Z 57 +ASCID 39 CREF 1, 44, 57 +ASCII character set 69 CREF pseudo-op 44 +Ascii Constants 13 Cross-Reference Listing 44, 57 +ASCII pseudo-op 39 +ASCIZ 39 DDT 1, 18, 22, 32, 39, 41 +Assembler Control Statements 41 DEC pseudo-op 37 +assignment statement 16 Decimal Numbers 12 +ASUPPRESS 35 decimal point 12 +at-sign 4, 51 DEFINE pseudo-op 45 +atomic statement 5, 7, 24 defined 10, 14, 15 +atoms 7, 9 DEPHASE 29 +available 11, 19, 21 Destination of Assembled + Code 27 +backslash 49 device code 6 +backward reference 14 Device Selection Field 6 +BEGIN 32 dollar sign 9 +BEND 32 dollar-point 17, 26, 29 +blank 45 double quote 13 +block 11 double-arrow 7 +block number 32 down-arrow 6, 21, 23, 55 +BLOCK pseudo-op 40 +Block Structure 19 END 41 +braces 45, 48, 52 Entering Data 37 +brackets 24, 40, 48 ENTRY 23, 33 +brokets 5, 24, 45, 48 entry blocks 23, 33 +BYTE 37 entry point 23 +byte pointer 38 epsilon 52 + equal sign 12, 16, 18, 42 +carriage return 7, 41, 43, 46, Expressions 7 + 48 EXTERNAL 23, 33 + 74 Index FAIL + + + +external symbols 23, 33 internal symbols 33 + IOWD 38 +fixup 15 IRP 51 +Floating-Point Numbers 12 IRPC 51 +FOR 51 +FOR-body 51 Labels 15 +form feed 44 LALL 43 +formal arguments 51 left-arrow 4, 16, 18, 23, 39, +forward reference 14, 41 42, 44, 53 +Full-Word Expression 5 library 23 + library search mode 23 +GDEFINE pseudo-op 45 line feed 7, 42, 46 +GLOBAL pseudo-op 33 LINK 34 +global symbols 22 Linkage with Separately + Assembled Programs 22 +Half-Killed Symbols 18 LINKEND 34 +Halfword Statement 5 LIST 43 +hardware input-output Listing Control Statements 43 + instruction 6 LIT 31, 41 +hardware instruction 3, 60 literal-label 26, 35, 36 +high segment 29 literals 24, 25, 31, 41 +HISEG 29 loader 1, 8, 10, 15, 22, 23, + 29, 33, 34, 35, 39, 40, 59 +Identifiers 9 LOC 27 +IF-body 54 local symbols 22 +IFAVL 55 location counter 15, 17, 27, 28 +IFDEF 55 +IFDIF 55 machine instruction 3, 60 +IFE 54 Macro Bodies 46 +IFG 54 Macro Calls 47 +IFGE 54 Macros 45 +IFIDN 55 multiple definition 16 +IFL 54 multiple location counters 28 +IFLE 54 +IFMAC 55 NOLIT 44 +IFN 54 NOSYM 44 +IFNAVL 55 null argument 48 +IFNDEF 55 null statement 2 +IFNMAC 55 number sign 4, 17, 31, 39, 40, +IFNOP 55 42, 44 +IFOP 55 Numbers 11 +Index Field 5 Numeric IFs 54 +indirect bit 4 +Indirect Field 4 OCT 37 +Input-Output Instruction octal 11 + Statement 6 Opcode Field 3 +Instruction Statement 3 OPDEF 32 +INTEGER 40 opdefs 32 +INTERNAL 23, 33 open single quote 4 + FAIL Index 75 + + + +operator 7 Statement Termination 7 +ORG 27 Statements 2 + String FOR 51 +PAGE pseudo-op 44 SUBTTL 43 +parameter 16 SUPPRESS 35 +parentheses 5, 7, 37, 45, 46, suppress bit 36 + 48, 51, 56 symbol 10 +percent sign 9 Symbol IFs 55 +PHASE 29 Symbol Modifiers 32 +point 9, 17, 26, 29 Symbols 14 +POINT pseudo-op 38 +Polish fixup 8 tab 45 +Predefined Opcodes 60 Text IFs 55 +PRGEND 41 text statements 39 +PRINTS 44 tilde 4, 19, 39, 42, 44 +PRINTX 44 TITLE 41 +program 22 Truncated Expression 6 +Pseudo-Ops 27 two-segment program 29 +PURGE 35 TWOSEG 29 + +question mark 21 unavailable 11, 20 + undefined 10, 59 +RADIX 42 underbar 9 +RADIX50 39 UNIVERSAL 36 +RAID 1, 18, 22, 32, 39, 41 universal program 36 +range specifier 51 universal symbols 36 +reference 14 unrelocatable 10, 59 +RELOC 27 up-arrow 4, 19, 23, 34, 39, 42, +relocatable 10, 16, 17, 59 44 +relocation constant 59 USASCII 13 +relocation factor 59 USE 28 +REPEAT 54 user-defined opcode 32 +reserved identifiers 10 UUO 1, 3, 6, 60 +Reserving Space for Data 40 +right-arrow 49 Values 10 +RPG 57 VAR 31, 41 + Variables 17, 31, 40, 41 +SEARCH 36 +segment 29 XALL 43 +semicolon 7, 41, 43, 48 XCREF 44 +SET 28 XLIST 43 +Simple Numbers 11 XLIST1 43 +sixbit 13, 39 XPUNGE 35 +Sixbit Constants 13 XWD 38 +SIXBIT pseudo-op 39 +slash 56 +special characters 70 +Stanford Character Set 69 +starting address 41, 42 + \ No newline at end of file diff --git a/doc/sail/fail.pub b/doc/sail/fail.pub new file mode 100644 index 00000000..65d7f2c0 --- /dev/null +++ b/doc/sail/fail.pub @@ -0,0 +1,4332 @@ +.FONT 1 "BASL30" +.FONT 2 "BASI30" +.FONT 3 "BASB30" +.FONT 4 "25fg" +.FONT 5 "20fg" +.FONT 6 "25vr" +.FONT 7 "66vr"; +.TURN ON "" FOR "%" +.TURN ON "" +.IF XCRIBL THEN START +. PAGE FRAME 59 HIGH 80 WIDE; << was 53, but bag-chomping PUB won't allow>> +. ODDLEFTBORDER_EVENLEFTBORDER_216; +. AT "ffi"  IF THISFONT  3 THEN "" ELSE "ffi" ; +. AT "ffl"  IF THISFONT  3 THEN "" ELSE "ffl" ; +. AT "ff"  IF THISFONT  3 THEN "" ELSE "ff" ; +. AT "fi"  IF THISFONT  3 THEN "" ELSE "fi" ; +. AT "fl"  IF THISFONT  3 THEN "" ELSE "fl" ; +. END + +.BEGIN +.<> +.<> + +.PORTION COVER +.NEXT PAGE <<hmmpph>> +.BEGIN TURN ON "_{" +.BEGIN NOFILL PLACE HEADING +_7FAIL1 +.END +.GROUP SKIP 35 +.BEGIN CENTER +Sponsored by +Advanced Research Projects Agency +ARPA Order No. 2494 +.END +.END + .PORTION TITLEPAGE +.SKIP TO COLUMN 1 +.VARIABLE FOO +.BEGIN TURN ON "_{" +.TURN ON "^"; +.BEGIN NOFILL <<PLACE HEADING>> +3Stanford Artificial Intelligence Laboratory{MONTH} {YEAR} +Memo AIM-226 + +Computer Science Department +Report STAN-CS-74-407 +.END +.GROUP SKIP 2; IF XCRIBL THEN GROUP SKIP 2; +_7FAIL1 +.BEGIN GROUP SKIP 1 NOFILL; +_by +.GROUP SKIP 1 +_F. H. G. Wright II +_R. E. Gorin +.GROUP SKIP 3 +_3COMPUTER SCIENCE DEPARTMENT* +_3STANFORD UNIVERSITY* +.END +.GROUP SKIP 2 +3Abstract1 + +This is a reference manual for FAIL, a fast, one-pass assembler for PDP-10 +and PDP-6 machine language. FAIL statements, +pseudo-operations, macros, and conditional assembly features are +described. Although FAIL uses substantially more main memory than +MACRO-10, it assembles typical programs about five times faster. +FAIL assembles the entire Stanford time-sharing +operating system (two million characters) in less than four minutes of CPU +time on a KA-10 processor. +FAIL permits an ALGOL-style block structure which provides a way of +localizing the usage of some symbols to certain parts of the program, +such that the same symbol name can be used to mean different things +in different blocks. + +.GROUP SKIP 2; IF XCRIBL THEN GROUP SKIP 2; +6This manual was supported by the Advanced Research +Projects Agency of the Department of Defense under Contract +No. DAHC15-73-C-0435. +The views and conclusions contained in this document should not be +interpreted as necessarily representing the official policies, either +expressed or implied, of the Advanced Research Projects Agency or the +U.S. Government. + +This manual supersedes SAILON-26. + +Available from the National Technical Information +Service, Springfield, Virginia 22151.* +.END +.END + .next page +.PORTION ACKS +.GROUP SKIP 20 +3Acknowledgments1 +.SKIP 1 +.IF XCRIBL THEN START +The original version of FAIL and the original manual (SAILON-26) were +written by Phil Petit in 1967. Various additions and modifications +were subsequently contributed by William Weiher, Fred Wright, Ralph +Gorin, and others. This manual was prepared using PUB, the document +compiler created by Larry Tesler, using the Xerox Graphics Printer, +with fonts by Brian Harvey. Brian McCune and Les Earnest reviewed +the manuscript and made helpful suggestions. Cover picture: United +Press International. +.END; +.IF XCRIBL THEN START +The original version of FAIL and the original manual (SAILON-26) were +written by Phil Petit in 1967. Various additions and modifications +were subsequently contributed by William Weiher, Fred Wright, Ralph +Gorin, and others. This manual was prepared using PUB, the document +compiler created by Larry Tesler. Brian McCune and Les Earnest reviewed +the manuscript and made helpful suggestions. +.END + +.TITLE AREA HEADING LINES 1 TO 3; +.EVEN HEADING (3{FOO_PAGE;FOO},3{SECNAME},3FAIL) +.ODD HEADING (3FAIL,3{SECNAME},3{FOO_PAGE;FOO}) + .MACRO SCRIPTS  TURN ON "^[]&"  +.MACRO GREEKS  TURN ON "{\#_"  +.MACRO FORMAT  SCRIPTS ; GREEKS  +.MACRO FAC FILL ADJUST COMPACT CRSPACE GREEKS +.MACRO BV  BEGIN VERBATIM  +.MACRO SUB(IND)  INDENT 0,IND; TABS IND+1; + +.COMMENT leave space for a full page figure; +.MACRO FIG(NAME)  SKIP TO COLUMN 1 +.GROUP SKIP 20 +_NAME GOES HERE +.NEXT PAGE  + +.!SPACES _ "#####################################################" ; +.!HYPHENS _ "--------------------------------------------------------------" ; +.MACRO FRACTION(NUM, DEN) ;  +.TURN ON "{^[]&#" ; +. N _ "NUM" ; D _ "DEN" ; +. LN _ LENGTH(N) ; LD _ LENGTH(D) ; +. IF LN > LD THEN START D _ !SPACES[1 TO (LN-LD) DIV 2] & D ; LMAX _ LN END ; +. IF LD > LN THEN START N _ !SPACES[1 TO (LD-LN) DIV 2] & N ; LMAX _ LD END ; +. "^[{N}]&[{D}]&[{(!HYPHENS[1 TO LMAX])}]" ; TURN OFF ;  + .COMMENT Section numbering and table of contents; + +.COUNT PAGE FROM 0 to 999; + +.COUNT SECTION +.MACRO S(NAME)  SECNAME_SSNAME_NULL +.BEGIN NEXT SECTION; TURN ON "{#" +.INDENT 0,8 +.SECNAME_"NAME" +.SUB3!_SECTION! +.NEXT PAGE +.SEND CONTENTS  SKIP +.IF LINES<4 THEN SKIP TO COLUMN 1; +{SECTION!}.##NAME#{PAGE} +.  +3{SECTION!}.##NAME {SKIP +.END  + +.COUNT SUBSECTION IN SECTION PRINTING "!.1" +.MACRO SS(NAME)  SSNAME_NULL +.BEGIN IF LINES<20 THEN SKIP TO COLUMN 1 ELSE SKIP 3 +.NEXT SUBSECTION; TURN ON "{#" +.INDENT 5,13 +3{SUBSECTION!}##NAME{SKIP 1 +.SSNAME_"NAME" +.SUB3!_SUBSECTION! +.SEND CONTENTS  +.IF LINES<4 THEN SKIP TO COLUMN 1; +{SKIP 1}6{SUBSECTION!}##NAME\#{PAGE} +.  +.END  + +.COUNT SUB2 IN SUBSECTION PRINTING "!.1" +.MACRO SSS(NAME)  +.IF LINES<8 THEN SKIP TO COLUMN 1 ELSE SKIP 1; NEXT SUB2 +.BEGIN TURN ON "{#" +.INDENT 10,18 +3{SUB2!}##NAME{SKIP +.SUB3!_SUB2! +.IF SUB2<10 THEN START +.IF XCRIBL THEN SEND CONTENTS  +(11){SUB2!}###NAME\(78)#{PAGE} +. ; +.IF XCRIBL THEN SEND CONTENTS  +(11){SUB2!}###NAME\ . #{PAGE} +. ; +.END ELSE START +.IF XCRIBL THEN SEND CONTENTS  +(11){SUB2!}##NAME\(78)#{PAGE} +. ; +.IF XCRIBL THEN SEND CONTENTS  +(11){SUB2!}##NAME\ . #{PAGE} +. ; +.END +.END  + +.COUNT SUB3 IN SUB2 PRINTING "!.1" +.MACRO SSSS(NAME)  +.IF LINES<8 THEN SKIP TO COLUMN 1 ELSE SKIP 1; NEXT SUB3 +.BEGIN TURN ON "{#" +.INDENT 15,26 +3{SUB3!}##NAME{SKIP +.IF SUB3<10 THEN START +.IF XCRIBL THEN SEND CONTENTS  +(18){SUB3!}###NAME\(78)#{PAGE} +. ; +.IF XCRIBL THEN SEND CONTENTS  +(18){SUB3!}###NAME\ . #{PAGE} +. ; +.END ELSE START +.IF XCRIBL THEN SEND CONTENTS  +(18){SUB3!}##NAME\(78)#{PAGE} +. ; +.IF XCRIBL THEN SEND CONTENTS  +(18){SUB3!}##NAME\ . #{PAGE} +. ; +.END +.END  + +.COMMENT Call this macro once at the end of the document; +.MACRO BACK  +.COUNT PAGE PRINTING "i" +.TURN ON "{" +.TITLE AREA HEADING LINES 1 TO 3; +.EVERY HEADING(3FAIL,,3i) +.FORMAT +.IF XCRIBL THEN START +. NOFILL +. END +.IF XCRIBL THEN START +. FILL NOJUST CRBREAK +. END +.SECNAME_SSNAME_NULL +.PORTION CONTENTS +.INDENT 0,18,10 PREFACE 0 TABS 18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63 +.SKIP TO COLUMN 1 +_3Table of Contents +.SKIP 2 +SectionPage1 +.TITLE AREA HEADING LINES 1 TO 3; +.EVEN HEADING(3{PAGE!},3Table of Contents,3FAIL) +.ODD HEADING(3FAIL,3Table of Contents,3{PAGE!}) +.RECEIVE +.  + +.COMMENT AISEC SENDS A SECTION NAME, BUT NO NUMBER, TO THE CONTENTS; +.COMMENT YOU MUST BE ON THE RIGHT PAGE! ; + +.MACRO AISEC(NAME) +.BEGIN TURN ON "{#" +.SEND CONTENTS  SKIP +NAME\#{PAGE} +.  +.END  + +.MACRO ASSEC(NAME) +.BEGIN TURN ON "{#" +.SEND CONTENTS  SKIP +6{APPNUM!}####NAME\#{PAGE} +.  +.END  + + .COMMENT Indexing; + +.AT "%<" TERM ">"  TURN ON "{" +TERM{ SEND INDEX  }<TERM>{PAGE}{ +.TURN OFF; + +.AT "~<" TERM ">"  TURN ON "{" +{ SEND INDEX  }<TERM>{PAGE}{ +.TURN OFF; + +.MACRO SENDIT(TERM)  TURN ON "{";SEND INDEX  }<TERM>{PAGE}{;TURN OFF; +.MACRO SI(SIN)  SENDIT |SIN|; S |SIN|  +.MACRO SSI(SIN)  SENDIT |SIN|; SS |SIN|  +.MACRO SSSI(SIN)  SENDIT |SIN|; SSS |SIN|  +.MACRO SSSSI(SIN)  SENDIT |SIN|; SSSS |SIN|  + +.COMMENT Call this macro where you want the index.; +.MACRO INDMAC (NAME,HDG1,HDG2,HDG3)  +.BEGIN NOJUST +.PREFACE 0; INDENT 0,5 +.PREVPG_LETTER_PHR_CURRENT_NULL +.SECNAME_"HDG1" +.NEXT PAGE +.AISEC(Index) +.AREA TEXT LINES 5 TO 53 IN 2 COLUMNS 7 APART +.TURN ON "{#_" +.AT "<" TERM ">" PGNO ""  +.IF ^"TERM"=PHR THEN START +. IF "PGNO" neq PREVPG THEN CURRENT_CURRENT&", PGNO" +. PREVPG_"PGNO" END +.ELSE START +.CURRENT +. IF LETTER=^"TERM"[1] THEN BREAK ELSE SKIP 1 +.CURRENT_"TERM#PGNO" +. PHR_^"TERM"; LETTER_^"TERM"[1]; PREVPG_"PGNO"; +. END  +.PORTION NAME +.PLACE HEADING +.<<SKIP 1>> +_3HDG2 +.PLACE TEXT +.TITLE AREA HEADING LINES 1 TO 3; +.EVEN HEADING(3{PAGE},3Index,3FAIL) +.ODD HEADING(3FAIL,3Index,3{PAGE}) +.SECNAME_"HDG3" +.RECEIVE "<>" +.CURRENT +. END  + +.MACRO IND  +.TITLE AREA HEADING LINES 1 TO 3; +.EVEN HEADING (3{PAGE},,3FAIL) +.ODD HEADING (3FAIL,,3{PAGE}) +.INDMAC (INDEX,,Index,Index)  + .COUNT APPNUM PRINTING "A" + +.MACRO APPMAC (NAME,TTITLE)  +.TITLE AREA HEADING LINES 1 TO 3; +.EVEN HEADING (3{PAGE},3{SECNAME},3FAIL) +.ODD HEADING (3FAIL,3{SECNAME},3{PAGE}) +.NEXT APPNUM  + +.MACRO APPNDX1 (NAME,TTITLE)  +.APPMAC (NAME,TTITLE) +.NEXT PAGE +.AISEC(Appendices) +.ASSEC(TTITLE) +.SECNAME_("Appendix "&APPNUM!) +.PORTION NAME +.TITLE AREA HEADING LINES 1 TO 3; +.PLACE HEADING +.PLACE TEXT +.TURN ON "_" +_3%<TTITLE>* +.TURN OFF +.SKIP 1  + +.MACRO APPNDX3 (NAME,TTITLE)  +.APPMAC (NAME,TTITLE) +.NEXT PAGE +.ASSEC(TTITLE) +.SECNAME_("Appendix "&APPNUM!) +.PORTION NAME +.TITLE AREA HEADING LINES 1 TO 3; +.PLACE HEADING +.PLACE TEXT +.TURN ON "_" +_3TTITLE* +.TURN OFF +.SKIP 1  + +.AT "$$" LABEL ":"  DEF("LABEL"&"P",) ; DEF("LABEL"&"S",SUB3!)  +.AT "$" LABEL ":"  DEF("LABEL"&"P",) ; DEF("LABEL"&"S",APPNUM!)  +.MACRO DEF(L,E)  L:E;  +.AT "%%" LABEL ";"  REF("LABEL"&"S","LABEL"&"P")  +.AT "%" LABEL ";"  AREF("LABEL"&"S","LABEL"&"P")  +.AT "%~" LABEL ";"  PREF("LABEL"&"P")  + +.MACRO REF(S,P)  +.TURN ON "{" +section {[7]S}, page {[2]P ;TURN OFF  + +.MACRO PREF(P)  +.TURN ON "{" +page {[2]P ;TURN OFF  + +.MACRO AREF(S,P)  +.TURN ON "{" +appendix {[2]S}, page {[2]P ;TURN OFF  + +.MACRO PSEUD1 (X)  +$$X: +.TURN ON "{" +.SENDIT "X" +.TURN OFF; + +.MACRO PSEUDO (X)  +.SSS "X" +.PSEUD1 "X"  + +.AT "$<" X ">"  TURN ON "{" +X{PSEUD1 "X"; TURN OFF; + +.MACRO PSEUDX (X)  +$$X: +.TURN ON "{" +.SENDIT (X pseudo-op) +.TURN OFF; + +.MACRO PSEUDOX (X)  +.SSS "X" +.PSEUDX "X"  + +.MACRO PENT(X)  +X\Pseudo-Op\%~X; +. + +.MACRO CDENT(X)  +X\Conditional\%~X; +. + .MACRO EXAMPLE (X)  BEGIN TURN ON "{" GROUP + + Example{("X")}: +.TURN OFF; VERBATIM; SELECT 4; IF XCRIBL THEN NARROW 8;  + +.AT PAGEMARK BREAK +.INSERT CONTENTS + .PORTION BODY +.S Introduction + +FAIL is an assembly program for PDP-6 and PDP-10 machine language. +FAIL operates in one pass, which means that it reads the input file +only once; the linking %<loader> program (LOADER or LINK-10) +completes any aspects of the assembly which could not be done by +FAIL. The efficiencies which have been employed in its +coding make FAIL five times faster than MACRO-10, the DEC assembler. + +FAIL processes source program +statements by translating mnemonic operation codes into the binary +codes needed in machine instructions, relating symbols to numeric +values, and assigning relocatable or absolute core addresses for program +instructions and data. The assembler can prepare a listing of the +program which includes a representation of the assembled code. Also, the +assembler notifies the user of any errors detected during +the assembly. + +FAIL has a powerful macro processor which allows the programmer to +create new language elements to perform special functions for each +programming job. + +FAIL permits an ALGOL-style block structure which provides a way of +localizing the usage of symbols to particular parts of the program, +called 2blocks*. Block structure allows the same symbol name to be +given different meanings in different blocks. + +The reader of this manual should be familiar with the PDP-10 instruction +set, which is described in both 2DECsystem-10 System Reference Manual* +and 2PDP-10 and PDP-6 Instruction Sets* (SAILON-71). + +Other documents of interest: +.BEGIN NOFILL TURN ON "\"; TABS 12; + +Frost, M.\2%<UUO> Manual*, SAILON-55.3, December 1973 +Petit, P.\2%<RAID>*, SAILON-58, September 1969 +Harvey, B.\2Monitor Command Manual*, SAILON-54.3, December 1973 + +The following are available in the 2DECsystem-10 Software Notebooks*: +.IF XCRIBL THEN TABS 8; + +\2Cross-Reference Listing: %<CREF>*, June 1973 +\2%<DDT>-10 Programmer's Reference Manual*, June 1973 +\2Linking Loader Programmer's Reference Manual*, August 1971 +\2LINK-10 Programmer's Reference Manual*, May 1973 +\2MACRO-10 Assembler Programmer's Reference Manual*, June 1972 +\2DECsystem-10 Operating System Commands*, February 1974 +\2DECsystem-10 Monitor Calls*, June 1973 +.end + .S Basic Syntax + +This section describes the basic components of a typical FAIL source +program. It covers the normal mode of turning each source statement +into a binary word. Pseudo-operations and macro features are +explained in later sections. + +This section is organized in a 2top-down* manner: the +complex constructs, statements, are described first, followed by +a description of the language elements from which statements are +built, etc. + +2Statements* are the +elements of the language that generate machine code and other +binary data. A statement is generally free format, consisting +of several 2fields*, each of which is an 2expression*. Expressions +are composed of 2atoms* and 2operators*. The operators signify +typical arithmetic and boolean operations, such as addition or logical +OR. Atoms are either 2constants*, 2symbols*, or 2complex atoms*. + .SSI Statements + +2Statements* are the syntactic units which actually produce code. +The statements that are described in this section usually generate +one word of code. A 2%<null statement>*, which consists of no +expressions, generates no code. A typical statement consists +of one or more expressions separated by spaces, commas, or parentheses. + +There are five kinds of statements: 2instruction statements*, +2full-word expressions*, 2truncated expressions*, 2halfword +statements*, and 2input-output statements*. The most common of these is +the instruction statement. +Also, there are +pseudo-operations (called 2pseudo-ops*), which are described in %%PSEUDO;. +A pseudo-op may direct FAIL to perform an assembler control function or +to assemble data in a particular format. + + + +The examples that are given below are intended to +be as general as possible. In most cases, many of the indicated fields +may be omitted. + +.SSSI Instruction Statement + +.BEGIN VERBATIM SELECT 4; + OPCODE AC,@ADDRESS(INDEX) ;COMMENT +.END + +An 2instruction statement* is used to assemble one +machine instruction. The typical format is shown above; +the parts will be explained later. Any portion of the instruction +statement may be omitted. The comment field is not +really part of the instruction statement, but may be included on the +same line for clarity and conciseness. The parts may appear in any +order, except that the opcode field, if present, must be the first +expression. Also, each part must be syntactically identifiable. The +form above is hallowed by years of use; departure from it will render +a program less intelligible to other readers. + +If the opcode field is omitted, all other fields will be recognized +and handled normally, unless the address expression is the first +field seen, in which case the statement is treated as a full-word +expression. + +.SSSSI Opcode Field + +$$OPCODE: + +If the first atom appearing in the statement (excluding labels and +assignment statements) is an identifier, it will be looked up in the +opcode table to see if it is an opcode, in which case the opcode +alone will be returned as the first expression, overriding any +significance it may have as a symbol. An 2opcode* (short for +~<hardware instruction> +2operation code*) may be a %<machine instruction> mnemonic, a %<UUO> mnemonic, +a pseudo-op, or a user-defined opcode (see OPDEF in +%%OPDEF;). An opcode, if it appears, must be the first +thing in the statement (except for labels or assignment statements). + +If an opcode is a pseudo-op mnemonic, FAIL will process that particular +pseudo-op as appropriate. The syntax of pseudo-ops differs from that of +normal statements. + +If an opcode is a machine instruction, %<UUO> mnemonic, or user +opcode, its value is placed in the binary word being assembled. +These opcodes are treated as having full-word values, but in most +cases only the 2opcode field* (bits 0-8) is non-zero. A few machine +instructions, and many UUO mnemonics, specify values for other +fields as well. The values of the other fields (except the address field, +if non-zero) can be modified by subsequent operands. + +Whenever an opcode is recognized, it is immediately +processed without regard for any arithmetic operator that might +follow. Although FAIL tries to allow a symbol and opcode with the +same name to co-exist, it cannot resolve the ambiguity in all +circumstances; it is a good idea to avoid conflicts as much as +possible. FAIL will 2not* recognize an identifier as an opcode if +the identifier is followed by any one of the characters +%<colon> (4:*), %<left-arrow> (4_*), %<up-arrow> (4^*), +%<tilde> (4~*), or %<number sign> (4#*). + +.SSSS "Accumulator (AC) Field" + +~<Accumulator Field> +If an expression appears in a statement followed by exactly one +%<comma>, its value will be placed in the 2accumulator field* of the +current word (bits 9-12), possibly replacing the accumulator field +indicated by an opcode. This expression must be defined, available, +and absolute (some of these terms are defined in %%VALSEC;). +For the sake of brevity, "accumulator" is often written as "%<AC>". + + +.SSSS "Indirect (4@*) Field" + +~<Indirect Field> +If one or more at-sign characters (4@*) appear as part of a +statement, the 2%<indirect bit>* (bit 13) will be turned on in the +word being assembled. The %<at-sign> may appear anywhere in the +statement as long as it is not embedded inside symbols or +expressions. The character %<open single quote> (4`*) may be used +as an alternative to at-sign. + +.SSSSI Address Field + +If in a statement an expression appears which is neither enclosed in +parentheses nor followed by a comma, it is considered to be an 2address +expression* unless it is the first expression (including the opcode) +in the statement. Address expressions are truncated to 18 bits and +placed in the 2address field* (bits 18-35) of the word being assembled. + +Only one address field may be assembled per statement; an attempt to +assemble more than one is an error. This error sometimes occurs because +an undefined opcode is used, which is treated as an expression in +case it is really an undefined symbol. This error can also occur when +an opcode includes an address field and the user attempts to supply another +address field. + +.SSSSI Index Field +$$INDEXF: + +If an expression is enclosed in %<parentheses> in a statement, the +right half of its value will be ORed into the left half of the +current word. Also, if no address field has appeared yet, the left +half of its value will be ORed into the right half of the current +word. The expression must be defined, available, and absolute. +This construct is most commonly used for specifying the 2index field* +(bits 14-17). + +Sometimes, this construct is used for putting left-half quantities in +address fields, or as a general halfword-swapping operation. Often +when this is done, the expression in parentheses must be enclosed in +%<brokets> (< and >) to force its evaluation as an %<atomic +statement>; see %%ATSTAT;. If the left half of the expression is +non-zero, the word will be flagged as containing an address field, +making another address field illegal. + +.Example s + +MOVEI 2,-1(6) ;assembles 201106 777777 +MOVSI 1,(<JRST>) ;assembles 205040 254000 + +.END + +.SSSI Halfword Statement + +.BEGIN VERBATIM SELECT 4; + EXPR,,@ADDRESS(INDEX) ;COMMENT +.END + +If an expression is followed by 2%<comma-comma>* (4,,*), it will be +placed in the left halfword of the current location, and FAIL +will continue to process an address field, index field, and indirect +field. This +is more convenient than the XWD pseudo-op for assembling halfwords since +it allows the entire effective address to be specified in the +usual way. The only restriction is to beware of possible +interpretation of the first symbol as an opcode. If the expression +followed by the comma-comma is not the first thing assembled in the +word, the warning message 2Illegal ,,* will be printed, although the +statement will assemble correctly. This prevents confusion if an +extra comma is typed after an accumulator field. + +.SSSI Full-Word Expression + +.BEGIN VERBATIM SELECT 4; + EXPR ;COMMENT +.END + +When the first expression in a statement is not preceded by a comma +and is not an opcode, FAIL assumes that the expression is a +2full-word expression*. The entire 36-bit value of the +expression is placed in the current word. The full-word expression +is the only ordinary statement (i.e., not a pseudo-op) that assembles +a single expression with a full 36-bit value. Full-word expressions +are treated as address fields for purposes of the multiple address +field error. + +If a full-word expression contains any undefined symbols, unavailable +symbols, or strange relocation constants, the +entire word will be updated with the value of the expression when it +becomes known. This will obliterate any index, indirect, or accumulator field +appearing after the expression on the line. If the expression +actually has only an 18-bit value, this can be fixed by prefixing +the expression with a comma (i.e., by using a truncated expression). +If a full-word value is actually needed and the +problem is not just one of availability (curable by the use of GLOBAL or +%<down-arrow> (4*); see +%%AVAIL;), it may be necessary to use an explicit expression to set +the accumulator, index, and indirect fields. + +.SSSI Truncated Expression + +.BEGIN VERBATIM SELECT 4; + ,EXPR ;COMMENT +.END + +If a %<comma> appears before any expression in a statement, it +flags the current word as containing data in order to force a subsequent +expression to be treated as an address field even when it is the +only expression in the statement. This can be used to form an 18-bit +2truncated expression*. Note that a statement consisting of a +single comma will assemble a zero word. + +.SSSI Input-Output Instruction Statement + +.BEGIN VERBATIM SELECT 4; + OPCODE DEV,@ADDRESS(INDEX) ;COMMENT +.END + +An 2input-output instruction statement* is used to assemble one +hardware I/O instruction. Most parts are the same as in an +instruction statement, except that a 2device selection field* +appears instead of an accumulator field. Also, the opcode portion must +be one of the PDP-10 2%<hardware input-output +instruction>s* (e.g., DATAO). Note that hardware I/O instructions +are 2not* related to operating system %<UUO>s. + +.SSSSI Device Selection Field + +The same syntax and restrictions that apply to an accumulator field +apply also to the 2device selection field*. The value of the +device selection field is placed in bits 3-9 of the current word. +This value is often called the 2%<device code>*. + +.SSS Comment Field + +$$COMM:~<comment> + +When FAIL's statement processor encounters a %<carriage return> or +%<semicolon> (4;*), all characters up to the next line feed or form feed +are completely ignored except for listing and certain macro processor +functions (see %%MACRO;). Upon reaching the line feed or form feed, +the comment is terminated. Usually, this is used to insert a relevant +comment at the end of a line of code. + +.SSSI Statement Termination + +A statement is terminated by a comment or by any of the characters +%<line feed>, %<double-arrow> (4*), right bracket (4]*), or right broket +(4>*) when not processing a comment. When a statement is terminated, +the value of the current word (if any) is returned. A statement +returns no value at all if no expressions appear in it or if it +is a pseudo-op which assembles no code. Terminating a statement +with one of the bracket characters often has special significance, as +in atomic statements or literals. Double-arrow can be used for +assembling more than one statement on a line, but will not terminate +a comment. + .SSI Expressions + +2Expressions* are built from 2%<atoms>* connected by +2%<operator>s* which allow the specification of values based upon +arithmetic and logical functions of several values. These +expressions follow essentially the same rules as conventional +programming languages. Each operand in an expression may be an atom, +an %<atomic statement>, +or an expression in %<parentheses>, preceded by any number of unary +operators. If parentheses are used, the expression inside the +parentheses is evaluated before performing any operations using that +operand. If a unary operator appears, its function will be evaluated +before any operations using that operand (but after the expression in +parentheses, if parentheses are used). Multiple unary operators are +evaluated from right to left, so 4-1* is processed as 4-(1)*. +Finally, these operands can be connected with binary infix operators +whose order of evaluation is determined by their assigned precedence +levels (highest first) and is left-to-right for operators of the +same level. An expression may, of course, consist of a single +operand (i.e., atom) with no operators at all. + +Surrounding an entire expression with parentheses sometimes signifies +an index field (see %%INDEXF;). All arithmetic is integer or boolean; +no type conversion is done for floating-point operands. + +.BEGIN GROUP +The following is a list of the available operators and their +precedence levels: + +.VERBATIM SELECT 4; + + Symbol Meaning Precedence Level + + binary operators + + + Addition 1 + - Subtraction 1 + * Multiplication 2 + / Division 2 +  Remainder from Division 2 + & Logical AND 3 +  Logical AND 3 + ! Logical OR 3 +  Logical OR 3 +  Exclusive OR 3 +  Exclusive OR 3 +  Logical Left-Shift 4 + + unary operators + + - Negation (two's complement) 5 +  Logical NOT (one's complement) 5 + | Absolute Value 5 +  JFFO (bit number of the first + 1 in the binary representation + of the argument) 5 + +.END + +If an expression contains any undefined values, its own value is +undefined. If an expression is used in a context where undefined values are +legal, FAIL retains a structure describing the evaluation needed, +called a 2%<Polish fixup>* for its similarity to Polish arithmetic +notation, in order to complete the evaluation when the unknowns +become defined. As soon as all values in the expression are defined, +a fixup will be output (to the %<loader>) to correct the value (or the +value will be corrected directly in the case of a literal). If the +expression is not completely defined by the end of the assembly (due +to external references or errors), the Polish structure is sent to +the loader for evaluation at load time. In other words, the right +thing usually happens with a partially undefined expression as long as +it is legal in the context where it is used. + +Expressions may also begin with any number of labels or assignment +statements, which have no effect on the value of the expression. + +.BEGIN NOFILL + + Examples +.SELECT 4; + + FOO2 ;value of FOO shifted left 2 bits + (BAR-1)-2 ;value of BAR-1 shifted right 2 bits + (A+2)*B + -(A+2)*-B ;same value as above + <A+2>*B ;another way (The symbol A must + ;be defined and available. See + ;Atomic Statements, %%ATSTAT;) + =60*=60 + "A"-40 + [0]-1 ;even literals can appear in expressions + FOO:BAR_1 105 ;the value of this expression is 105 + ;(labels and assignment statements have no + ;effect on the value of the expression) + 1 ;value is 43 (bit 35 is the leftmost 1) + 4 ;value is 41 + -1 ;value is 0 (bit 0, the sign bit, is 1) + 0 ;value is 44 (no bits are 1) + 7/3 ;value is 2 + 65 ;value is 1 + +.END + +2Note:* the operators 4*, 4*, and 4|* are new. They require +a modification to the loader to handle additional Polish operators. +Unless this modification has been made, do not attempt to use these +operators where the value of their arguments is undefined. + .SSI Atoms + +An 2atom* is the most basic syntactic element. An atom is either +a 2symbol* or a 2constant*. There are also 2complex atoms* +which are not really atoms at all, but which can be used in the +same way as atoms in forming expressions. Every atom represents a value. + +.SSSI Identifiers + +2Identifiers* are very basic syntactic elements. They have many +different uses, all of which involve referring to something by a +convenient symbolic name. The uses of identifiers will be covered as +the various applications arise. Identifiers may be defined either by +the programmer or by FAIL. + +The characters legal in an identifier are letters, digits, and the +four characters %<dollar sign> (4$*), +%<percent sign> (4%*), +%<point> (4.*), and %<underbar> (4*). An identifier is any +non-null string of characters from this set, delimited by characters +not from this set, except that the first character of an identifier +must not be a digit. Only the first six characters of an identifier +are significant, and upper and lower case letters are treated as +equivalent. Thus "4FOOBAR*" and "4foobarbletch*" are equivalent +identifiers. Also, "4*" is considered equivalent to "4.*", so, for +example, "4A7*" and "4A.7*" are equivalent identifiers. + +Certain identifiers have special meaning in FAIL, and cannot be used +except with their own special meanings. Some of these 2%<reserved +identifiers>* are +IFAVL, IFDEF, IFDIF, IFE, IFG, IFGE, IFIDN, IFL, IFLE, IFMAC, IFN, +IFNAVL, IFNDEF, IFNMAC, IFNOP, IFOP, IOWD, 4.*INSERT, +4.*FNAM1, 4.*FNAM2, 4.*CPU4.*, "4.*", and "4$.*". + .SSSI Values +$$VALSEC: + +Most of the normal assembly process consists of translating text +strings into their corresponding binary 2values*. The main +transformation happens when the atomic elements are converted to +their binary representations; these are combined by binary operations +into more complex constructs. + +Often the final 36-bit value of an atom depends upon information not +available at the time the atom is seen. This value may become known +when a later part of the program is assembled, or it may not be known +until the program is actually loaded. Consequently, up until the +final loading of a program into a core image, its representation must +be a slightly expanded form of simple binary so that the steps +necessary to complete the calculation of all binary values can be +adequately described. Partially defined values are commonly used in +writing FAIL programs; several mechanisms exist to enable FAIL (and +the %<loader>) to handle such values correctly. The full impact +of forward references and relocatable values is discussed in %VALAPP;. + +Some of the different kinds of values that often occur in FAIL are +distinguished by particular names: 2relocatable*, 2absolute*, +2defined*, 2undefined*, 2available*, and 2unavailable*. The +definitions that +follow involve symbols and block structure to some extent. Refer to +%%SYMBOLP;, and %%BLOCKS;, for further elucidation. + +A value that depends on where the program is when it is loaded +in core is called 2%<relocatable>*. Relocatable values occur +most frequently when some location in the program or in the data +is referred to. Values that do not depend on where the program is +located are called 2%<absolute>* or 2%<unrelocatable>*. An example +of an absolute value is a constant. Another example of an unrelocatable +value is the length of a table (that is, the difference between two +relocatable values). + +A 2%<symbol>* is an identifier that has a value. +A symbol is 2%<defined>* when a value is assigned to it. A symbol +can be referenced before it is defined, that is, when the value of +the symbol is 2%<undefined>*. FAIL makes sure that the right thing happens +when the value becomes defined as long as an undefined value is legal +in the particular context where it is used. + +A symbol that is defined is said to be 2%<available>* +(after the point of definition) in the %<block> where it is defined. When +another (lower) block is entered, such a symbol becomes 2%<unavailable>* +unless the programmer has taken steps to force the availability of that +symbol in lower blocks. + .SSSI Constants + +2Constants* are the simplest forms of atoms; their values do not +depend on context or previous operations (with the exception of the +radix for interpretation of numbers). Constants are absolute, i.e., +independent of where the program is loaded. A constant may be +one of several types of numerical or text constants. In addition to +the atomic constants described here, there are various data entry +pseudo-ops described in %%DATAE;. + +.SENDIT Numbers + +.SSSSI Simple Numbers + +A 2simple number* consists of a string of digits, interpreted as a number +in the current radix. Since the radix is initialized to 8, simple +numbers are usually interpreted as 2%<octal>* by default. In this +case, the accumulation is done by logical shifting, so the number is +considered unsigned. If the radix is anything other than 8, the +accumulation is done by multiplication, and the sign bit cannot be +set (but a negative number can be entered as an expression). +The current radix can be set with the RADIX pseudo-op (see +%%RADIX;). + +.Example s + + 1743 + 2 +.END + +.SSSSI Decimal Numbers + +2Decimal numbers* provide a way of entering decimal information +regardless of the current radix. A decimal number is a simple number +preceded by an %<equal sign> (4=*). + +.Example s + + =100 assembles as: 000000000144 + =69 000000000105 +.END + +.SSSSI Scaled Numbers + +A simple number or decimal number may be followed by the letter +"4B*" and a scale factor. The scale factor may be any atom that is +defined and absolute. Any simple numbers that appear in the scale +factor will be interpreted as decimal, regardless of the current +radix. The value of the scale factor specifies the low-order bit +position of the number in the word. That is, the number preceding +the 4B* is shifted left logically a number of bit positions equal +to 35 (decimal) minus the scale factor. + +.Example s + + 254B8 assembles as: 254000000000 + 1B33 000000000004 + 22B18 000011000000 + 22B<17+1> 000011000000 + 10B37 000000000002 + =10B27 000000005000 +.END + +.SSSSI Floating-Point Numbers + +Numbers may also be entered in standard floating-point notation, in +which case they will be converted to PDP-10 single-precision +floating-point format. Floating-point numbers are always interpreted +in decimal regardless of the current radix. Note that any arithmetic +performed by FAIL on numbers is always integer arithmetic, even if +the operands are floating-point numbers. + +A 2floating-point number* consists of two strings of digits, separated +by a %<decimal point> and followed by an optional scale factor. The +digit strings before and after the decimal point represent the +integer and fraction parts of the floating-point number, +respectively. The scale factor is the letter "4E*", an optional minus +sign, and one or two digits. The number following the "4E*" +specifies a power of ten by which the number will be +multiplied. + +Although the fraction part of the number may be omitted, it is +probably better to include the redundant 40* to avoid a possible +future conflict that could arise if FAIL were modified to allow a +decimal point following a digit string to signify a decimal number. + + +.Example s + + 10.7E1 ;equivalent to 107.0 + 9.973 + 0.13 + 10. ;better to write this as 10.0 + 1.86E05 + 31.4159E-1 + 69E1 ;presently equivalent to 690.0 +.END + +.SSSSI Ascii Constants + +Constants may also be specified as the ascii value of a character +or string of characters. The ascii value of a character is its 7-bit +code in the Stanford Character Set, a modified form of the %<USASCII> +code (see %SCS;). An 2ascii constant* is written as a string +of characters not containing a %<double quote> (4"*), enclosed with +double quotes, e.g, 4"Foo"*. If the string is null, i.e., 4""*, +the resulting value will be zero. If the string contains exactly one +character the resulting value will be the ascii value of that +character. If the string contains more than one character, each +additional character will shift the total left 7 bits and add its own +value, much as an octal number is accumulated. This results in +packing characters into right-justified 7-bit bytes. Only the +low-order 36 bits of the total are used, so if more than 5 +characters appear in the string, only the last 5 characters and the +low-order bit of the sixth-from-last character will affect the value. + +This right-justified form is not the standard way of +packing text for addressing with byte instructions, but is intended +mainly for small immediate operands, etc. Text pseudo-ops (described +in %%TEXT;) are used to store text in the +usual left-justified format in multiple words. + +.Example s + + "A" ;101 octal + "^C" ;27503 + "foobar" ;337576130362 +.END + +.SSSSI Sixbit Constants +Another character code that is frequently used is %<sixbit>. +It is a modified version of ascii code which uses only 6, +instead of 7, bits in order to pack 6 characters into a word rather +than 5. + +The basic ascii to sixbit transformation consists of +subtracting 40 (octal) from the ascii code, which maps ascii 40-137 +(all the printing characters of 64-character ASCII) into the desired +0-77. Since the 140-177 range consists mostly of lower-case versions of the +100-137 characters, a better transformation also maps this range to +40-77. The method used by FAIL is to copy the 100 bit into the 40 +bit and set the 100 bit to 0. +The inverse transformation is accomplished by adding 40 to each sixbit character. + +2Sixbit constants* can be specified in FAIL in the same way as ascii +constants, except that %<close single quote>s (%<apostrophe>s) +(4'*) should be used instead of +double quotes. Naturally, if more than one character appears in the +string, the shifting will be 6 bits at a time instead of 7, and the +last 6 characters of the string will always be completely +significant. Again, a pseudo-op is available (see %%TEXT;) to pack +longer strings into multiple words. + +.Example s + + 'a' ;41 + 'DSK ' ;446353000000 + 'gronker' ;625756534562 +.END + .SSSI Symbols +$$SYMBOLP: + +Symbols are one of the most important features provided by an +assembler. One capability provided by symbols is the ability to +abbreviate a complex expression with a single identifier. Another is +to represent an assembly parameter, so that its value can be +changed at the symbol definition only, without having to modify the +places where the parameter is used. A third use is to represent +values which are difficult for the programmer to calculate, such as +values dependent upon exactly where certain parts of the program are +stored. + +A 2symbol* is an identifier which at some point in the program (or +possibly in an external program) is assigned a value which will +be associated with that identifier whenever it is used in a context +where symbols are recognized (see %%OPCODE;, and %%MCALLS;, for +discussion of possible conflicts with opcodes or macros). The point +at which a value is assigned to a symbol is said to be the point +where it is 2%<defined>*. + +In most circumstances, a symbol may be used to stand for a value +either before or after it is defined. A symbol is said to be 2referenced* +when it is used to stand for a value. If this %<reference> occurs +earlier in the source file(s) than the definition, it is said to be a +2%<forward reference>*; if the reference follows the definition, +it is said to be a 2%<backward reference>*. +Backward references can be handled fairly easily, by merely replacing +the symbol by its known value. However, forward references create +some complication since FAIL does not know the value of the symbol until +later in the file. + +Two-pass assemblers avoid the forward reference problem by +assembling the program twice. On the first pass the assembler +calculates the value for each symbol; on the second pass these known +values are used when the corresponding symbols are referenced. +This method probably has the smaller storage +requirements, but it requires more cpu time since +the entire source file is scanned twice. + +FAIL uses the one-pass approach to save +execution time (at the expense of increasing the storage +requirements). In this method, each forward reference +assembles an incomplete word, but sufficient information +is included in the binary file to enable the %<loader> to complete the assembly. +Part of the necessary mechanism exists in the loader anyway in +order to handle externally defined symbols, which must be treated as +forward references even by a two-pass assembler. Information placed +in the binary file to update the value of an incompletely +assembled word is referred to as a 2%<fixup>*. + +Because of the problem of forward references in a one-pass assembler, +the meaning of "%<defined>" as used in this manual is not "defined +somewhere within the program", but rather "defined in the program +before the place being considered". In this sense a symbol is not +considered to be "defined" at the time of a forward reference, even +if it is defined later in the program. + +A symbol may be defined in one of four ways. It may be defined as a +label, as a parameter, or as a variable, or it may be a predefined +symbol. These types of symbols are discussed in the following +subsections. + +.SSSSI Labels +$$LABELS: + +Labels are the most common type of symbol. They are used as +symbolic references to locations in the program. Labels help to keep such +references independent of the exact placement of those parts of the +program in the core image. The value of a label is calculated +automatically by FAIL, so that the programmer need not keep careful +account of the exact numeric locations of all parts of his program. + +A 2label* is defined by simply writing an identifier followed by a +%<colon> (4:*) at the beginning of any expression being scanned. +This will normally define the symbol as equal to the 2%<location counter>*, +i.e., the location where the next word will be assembled. +However, in some circumstances involving the use of +literals (%%LITERAL;) or the PHASE pseudo-op (%%PHASE;), +the value of the label may differ from the location counter. +The value assigned to +a label is usually relocatable because the location +counter is initialized to relocatable zero, but it may be absolute. + +Although labels may occur at the beginning of any expression, +they almost always occur at +the beginning of a line. This convention improves the readability of +programs by keeping labels in a place where they are easily +recognized. + +In order to detect possible conflicts in label usage, FAIL does not +allow any label to be defined more than once. (However, FAIL +block structure allows a label to be redefined in different blocks; +see %%BLOCKS;.) +Once a symbol has been +defined as a label, it cannot be redefined; a symbol cannot be +defined as a label if it has any previous definition. An attempt to +do either of these things will result in a 2%<multiple definition>* +error message, and the new definition will not take effect. + +.Example s + +LOOP: JRST LOOP ;points to itself +FOO: ;labels the location of the next instruction +.END + .SSSS "Parameters (Assignment Statements)" + +~<parameter> +A 2parameter* is a symbol that is given an arbitrary 38-bit value +by an %<assignment statement>. Actually, the final value is 36 +bits, but since either 18-bit halfword may be %<relocatable> two more +bits are included in the representation of the value. The basic format of an +2assignment statement* is an identifier followed by a %<left-arrow> (4_*) +followed by an expression. The 38-bit value of the expression, which +must be defined, will be given to the specified symbol. An %<equal sign> (4=*) +may also be used as an alternative to left-arrow to allow partial +compatibility with other assemblers, but if the first atom +after the 4=* begins with another 4=* to indicate a decimal number, at +least one space should separate the two to distinguish them from ==, +which has a different function (see %%HFKIL;). + +As with labels, any +number of assignment statements may appear at the beginning of any +expression, but they are normally written as separate +statements for improved readability. In its full generality, an +assignment statement may define more than one symbol by beginning +with several symbol names, each followed by a left-arrow, and finally +followed by the expression, whose value will be given to all symbols +mentioned. + +Unlike labels, parameters may be redefined as often as desired. Once +a parameter has been defined, each reference to it will use the +value in effect at the time of that reference +(i.e., as of the last assignment). The +value appearing in the symbol table in the binary output file will be the +last value assigned. The value used for forward references (i.e., +before the first definition) will be that of the first assignment. +Note that this is an incompatibility with two-pass assemblers, which +would instead use the last value assigned during pass one. + +.Example s + + FOO_105 + BAR_=69 + BLETCH_BARF_LOSS_FOO+BAR*3 + garp= =97 ;note space between = is necessary +.END + .SSSSI Variables + +2Variables* are symbols whose values are the addresses of cells +automatically allocated by FAIL for data storage. A variable is +usually created by immediately following a symbol reference with a +%<number sign> (4#*). The symbol, which must not be previously defined, +is declared to be a variable and will have its location assigned +when the location of the variables area is known (see %%VAR;). +The symbol is not +defined at this point; it cannot be used in +contexts which do not allow forward references. However, +it can be used as any other +forward-referenced symbol; the number sign need not be used with +more than one occurrence of the symbol. Similar effects can also be +obtained with the INTEGER and ARRAY pseudo-ops (see %%INTEGER;). + +.Example s + + SETZM FOO# + MOVEI A,BAR#-1 +.END + +.SSSS Predefined Symbols +$$PDFSYM: + +2Predefined symbols* are available for use in 2all* circumstances +where symbols are recognized. + +.SENDIT "."; SENDIT "$." +Two predefined symbols, %<point> (4.*) and %<dollar-point> (4$.*) +refer to the 2%<location counter>*, which is +the location where the next complete word will be stored. +In the absence of special circumstances, "4.*" and "4$.*" have the +same value; "4.*" is the one usually used. These values are usually +%<relocatable> but may be %<absolute>; see %%ORG;. + +The reason for having two of these symbols is that some features of FAIL +create complications affecting the location counter; see the discussion +of literals (%%LITERAL;) and the PHASE pseudo-op (%%PHASE;). + +.Example s + + JRST .-1 + JUMPN T,$.+3 +.END + +$$FNAM1: $$FNAM2: +.BEGIN TURN ON "{" +.SENDIT ".FNAM1" +.SENDIT ".FNAM2" +.END; +The predefined symbols, 4.*FNAM1 and 4.*FNAM2 refer to the +name of the current source file. The +value of 4.*FNAM1 is the 36-bit binary representation of the source file +name; 4.*FNAM2 has the value of the source file extension (or second file name). + +$$CPU: +.BEGIN TURN ON "{" +.SENDIT ".CPU." +.END; +The predefined symbol 4.*CPU4.* denotes the type of processor that FAIL is +running on. This symbol has the value 1 for the PDP-6, 2 for the KA-10, and +3 for the KI-10. + +Two other symbols, 4.*INSERT and IOWD, are predefined. These symbols +cause actions like pseudo ops so their descriptions appear later; +see %%INSERT;, and %%IOWD;, respectively. + .SSSSI Half-Killed Symbols +$$HFKIL: + +Symbols are included in the binary output file to aid +debugging and to allow the loader to link several programs together. +The debuggers (%<RAID> and %<DDT>) have symbolic disassemblers which +take binary words and interpret their fields to display mnemonic opcodes, +addresses, accumulator names, etc. Sometimes, the user wants to prevent particular +symbol names from being displayed by the symbolic disassembler. Symbols +that have been marked to prevent their display are called 2half-killed*. +Half-killing a symbol is useful for parameters which might incorrectly be +displayed as core addresses or accumulator names. Half-killing is also handy +for labels in code that is relocated at runtime. +The debuggers do recognize half-killed symbols when they are input. + +FAIL treats half-killed symbols precisely the same as other symbols, except, +when the symbol is written in the binary output file, a bit +is set to inform the debugger that the symbol is half-killed. + +In FAIL, half-killing a symbol is +accomplished by doubling the defining character (e.g., 4::*, 4__*, or +4==*). In the case of 4==*, the two equal signs must not be separated +by any spaces, because this is how the ambiguity is resolved with respect +to the other use of %<equal sign> to indicate decimal numbers. A parameter will +be half-killed if any one of its definitions specifies half-killing. +~<colon>~<left-arrow> + +.Example s + +ERRFLG__100 ;the usual way of writing it +IOFLG _ _ 2000 ;this can have spaces anywhere +BUFSIZ == 100 ;but this can't (100 is octal) +BUFSIZ = = 100 ;since this means decimal, not half-killed +BUFSIZ === 100 ;this is unambiguous (100 is decimal) +BUFSIZ == = 100 ;(100 is decimal) +LOOP:: SKIPN A,(B) ;a half-killed label +.END + .SSSSI Block Structure + +$$BLOCKS: + +Block structure is +very basic to the usage of symbols. This section may be skipped if +the reader does not plan to use block structure. The one thing to +remember is that in the absence of block structure any symbol which +is 2defined* is also 2%<available>*. + +FAIL 2block structure* provides a way of +localizing the usage of symbols to particular parts of the program, +called 2blocks*. Block structure allows the same symbol name to be +given different meanings in different blocks. +The block structure used in FAIL is similar to that of ALGOL, +but is somewhat less restrictive. + +A program is +considered to be a block whose name is the same as the program name +(set by the TITLE statement; see %%TITLE;). Each block may contain +any number of inner blocks, but the depth of nesting may not exceed +17 (decimal). A definition of a symbol, a user-defined opcode (see +%%OPDEF;), or a macro (see %%MACROS;) applies only within the scope +of the outermost block in which it is defined. The scope of a +block includes the scope of each block it contains, unless the +symbol (etc.) in question is defined again in an inner block, in +which case the more local definition takes precedence within the +scope of that block. A block is delimited by a BEGIN +statement and a BEND statement (see %%BEND;). + +Features exist in FAIL for controlling the block level +of symbols. If a symbol, when defined as a label or parameter, is +preceded by an %<up-arrow> (4^*), it will be treated +as if it were +defined in the next-outer block. If a double up-arrow (4^^*) is used, +the symbol will be treated as though it were defined in the outermost +block of the program. +These features are most commonly used for such things as making +subroutine entry points available to outer blocks when the subroutines +themselves are contained in blocks. In simple cases, this could +be done by beginning the block after the entry label(s) or even +after some of the code, but this makes reading the routine more +difficult and hence the up-arrow construct is preferred. Tilde~<tilde> +(4~*) may be used instead of up-arrow. + +Here are some examples of symbol usage, with and without block +structure. Both examples generate the same code: + +.BEGIN VERBATIM GROUP SELECT 4; + + FOO1: JRST FOO1 FOO1: JRST FOO1 + JRST FOO2 JRST FOO2 + JRST FOO3 JRST FOO3 + JRST FOO5 JRST FOO5 + BEGIN + FOO2: JRST FOO1 FOO22: JRST FOO1 + ^FOO3: JRST FOO2 FOO3: JRST FOO22 + JRST FOO3 JRST FOO3 + BEGIN + JRST FOO1 JRST FOO13 + ^^FOO5: JRST FOO2 FOO5: JRST FOO22 + JRST FOO3 JRST FOO3 + FOO1: JRST FOO4 FOO13: JRST FOO4 + BEND + ^FOO4: JRST FOO4 FOO4: JRST FOO4 + BEND + FOO2: JRST FOO4 FOO2: JRST FOO4 + +.END + +A complication arises with FAIL block structure due to the absence of +the ALGOL requirement that all identifiers be declared at block entry +time. FAIL allows forward references, yet does not require any +declaration of symbols other than their defining occurrences. +Hence, FAIL cannot decide whether to use an existing +outer-block version of a symbol or to make a forward reference to a +more local definition that may occur later. + +$$AVAIL: +To resolve this ambiguity, FAIL always considers +a symbol reference to be a forward reference when the symbol has not been +defined in the current block, even if it has been defined in some +outer block. If no other definition is given by the time the block ends, +then the outer-block definition is used to resolve +the forward reference. While in the inner block in this situation, +the outer-block symbol is still said to be 2defined*, but it is also +said to be 2%<unavailable>*. Thus block structure forces many +references to be forward references, even when they would not +otherwise be such. + +Macros and user-defined opcodes cannot be forward-referenced. Such +symbols are always available; references to them will +use their outer-block definitions. + +.Example s + +FOO: MOVSI 1,-62 ;FOO is defined as a label +BAR: CAME 2,ZOT(1) ;so is BAR + AOBJN 1,BAR ;BAR is referenced +BEGIN ;FOO and BAR are defined, but now unavailable +LOSS: MOVEI 1,0 ;LOSS is defined + JRST LOSS ;a backward reference to LOSS + JRST FOO ;this is treated as a forward reference +FOO: HRRM 6,LOSS ;so it can reference this definition +BAZ: JRST BAR ;this is treated as a forward reference + JRST FOO ;this refers to this block's FOO +BEND ;The outer-block definition of BAR becomes + ;available at this BEND. A fixup is emitted + ;to fix the reference to BAR at BAZ + +.END + +Many contexts do not accept forward references (e.g., accumulator and index +fields). In these +contexts unavailable symbols cannot be used, even if they +are defined. Therefore, FAIL provides two mechanisms for +forcing defined symbols to be 2%<available>* to lower blocks. +One is the down-arrow mechanism, which is used at +the defining occurrence of the symbol, and the other is the +GLOBAL pseudo-op (see %%GLOBAL;), which is used in the referencing block. + +The %<down-arrow> mechanism is the more commonly used method, since +this problem is most often associated with particular symbols (accumulator +names, assembly parameters, etc.). +Preceding the symbol name in a label or assignment statement with a +down-arrow (4*) causes that symbol to remain +available whenever inner blocks are entered. Usually it is dangerous +to redefine such symbols locally, since any forward references will +have incorrectly referred to the outer-block definition. +Consequently a warning message is printed in this case, but if no +forward references are made to the local version, it will assemble +correctly. However, if the redefinition of a down-arrowed parameter +is effective at its original block level (possibly via ^ or ^^), +FAIL will change the original definition without complaint. +This allows redefinition of global parameters from inner blocks. +A %<question mark> (4?*) may be used instead of down-arrow. + +.Example s + +A_1 ;some accumulator (AC) definitions +B_2 +FOO__=69 ;and a parameter +BEGIN + ADD B,A ;this is illegal because AC + ;symbols must be available + MOVE A,B ;but this is legal since A is available + ;by  +A_5 ;this will produce a message and is too + ;late to affect the instruction above +B_6 ;this is legal and will fix up the MOVE + ;to be MOVE 1,6 + MOVE A,B ;whereas this will be MOVE 5,6 +^FOO__105 ;this is legal since it is "aimed" at the + ;FOO in the outer block +BEND + +.END + +There are further details in %%BLOCKP;, and %%GLOBAL;, about the block structure +pseudo-ops BEGIN, BEND, and GLOBAL. + .SSSSI Linkage with Separately Assembled Programs + +It is sometimes desirable to have a program which is assembled in +several parts, either to save reassembling the entire program for +each change or because the program is written in a mixture of +languages. Even with a single assembly it is usually necessary to +use some of the job data area symbols, and sometimes symbols from +the debuggers +(%<RAID> or %<DDT>), all of which are reached through the linking %<loader>. In +this context, the word 2%<program>* refers to the result of one +assembly or compilation, and thus a core image may contain several +programs. + +To allow reasonable communication between these programs, the loader +allows symbol definitions to be passed between programs. For this +purpose, symbols are divided into two classes, %<local symbols> +and %<global symbols>. (There is no relation between the GLOBAL pseudo-op +and the global symbols discussed here.) + +Symbols are normally considered 2local*, which means that they will not be +available outside their own program and may be defined in more +than one program without conflict. 2Global symbols*, however, are +available to all programs and hence must not have conflicting +definitions within the set of programs to be loaded. The easiest way +to declare a symbol to be global is to follow some occurrence of the +symbol by an %<up-arrow>. This flags the symbol as a global without +specifying whether it is defined in this program or another program, +since FAIL will have figured that out by the end of the assembly. +Undefined globals (2%<external symbols>*) will have appropriate +fixup information +passed to the loader for resolution when the defining programs are +loaded. Globals may also be declared with the %<EXTERNAL> (%%EXTERNAL;) +and %<INTERNAL> (%%INTERNAL;) pseudo-ops. + +Declaring a symbol global forces its scope to the outermost block in +the same way as does a double up-arrow. Therefore, if a symbol is +defined and declared global in an inner block, there must not be a +conflicting definition in an outer block. + +$$LIBM: +One other related feature is the library mechanism. A 2%<library>* +is a file that contains a set of utility programs. Each program in the library +may be loaded independent of the others, depending on whether +it is required by the programs that have been +loaded thus far. To implement this, there is associated with each program in +the library (in one or more 2%<entry blocks>*) a list of certain +global 2%<entry point>s* defined in that program. In most cases +these are the names of the routines contained in the program. When +the %<loader> is in 2%<library search mode>*, it loads only those +programs for which at least one of the entry points corresponds to an +existing unsatisfied global request (external symbol). Only +those programs actually needed are loaded from the library; the +rest are ignored. The %<ENTRY> pseudo-op (%%ENTRY;) is used to +declare symbols to be entry points which will be available to a library +search. + +.SSSS Symbols and Arrows + +This is a brief restatement of the ways that identifiers are used +as symbols in conjunction with arrows.~<up-arrow>~<down-arrow>~<left-arrow> + +.Example s + +^SYM: ;SYM is available at the next-outer block +^^BOL__10 ;BOL is half killed and available at the + ;outermost block +^^ZOT= =69 ;ZOT is available at the outermost block +A^_7 ;A is global and available to lower blocks +FOO^: ;FOO is global and defined here (internal), + ;available at the outermost block +PUSHJ P,BAZ^ ;BAZ is global, may be external, available at the + ;outermost block +.END + .SSSI Complex Atoms + +Two constructs exist which assemble one or more statements in much +the same way as FAIL's normal top-level statement processor, but then +return as an atom the value associated with the statement(s) assembled, rather +than outputting the binary data. Both of these constructs involve the +use of opening and closing characters to delimit the text. For an atomic +statement, broken brackets, called 2%<brokets>* (4<* and 4>*), are the +delimiters. For +%<literals>, the delimiters are square %<brackets> (4[* and 4]*). + +When the opening character is recognized, FAIL saves its present +state and enters an auxiliary statement-assembly loop, continuing to +assemble statements until a statement is encountered which terminates +with the closing character. The closing character is located as a +statement delimiter, not by keeping a count of the opening and +closing characters. Thus if the delimiter character appears in a text +constant, it will not be counted toward the match; also, attempting +to use a comment (see %%COMM;) in the final statement of the sequence +will prevent recognition of the closing delimiter. +Note that this method of counting brokets is different from the macro +processor, which counts brokets rigidly, independent of context. Nesting of +complex atoms is handled by the recursive nature of FAIL's statement processor. + +.SSSS Atomic Statements +$$ATSTAT:~<atomic statement> + +When it is useful to have the value of an entire statement +treated as an atom, enclose that statement in %<brokets>. +Some number of statements will +be assembled as described above, and the value of the first word +assembled will be returned as the value of the atom, just as if the +corresponding number had been typed. The values of any additional +words assembled up to the closing broket will be ignored, although +their side effects (if certain pseudo-ops are used) may remain. For +example, if one of the multiple-word text pseudo-ops is used inside +brokets, only the first text word will be returned, and the rest +will be dispatched to the great bit bucket in the sky. This +type of atom is constrained by FAIL to be handled as a number, so +all symbols used in this context must be defined and available. + +.Example s + +<JRST> ;equivalent to 254000000000 +<JRST 105 ;254000000105 will be the value +JRST BAR ;and this statement won't do anything except + ;possibly produce an error message if BAR + ;isn't defined and available > + > ;this broket will end it, not the one above + +.END + +.SSSS Literals + +$$LITERAL: + +Although the PDP-10 instruction set allows a large percentage of +constants to be specified as immediate operands, it is still +frequently necessary to reference constants stored elsewhere in +memory. Instead of explicitly setting up these constants and +referencing them by labels, it is possible to reference these +constants as 2%<literals>*. The basic function of literals is to +allow the programmer to write the value of the desired constant +directly (i.e., literally), while the assembler automatically allocates a +memory location for it, stores the value in it, and supplies the +address of the cell for the reference. Also, an operation called +2%<constants optimization>* occurs, which consists of comparing +(the binary value of) each literal with previous literals to see if the +required constant has already been allocated, in which case the +existing cell will be used rather than allocating another. This +avoids multiple copies of a given constant. + +To use a literal, put a statement of the desired value in square +brackets and use it as an atom. The value (of the literal) will +be the address of the literal in memory, which is treated like an +undefined symbol since the actual location will not be assigned until +later (usually the end of the program; also, see %%LIT;). Literals +can be used 2only* where forward references are legal. + +Because of the constants optimization, it is often dangerous (and +considered poor form) to write a program which changes the contents +of a literal. Such a change affects all parts of the program +attempting to use that constant, which is not usually the desired +effect. + +A literal may contain more than one word if desired. The syntax of +literals is basically the same as that of atomic statements, +except that 2all* words assembled are used. Multiple-word literals are +most commonly used to store long text strings, but may be used +to store sequences of instructions. There is no rigid limit on +the maximum size of a literal, but large literals do consume +assembler core fairly rapidly. + +.SENDIT ".";SENDIT "$."; +~<point>~<dollar-point> +For purposes of assembling code in literals, it should be noted that +the predefined symbol "4.*" retains its value during the assembly of a +literal, rather than referring to the current location within the +literal. Thus it refers to the location where the reference to the +outermost literal is being made. The current location within the +(current) literal can be referred to by using the symbol "4$.*" +(but this may not do the right thing if the PHASE pseudo-op is in use). + +Naturally, labels may appear inside literals, but if they do they +will be assigned the value of the current location within the +literal, rather than the value outside. (Labels that appear inside +literals are called 2%<literal-label>s*.) This is the only time that +4FOO:* and 4FOO_.* assign different values to FOO. The location of +a literal is unknown at the time it is processed; hence, labels +that are defined within literals (and "4$.*" when used inside literals) are +undefined symbols. For example, it is illegal to +say 4FOO_$.* inside a literal because assignment statements do not +accept undefined values. Note also that constants optimization will +still occur with labeled literals, and this may result in several +labels having the same value, if appropriate. + +.Example s + +PUSH P,[5] ;no PUSHI, so a literal is handy +OUTSTR [ASCIZ /FOOBAR/] ;a two-word text constant +JRST [ MOVEI C,12 ;some code in a literal + PUSHJ P,WRCH + SUB P,[1,,1] ;a nested literal + JRST .+1] ;returns to the next instruction + ;outside the literal + +PUSHJ P,[YTST: CAIE C,"Y" ;a subroutine in a literal + CAIN C,"y" ;(very rarely done actually) + AOS (P) + POPJ P,] + +PUSHJ P,YTST ;calling the above subroutine +.END + .SI Pseudo-Ops + +$$PSEUDO: + +Most statements are translated into operations for the computer to +perform when the program is executed. 2Pseudo-ops* (short for +2pseudo-operations*), on the other +hand, signify operations to be performed at assembly time. Some of +these operations affect the behavior of the assembler in particular +ways; others serve as convenient methods of entering data in commonly +used formats. + +.SSI Destination of Assembled Code + +The assembler uses a 2%<location counter>* to keep +track of the location where the code it is assembling will go. This +counter is initialized to relocatable 40* at the start of the +assembly; it is incremented by 41* for each instruction assembled. The +value in the location counter is the location where the next word +assembled will go. + +.SSS "LOC, RELOC, and ORG" + +The contents of the location counter can be changed with the LOC, +RELOC, and ORG statements. + +.PSEUD1 LOC +The LOC pseudo-op takes one argument, an expression, which must be +defined and available. The effect of LOC is to put the value of +the expression into the location counter and to set the relocation of +the counter to absolute, regardless of the relocation of the +argument. + +.PSEUD1 RELOC +The RELOC statement has the same effect as the LOC statement except +that the relocation is set to relocatable, regardless of the +relocation of the argument. + +.PSEUD1 ORG +$$ORG: +.BEGIN TURN ON "{" +.SENDIT ".ORG" +.END; +The ORG statement has the same effect as the LOC and RELOC statements +except that the relocation is set to the relocation of the argument. +For compatibility with MACRO-10, the pseudo op 4.*ORG is also accepted. + +Whenever LOC, RELOC or ORG is used, the current value (and +relocation) of the location counter is saved (there is only one such +saved location counter, 2not* one for each pseudo-op). A LOC, +RELOC, or ORG statement with no +argument will cause the saved value and relocation to be swapped +with the current value (and relocation) of the location counter. + .SSS SET and USE + +.PSEUD1 SET;PSEUD1 USE + +It is possible to have 2%<multiple location counters>* and to +switch back and forth among them. Only the currently active location +counter is incremented. %<Location counter>s may be given any names +which fit the syntax of identifiers. There is no relationship +between location counters and labels with the same name. + +The SET pseudo-op is used to initialize a location counter. It takes +two arguments separated by a %<comma>. The first is the name of the +location counter; the second is the value to which the counter will +be set. SET has the same effect as ORG except that it changes the +indicated location counter and has no effect on the current location +counter unless it is the same as the indicated one. SET is usually +used to create a new location counter. + +The USE pseudo-op is used to change location counters. It takes one +argument, the name of the location counter to change to. USE causes +the current location counter value to be saved away and the value of +the indicated counter to be used. If a subsequent USE indicates the +location counter which was saved away, the value it had when it was +saved away will become the current value. If the indicated location +counter has not appeared in a SET before its appearance in a USE +(i.e., if it has no value), it will be given the value of the current +location counter. The location counter which the assembler starts +with has a blank name (i.e., a null argument indicates this first +one). + +In the example below, a %<close single quote> (%<apostrophe>) (4'*) +is used to denote that the value it follows is 2relocatable*. This +is the convention that FAIL uses when making a listing of the +assembled code. + +.Example + + Location Instructions + + 0' JRST FOO + 1' JRST BAZ + 2' SET GARP,37 + 2' USE GARP + 37 JRST FOO + 40 USE + 2' JRST FOO +.END + + .SSS PHASE and DEPHASE + +.PSEUD1 PHASE;PSEUD1 DEPHASE + +.SENDIT "."; SENDIT "$."; +It is sometimes desired to assemble code in one place which will +later be moved by the program itself to another place. In this case, +it is desired that labels be defined as referring to locations in the +place where the code will be moved, rather than where the assembler +will put it. To accomplish this, the PHASE pseudo-op is used. +PHASE has one argument, the location to which the next word assembled +will be moved by the program. For instance, if, while the location +counter is at 74, a 4PHASE 32* appears and a label appears on the next +line, the label will be given the value 32, but the code on that +line will be placed in location 74. Under these circumstances, the +~<point>~<dollar-point> +"4.*" symbol will have the value 32, but the "4$.*" symbol will +have the value 74. The PHASE pseudo-op remains in effect until +cancelled by a DEPHASE pseudo-op (no argument). + +If a RELOC, LOC, or ORG pseudo-op (see %%RELOC;) appears while +PHASE is in effect, the following considerations apply. If the +relocation of the location counter remains unchanged by the RELOC +(or LOC or ORG), then the value of the phase +will be offset by the same amount as the location counter changes. +That is, the value of "4.*" and "4$.*" will be changed by the same amount. +If the relocation of the location counter changes and the relocation +of the phase was the same as the relocation of the (old) location counter, +then the relocation of the phase will be changed and the phase will be +offset by the same amount as the location counter changes. +Otherwise, the error message 2Indeterminate Phase due to RELOC* will +occur and FAIL will dephase. + +.PSEUDO HISEG + +This statement outputs information directing the %<loader> to load +the program into the %<high segment>. It should appear before any code +is assembled. + +.PSEUDO TWOSEG + +This statement directs FAIL and the %<loader> to assemble and load a +%<two-segment program>. This complicates the relocation process +because the loader must maintain two relocation constants, one +for each %<segment>. Since only one bit of relocation information is +available for each value in the relocatable binary file, a kludge +is used to decide which relocation to apply to each relocatable +value. To do this, the loader compares the unrelocated value to +a quantity known as the 2high-segment origin*, which is the first +address used for the high segment within that program. Any value +greater than or equal to this quantity will be considered a high-segment +address, while any value less than this quantity will be considered +a low-segment address. When the value in question is a location +specifier, the choice of relocation will determine which segment the +code is actually loaded into. + +.BEGIN TURN ON "" +Unfortunately, there is a possible bug in this relocation method. It +is possible to have an expression which evaluates, through normal +relocation arithmetic, to a relocatable quantity whose unrelocated +value does not correspond to the segment the relocation was +originally derived from. For example, if FOO is a label at high +segment location 120, it will probably have a value of relocatable 400120. The +expression 4FOO-400000* would be calculated by FAIL to have the value +relocatable 120. This value would be passed directly to the loader +since Polish appears unnecessary. However, +the loader would apply the low-segment relocation to this value +and probably have incorrect results. At present, the best way to +get around this is to say 4FOO*1-400000*, which will force the Polish +to be passed to the loader. +.END + +The high-segment origin is specified by +an optional argument to the TWOSEG pseudo-op, or set to the default +of 400000 in its absence. In this case a 4RELOC 400000* followed by a +4RELOC 0* will initialize the dual location counter to assemble into +the low segment and to switch segments whenever a RELOC statement +with no argument is encountered (see %%RELOC;). Like +HISEG, TWOSEG should be used before any code is assembled. + +.Example + + TITLE EXAMPLE +PDLEN__100 +P_17 + TWOSEG 400000 ;initialize to two segments + RELOC 0 ;initialize dual location counters + RELOC 400000 ;now assemble code in the high segment +START: TDZA 1,1 + MOVNI 1,1 + MOVEM 1,RPGSW# + CALLI 0 + MOVE P,[IOWD PDLEN,PDLIST] + RELOC ;set the relocation to low segment +PDLIST: BLOCK PDLEN ;define space for data storage + RELOC ;set location counter to the high segment + PUSHJ P,CORINI ;code is assembled in the high segment + ;the rest of the program goes here + RELOC ;back to the low segment + VAR ;do variables in the low segment + RELOC ;to the high segment + LIT ;and literals here + END START +.END + + +.PSEUDO LIT + +The LIT statement causes all previously defined %<literals> +to be placed where the LIT statement occurs. The LIT +statement must not appear inside a literal. If a two segment sharable program +is being assembled, LIT should appear in the upper segment. + +.PSEUDO VAR + +~<number sign> +The VAR statement causes all %<variables> which appeared with a 4#* in +this block (or a sub-block of this one) to be placed where the VAR +appears. VAR must not appear inside a literal. If a two segment sharable program +is being assembled, VAR should appear in the lower segment. + .SSI Symbol Modifiers + +The pseudo-ops in this section perform several functions, all relating +to the definition or availability of symbols, or affecting the linkage +of this program to others. + +.PSEUDO OPDEF + +The OPDEF statement has the following form: + +.BEGIN VERBATIM SELECT 4; + + OPDEF symbol [value] +.END + +OPDEF inserts the symbol into +FAIL's opcode table with the indicated value. The symbol, which +is a 2%<user-defined opcode>*, +may then be +used as any other opcode. The value part of the OPDEF must be +defined and available. User-defined opcodes are sometimes called +2%<opdefs>* because of the pseudo-op by which they are defined. + +.SSS BEGIN and BEND + +.PSEUD1 BEGIN;PSEUD1 BEND + +$$BLOCKP: + +The BEGIN statement is used to start a block. The block it starts +will end at the corresponding BEND statement. The BEGIN may be +followed by an identifier that will be used as the name of that +block. %<DDT> and %<RAID> recognize block names. If no identifier +appears, the assembler will create one of the form 4A.000*, where +the 4000* will be replaced by the block number of this block in +octal. (The 2%<block number>* is initialized to zero and incremented for +each BEGIN.) There is no relationship between labels and blocks with +the same name. All text following the identifier is ignored until +the next line feed or double-arrow. + +BEND may be followed by an +identifier which, if present, is compared to the block name of the block being +ended; if they don't match, FAIL prints an error message. + +FAIL does not require block names to be unique; however, +the loader and the debuggers sometimes depend on +unique block names, so the user would be wise to avoid conflicts. + +For a discussion of block structure, see %%BLOCKS;. + +.PSEUDOX GLOBAL + +The GLOBAL pseudo-op should be followed by a list of symbols +separated by %<comma>s. Each symbol should be defined in an outer +block. The effect of GLOBAL is to find the nearest outer block in which +that symbol is defined and to make the definition in that block +immediately available in the block in which the GLOBAL appears. +GLOBAL does not affect the definition of the symbol in any +intervening blocks. + +If a symbol has been declared GLOBAL in a block and later is +redefined in that block, the redefinition affects +the definition in the outer block where GLOBAL found the +original definition. Doing this causes strange effects if the definition was +not in the next-outer block; it should not be done without some +careful thought. + +The GLOBAL pseudo-op has no relation to the concept of global symbols. + +.SSS INTERNAL and ENTRY +.PSEUD1 INTERNAL; PSEUD1 ENTRY + +These statements declare certain locally defined symbols +to be %<internal symbols>. 2Internal symbols* are those which are made available +to other programs by the %<loader>. INTERNAL (or ENTRY) +should be followed by a list of symbols separated by %<comma>s. +These symbols need not +be defined before the INTERNAL (or ENTRY) statement appears, but +they must be defined by the end of the program. + +ENTRY emits special library %<entry blocks> to the loader; see %%LIBM;. +ENTRY statements must appear before any other statements that emit +code, except that it is specifically legal to precede ENTRY +statements by a TITLE statement. + +.PSEUDO EXTERNAL + +The EXTERNAL statement declares that certain symbols are +%<external symbols>. An 2external symbol* is a symbol that +is declared internal in some other program. +EXTERNAL is followed by a list of symbols separated by %<comma>s. +The %<loader> will fix up any references to an external symbol when the +program in which it is defined is loaded. + +Symbols must not be defined at the time they are declared with an EXTERNAL +statement. If an external symbol is subsequently defined, +it is automatically converted to an internal symbol. + +If any occurrence of a +symbol is immediately followed by an %<up-arrow> (4^*), that symbol is +made external if it is not yet defined, or internal if it is defined. If +an external symbol is subsequently defined, it will be made internal. + + +.SSS LINK and LINKEND +.PSEUD1 LINK;PSEUD1 LINKEND +$$LINK: +$$LNKEND: +.BEGIN TURN ON "{" +.SENDIT ".LINK" +.SENDIT ".LNKEND" +.END; + +LINK and LINKEND are used to establish a single-linked list among several +separately assembled programs. Each linked list is identified by a link +number in the range 1-20 (octal). +The formats are + +.BEGIN VERBATIM SELECT 4; + + LINK number,location + + LINKEND number,location +.END + +The number is the link number; the location is the address where the +link information will be stored. The effect is to allow 20 lists to +be threaded through several separately assembled programs. + +The %<loader> initializes each link (and linkend) to zero. 4LINK +N,FOO* causes the loader to store in FOO the current value of link +N. Then link N is set to (point at) FOO. 4LINKEND N,BAZ* causes +the the loader to store the address BAZ as the linkend for link N. When +the loader finishes loading all programs, the final value of each +link will be stored in the corresponding linkend address, only if +that address is non-zero. +The LINKEND feature allows the head of the list +to be in a known place, rather than in the last place LINKed. + +For compatibility with MACRO-10, the pseudo ops 4.*LINK and 4.*LNKEND +are accepted for LINK and LINKEND, respectively. + +.SSS (".LOAD and .LIBRARY"); +$$LOAD: +$$LIBRARY: +$$REQUEST: +$$REQUIRE: +.BEGIN TURN ON "{" +.SENDIT ".LOAD" +.SENDIT ".LIBRARY" +.SENDIT ".REQUEST" +.SENDIT ".REQUIRE" +.END; + +The 4.*LOAD pseudo-op causes the %<loader> to load a specific 4REL* +file as a consequence of loading the program in which this pseudo-op occurs. +The format is + +.BEGIN VERBATIM SELECT 4; + + .LOAD DEV:FILE[PRJ,PRG] +.END + + +The 4DEV:* field is optional (the default is 4DSK:*); it specifies +the device where the 4REL* +file can be found. The 4[PRJ,PRG]* field is optional; it has the +usual meaning. The file named must have the extension 4REL* (this is +a loader restriction). + +In non-Stanford FAIL installations, the file name is scanned +in accordance with the convention that prevails at that site. + +The 4.*LIBRARY pseudo-op is similar to 4.*LOAD, except that +instead of loading the file, the loader +will search the named file as a library. + +For compatibility with MACRO-10, the pseudo ops 4.*REQUIRE and 4.*REQUEST +are accepted for 4.*LOAD and 4.*LIBRARY, respectively. + + +.PSEUDO PURGE + +The PURGE pseudo-op takes a list of symbols, separated by commas, as its +argument. Each of the symbols named will be purged, i.e., removed from +FAIL's symbol table. A purged symbol can be an opcode, macro, label or +other symbol. For PURGE to be legal, the symbol must be defined and +available when the PURGE occurs. Some symbols, such as variable names +%<literal-label>s, and global symbols, +cannot be purged. Purged symbols are not passed to the loader or debugger. + +PURGE searches the symbol table for opcodes first, then macro names, and +finally labels (and parameters). This means that if a symbol has +a definition as both an opcode and a label, purging that symbol will delete +the opcode, and a second purge of that symbol will delete the label definition. + +If the identifier name of some purged symbol is used after the purge, FAIL makes +a new and totally different symbol, which has no relation to the purged symbol. +The CREF program will also consider such a symbol to be different from the purged +symbol. + +Caution: if an opcode, pseudo-op, or other predefined symbol is purged, +it will remain unavailable to subsequent assemblies performed by the FAIL +core-image from which it was purged. Also, it is unwise to purge a macro +while it is being expanded. + + +.PSEUDO XPUNGE + +XPUNGE is used to delete all local symbols from one block. XPUNGE takes +effect 2only* at the next BEND (or END or PRGEND) statement following the +XPUNGE. At that BEND, most local symbols will 2not* be emitted to the +%<loader>. This +decreases the size of the 4REL* file and makes loading it faster. Block names, +internal and external symbols, variables, and %<literal-label>s will be passed +to the loader. + +.SSS SUPPRESS and ASUPPRESS +.PSEUD1 SUPPRESS;PSEUD1 ASUPPRESS + +When a parameter file (i.e., a file that contains assembly parameters for use +in several assemblies) is used in assemblies, many symbols get defined +but are never used. Unused defined symbols take up space in the +binary file. Unused symbols may +be removed from symbol tables by means of the SUPPRESS or ASUPPRESS pseudo-ops. +These pseudo-ops control a 2%<suppress bit>* associated with each +symbol; if the suppress bit is on and the symbol is not referenced, +the symbol will not be output to the binary file. + +SUPPRESS takes a list of symbols, separated by commas, as its argument. The +suppress bit is turned on for each symbol named. A symbol may be an opdef, +a parameter, or a label. The symbol should be defined before +the SUPPRESS statement occurs. + +ASUPPRESS turns on the suppress bit for every user-defined symbol and opcode +that exists in the symbol table at the time the ASUPPRESS occurs. + +Variables, literal-labels, internals, and entry point symbols are +never suppressed. Externals that are not referenced can be +suppressed. + +If ASUPPRESS appears in a %<universal program> (see %%UNIVERSAL;), +then 2all* symbols in the universal symbol table will have the suppress bit +set when they are used in a subsequent SEARCH. + + .PSEUDO UNIVERSAL + +The UNIVERSAL pseudo-op has the same syntax as TITLE (see %%TITLE;). +In addition to the functions of TITLE, UNIVERSAL declares the symbols +defined in this program to be %<universal symbols>. 2Universal +symbols* are symbols which can be accessed by other programs that +are assembled after the universal symbols have been defined. That +is, UNIVERSAL causes symbols to be retained by FAIL after it finishes +assembling the universal program. + +The program name that is set by UNIVERSAL names the universal symbol +table. The universal symbol table contains the universal symbols +defined by this program. Only outer block symbols (and macros and +opdefs) are retained in the universal symbol table. Variables, +%<literal-label>s, and internal symbols are 2not* retained. + +Universal symbols are written into a 2%<binary universal file>* +which can be accessed in subsequent assemblies without reassembling +the source text of the universal program. The binary universal file is given +the same name as the name in the universal statement. This file has +the extension "FUN" and it is written in the current directory. +Output of the binary universal file is automatic, but may be +prevented by use of 4.*NOUNV in 4.*DIRECT (see %%DIRECT;), or by +the 4/O* switch in the command line (see %APPCOM;). + +Access to the symbols in a universal symbol table is controlled by +the SEARCH pseudo op (see %%SEARCH;). Once access is established, +universal symbols can be referenced as any other local symbols. + +Universal programs are intended for making definitions, not for +assembling code. The usual use for UNIVERSAL is to define opcodes, +macros, and parameters for use in subsequent assemblies. It is not +wise to include relocatable symbols in a universal program. The +exception is that a universal program may declare a symbol to be +external; that declaration can be used by subsequent assemblies that +search this universal symbol table. + +.PSEUDO SEARCH + +Access to universal symbols is established by SEARCH. SEARCH takes a +list of arguments, each of which is the name of a universal symbol +table. For each universal table named, all the symbols in that table +are added to 2the end of* the main symbol (or macro or opcode) +table. Thus, when the symbol table is searched, if there is no other +definition of the symbol, the universal definition will be found. +Universal symbols are considered to be defined at the outer block. +If such symbols are to be made available to inner blocks, they must +be defined with a down-arrow, or declared GLOBAL. + +If the universal symbol table named in SEARCH does not exist already, +FAIL looks for a %<binary universal file> (sometimes called a %<FUN> +file, because it has the extension "FUN"). The file sought has the +same name as the argument to SEARCH, the extension FUN, and is on the +current file directory, or on device UNV, or on device SYS. +Alternatively, the argument to SEARCH may be followed by a file name +enclosed in parentheses, in which case the named file will be sought +instead of the default. + .SSI Entering Data +$$DATAE: + +.SSS DEC and OCT + +.PSEUDX DEC;PSEUD1 OCT + +The DEC and OCT statements both take a string of arguments, each a +number, separated by %<comma>s. The radix is temporarily set for this +one statement to 10 for DEC or to 8 for OCT. The numbers are placed in +successive locations. + +.Example s + + DEC 5,9,4096 ;assembles three words + OCT 5,11,10000 ;assembles the same three words +.end + +.PSEUDO BYTE + +The BYTE statement is used to enter bytes of data. Arguments in +%<parentheses> indicate the byte size to be used until the next such +argument. The first argument of a BYTE statement must be a byte +size argument. Other arguments are the byte values. An argument may be +any expression that is defined, available, and absolute. Arguments in +parentheses (byte size) are interpreted in decimal (base 10) and +other arguments in the prevailing radix. Bytes are deposited with +the byte instructions, so if a byte will not fit in the current word, +it will be put in the left part of the next word. Unused parts of words +are filled with zeros. Byte size arguments are not surrounded by +commas, but other arguments are separated by commas. For instance, +the statement + +.BEGIN VERBATIM SELECT 4; + + BYTE (7) 3,5(11)6 +.END + +will put two 7-bit bytes (3 and 5) and an 11-bit byte (6) +in a word, left justified. + +Two successive delimiters, i.e., two commas or a comma and parenthesis, indicate +a null argument, which is the same as a zero. + + +.PSEUDOX POINT + +The POINT pseudo-op assembles a %<byte pointer> +in one word. The first argument should be an expression and is +interpreted in decimal. The expression must be defined and +available. It indicates the byte size, and its value is placed in the +size field of the assembled word. The second argument should contain +one or more of an index field, an address field, and an at-sign. The +third field, if present, indicates the bit +position of the low order bit of the byte, i.e., its value is +subtracted from 35 (decimal) and placed in the position field. It is +interpreted in decimal and must be available. If the third argument is +omitted (no comma should be present after the second argument), the position +field is set to 36 (decimal) so that the first time the pointer is +incremented, it will point to the first byte of the word. + + +.PSEUDO XWD + +The XWD statement takes two arguments, separated by a %<comma>, and assembles +a single word with the value of the first argument in the left half and +the value of the second argument in the right half. Both arguments must +be present. + .PSEUDO IOWD + +IOWD is a permanently defined macro (see %%MACROS;). +Its definition is + +.BEGIN VERBATIM GROUP SELECT 4; + + DEFINE IOWD (A,B) + < XWD -(A),B-1 > +.END + +IOWD takes two arguments and assembles a word in which the negative +of the first argument goes in the left halfword and one less than the +value of the second argument goes in the right halfword. This format +(i.e., negative word count, and memory address minus 1) is often used +in communicating with the operating system to specify the address and +length of a data block. Also, IOWD may be used to initialize an +accumulator for use as a push down pointer. + +.SSS "ASCII, ASCIZ, ASCID, and SIXBIT" +$$TEXT: +.PSEUD1 ASCIZ;PSEUD1 ASCID;PSEUDX SIXBIT;PSEUDX ASCII; + +There are four %<text statements>: ASCII, ASCIZ, ASCID, and +SIXBIT. Each takes as its argument a string of characters starting and +ending with, and not otherwise containing, some non-blank +character which serves as a delimiter. This delimiter should 2not* +be any one of the characters: %<left-arrow> (4_*), %<colon> (4:*), +%<up-arrow> (4^*), %<tilde> (4~*), or %<number sign> (4#*). + +ASCII puts the 7-bit representation of each successive +character in the string (excluding the delimiters) in successive words, 5 +characters per word, until the string is exhausted. The low order +bit of each word and the left-over part of the last word are filled +with zero. + +ASCIZ is the same as ASCII except that if the last +character is the 5th of a word, a word of zero is added at the end. +This is to ensure that there is at least one 0 byte at the end. + +ASCID works as ASCII except that the low order bit of each word generated +is a 1. ASCID assembles data suitable for either the III or Data Disc +display systems at Stanford. Also, the ASCID format is used for line numbers +in the SOS editor. + +SIXBIT works as ASCII except that the characters are +converted to the %<sixbit> representation and packed 6 to a word. +The last word is filled out with zeros if necessary. Ascii characters are +converted to sixbit by replacing the 40 bit with the 100 bit and +removing the 100 bit. + +.PSEUDO RADIX50 + +This pseudo-op takes two arguments, separated by a %<comma>. +The first argument is a number; the second argument is an identifier. +The value assembled by the RADIX50 statement +is the radix50 representation of the identifier, with +the number ORed into the high-order 6 bits. The 2 low-order +bits of the number are cleared before ORing. + +2Radix50* is the representation used for symbol names in the %<loader>, +%<DDT>, and %<RAID>. Radix50 is used to condense 6-character symbols into +32 bits. Legal characters are reduced to a value in the range 0-47 +octal. The radix50 value is obtained by accumulating +a total composed of each character value times a weight. The weight +is the power of 50 (octal) corresponding to the character position. +The weight of the rightmost non-blank character is 1; the second from +the right has weight 50; the third has weight 50*50; etc. The +correspondence between characters and their radix50 value is given below: + +.BEGIN VERBATIM GROUP SELECT 4; + + Blank  0 + 0-9  1-12 + A-Z  13-44 + .  45 + $  46 + %  47 +.END + + .SSI Reserving Space for Data +.PSEUDOX BLOCK + +The BLOCK statement is used to reserve a storage area for data. +The value of the argument is added to the location counter, so +subsequent statements will be assembled beyond the area reserved +by BLOCK. The argument must be defined and available. A +warning will be given if the argument is negative. +The %<loader> will initialize each word reserved by the BLOCK statement +to zero; however, well-written programs do their own initialization. +Note that the BLOCK pseudo-op has no relation to block structure. + +4BLOCK N* and 4ORG .+N* are equivalent. + + + +.SSS INTEGER and ARRAY +.PSEUD1 INTEGER; PSEUD1 ARRAY; + +INTEGER should be followed by a list of symbols, separated +by %<comma>s. Each of these symbols is then treated as a variable, ~<variables> +i.e., as though it had +appeared in the block where the INTEGER appears, followed by a %<number sign>. + +The ARRAY statement takes a list of arguments separated by %<comma>s. +Each argument is a symbol followed by an expression in %<brackets>. +The effect is similar to INTEGER, except that the expression (which ought to +be defined and available) denotes the number of locations to be reserved +(as in BLOCK), with the symbol being the address of the first one. +For example, + +.BEGIN VERBATIM SELECT 4; + + ARRAY FOO[10],BAZ[20] +.END + +will reserve 10 words for FOO and 20 words for BAZ. The symbols +FOO and BAZ are not defined by this statement; they can only be used +where %<forward reference>s are legal. + + .SSI Assembler Control Statements + +.PSEUDO TITLE +$$TITLEP: + +TITLE names the program and +sets the heading for the pages of the listing. There should be +precisely one TITLE statement per program; it should +appear before any statement that generates code. + +TITLE should be followed by a string of characters, the first part of +which should be an identifier. That identifier is used as the +program name which %<DDT> and %<RAID> will recognize. It is also used as +the name of the outermost block. + +The string of characters in the TITLE statement is printed as a part +of the heading on all pages subsequent to the one on which the TITLE +statement appears; if TITLE appears on the first line of a page, it +also affects the heading on that page. The string used in the heading +for TITLE is terminated by the first %<carriage return> or %<semicolon>. + +If no TITLE statement appears before the first symbols are emitted +(generally, at the first BEND or END), then FAIL will generate a title +with program name "4.MAIN*". If a TITLE statement appears after code +has been emitted (except for entry blocks), the resulting binary +file may be unsuitable for use as part of a library file. + +.SSS END and PRGEND +.PSEUD1 END; PSEUD1 PRGEND + +The END statement is the last statement of a program. It signals the +assembler to stop assembling; no text following it will be +processed. +If an argument is given, it is taken as the %<starting address> of +the program. + +An END statement includes implicit %<VAR> and %<LIT> statements +(see %%VAR;, and %%LIT;). That is, +all outstanding %<variables> and %<literals> are placed starting at +the current value of the location counter when the END is seen. +Variables are put out first. + +PRGEND is used in place of END when it is desired to assemble +more than one program to and/or from a single file. It behaves +exactly like END, including taking an optional argument as the +%<starting address>, and then restarts FAIL completely, except that +I/O is undisturbed. It therefore cannot appear in a macro expansion +or similar situation. PRGEND is particularly useful for directly +assembling a library which consists of many small programs. + + +.PSEUDOX COMMENT + +The first non-blank character following the COMMENT pseudo-op is taken +as the delimiter. All text from it to the %<line feed> following the +next occurrence of this delimiter is ignored by the +assembler, except that it is passed to the listing file. +The delimiter should 2not* be any one of the characters +%<left-arrow> (4_*), %<colon> (4:*), %<up-arrow> (4^*), +%<tilde> (4~*), or %<number sign> (4#*). + +.PSEUDO RADIX + +The RADIX statement changes the prevailing radix until the next RADIX +statement is encountered. It has no effect on numbers preceded by an +%<equal sign>. +The one argument of RADIX is interpreted in the current radix unless +it is preceded by a equal sign. Thus, the statement 4RADIX 10* will have no +effect (since 10 in the current radix equals the current +radix). The radix may be set to almost anything, but for radices above +10 (decimal) there are no digits to represent 10, 11, etc. Zero is not +permitted, and 1 should be avoided if one is going to use either an +arithmetic FOR macro or a macro argument with this radix. + +.SSS (".INSERT"); +$$INSERT: +.BEGIN TURN ON "{" +.SENDIT ".INSERT" +.END; + +The 4.*INSERT pseudo-op causes FAIL to remember its position in the current +input file and then start reading (and assembling) another file. When +the end of the inserted file is reached, FAIL continues processing the +original file from the point where it left off. The format is: + +.BEGIN VERBATIM SELECT 4; + + .INSERT DEV:FILE.EXT[PRJ,PRG] +.END + +The 4DEV:* field is optional (the default is 4DSK:*); it specifies +the device where the inserted +file can be found. The 4[PRJ,PRG]* field is optional; it has the +usual meaning. +In non-Stanford FAIL installations, the file name is scanned +in accordance with the convention that prevails at that site. + +This pseudo-op will 2not* work if it appears in the input stream from +any device other than DSK, since random access features are required to +accomplish the repositioning of the file. + +Unlike a normal pseudo-op, which is recognized only if it appears +as the op-code, 4.*INSERT is recognized anywhere in a line. It is +suggested that 4.*INSERT not be used as a macro argument. + +.SSS (".FATAL"); +$$FATAL: +.BEGIN TURN ON "{" +.SENDIT ".FATAL" +.END; + +The 4.*FATAL pseudo-op prints the text of the line on which it appears, and stops +the assembly. Usually, 4.*FATAL appears under some conditional assembly switch +to stop the assembly because some parameter settings are inconsistient. + +.SSS (".DIRECT") +$$DIRECT: +.BEGIN TURN ON "{" +.SENDIT ".DIRECT" +.END; +.BEGIN TURN ON "{" +.SENDIT "KA10" +.END; +.BEGIN TURN ON "{" +.SENDIT "KI10" +.END; +.BEGIN TURN ON "{" +.SENDIT ".NOBIN" +.END; +.BEGIN TURN ON "{" +.SENDIT ".XTABM" +.END; +.BEGIN TURN ON "{" +.SENDIT ".ITABM" +.END; +.BEGIN TURN ON "{" +.SENDIT ".NOUNV" +.END; + +The 4.*DIRECT pseudo op takes a list of function names separated by commas +as its argument. The available functions and their uses are listed below. + +The functions KA10 and KI10 are used when the program being assembled +is known to be suitable for only one of these processors. The default situation +allows the code to be executed on either processor. LINK-10 checks this +information to prevent code from being executed on the wrong kind of processor. + +.BEGIN TURN ON "" +4.*NOBIN suppresses binary output. + +4.*NOUNV suppresses output of the binary universal (%<FUN>) file +(see %%UNIVERSAL;). + +The functions 4.*XTABM and 4.*ITABM modify the behavior of the +macro processor with respect to the treatment of tabs and blanks that +appear in actual arguments to a macro call (see %%MARGL;). +4.*ITABM is the default; tabs and blanks are kept as part of the +argument. If 4.*XTABM is used, leading and trailing blanks and +tabs are deleted from a macro argument, unless the argument is +enclosed in %<brokets> or %<braces>. +.END; + .SSI Loader Control Statements + +The following pseudo-ops are used to pass control information to +LINK-10. + +.SSS (".COMMON") +$$COMMON: +.BEGIN TURN ON "{" +.SENDIT ".COMMON" +.END; +The 4.*COMMON statement passes information to LINK-10, and does not +otherwise affect the assembly. This statement has the same syntax as +ARRAY (see %%ARRAY;). LINK-10 will reserve the requested amount +of space for each block of named common. + +.SSS (".ASSIGN") +$$ASSIGN: +.BEGIN TURN ON "{" +.SENDIT ".ASSIGN" +.END; +.PSEUD1 ASSIGN; + +The 4.*ASSIGN pseudo op (and ASSIGN in the Tenex version) takes three +arguments: two identifiers, and an optional expression. At load +time, the value of the first identifier, which is treated as an +external by the assembler, is assigned to the second identifier. +Then the value of the expression (which is taken as 1 if the +expression is omitted) is added to the value of the first identifier. + +.SSS (".TEXT") +$$TEXT: +.BEGIN TURN ON "{" +.SENDIT ".TEXT" +.END; +The 4.*TEXT statement is used to pass the ascii text of control statements +to LINK-10. The 4.*TEXT pseudo op is like ASCIZ (see %%ASCIZ;) except it +does not have a value and does not affect the location counter. + + .SSI Listing Control Statements + +These pseudo-ops affect the format of the assembly listing. +Several +descriptions below refer to command line switches; %APPCOM;, describes +the command line format and the different switches. + +.SSS TITLE and SUBTTL +.PSEUD1 SUBTTL + +The TITLE statement can be used to set the heading that appears on +the pages of the listing. See %%TITLEP;. + +SUBTTL is followed by a string of characters which +is used as a subheading on all subsequent pages until +another SUBTTL appears. If SUBTTL appears on the first line of +a page, it will affect the subheading of that page also. +The string used in the heading for SUBTTL +is terminated by the first %<carriage return> or %<semicolon>. + +.SSS "LIST, XLIST, and XLIST1" + +.PSEUD1 LIST;PSEUD1 XLIST;PSEUD1 XLIST1; + +The XLIST statement causes listing to stop until the next LIST +statement. LIST causes listing to resume if it has been stopped by +an XLIST or XLIST1 statement. Otherwise it is ignored. +LIST is the default. + +The XLIST1 statement has exactly the same effect as XLIST unless the 4/I* +switch was used in the command string, in which case it is ignored. + + +.SSS LALL and XALL +.PSEUD1 LALL;PSEUD1 XALL + +XALL causes the listing of the body of macros, REPEATs, and FORs to +be suppressed during macro expansion. LALL causes it to start up +again. LALL is the default. + +.PSEUDO NOLIT + +This statement causes the binary listing of code in literals to be +suppressed. This has the same effect as 4/L* in the command string. + +.PSEUDO NOSYM + +This statement disables the listing of the symbol table, counteracting +4/S* in the command string. + +.SSS CREF and XCREF + +.PSEUD1 XCREF;PSEUDX CREF + +These turn on and off the emission of information to %<CREF>, the +2%<Cross-Reference Listing>* program. These pseudo-ops have +no effect unless 4/C* was used in the command string. CREF is the default. + +.SSS PAGE +.PSEUDX PAGE + +This pseudo-op has the same function as a %<form feed>; it is +included for compatibility with MACRO-10. A form feed is +placed in the listing immediately following PAGE. The effect is to +skip to the top of the next page of the listing. Use of this pseudo-op +will destroy the correspondence between listing pages and source file +pages, so its use is generally not recommended. + +.PSEUDO PRINTX + +This pseudo-op causes the line on which it appears to be printed on the +user's terminal. This is sometimes useful for giving a progress report +during long assemblies. + +.PSEUDO PRINTS + +The first non-blank character following the PRINTS pseudo-op is taken +as the delimiter. All text from it to the next occurrence of this +delimiter is printed on the user's terminal. The delimiter should +2not* be any one of the characters %<left-arrow> (4_*), %<colon> +(4:*), %<up-arrow> (4^*), %<tilde> (4~*), or %<number sign> +(4#*). + + .S Macro Operations + +$$MACROS: + +The FAIL macro processor provides features for modifying the input +text stream in many ways, such as the ability to abbreviate a +frequently occurring sequence with a single identifier or to +iterate the input of a stream of text a number of times. In both +cases, substitutions can be specified which allow each different +occurrence of the text to be somewhat modified. Provision for making +the assembly of a body of text conditional on any of a variety of +circumstances is also included. + +.SSI Macros + +$$MACRO: + +2Macros* are named text strings which may have substitutable arguments. +Macros may be used whenever the same or similar pieces of text (code) occur +in several places. A macro has a 2name* and a 2macro body*; also, +it may have a 2concatenation character* and an 2argument list*. The +several characteristics of a macro are specified by a DEFINE +statement. + +.PSEUDX DEFINE + +DEFINE and the macro name must appear on the same line. The 2macro name* +is an identifier; it may be followed by an optional +concatenation character, which must also be on the same line as +DEFINE. The formal arguments, if any, are enclosed in %<parentheses> +and separated by %<comma>s. The argument list may occur on a subsequent +line. The macro body, enclosed in 2%<braces>* (4{* and +4}*), appears after the argument list in DEFINE. + +In the macro processor, braces and %<brokets> are equivalent, i.e., +"4{*" and "4<*" are equivalent, as are "4}*" and "4>*". +The equivalence between brokets and braces applies at all times within +the macro processor; the text and examples that follow use braces, but +brokets can be used instead. +The macro processor counts braces independent of context; specifically, +braces and brokets that appear in comments, text constants, etc. +2are* counted by the macro processor. In the discussion that follows, +"non-blank character" omits both %<blank> and %<tab> characters. + +.PSEUDX GDEFINE +GDEFINE is similar to DEFINE except that the macro is defined at the outermost +block level. A macro defined by GDEFINE will remain defined +after exiting the block in which it was defined. + +.SSSI Macro Bodies +$$MBODY: + +The 2macro body* may be any string of characters, subject to the +restriction that the right and left braces must be balanced. The +macro body itself is enclosed in braces and appears after the +argument list in a DEFINE statement. +The macro body is stored in FAIL's memory, associated with the macro +name. At any point following the DEFINE statement, the macro body +will be substituted for occurrences of the macro name. + +.SSS Concatenation + +The 2%<concatenation character>* may be any non-blank character +(excluding also %<carriage return>, %<line feed>, and right brace) +that appears in DEFINE after the macro name and before the argument +list and macro body. This character may then be used to delimit +identifiers so that they will be recognized as arguments. +Appearances of this character will be deleted from the macro body +whenever they appear. This allows a macro argument to be part of an +identifier, instead of an entire identifier. See the example at the +end of %%CATEX;. + +.SSSI Arguments in Macro Definitions + +2Arguments* in macro definitions must be identifiers. A list of them, +enclosed in %<parentheses>, may appear after the macro name in the +definition. If no list of arguments appears +before the macro body, it is assumed that there are no arguments. + +Each instance of an identifier in the macro body which is the same +as one of the arguments will be replaced with the +string of text corresponding to that argument when the macro is +called. Thus, if FUDLY is one of the arguments in the definition of +a macro and the following text appears in the body: + +.BEGIN VERBATIM SELECT 4; + + A+FUDLY B +.END + +then FUDLY will be recognized as an argument. But if the following +appears: + +.BEGIN VERBATIM SELECT 4; + + A+FUDLYB +.END + +then, since FUDLYB is an identifier and is different from FUDLY, it +will not be recognized as an argument. To concatenate the "4B*" above +with an actual argument, use a concatenation character. For example, +if the concatenation character is "4$*" and + +.BEGIN VERBATIM SELECT 4; + + A+FUDLY$B +.END + +appears in the macro body, then FUDLY will be recognized as an argument, +and the "4$*" will disappear when the macro is expanded. + +Here is a sample macro definition: + +.BEGIN VERBATIM GROUP SELECT 4; + + DEFINE FOO (AC,ADDRS) + {MOVNI AC,3 + IMUL AC,ADDRS + ADDI AC,37 + MOVEM AC,ADDRS+1} +.END + +If the text: + +.BEGIN VERBATIM SELECT 4; + + FOO (A,FARB+7) +.END + +appears in the program somewhere after the DEFINE above, it will +expand into: + +.BEGIN VERBATIM GROUP SELECT 4; + + MOVNI A,3 + IMUL A,FARB+7 + ADDI A,37 + MOVEM A,FARB+7+1 +.END + + .SSSI Macro Calls +$$MCALLS: + +A macro name may appear anywhere and will be replaced by the macro +body, as long as the name appears as an identifier and is considered +to be an identifier by the assembler. A macro name may appear alone on a +line or in the accumulator, index, or address field. +If the macro name appears in a context where it is not considered to +be an identifier, the macro will not be expanded. For example, +macro names that appear in a comment or in the text argument of an +ASCII statement will not be expanded. Also, there are some other +cases where a macro name will not be expanded: +.BEGIN NOFILL INDENT 8,8; PREFACE 0; + +the macro name in DEFINE and GDEFINE, +the formal argument list in DEFINE, GDEFINE and FOR, +the symbol name in OPDEF, PURGE, SUPPRESS and RADIX50, +the tested symbol in a symbol IF, +the block name in BEGIN and BEND, +the location counter name in USE and SET, +the program name in TITLE and UNIVERSAL, and +in any file name scan, e.g., 4.*LOAD, 4.*INSERT, etc. +.END + +Macros may be used recursively. That is, a macro body may contain a macro +call or macro definition. However, if such macro calls are nested +too deep, the macro push-down list may overflow, resulting in an +error message and termination of the assembly. If this occurs, +the 4/P* switch should be used in the command string. Every occurrence +of 4/P* in the command string causes the assembler to allocate an extra +200 (octal) words of memory for the macro push-down list (see %APPCOM;). +In similar circumstances, a main push-down list overflow may occur. +In this case, the 4/E* switch in the command string may be used to allocate +a larger main push-down list. + .SSSI Arguments in Macro Calls +$$MARGL: + +.BEGIN turn on "#" +The list of arguments to a macro call may be enclosed in %<parentheses>, or +not. The arguments themselves are separated by %<comma>s. +For example, if FOO is the name of a macro that requires two arguments, +4FOO#A,FARB+7* and 4FOO#(A,FARB+7)* have the same effect. +.END + +If the argument list is enclosed in parentheses, then the first argument +begins with the first character after the "4(*", even if it is blank. +Subsequent arguments begin with the first character +after the comma that terminates the previous argument. Arguments +do not include the comma or "4)*" used to terminate them. Arguments +are scanned until the matching "4)*" is seen. + +If the argument list is not enclosed in parentheses, the first argument +begins with the first non-blank character after the macro name. +Subsequent arguments begin with the first character +after the comma that terminated the previous argument. Arguments +do not include the comma or other character used to terminate them. +Arguments are scanned until any one of right bracket, +right broket, right brace, %<semicolon>, or %<carriage return> is seen. +~<brokets>~<braces>~<brackets> + +Two commas in a row with nothing in between signify a 2%<null argument>*, +i.e., an argument that consists of no characters. If more arguments +are called for than are supplied, the last ones are considered to be +null. If more arguments are supplied than are called for, the extras +are ignored by the macro processor; see %%EATMAC;. + +Unless the first character of an argument is "4{*", the argument terminates +at the first comma, right parenthesis, right brace (or broket), right bracket, +or carriage return. +If the first character of an argument is "4{*" (or "4<*"), then all characters +included 2between* the matching braces are taken as the argument. This +allows the argument to contain commas, parentheses, etc. which would +not be legal otherwise, but the braces must be kept balanced. +In addition, all characters between the "4}*" that closes the argument +and the next argument terminator are ignored. This allows the +continuation of a list of arguments from one line to the next (i.e., +enclose the last argument on the line in braces and put the +comma for it at the start of the next line). + +If the first character of an argument is a +%<backslash> (4\*) or %<right-arrow> (4*), then the next thing +after the backslash (or right-arrow) is considered to be an expression +(and it better be defined). +The expression is evaluated and the +value is converted to a string of ascii digits in the current radix +(the radix ought not be 1). This string of digits is taken as the +argument. All characters from the end of the expression to the next +argument termination character (comma, etc.) are ignored. + +.BEGIN TURN ON "{" +.SENDIT ".XTABM" +.SENDIT ".ITABM" +.END; +After a 4.*DIRECT pseudo op has appeared with the 4.*XTABM +argument (see %%DIRECT;) then in a macro call where the macro +argument is 2not* enclosed in braces, the leading and trailing +blanks and tabs adjacent to the argument in the call will be omitted +from the actual argument passed to the macro. The argument +4.*ITABM to 4.*DIRECT restores FAIL to the normal treatment of +tabs and spaces in arguments. + .SSS How Much is Eaten by a Macro Call +$$EATMAC: + +When a macro call appears, some of the text following the macro name +is considered to be part of the call. Any text that is not part of the macro +call will be assembled as usual. +For instance, if + +.BEGIN VERBATIM SELECT 4; + + DEFINE FOO (A) {A + 7/6} +.END + +has appeared, then when + +.BEGIN VERBATIM SELECT 4; + + MOVEI A,FOO (3) (6) ;comment +.END + +appears, it will be assembled as + +.BEGIN VERBATIM SELECT 4; + + MOVEI A,3 + 7/6 (6) ;comment +.END + +Thus, the text 4FOO (3)* is considered to be part of the macro +call and is "eaten". + +The following rules govern how much text gets +eaten in a macro call. If the macro was defined as having no +arguments, then only the macro name and any following spaces (or +tabs) are eaten. If the macro was defined as having arguments and +the first non-blank character after the macro name is a +left parenthesis, then everything from the macro name to the right +parenthesis which closes the argument list, inclusive, is eaten. If +the macro was defined as having arguments and the first non-blank +character is not a left parenthesis, then everything from the macro +name to the comma or carriage return which terminates the last macro +argument used is eaten. Thus, if parentheses are not used and too +few arguments are supplied, everything from the macro name to the +carriage return will be eaten. If parentheses are not used and the +macro was defined as having arguments and enough or too many +arguments are supplied, then everything from the macro name to the comma +(or carriage return) which terminates the last argument used will be +eaten. + +.Comment this must appear at "the end of section ..."; +$$CATEX: +.Example + + DEFINE FOO $ (A,B) {A$B} + MOVEI FOO 1,2, ,37(6) ;will expand to: + ;MOVEI 12 ,37(6) + ;"FOO 1,2," has been eaten +.END + .SSS Complex Example +This example is given without a full explanation. It shows an +example of an information carrying macro. The macro BAR is expanded +(by being redefined) every time that ADD1 is used. The 4\BAR* in +the definition of ADD1 is necessary to cause the evaluation of 4BAR* +as an expression (which causes a macro expansion to occur). + +.Example + + DEFINE BAR {0,} + DEFINE FOO (A,B,C) {DEFINE BAR {0,<B +C>}} + DEFINE ADD1 (X) {FOO(\BAR,X)} + DEFINE SEC (A,B) {B} + + ;BAR = 0, + ADD1(X1) + ;BAR = 0,< + ; X1> + ADD1(X2) + ;BAR = 0,< + ; X1 + ; X2> + ADD1(X3) + ;BAR = 0,< + ; X1 + ; X2 + ; X3> + + SEC(\BAR) ;THIS GENERATES THE FOLLOWING: + ; X1 + ; X2 + ; X3 +.END + .SSI FOR +.PSEUD1 FOR + +There are three types of FORs; all have the same general form. Each +consists of the word FOR, an optional 2concatenation character*, a +2range specifier*, and a 2%<FOR-body>*. The FOR statement expands +into the text of +its FOR-body, possibly with substitutions, repeated once for +each element in the range of the FOR. FOR replaces the %<IRP> and %<IRPC> +pseudo-ops found in MACRO-10. FOR is a pseudo-op; it is recognized only +where FAIL allows opcodes to appear. + +The optional 2%<concatenation character>* is specified by following the +word FOR with an %<at-sign> followed immediately by the +concatenation character. If a FOR is used inside a macro and +concatenation of FOR arguments is desired, it is necessary to have a +concatenation character specified for the FOR which is different from +the one for the macro. + +The 2%<range specifier>* is different for each type of FOR and will be +explained below. The FOR statement may have one or two 2%<formal arguments>* +which are specified in the range specification. + +The 2FOR-body* has the same form as a macro body; the text is enclosed in +braces, and braces must be balanced. + + +.SSSI String FOR + +The range specification consists of one or two formal argument +identifiers, followed by either the identifier "4IN*" or the +2%<containment character>* (4*), +followed by an argument list. The argument list has the same syntax +as a macro call argument list (see %%MARGL;), but the list 2must* be in +%<parentheses>. The effect is that the body of the FOR is assembled +once for each element in the argument list, and that element is +substituted for the first (or only) formal argument each time. The +second formal argument, if present, will have the remainder of the +argument list (starting with the element following the one currently +substituted for the first argument) substituted for it. + +.Example s + + Source Expansion + +FOR A IN (QRN,{(<JRST 4,>)},STORP) MOVSI 13,QRN +{MOVSI 13,A PUSHJ P,GORP +PUSHJ P,GORP MOVSI 13,(<JRST 4,>) +} PUSHJ P,GORP + MOVSI 13,STORP + PUSHJ P,GORP + +.END +.BEGIN VERBATIM GROUP SELECT 4; IF XCRIBL THEN NARROW 8; + Source Expansion + +FOR ZOT,FUB  (A,B,C,D) MOVEI A,137 ; B,C,D LEFT +{MOVEI ZOT,137 ; FUB LEFT MOVEI B,137 ; C,D LEFT +} MOVEI C,137 ; D LEFT + MOVEI D,137 ; LEFT +.END + +.SSSI Character FOR + +The range specifier consists of one or two formal arguments followed +by either the letter "4E*" or the character %<epsilon> (4*), +followed by a string of +characters enclosed in %<braces>. The only restriction on the +string of characters is that the braces must balance. The +body of the FOR is assembled once for each character in the list, +with that character substituted for the first formal argument each +time and the rest of the string substituted for the second formal +argument, if any. + +.Example s + + Source Expansion + +FOR ZOT,FUB  {ABCD} MOVEI A,137 ; BCD LEFT +{MOVEI ZOT,137 ; FUB LEFT MOVEI B,137 ; CD LEFT +} MOVEI C,137 ; D LEFT + MOVEI D,137 ; LEFT + +.END +.BEGIN VERBATIM GROUP SELECT 4; IF XCRIBL THEN NARROW 8; + Source Expansion + +FOR @$ QRN E {AZ1Q5} ZORPA_0 +{ZORP$QRN_0 ZORPZ_0 +} ZORP1_0 + ZORPQ_0 + ZORP5_0 + +.END + +.SSSI Arithmetic FOR + +This type of FOR is similar to the ALGOL FOR statement. The range specifier +consists of one or two formal arguments followed by a %<left-arrow>, +followed by two or three expressions, separated by %<comma>s. The +expressions are like the two or three arguments of a FORTRAN DO +statement. The value of the first is the starting value, the value +of the second is the ending value, and the value of the third is the +increment. If the third expression is not present, 1 is used as the +increment. + +The body of the FOR is assembled repeatedly, first for the starting +value, then for the starting value plus the increment, etc. until it +has been assembled once for each such value which is less than or +equal to the ending value (greater than or equal if the increment +is negative). If the starting value is already greater than the +ending value (less than, for negative increment), the FOR body is not +assembled at all. For each repetition, the current value is +converted to ascii digits in the current radix, and that string is +substituted for the formal argument(s) (both arguments have the same +value). Note that all expressions must be defined, available, and absolute. + +.Example "s (assume RADIX =8)" + + Source Expansion + +FOR I_1+3, 25, 7 XWD FOO,4 +{XWD FOO,I XWD FOO,13 +} XWD FOO,22 + +.END +.BEGIN VERBATIM GROUP SELECT 4; IF XCRIBL THEN NARROW 8; + Source Expansion + +FOR @$ ZOT_11,4,-1 ZOTQ11 : 11 +3 +{ZOTQ$ZOT : ZOT +3 ZOTQ10 : 10 +3 +} ZOTQ7 : 7 +3 + ZOTQ6 : 6 +3 + ZOTQ5 : 5 +3 + ZOTQ4 : 4 +3 + +.END + .SSI REPEAT +.PSEUD1 REPEAT + +The REPEAT statement is included for compatibility with MACRO-10. +REPEAT is a pseudo-op; it is recognized only where FAIL allows +opcodes to appear. The format is + +.BEGIN VERBATIM SELECT 4; + + REPEAT exp,{text} +.END + +The expression 4exp* is evaluated, and the text is assembled that +number of times, with a carriage return and line feed inserted at its +end each time. The text is like a macro body: braces must balance. + +For example, the statement: + +.BEGIN VERBATIM SELECT 4; + + REPEAT 3, {0} +.END + +will expand to: + +.BEGIN VERBATIM SELECT 4; + + 0 + 0 + 0 +.END + +.SSI Conditional Assembly + +The 2conditional assembly* opcodes (the IFs) are like macros: +they will be recognized +wherever they appear, as long as the assembler sees them as +identifiers. Thus, an IF need not be the first thing on a line. +Attempts to use IFs as symbols will produce erroneous results. + +.SSSI Numeric IFs + +.PSEUD1(IFE);PSEUD1(IFN);PSEUD1(IFG);PSEUD1(IFL);PSEUD1(IFGE);PSEUD1(IFLE); +There are six numeric IFs: + +.BEGIN TURN ON "\"; nofill; tabs 8,30; + +\4IFE exp,{text}*\assembles 4text* if 4exp=0* +\4IFN exp,{text}*\assembles 4text* if 4exp0* +\4IFG exp,{text}*\assembles 4text* if 4exp>0* +\4IFL exp,{text}*\assembles 4text* if 4exp<0* +\4IFGE exp,{text}*\assembles 4text* if 4exp0* +\4IFLE exp,{text}*\assembles 4text* if 4exp0* +.END + +The expression 4exp* is evaluated. If its value bears the indicated +relation to zero, the text is assembled once; otherwise it is not +assembled. The text, which is called the 2%<IF-body>*, is like a macro body: +braces must balance. + +.BEGIN NOFILL GROUP TURN ON "\"; IF XCRIBL THEN TABS 8,40; +.IF XCRIBL THEN TABS 2,32; + +Examples: + +\4IFE 3, {ZOT}*\assembles nothing +\4IFGE 15, {JRST START}*\assembles 4JRST START* +\4PUSHJ P,IFN PARM,{BAZ;}FOO*\assembles 4PUSHJ P,BAZ;FOO* if 4PARM0* +\4PUSHJ P,IFN PARM,{BAZ;}FOO*\assembles 4PUSHJ P,FOO* if 4PARM=0* +. +.END + .SSSI Text IFs +.PSEUD1(IFIDN);PSEUD1(IFDIF) + +There are two text IFs. They are IFIDN and IFDIF, which stand +for "if identical" and "if different", respectively. The format is + +.BEGIN VERBATIM SELECT 4; + + IFIDN {text 1} {text 2} {text 3} +.END + +.begin turn on "#" +The texts can be any string of characters in which the braces +balance. For IFIDN, if the two strings 4text#1* and 4text#2* are +identical in each and every character, the string 4text#3* will be +assembled, otherwise it will not. For IFDIF, if 4text#1* and 4text#2* +are different, 4text#3* will be assembled, otherwise it will not. +.end + +.SSSI Symbol IFs +.PSEUD1(IFDEF);PSEUD1(IFNDEF);PSEUD1(IFAVL);PSEUD1(IFNAVL); +.PSEUD1(IFOP);PSEUD1(IFNOP);PSEUD1(IFMAC);PSEUD1(IFNMAC); + +There are eight symbol IFs. They are IFDEF, IFNDEF, +IFAVL, IFNAVL, IFOP, IFNOP, IFMAC, and IFNMAC. A typical example is + +.BEGIN VERBATIM SELECT 4; + + IFDEF symbol,{text} +.END + +If the indicated condition is true for the symbol, the text is +assembled; otherwise it is not. These conditionals come in pairs; +if one of a pair is true, the other is false. + +IFDEF is true if the symbol is defined in this block or in an outer block. +Defined symbols may be either opcodes, macro names, labels, or parameters. +IFDEF will be true if the symbol could be used on a line by +itself (ignoring possible future definitions). + +IFAVL is true if the symbol is available. +That is, IFAVL is true if the symbol is +defined as an opcode or macro or if it has been defined in this +block, declared global in this block and defined in an outer +block, or defined in an outer block with a %<down-arrow>. + +IFOP is true if the symbol is defined as an opcode. + +IFMAC is true if the symbol is defined as a macro (including the IFs, +IOWD, and the predefined symbols 4.*CPU4.*, 4.*FNAM1, 4.*FNAM2, +4.*INSERT, "4$.*", and "4.*"). + .APPNDX1 (COMMANDS,Command Language) +$APPCOM: + +The basic format of a FAIL command is + +.BEGIN VERBATIM SELECT 4; +.SKIP 1; + binary-file,listing-file_source-file-1, ... ,source-file-n +.END + +File specifications consist of + +.BEGIN VERBATIM SELECT 4; +.SKIP 1; + device:file +.END + +If 4device:* is missing, 4DSK:* is assumed. Either (or both) +output file(s) may be omitted. If the 4listing-file* is included, +a %<comma> must precede it. 4Source-file* names are separated by +commas. The device name for source files is sticky, so to change +devices the device name must be explicit, even if it is 4DSK:*. +Multiple source files are concatenated as one assembly. If the last +4source-file* name on a line ends with a comma (and carriage return-line feed) +then the next line is taken as a continuation of this command. + +If no file extension is given for the binary and list files, 4REL* +and 4LST* are assumed, respectively (in the non-Stanford FAIL, +4CRF* is the default extension for the list file). If no extension +is given for the source file(s), 4FAI* is tried first; failing +that, a blank extension is tried. + +Switches should follow file names and may be either of the %<slash> type +or %<parentheses> type (e.g., "4/x*" or "4(x)*"). + +Device switches (must follow the name of the affected file): +.BEGIN NOFILL GROUP SELECT 4 SKIP 1; + nA advance magnetic tape n files + nB backspace magnetic tape n files + T skip to logical end of magnetic tape + W rewind magnetic tape + Z zero DECtape directory +.END + +Assembler switches (may appear after any file name): +.BEGIN NOFILL GROUP SELECT 4 SKIP 1 + C make a cross-reference (%<CREF>) listing + F don't pause after errors (inverse of R) + I ignore XLIST1 pseudo-op + J turn on %<cross-reference listing> output + K turn off cross-reference listing output + L don't list literal values with text + N don't list assembly errors on TTY + O omit binary universal (%<FUN>) file output + R pause after each assembly error + S list symbol table + U underline macro expansions on listing + nV set the number of lines/page in listing to n + X don't list macro expansions +.END + + +The 4P* switch is used to allocate extra space for the macro push-down list +(PDL), which is normally 200 (octal) locations long. +If recursive macros are used, more space may be needed. The +macro PDL will be expanded by 200 words for every occurrence of the P +switch in the command string. A numeric argument may given with the P +switch to specify a multiple of 200 words by which to expand the PDL. + +The 4E* switch is used to allocate extra space for the main push-down list. +The main PDL will be expanded by 200 words for every occurrence of the E +switch in the command string. A numeric argument may given with the E +switch to specify a multiple of 200 words by which to expand the PDL. + +Sometimes, assembly parameters are specified from the user terminal, rather +than being included in the source program. +Suppose the line 4SEGSW__1* needs to be included in +the assembly of the file BAZ. The following command sequence would do that +(and make a cross-reference listing of BAZ): + +.BEGIN VERBATIM GROUP SELECT 4 SKIP 1; +BAZ,BAZ/C_TTY:,DSK:BAZ +SEGSW__1 +^Z +.END + +The text is typed to FAIL and terminated with %<control-Z> (4^Z*) (at +Stanford displays, %<control-meta-line feed> is used instead of control-Z). +Using %<RPG> (known elsewhere as %<COMPIL>), the command sequence would be + +.BEGIN VERBATIM GROUP SELECT 4 SKIP 1; +COMPILE/CREF TTY:F+DSK:BAZ +SEGSW__1 +^Z +.END + +The file name 4F* is needed to satisfy the RPG +syntax; the device name 4DSK:* is needed to switch the default input device +to DSK. + +If the command 4FILE@* is seen, the +named file will be read and interpreted as containing a series of commands of +the usual form. + +The command 4FILE!* causes FAIL to exit and run the named program. The +default device for this command is 4SYS:*. + +To provide some compatibility with RPG-style commands, FAIL accepts "4=*" for +"4_*" in the command line. Also, either "4+*" or "4;*" may be used +instead of "4,*" to separate 4source-file* names. + .APPNDX3(VAL,Relocatable and Undefined Values) +$VALAPP: + +FAIL binary programs are usually required to be 2%<relocatable>*, +i.e., loadable anywhere in a core image. Many values depend upon the +absolute location of a program within its core image, e.g., the +target address of a branch instruction. The final determination of +these values must be made by the %<loader>. + +The problem of relocation can usually be reduced to a question of +whether or not to augment a value by the 2%<relocation constant>*, +which is simply the location at which the loader decides to begin +loading this program. The mechanism for handling this involves +associating with each value a 2%<relocation factor>*, which is (at +load time) to be multiplied by the relocation constant and added to +the value. For the simple relocation mechanism to work, the +relocation factor must be a constant and either 0 or 1. Since 36 +bits may contain two 18-bit addresses, a relocation factor is +provided for each halfword. Thus, a value which is completely +determined except for simple relocation can be expressed in 38 bits. +A value in which at least one relocation factor is non-zero is said +to be 2relocatable*; one in which both are zero is said to be +2%<unrelocatable>* or 2%<absolute>*. + +There is a more general, less efficient mechanism for delaying +calculations until load time. This is used in more complex cases +where the simple relocation scheme is inadequate. Whenever a +value cannot be calculated immediately and cannot be handled by the +relocation mechanism because it requires some other type of deferred +calculation, the value is said to be 2%<undefined>*. Undefined +values are represented by relatively complex structures which are +retained in FAIL for final evaluation or, if necessary, passed to the +loader for evaluation. Undefined values are illegal in those +contexts which require the value to be immediately known, including +some situations where the relocation factor mechanism is legal. The +legality of undefined or relocatable values is indicated in the +discussion of each possible usage. + .APPNDX3(PDOP,Predefined Opcodes) +~<hardware instruction>~<Predefined Opcodes> +The standard %<machine instruction> mnemonics of the PDP-10 (KA-10) +are defined in FAIL. + +When the Stanford version of FAIL is started, it obtains from the +system the definitions for all system %<UUO>s and CALLIs that are +available at the time of the assembly. + +The table that follows includes all the pseudo-ops, machine instruction +mnemonics, special symbols, and UUO mnemonics currently available at Stanford. +The indication 4SAIL* is used to indicate UUOs and machine instructions +available only at Stanford. The indication 4UUO* is used to mark system +calls that are also available on a DEC system. Hardware I/O instructions +are indicated by 4I/O*; these instructions are not available to normal user +programs. Machine instruction mnemonics for the KI-10 processor are available +as a conditional assembly feature in FAIL; +these are flagged with the indication 4KI*. +The entry for each pseudo-op includes the page number where that +pseudo-op is explained. + +Note that there are sometimes +subtle differences between DEC system UUOs and Stanford UUOs; consult the +appropriate reference manual. Also note that some DEC mnemonics conflict +with those used at Stanford. + +.BEGIN SKIP TO COLUMN 1 +.IF XCRIBL THEN AREA FOO LINES 5 TO 53 IN 2 COLUMNS 5 APART; +.IF XCRIBL THEN AREA FOO LINES 5 TO 51 IN 3 COLUMNS 3 APART; +.NOFILL; PLACE FOO; TURN ON "\"; SELECT 5; +.IF XCRIBL THEN TABS 8,19 ELSE TABS 11,26; +$.\Predefined\%~PDFSYM; +.\Predefined\%~PDFSYM; +.ASSIGN\Pseudo-op\%~ASSIGN; +.COMMON\Pseudo-op\%~COMMON; +.CPU.\Predefined\%~CPU; +.DIRECT\Pseudo-op\%~DIRECT; +.FATAL\Pseudo-op\%~FATAL; +.FNAM1\Predefined\%~FNAM1; +.FNAM2\Predefined\%~FNAM2; +.INSERT\Pseudo-Op\%~INSERT; +.LIBRARY\Pseudo-Op\%~LIBRARY; +.LINK\Pseudo-Op\%~LINK; +.LNKEND\Pseudo-Op\%~LNKEND; +.LOAD\Pseudo-Op\%~LOAD; +.ORG\Pseudo-Op\%~ORG; +.REQUEST\Pseudo-Op\%~REQUEST; +.REQUIRE\Pseudo-Op\%~REQUIRE; +.TEXT\Pseudo-Op\%~TEXT; +.SKIP 1 +ACCTIM\CALLI 400101\SAIL +ACTCHR\CALLI 400105\SAIL +ADD\270000,,0 +ADDB\273000,,0 +ADDI\271000,,0 +ADDM\272000,,0 +ADSMAP\CALLI 400110\SAIL +AND\404000,,0 +ANDB\407000,,0 +ANDCA\410000,,0 +ANDCAB\413000,,0 +ANDCAI\411000,,0 +ANDCAM\412000,,0 +ANDCB\440000,,0 +ANDCBB\443000,,0 +ANDCBI\441000,,0 +ANDCBM\442000,,0 +ANDCM\420000,,0 +ANDCMB\423000,,0 +ANDCMI\421000,,0 +ANDCMM\422000,,0 +ANDI\405000,,0 +ANDM\406000,,0 +AOBJN\253000,,0 +AOBJP\252000,,0 +AOJ\340000,,0 +AOJA\344000,,0 +AOJE\342000,,0 +AOJG\347000,,0 +AOJGE\345000,,0 +AOJL\341000,,0 +AOJLE\343000,,0 +AOJN\346000,,0 +AOS\350000,,0 +AOSA\354000,,0 +AOSE\352000,,0 +AOSG\357000,,0 +AOSGE\355000,,0 +AOSL\351000,,0 +AOSLE\353000,,0 +AOSN\356000,,0 +APRENB\CALLI 16\UUO +.PENT ARRAY +.PENT ASCID +.PENT ASCII +.PENT ASCIZ +ASH\240000,,0 +ASHC\244000,,0 +.PENT ASSIGN +.PENT ASUPPRESS +ATTSEG\CALLI 400016\SAIL +.SKIP 1 +BEEP\CALLI 400111\SAIL +.PENT BEGIN +.PENT BEND +BLKI\700000,,0\I/O +BLKO\700100,,0\I/O +.PENT BLOCK +BLT\251000,,0 +BUFLEN\CALLI 400042\SAIL +.PENT BYTE +.SKIP 1 +CAI\300000,,0 +CAIA\304000,,0 +CAIE\302000,,0 +CAIG\307000,,0 +CAIGE\305000,,0 +CAIL\301000,,0 +CAILE\303000,,0 +CAIN\306000,,0 +CALL\040000,,0\UUO +CALLI\047000,,0\UUO +CALLIT\CALLI 400074\SAIL +CAM\310000,,0 +CAMA\314000,,0 +CAME\312000,,0 +CAMG\317000,,0 +CAMGE\315000,,0 +CAML\311000,,0 +CAMLE\313000,,0 +CAMN\316000,,0 +CHNSTS\716000,,0\SAIL +CLKINT\717000,,0\SAIL +CLOSE\070000,,0\UUO +CLRBFI\051440,,0\UUO +CLRBFO\051500,,0\UUO +.PENT COMMENT +CONI\700240,,0\I/O +CONO\700200,,0\I/O +CONS\257000,,0\SAIL +CONSO\700340,,0\I/O +CONSZ\700300,,0\I/O +CORE\CALLI 11\UUO +CORE2\CALLI 400015\SAIL +.PENT CREF +CTLV\CALLI 400001\SAIL +.SKIP 1 +DATAI\700040,,0\I/O +DATAO\700140,,0\I/O +DATE\CALLI 14\UUO +DAYCNT\CALLI 400100\SAIL +DDCHAN\CALLI 400067\SAIL +DDTGT\CALLI 5\UUO +DDTIN\CALLI 1\UUO +DDTOUT\CALLI 3\UUO +DDTRL\CALLI 7\UUO +DDUPG\715140,,0\SAIL +DEBREAK\CALLI 400035\SAIL +.PENT DEC +.PENT DEFINE +.PENT DEPHASE +DETSEG\CALLI 400017\SAIL +DEVCHR\CALLI 4\UUO +DEVNUM\CALLI 400104\SAIL +DEVUSE\CALLI 400051\SAIL +DFAD\110000,,0\KI +DFDV\113000,,0\KI +DFMP\112000,,0\KI +DFN\131000,,0 +DFSB\111000,,0\KI +DIAL\CALLI 400117\SAIL +DISMISS\CALLI 400024\SAIL +DIV\234000,,0 +DIVB\237000,,0 +DIVI\235000,,0 +DIVM\236000,,0 +DMOVE\120000,,0\KI +DMOVEM\124000,,0\KI +DMOVN\121000,,0\KI +DMOVNM\125000,,0\KI +DPB\137000,,0 +DPYCLR\701000,,0\SAIL +DPYOUT\703000,,0\SAIL +DPYPOS\702100,,0\SAIL +DPYSIZ\702140,,0\SAIL +DSKPPN\CALLI 400071\SAIL +DSKTIM\CALLI 400072\SAIL +.SKIP 1 +EIOTM\CALLI 400005\SAIL +.PENT END +ENTER\077000,,0\UUO +.PENT ENTRY +EQV\444000,,0 +EQVB\447000,,0 +EQVI\445000,,0 +EQVM\446000,,0 +EXCH\250000,,0 +EXIT\CALLI 12\UUO +.PENT EXTERNAL +.SKIP 1 +FAD\140000,,0 +FADB\143000,,0 +FADL\141000,,0 +FADM\142000,,0 +FADR\144000,,0 +FADRB\147000,,0 +FADRI\145000,,0 +FADRL\145000,,0 +FADRM\146000,,0 +FBREAD\706000,,0\SAIL +FBWAIT\CALLI 400057\SAIL +FBWRT\707000,,0\SAIL +FDV\170000,,0 +FDVB\173000,,0 +FDVL\171000,,0 +FDVM\172000,,0 +FDVR\174000,,0 +FDVRB\177000,,0 +FDVRI\175000,,0 +FDVRL\175000,,0 +FDVRM\176000,,0 +FIX\247000,,0\SAIL +FIX\122000,,0\KI +FIXR\126000,,0\KI +FLTR\127000,,0\KI +FMP\160000,,0 +FMPB\163000,,0 +FMPL\161000,,0 +FMPM\162000,,0 +FMPR\164000,,0 +FMPRB\167000,,0 +FMPRI\165000,,0 +FMPRL\165000,,0 +FMPRM\166000,,0 +.PENT FOR +FSB\150000,,0 +FSBB\153000,,0 +FSBL\151000,,0 +FSBM\152000,,0 +FSBR\154000,,0 +FSBRB\157000,,0 +FSBRI\155000,,0 +FSBRL\155000,,0 +FSBRM\156000,,0 +FSC\132000,,0 +.SKIP 1 +.PENT GDEFINE +GDPTIM\CALLI 400065\SAIL +GETCHR\CALLI 6 \UUO +GETLIN\051300,,0\SAIL +GETLN\CALLI 34\UUO +GETNAM\CALLI 400062\SAIL +GETPPN\CALLI 24\UUO +GETPR2\CALLI 400053\SAIL +GETPRV\CALLI 400115\SAIL +GETSEG\CALLI 40\UUO +GETSTS\062000,,0\UUO +GETTAB\CALLI 41\UUO +.PENT GLOBAL +.SKIP 1 +HALT\254200,,0 +.PENT HISEG +HLL\500000,,0 +HLLE\530000,,0 +HLLEI\531000,,0 +HLLEM\532000,,0 +HLLES\533000,,0 +HLLI\501000,,0 +HLLM\502000,,0 +HLLO\520000,,0 +HLLOI\521000,,0 +HLLOM\522000,,0 +HLLOS\523000,,0 +HLLS\503000,,0 +HLLZ\510000,,0 +HLLZI\511000,,0 +HLLZM\512000,,0 +HLLZS\513000,,0 +HLR\544000,,0 +HLRE\574000,,0 +HLREI\575000,,0 +HLREM\576000,,0 +HLRES\577000,,0 +HLRI\545000,,0 +HLRM\546000,,0 +HLRO\564000,,0 +HLROI\565000,,0 +HLROM\566000,,0 +HLROS\567000,,0 +HLRS\547000,,0 +HLRZ\554000,,0 +HLRZI\555000,,0 +HLRZM\556000,,0 +HLRZS\557000,,0 +HRL\504000,,0 +HRLE\534000,,0 +HRLEI\535000,,0 +HRLEM\536000,,0 +HRLES\537000,,0 +HRLI\505000,,0 +HRLM\506000,,0 +HRLO\524000,,0 +HRLOI\525000,,0 +HRLOM\526000,,0 +HRLOS\527000,,0 +HRLS\507000,,0 +HRLZ\514000,,0 +HRLZI\515000,,0 +HRLZM\516000,,0 +HRLZS\517000,,0 +HRR\540000,,0 +HRRE\570000,,0 +HRREI\571000,,0 +HRREM\572000,,0 +HRRES\573000,,0 +HRRI\541000,,0 +HRRM\542000,,0 +HRRO\560000,,0 +HRROI\561000,,0 +HRROM\562000,,0 +HRROS\563000,,0 +HRRS\543000,,0 +HRRZ\550000,,0 +HRRZI\551000,,0 +HRRZM\552000,,0 +HRRZS\553000,,0 +.SKIP 1 +IBP\133000,,0 +IDIV\230000,,0 +IDIVB\233000,,0 +IDIVI\231000,,0 +IDIVM\232000,,0 +IDPB\136000,,0 +IENBW\CALLI 400045\SAIL +.CDENT IFAVL +.CDENT IFDEF +.CDENT IFDIF +.CDENT IFE +.CDENT IFG +.CDENT IFGE +.CDENT IFIDN +.CDENT IFL +.CDENT IFLE +.CDENT IFMAC +.CDENT IFN +.CDENT IFNAVL +.CDENT IFNDEF +.CDENT IFNMAC +.CDENT IFNOP +.CDENT IFOP +ILDB\134000,,0 +IMSKCL\722000,,0\SAIL +IMSKCR\723240,,0\SAIL +IMSKST\721000,,0\SAIL +IMSTW\723040,,0\SAIL +IMUL\220000,,0 +IMULB\223000,,0 +IMULI\221000,,0 +IMULM\222000,,0 +IN\056000,,0\UUO +INBUF\064000,,0\UUO +INCHRS\051100,,0\UUO +INCHRW\051000,,0\UUO +INCHSL\051240,,0\UUO +INCHWL\051200,,0\UUO +INIT\041000,,0\UUO +INPUT\066000,,0\UUO +INSKIP\051540,,0\SAIL +INTACM\CALLI 400027\SAIL +INTDEJ\723000,,0\SAIL +INTDMP\723140,,0\SAIL +.PENT INTEGER +INTENB\CALLI 400025\SAIL +INTENS\CALLI 400030\SAIL +.PENT INTERNAL +INTGEN\CALLI 400033\SAIL +INTIIP\CALLI 400031\SAIL +INTIPI\723200,,0\SAIL +INTIRQ\CALLI 400032\SAIL +INTJEN\723000,,0\SAIL +INTMSK\720000,,0\SAIL +INTORM\CALLI 400026\SAIL +INTUUO\723000,,0\SAIL +INWAIT\051600,,0\SAIL +IOPDL\726000,,0\SAIL +IOPOP\725000,,0\SAIL +IOPUSH\724000,,0\SAIL +IOR\434000,,0 +IORB\437000,,0 +IORI\435000,,0 +IORM\436000,,0 +.PENT IOWD +IWAIT\CALLI 400040\SAIL +IWKMSK\723100,,0\SAIL +.SKIP 1 +JBTSTS\CALLI 400013\SAIL +JCRY\255300,,0 +JCRY0\255200,,0 +JCRY1\255100,,0 +JEN\254500,,0 +JFCL\255000,,0 +JFFO\243000,,0 +JFOV\255040,,0 +JOBRD\CALLI 400050\SAIL +JOV\255400,,0 +JRA\267000,,0 +JRST\254000,,0 +JRSTF\254100,,0 +JSA\266000,,0 +JSP\265000,,0 +JSR\264000,,0 +JUMP\320000,,0 +JUMPA\324000,,0 +JUMPE\322000,,0 +JUMPG\327000,,0 +JUMPGE\325000,,0 +JUMPL\321000,,0 +JUMPLE\323000,,0 +JUMPN\326000,,0 +.SKIP 1 +.PENT LALL +LDB\135000,,0 +LEYPOS\702300,,0\SAIL +.PENT LINK +.PENT LINKEND +LINKUP\CALLI 400023\SAIL +LIOTM\CALLI 400006\SAIL +.PENT LIST +.PENT LIT +.PENT LOC +LOCK\CALLI 400076\SAIL +LOGIN\CALLI 15\UUO +LOGOUT\CALLI 17\UUO +LOOKUP\076000,,0\UUO +LSH\242000,,0 +LSHC\246000,,0 +.SKIP 1 +MAIL\710000,,0\SAIL +MAP\257000,,0\KI +MOVE\200000,,0 +MOVEI\201000,,0 +MOVEM\202000,,0 +MOVES\203000,,0 +MOVM\214000,,0 +MOVMI\215000,,0 +MOVMM\216000,,0 +MOVMS\217000,,0 +MOVN\210000,,0 +MOVNI\211000,,0 +MOVNM\212000,,0 +MOVNS\213000,,0 +MOVS\204000,,0 +MOVSI\205000,,0 +MOVSM\206000,,0 +MOVSS\207000,,0 +MSTIME\CALLI 23\UUO +MTAPE\072000,,0\UUO +MUL\224000,,0 +MULB\227000,,0 +MULI\225000,,0 +MULM\226000,,0 +.SKIP 1 +NAMEIN\CALLI 400043\SAIL +.PENT NOLIT +.PENT NOSYM +.SKIP 1 +.PENT OCT +.PENT OPDEF +OPEN\050000,,0\UUO +OR\434000,,0 +ORB\437000,,0 +ORCA\454000,,0 +ORCAB\457000,,0 +ORCAI\455000,,0 +ORCAM\456000,,0 +ORCB\470000,,0 +ORCBB\473000,,0 +ORCBI\471000,,0 +ORCBM\472000,,0 +ORCM\464000,,0 +ORCMB\467000,,0 +ORCMI\465000,,0 +ORCMM\466000,,0 +.PENT ORG +ORI\435000,,0 +ORM\436000,,0 +OUT\057000,,0\UUO +OUTBUF\065000,,0\UUO +OUTCHR\051040,,0\UUO +OUTFIV\051740,,0\SAIL +OUTPUT\067000,,0\UUO +OUTSTR\051140,,0\UUO +.SKIP 1 +.PENT PAGE +PEEK\CALLI 33\UUO +PGACT\715040,,0\SAIL +PGCLR\715100,,0\SAIL +PGINFO\715200,,0\SAIL +PGIOT\715000,,0\SAIL +PGSEL\715000,,0\SAIL +.PENT PHASE +PJOB\CALLI 30\UUO +PNAME\CALLI 400007\SAIL +.PENT POINT +POINTS\712000,,0\SAIL +POP\262000,,0 +POPJ\263000,,0 +PORTAL\254040,,0\KI +PPACT\702040,,0\SAIL +PPHLD\702340,,0\SAIL +PPINFO\702240,,0\SAIL +PPIOT\702000,,0\SAIL +PPREL\702200,,0\SAIL +PPSEL\702000,,0\SAIL +PPSPY\CALLI 400107\SAIL +.PENT PRGEND +.PENT PRINTS +.PENT PRINTX +PTGETL\711540,,0\SAIL +PTIFRE\711100,,0\SAIL +PTJOBX\711700,,0\SAIL +PTLOAD\711640,,0\SAIL +PTOCNT\711140,,0\SAIL +PTRD1S\711200,,0\SAIL +PTRD1W\711240,,0\SAIL +PTRDS\711400,,0\SAIL +PTSETL\711600,,0\SAIL +PTWR1S\711300,,0\SAIL +PTWR1W\711340,,0\SAIL +PTWRS7\711440,,0\SAIL +PTWRS9\711500,,0\SAIL +PTYGET\711000,,0\SAIL +PTYREL\711040,,0\SAIL +PTYUUO\711000,,0\SAIL +.PENT PURGE +PUSH\261000,,0 +PUSHJ\260000,,0 +PZE\000000,,0 +.SKIP 1 +.PENT RADIX +.PENT RADIX50 +REASSI\CALLI 21\UUO +RELEAS\071000,,0\UUO +.PENT RELOC +REMAP\CALLI 37\UUO +RENAME\055000,,0\UUO +.PENT REPEAT +RESCAN\051400,,0\UUO +RESET\CALLI 0\UUO +RLEVEL\CALLI 400054\SAIL +ROT\241000,,0 +ROTC\245000,,0 +RUN\CALLI 35\UUO +RUNMSK\CALLI 400046\SAIL +RUNTIM\CALLI 27\UUO +.SKIP 1 +.PENT SEARCH +SEGNAM\CALLI 400037\SAIL +SEGNUM\CALLI 400021\SAIL +SEGSIZ\CALLI 400022\SAIL +SEND\710000,,0\SAIL +.PENT SET +SETA\424000,,0 +SETAB\427000,,0 +SETACT\051640,,0\SAIL +SETAI\425000,,0 +SETAM\426000,,0 +SETCA\450000,,0 +SETCAB\453000,,0 +SETCAI\451000,,0 +SETCAM\452000,,0 +SETCM\460000,,0 +SETCMB\463000,,0 +SETCMI\461000,,0 +SETCMM\462000,,0 +SETCRD\CALLI 400073\SAIL +SETDDT\CALLI 2\UUO +SETLIN\051340,,0\SAIL +SETM\414000,,0 +SETMB\417000,,0 +SETMI\415000,,0 +SETMM\416000,,0 +SETNAM\CALLI 43\UUO +SETNM2\CALLI 400036\SAIL +SETO\474000,,0 +SETOB\477000,,0 +SETOI\475000,,0 +SETOM\476000,,0 +SETPOV\CALLI 32\UUO +SETPR2\CALLI 400052\SAIL +SETPRO\CALLI 400020\SAIL +SETPRV\CALLI 400066\SAIL +SETSTS\060000,,0\UUO +SETUWP\CALLI 36\UUO +SETZ\400000,,0 +SETZB\403000,,0 +SETZI\401000,,0 +SETZM\402000,,0 +.PENT SIXBIT +SKIP\330000,,0 +SKIPA\334000,,0 +SKIPE\332000,,0 +SKIPG\337000,,0 +SKIPGE\335000,,0 +SKIPL\331000,,0 +SKIPLE\333000,,0 +SKIPN\336000,,0 +SKPHIM\710200,,0\SAIL +SKPME\710140,,0\SAIL +SKPSEN\710240,,0\SAIL +SLEEP\CALLI 31\UUO +SLEVEL\CALLI 400044\SAIL +SNEAKS\CALLI 400064\SAIL +SNEAKW\CALLI 400063\SAIL +SOJ\360000,,0 +SOJA\364000,,0 +SOJE\362000,,0 +SOJG\367000,,0 +SOJGE\365000,,0 +SOJL\361000,,0 +SOJLE\363000,,0 +SOJN\366000,,0 +SOS\370000,,0 +SOSA\374000,,0 +SOSE\372000,,0 +SOSG\377000,,0 +SOSGE\375000,,0 +SOSL\371000,,0 +SOSLE\373000,,0 +SOSN\376000,,0 +SPCWAR\043000,,0\SAIL +SPCWGO\CALLI 400003\SAIL +SPWBUT\CALLI 400000\SAIL +SRCV\710100,,0\SAIL +STATO\061000,,0\UUO +STATZ\063000,,0\UUO +SUB\274000,,0 +SUBB\277000,,0 +SUBI\275000,,0 +SUBM\276000,,0 +.PENT SUBTTL +.PENT SUPPRESS +SWAP\CALLI 400004\SAIL +SWITCH\CALLI 20\UUO +.SKIP 1 +TDC\650000,,0 +TDCA\654000,,0 +TDCE\652000,,0 +TDCN\656000,,0 +TDN\610000,,0 +TDNA\614000,,0 +TDNE\612000,,0 +TDNN\616000,,0 +TDO\670000,,0 +TDOA\674000,,0 +TDOE\672000,,0 +TDON\676000,,0 +TDZ\630000,,0 +TDZA\634000,,0 +TDZE\632000,,0 +TDZN\636000,,0 +TIMER\CALLI 22\UUO +.PENT TITLE +TLC\641000,,0 +TLCA\645000,,0 +TLCE\643000,,0 +TLCN\647000,,0 +TLN\601000,,0 +TLNA\605000,,0 +TLNE\603000,,0 +TLNN\607000,,0 +TLO\661000,,0 +TLOA\665000,,0 +TLOE\663000,,0 +TLON\667000,,0 +TLZ\621000,,0 +TLZA\625000,,0 +TLZE\623000,,0 +TLZN\627000,,0 +TMPCOR\CALLI 44\UUO +TMPCRD\CALLI 400103\SAIL +TRC\640000,,0 +TRCA\644000,,0 +TRCE\642000,,0 +TRCN\646000,,0 +TRN\600000,,0 +TRNA\604000,,0 +TRNE\602000,,0 +TRNN\606000,,0 +TRO\660000,,0 +TROA\664000,,0 +TROE\662000,,0 +TRON\666000,,0 +TRZ\620000,,0 +TRZA\624000,,0 +TRZE\622000,,0 +TRZN\626000,,0 +TSC\651000,,0 +TSCA\655000,,0 +TSCE\653000,,0 +TSCN\657000,,0 +TSN\611000,,0 +TSNA\615000,,0 +TSNE\613000,,0 +TSNN\617000,,0 +TSO\671000,,0 +TSOA\675000,,0 +TSOE\673000,,0 +TSON\677000,,0 +TSZ\631000,,0 +TSZA\635000,,0 +TSZE\633000,,0 +TSZN\637000,,0 +TTCALL\051000,,0\UUO +TTREAD\051700,,0\SAIL +TTYIOS\CALLI 400014\SAIL +TTYJOB\CALLI 400113\SAIL +TTYMES\CALLI 400047\SAIL +TTYSKP\CALLI 400116\SAIL +TTYUUO\051000,,0\UUO +.PENT TWOSEG +.SKIP 1 +UFA\130000,,0 +UFBCLR\CALLI 400012\SAIL +UFBERR\CALLI 400060\SAIL +UFBGET\CALLI 400010\SAIL +UFBGIV\CALLI 400011\SAIL +UFBPHY\CALLI 400055\SAIL +UFBSKP\CALLI 400056\SAIL +UGETF\073000,,0\UUO +UINBF\704000,,0\SAIL +.PENT UNIVERSAL +UNLOCK\CALLI 400077\SAIL +UNPURE\CALLI 400102\SAIL +UOUTBF\705000,,0\SAIL +UPGIOT\703000,,0\SAIL +UPGMVE\713000,,0\SAIL +UPGMVM\714000,,0\SAIL +.PENT USE +USETI\074000,,0\UUO +USETO\075000,,0\UUO +USKIP\CALLI 400041\SAIL +UTPCLR\CALLI 13\UUO +UUOSIM\CALLI 400106\SAIL +UWAIT\CALLI 400034\SAIL +.SKIP 1 +.PENT VAR +VDSMAP\CALLI 400070\SAIL +.SKIP 1 +WAIT\CALLI 10\UUO +WAKEME\CALLI 400061\SAIL +WHO\CALLI 400112\SAIL +WRCV\710040,,0\SAIL +.SKIP 1 +.PENT XALL +.PENT XCREF +XCT\256000,,0 +XGPUUO\CALLI 400075\SAIL +.PENT XLIST +.PENT XLIST1 +XOR\430000,,0 +XORB\433000,,0 +XORI\431000,,0 +XORM\432000,,0 +.PENT XPUNGE +.PENT XWD +.END + .APPNDX3(SCS,Stanford Character Set) +$SCS: + +~<ASCII character set> +The 2%<Stanford Character Set>* is displayed in the following table. The +three-digit octal code for a character is composed of the number at the left of +its row plus the digit at the top of its column. For example, the code +for 4A* is 100+1 or 101. + +.begin verbatim group select 4 + + 0 1 2 3 4 5 6 7 + 000 NUL        + 010  TAB LF VT FF CR   + 020         + 030   ~      + 040 SP ! " # $ % & ' + 050 ( ) * + , - . / + 060 0 1 2 3 4 5 6 7 + 070 8 9 : ; < = > ? + 100 @ A B C D E F G + 110 H I J K L M N O + 120 P Q R S T U V W + 130 X Y Z [ \ ] ^ _ + 140 ` a b c d e f g + 150 h i j k l m n o + 160 p q r s t u v w + 170 x y z { | ALT } BS + + + NUL Null + TAB Horizontal Tab + LF Line Feed + VT Vertical Tab + FF Form Feed + CR Carriage Return + SP Space + ALT Altmode + BS Back Space + + +.END + + + .APPNDX3(FCS,Summary of Character Interpretations) + +The characters listed below have special meaning in the contexts indicated. +These interpretations do not apply when these characters appear in text +strings or in comments.~<character interpretations>~<special characters> + +.BEGIN SELECT 5; TURN ON "\"; +.FILL; CRBREAK; PREFACE 0; +.IF XCRIBL THEN START TABS 5,9,33; INDENT 0,32; END +.IF XCRIBL THEN START TABS 4,8,24; INDENT 0,23; END +.SKIP +000\NUL\null\ignored on input +001\\down-arrow\makes a symbol available in a lower block +.TURN OFF "" +002\\alpha +.TURN ON "" +003\\beta +004\\logical and\boolean AND +005\\logical not\boolean NOT +006\\epsilon\delimiter in FOR +007\\pi +010\\lambda +011\TAB\tab\same as space (040) +012\LF\line feed\line delimiter +013\VT\vertical tab +014\FF\form feed\line delimiter; causes new listing page +015\CR\carriage return\statement terminator +016\\infinity +017\\partial\integer remainder in division +020\\containment\delimiter in FOR +021\\implication +022\\set intersection +023\\set union +024\\for all +025\\there exists\unary JFFO operator +026\\circle times\arithmetic shift operator +027\\double-arrow\statement terminator; remainder of line is interpreted as another statement +030\\underbar\same as . (056) in identifiers +031\\right-arrow\same as backslash (134) +032\~\tilde\same as up-arrow (136); illegal as the delimiter in ASCIZ, COMMENT, etc. +033\\not equal\boolean XOR +034\\less or equal +035\\greater or equal\same as not equal (033) +036\\equivalence +037\\logical or\boolean OR +040\SP\space\general delimiter +041\!\exclamation\same as logical or (037) +042\"\double quote\delimits ascii constants +043\#\number sign\declares a variable; illegal as the delimiter in ASCIZ, COMMENT, etc. +044\$\dollar sign\may be used in identifiers +045\%\percent\may be used in identifiers +046\&\ampersand\same as logical and (004) +047\'\close single quote\delimits sixbit constants +050\(\left parenthesis\encloses macro arguments, expressions, and index fields +051\)\right parenthesis\see left parenthesis (050) +052\*\asterisk\integer multiply +053\+\plus\integer addition +054\,\comma\general argument separator +055\-\minus\integer subtraction or negation +056\.\point\may be used in identifiers, floating point numbers, or predefined symbol +057\/\slash\integer division +060\0\digits\used to form number, parts of identifiers +... +071\9 +072\:\colon\used to define labels; illegal as the delimiter in ASCIZ, COMMENT, etc. +073\;\semicolon\forces remainder of line to be a comment +074\<\left broket\delimits complex atoms; same as left brace (173) to the macro processor +075\=\equal\denotes decimal number; alternate to left-arrow (137) in assignment statements +076\>\right broket\see left broket (074) +077\?\question mark\same as down-arrow (001) +.IF XCRIBL THEN NEXT PAGE; +100\@\at-sign\sets indirect bit in instructions; precedes concatenation character in FOR +101\A\upper case letters\used for identifiers; B and E are special in numbers; E is special in FOR +... +132\Z +133\[\left bracket\delimits literals, value part of OPDEF, size in ARRAY, PPN in .LOAD +134\\\backslash\evaluate a macro argument and converts the result to a digit string +135\]\right bracket\see left bracket (133) +.CRSPACE +136\^\up-arrow\moves a symbol definition to an outer block; +makes a symbol INTERNAL or EXTERNAL; +illegal as the delimiter in ASCIZ, COMMENT, etc. +.BREAK; +137\_\left-arrow\denotes assignment statement; +arithmetic FOR; illegal as the delimiter in ASCIZ, COMMENT, etc. +.BREAK; CRBREAK +140\`\open single quote\same as at-sign (100) +141\a\lower case letters\same as upper case letters, except in text constants +... +172\z +173\{\left brace\delimits macro bodies, IF-bodies, FOR-bodies, macro arguments +174\|\vertical bar\absolute value operator +175\ALT\altmode\same as right brace (176) +176\}\right brace\see left brace (173) +177\BS\backspace\illegal in input +.END + + +.IND +.BACK + \ No newline at end of file