perm filename FAIL.DOC[CMU,AIL] blob sn#288418 filedate 1977-06-19 generic text, type T, neo UTF8

                            Sponsored by
                  Advanced Research Projects Agency
                         ARPA Order No. 2494
Stanford Artificial Intelligence Laboratory                 June 1977
Memo AIM-291

Computer Science Department
Report STAN-CS-76-577



                         F. H. G. Wright II
                             R. E. Gorin

                         STANFORD UNIVERSITY


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  A. I.  Lab 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.  MDA903-76-C-0206.  The
views and  conclusions contained  in this document  are those  of the
authors and should not be interpreted as necessarily representing the
official  policies,   either  expressed   or  implied,   of  Stanford
University,  the   Advanced  Research   Projects  Agency,   the  U.S.
Government, or, for that matter, anyone else.

This manual supersedes SAILON-26 and AIM-226.

Available   from   the   National   Technical   Information  Service,
Springfield, Virginia 22161.


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
          Opcode Field   .  .  .  .  .  .  .  .  . 3
          Accumulator (AC) Field  .  .  .  .  .  . 4
          Indirect (@) Field   .  .  .  .  .  .  . 4
          Address Field  .  .  .  .  .  .  .  .  . 4
          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
          Device Selection Field  .  .  .  .  .  . 6
          2.1.6   Comment Field  .  .  .  .  .  .  .  .  .  .  .  . 7
          2.1.7   Statement Termination   .  .  .  .  .  .  .  .  . 7

     2.2  Expressions                                               7

     2.3  Atoms                                                    10
          2.3.1   Identifiers .  .  .  .  .  .  .  .  .  .  .  .   10
          2.3.2   Values   .  .  .  .  .  .  .  .  .  .  .  .  .   10
          2.3.3   Constants   .  .  .  .  .  .  .  .  .  .  .  .   11
          Simple Numbers .  .  .  .  .  .  .  .   12
          Decimal Numbers   .  .  .  .  .  .  .   12
          Scaled Numbers .  .  .  .  .  .  .  .   12
          Floating-Point Numbers  .  .  .  .  .   13
          Ascii Constants   .  .  .  .  .  .  .   14
          Sixbit Constants  .  .  .  .  .  .  .   14
          2.3.4   Symbols  .  .  .  .  .  .  .  .  .  .  .  .  .   15
          Labels   .  .  .  .  .  .  .  .  .  .   16
          Parameters (Assignment
                  Statements) .  .  .  .  .  .  .  .  .  .  .  .   17
          Variables   .  .  .  .  .  .  .  .  .   18
          Predefined Symbols   .  .  .  .  .  .   18
          Half-Killed Symbols  .  .  .  .  .  .   19
          Block Structure   .  .  .  .  .  .  .   20
          Linkage with Separately
                  Assembled Programs   .  .  .  .  .  .  .  .  .   23
          Symbols and Arrows   .  .  .  .  .  .   24
          2.3.5   Complex Atoms  .  .  .  .  .  .  .  .  .  .  .   25
          Atomic Statements .  .  .  .  .  .  .   25
          Literals .  .  .  .  .  .  .  .  .  .   26
ii                        Table of Contents                      FAIL

3.  Pseudo-Ops                                                     28

     3.1  Destination of Assembled Code                            28
          3.1.1   LOC, RELOC, and ORG  .  .  .  .  .  .  .  .  .   28
          3.1.2   SET and USE .  .  .  .  .  .  .  .  .  .  .  .   29
          3.1.3   PHASE and DEPHASE .  .  .  .  .  .  .  .  .  .   30
          3.1.4   HISEG .  .  .  .  .  .  .  .  .  .  .  .  .  .   30
          3.1.5   TWOSEG   .  .  .  .  .  .  .  .  .  .  .  .  .   30
          3.1.6   LIT   .  .  .  .  .  .  .  .  .  .  .  .  .  .   32
          3.1.7   VAR   .  .  .  .  .  .  .  .  .  .  .  .  .  .   32

     3.2  Symbol Modifiers                                         33
          3.2.1   OPDEF and .GOPDEF .  .  .  .  .  .  .  .  .  .   33
          3.2.2   BEGIN and BEND .  .  .  .  .  .  .  .  .  .  .   33
          3.2.3   GLOBAL   .  .  .  .  .  .  .  .  .  .  .  .  .   34
          3.2.4   INTERNAL and ENTRY   .  .  .  .  .  .  .  .  .   34
          3.2.5   EXTERNAL .  .  .  .  .  .  .  .  .  .  .  .  .   34
          3.2.6   LINK and LINKEND  .  .  .  .  .  .  .  .  .  .   35
          3.2.7   .LOAD and .LIBRARY   .  .  .  .  .  .  .  .  .   35
          3.2.8   PURGE .  .  .  .  .  .  .  .  .  .  .  .  .  .   36
          3.2.9   XPUNGE   .  .  .  .  .  .  .  .  .  .  .  .  .   36
          3.2.10  SUPPRESS and ASUPPRESS  .  .  .  .  .  .  .  .   37
          3.2.11  UNIVERSAL   .  .  .  .  .  .  .  .  .  .  .  .   37
          3.2.12  SEARCH   .  .  .  .  .  .  .  .  .  .  .  .  .   38

     3.3  Entering Data                                            39
          3.3.1   DEC and OCT .  .  .  .  .  .  .  .  .  .  .  .   39
          3.3.2   BYTE  .  .  .  .  .  .  .  .  .  .  .  .  .  .   39
          3.3.3   POINT .  .  .  .  .  .  .  .  .  .  .  .  .  .   39
          3.3.4   XWD   .  .  .  .  .  .  .  .  .  .  .  .  .  .   40
          3.3.5   IOWD  .  .  .  .  .  .  .  .  .  .  .  .  .  .   40
          3.3.6   ASCII, ASCIZ, ASCID, and SIXBIT  .  .  .  .  .   40
          3.3.7   RADIX50  .  .  .  .  .  .  .  .  .  .  .  .  .   41

     3.4  Reserving Space for Data                                 42
          3.4.1   BLOCK .  .  .  .  .  .  .  .  .  .  .  .  .  .   42
          3.4.2   INTEGER and ARRAY .  .  .  .  .  .  .  .  .  .   42

     3.5  Assembler Control Statements                             43
          3.5.1   TITLE .  .  .  .  .  .  .  .  .  .  .  .  .  .   43
          3.5.2   END and PRGEND .  .  .  .  .  .  .  .  .  .  .   43
          3.5.3   COMMENT  .  .  .  .  .  .  .  .  .  .  .  .  .   44
          3.5.4   RADIX .  .  .  .  .  .  .  .  .  .  .  .  .  .   44
          3.5.5   .INSERT  .  .  .  .  .  .  .  .  .  .  .  .  .   44
          3.5.6   .FATAL   .  .  .  .  .  .  .  .  .  .  .  .  .   45
          3.5.7   .DIRECT  .  .  .  .  .  .  .  .  .  .  .  .  .   45
FAIL                      Table of Contents                       iii

     3.6  Loader Control Statements                                46
          3.6.1   .COMMON  .  .  .  .  .  .  .  .  .  .  .  .  .   46
          3.6.2   .ASSIGN  .  .  .  .  .  .  .  .  .  .  .  .  .   46
          3.6.3   .TEXT .  .  .  .  .  .  .  .  .  .  .  .  .  .   46

     3.7  Listing Control Statements                               47
          3.7.1   TITLE and SUBTTL  .  .  .  .  .  .  .  .  .  .   47
          3.7.2   LIST, XLIST, and XLIST1 .  .  .  .  .  .  .  .   47
          3.7.3   LALL and XALL  .  .  .  .  .  .  .  .  .  .  .   47
          3.7.4   NOLIT .  .  .  .  .  .  .  .  .  .  .  .  .  .   47
          3.7.5   NOSYM .  .  .  .  .  .  .  .  .  .  .  .  .  .   48
          3.7.6   CREF and XCREF .  .  .  .  .  .  .  .  .  .  .   48
          3.7.7   PAGE  .  .  .  .  .  .  .  .  .  .  .  .  .  .   48
          3.7.8   PRINTX   .  .  .  .  .  .  .  .  .  .  .  .  .   48
          3.7.9   PRINTS   .  .  .  .  .  .  .  .  .  .  .  .  .   48

4.  Macro Operations                                               49

     4.1  Macros                                                   49
          4.1.1   Macro Bodies   .  .  .  .  .  .  .  .  .  .  .   50
          4.1.2   Concatenation  .  .  .  .  .  .  .  .  .  .  .   50
          4.1.3   Arguments in Macro Definitions   .  .  .  .  .   50
          4.1.4   Macro Calls .  .  .  .  .  .  .  .  .  .  .  .   51
          4.1.5   Arguments in Macro Calls   .  .  .  .  .  .  .   52
          4.1.6   How Much is Eaten by a Macro Call   .  .  .  .   53
          4.1.7   Complex Example   .  .  .  .  .  .  .  .  .  .   54

     4.2  FOR                                                      55
          4.2.1   String FOR  .  .  .  .  .  .  .  .  .  .  .  .   56
          4.2.2   Character FOR  .  .  .  .  .  .  .  .  .  .  .   56
          4.2.3   Arithmetic FOR .  .  .  .  .  .  .  .  .  .  .   57

     4.3  REPEAT                                                   58

     4.4  Conditional Assembly                                     59
          4.4.1   Numeric IFs .  .  .  .  .  .  .  .  .  .  .  .   59
          4.4.2   Text IFs .  .  .  .  .  .  .  .  .  .  .  .  .   59
          4.4.3   Symbol IFs  .  .  .  .  .  .  .  .  .  .  .  .   60

Appendices                                                         61

     A    Command Language                                         61

     B    Relocatable and Undefined Values                         64

     C    Predefined Opcodes                                       65

     D    Stanford A. I. Lab Character Set                         74

     E    Summary of Character Interpretations                     76
iv                        Table of Contents                      FAIL

Index                                                              79
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,

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

     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  28.   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
FAIL                        Basic Syntax                            3

          2.1.1  Instruction Statement


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

       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 33).  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 (#).

       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

       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.

       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

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

       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, page 25.  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.


MOVEI 2,-1(6)           ;assembles 201106 777777
MOVSI 1,(<JRST>)        ;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,  page 21), 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


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.

       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 right-shifted by two places (by convention, device
FAIL                        Basic Syntax                            7

numbers are  multiples of 4)  and stored in  bits 3-9 of  the current
word.   This value  is often  called the  device code  or  the device

          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  49).   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
8                           Basic Syntax                         FAIL

(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 section, page  5).  All  arithmetic is
integer or  boolean; no  type conversion  is done  for floating-point

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
         ∂      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

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
FAIL                        Basic Syntax                            9

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.


        FOO⊗2           ;value of FOO shifted left 2 bits
        (BAR-1)⊗-2      ;value of BAR-1 shifted right 2 bits
        -(A+2)*-B       ;same value as above
        <A+2>*B         ;another way  (The symbol A must
                        ;be defined and available.  See
                        ;Atomic Statements, section, page 25)
        [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
        6∂5             ;value is 1

Note: the operators ∂, ∃, and | 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.
10                          Basic Syntax                         FAIL

     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,  "A_7" and "A.7"  are equivalent

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,
.FNAM1, .FNAM2, .CPU., ".", 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
FAIL                        Basic Syntax                           11

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 64.

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   15,  and  section,  page  20,   for  further

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.

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 39.
12                          Basic Syntax                         FAIL

       Simple Numbers

A simple  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 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 44).



       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 (=).


        =100            assembles as: 000000000144
        =69                           000000000105

       Scaled Numbers

A simple number or decimal  number may be followed by the  letter "B"
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 B  is shifted
left logically a number of bit positions equal to 35  (decimal) minus
the scale factor.
FAIL                        Basic Syntax                           13


        254B8           assembles as:  254000000000
        1B33                           000000000004
        22B18                          000011000000
        22B<17+1>                      000011000000
        10B37                          000000000002
        =10B27                         000000005000

       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.


        10.7E1          ;equivalent to 107.0
        10.             ;better to write this as 10.0
        69E1            ;presently equivalent to 690.0
14                          Basic Syntax                         FAIL

       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 74).  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 40)  are used to store  text in the  usual left-justified
format in multiple words.


        "A"             ;101 octal
        "↑C"            ;27503
        "foobar"        ;337576130362

       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
FAIL                        Basic Syntax                           15

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  40) to pack  longer strings  into multiple


        '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,  page  3, and
section 4.1.4,  page 51,  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
16                          Basic Syntax                         FAIL

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


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,
page 26) or the PHASE  pseudo-op (section 3.1.3, page 30),  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.
FAIL                        Basic Syntax                           17

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, page 20.) 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.


LOOP:   JRST LOOP       ;points to itself
FOO:                    ;labels the location of the next instruction

       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, page 19).

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.
18                          Basic Syntax                         FAIL


        garp= =97       ;note space between = is necessary


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 32).   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 42).


        SETZM FOO#
        MOVEI A,BAR#-1

       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

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,  page 26)  and  the PHASE
pseudo-op (section 3.1.3, page 30).
FAIL                        Basic Syntax                           19


        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).

The predefined symbol .CPU.  denotes the type of processor  that FAIL
is running on.  This symbol has the value 1 for the PDP-6, 2  for the
KA10, 3 for the KI10, and 4 for the KL10.

Two other symbols, .INSERT  and IOWD, are predefined.   These symbols
cause actions like pseudo ops so their descriptions appear later; see
section 3.5.5, page 44, and section 3.3.5, page 40, respectively.

       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.
20                          Basic Syntax                         FAIL


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

       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
43).  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 33),  or a
macro  (see section  4, page  49) 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 33).

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
FAIL                        Basic Syntax                           21

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:

        FOO1:   JRST FOO1               FOO1:   JRST FOO1
                JRST FOO2                       JRST FOO2
                JRST FOO3                       JRST FOO3
                JRST FOO5                       JRST FOO5
        FOO2:   JRST FOO1               FOO22:  JRST FOO1
        ↑FOO3:  JRST FOO2               FOO3:   JRST FOO22
                JRST FOO3                       JRST FOO3
                JRST FOO1                       JRST FOO13
        ↑↑FOO5: JRST FOO2               FOO5:   JRST FOO22
                JRST FOO3                       JRST FOO3
        FOO1:   JRST FOO4               FOO13:  JRST FOO4
        ↑FOO4:  JRST FOO4               FOO4:   JRST FOO4
        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.
22                          Basic Syntax                         FAIL


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 34), 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.
FAIL                        Basic Syntax                           23


↓A←1                    ;some accumulator (AC) definitions
↓FOO←←=69               ;and a parameter
        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

There  are further  details in  section 3.2.2,  page 33,  and section
3.2.3, page  34, about  the block  structure pseudo-ops  BEGIN, BEND,

       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
24                          Basic Syntax                         FAIL

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  34) and  INTERNAL  (section  3.2.4,  page 34)

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  34) is  used to  declare symbols  to  be entry
points which will be available to a library search.

       Symbols and Arrows

This is a brief restatement of the ways that identifiers are  used as
symbols in conjunction with arrows.


↑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
FAIL                        Basic Syntax                           25

          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.

       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.
26                          Basic Syntax                         FAIL


<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


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 32).   Literals can  be used only  where forward  references are

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

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
FAIL                        Basic Syntax                           27

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.


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
28                           Pseudo-Ops                          FAIL

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.
For compatibility with MACRO-10, the pseudo op .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, 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.
FAIL                         Pseudo-Ops                            29

          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

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


        Location                Instructions

             0'                  JRST FOO
             1'                  JRST BAZ
             2'                  SET GARP,37
             2'                  USE GARP
            37                   JRST FOO
            40                   USE
             2'                  JRST FOO
30                           Pseudo-Ops                          FAIL

          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 28)
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

          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
FAIL                         Pseudo-Ops                            31

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 28).   Like HISEG,  TWOSEG should  be used
before any code is assembled.
32                           Pseudo-Ops                          FAIL


        TWOSEG 400000   ;initialize to two segments
        RELOC 0         ;initialize dual location counters
        RELOC 400000    ;now assemble code in the high segment
        MOVNI 1,1
        MOVEM 1,RPGSW#
        CALLI 0
        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
FAIL                         Pseudo-Ops                            33

     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 and .GOPDEF

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.

Symbols defined  by OPDEF  follow block structure.   If, in  an inner
block  it  is necessary  to  define opcodes  that  will  be available
outside that block, the .GOPDEF pseudo op may be used.   .GOPDEF will
define an opcode at the outermost block level.

          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, page 20.
34                           Pseudo-Ops                          FAIL

          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

          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,  page 24.   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.
FAIL                         Pseudo-Ops                            35

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

        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.

For compatibility with MACRO-10, the pseudo ops .LINK and .LNKEND are
accepted for LINK and LINKEND, respectively.

          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


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).
36                           Pseudo-Ops                          FAIL

The FAIL assembly has conditional assembly switches for a  variety of
sites;  file names  are scanned  in accordance  with the  file naming
conventions that prevail at each site.

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.

For compatibility with MACRO-10, the pseudo ops .REQUIRE and .REQUEST
are accepted for .LOAD and .LIBRARY, respectively.

          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.
FAIL                         Pseudo-Ops                            37

          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
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

Variables,  literal-labels, internals,  and entry  point  symbols are
never  suppressed.   Externals   that  are  not  referenced   can  be

If  ASUPPRESS appears  in a  universal program  (see  section 3.2.11,
page 37), 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

The UNIVERSAL  pseudo-op has  the same syntax  as TITLE  (see section
3.5.1, page 43).   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  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-labels, and internal symbols are not retained.

Universal symbols are written into a binary universal file  which can
be accessed in subsequent assemblies without reassembling  the source
38                           Pseudo-Ops                          FAIL

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 .NOUNV  in .DIRECT (see section 3.5.7,  page 45),
or by the /O switch in the command line (see appendix A, page 61).

Access to the  symbols in a universal  symbol table is  controlled by
the SEARCH pseudo op (see  section 3.2.12, page 38).  Once  access is
established, universal symbols can  be referenced as any  other local

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.

          3.2.12  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 the 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.
FAIL                         Pseudo-Ops                            39

     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.


        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

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
40                           Pseudo-Ops                          FAIL

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 49).
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.

          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 (#).
FAIL                         Pseudo-Ops                            41

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 the Stanford  A.I. Lab.   Also, the
ASCID format is used for line numbers in the SOS and EDIT editors.

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

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
the  right has  weight 50;   the third  has weight  50*50;  etc.  The
correspondence between  characters and their  radix50 value  is given

        Blank   → 0
        0-9     → 1-12
        A-Z     → 13-44
        .       → 45
        $       → 46
        %       → 47
42                           Pseudo-Ops                          FAIL

     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]

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.
FAIL                         Pseudo-Ops                            43

     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

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  32, and section 3.1.6,  page 32).  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
44                           Pseudo-Ops                          FAIL

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

          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:


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.   The file  name is  scanned in
accordance with the convention that prevails at each installation.

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.
FAIL                         Pseudo-Ops                            45

Unlike a normal pseudo-op, which is recognized only if it  appears as
the  op-code,  .INSERT  is  recognized anywhere  in  a  line.   It is
suggested that .INSERT not be used as a macro argument.

          3.5.6  .FATAL

The .FATAL pseudo-op prints the text of the line on which it appears,
and  stops  the   assembly.   Usually,  .FATAL  appears   under  some
conditional  assembly  switch  to  stop  the  assembly  because  some
parameter settings are inconsistient.

          3.5.7  .DIRECT

The .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.

.NOBIN suppresses binary output.

.NOUNV  suppresses output  of the  binary universal  (FUN)  file (see
section 3.2.11, page 37).

The  functions .XTABM  and .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 section  4.1.5, page
52).  .ITABM is the default; tabs and blanks are kept as part  of the
argument.  If .XTABM  is used, leading  and trailing blanks  and tabs
are deleted from a macro argument, unless the argument is enclosed in
brokets or braces.
46                           Pseudo-Ops                          FAIL

     3.6  Loader Control Statements

The  following pseudo-ops  are used  to pass  control  information to

          3.6.1  .COMMON

The .COMMON  statement passes  information to  LINK-10, and  does not
otherwise affect the assembly.  This statement has the same syntax as
ARRAY  (see  section  3.4.2,  page  42).   LINK-10  will  reserve the
requested amount of space for each block of named common.

          3.6.2  .ASSIGN

The .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.

          3.6.3  .TEXT

The  .TEXT  statement is  used  to  pass the  ascii  text  of control
statements  to  LINK-10.  The  .TEXT  pseudo op  is  like  ASCIZ (see
section 3.3.6, page 40) except it does not have a value and  does not
affect the location counter.
FAIL                         Pseudo-Ops                            47

     3.7  Listing Control Statements

These pseudo-ops affect the format of the assembly  listing.  Several
descriptions below refer to command line switches;  appendix  A, page
61, describes the command line format and the different switches.

          3.7.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 43.

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.7.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

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

          3.7.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.

          3.7.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.
48                           Pseudo-Ops                          FAIL

          3.7.5  NOSYM

This   statement  disables   the   listing  of   the   symbol  table,
counteracting /S in the command string.

          3.7.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.7.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.7.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.7.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                         49

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

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.
50                        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 54.

          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


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                         51

with an actual argument, use a concatenation character.  For example,
if the concatenation character is "$" and


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:

        {MOVNI AC,3
        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 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., .LOAD, .INSERT, etc.
52                        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 61).   In similar  circumstances, a  main push-down
list overflow may occur.  In this case, the /E switch in  the command
string may be used to allocate a larger main push-down list.

          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 53.

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
FAIL                      Macro Operations                         53

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 (\)  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.

After a .DIRECT pseudo op has appeared with the .XTABM  argument (see
section 3.5.7, page 45) then in a macro call where the macro argument
is not 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  .ITABM  to .DIRECT
restores  FAIL  to  the  normal  treatment  of  tabs  and  spaces  in

          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,
54                        Macro Operations                       FAIL

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.


        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).
FAIL                      Macro Operations                         55


        DEFINE BAR {0,}
        DEFINE FOO (A,B,C) {DEFINE BAR {0,<B
        DEFINE ADD1 (X) {FOO(\BAR,X)}
        DEFINE SEC (A,B) {B}

                        ;BAR = 0,
                        ;BAR = 0,<
                        ;       X1>
                        ;BAR = 0,<
                        ;       X1
                        ;       X2>
                        ;BAR = 0,<
                        ;       X1
                        ;       X2
                        ;       X3>

                        ;       X1
                        ;       X2
                        ;       X3

     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.   FOR is a pseudo-op; it  is recognized
only where FAIL allows opcodes to appear.

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.
56                        Macro Operations                       FAIL

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  52), 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.


        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

        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
FAIL                      Macro Operations                         57

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


        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

          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

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
58                        Macro Operations                       FAIL

        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

     4.3  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

        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:

FAIL                      Macro Operations                         59

     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 exp≠0
       IFG exp,{text}        assembles text if exp>0
       IFL exp,{text}        assembles text if exp<0
       IFGE exp,{text}       assembles text if exp≥0
       IFLE exp,{text}       assembles text if exp≤0

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.


 IFE 3, {ZOT}                  assembles nothing
 IFGE 15, {JRST START}         assembles JRST START

          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.
60                        Macro Operations                       FAIL

          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 .CPU.,  .FNAM1,  .FNAM2, .INSERT,
"$.", and ".").
FAIL                         Appendix A                            61

                          Command Language

The basic format of a FAIL command is

        binary-file,listing-file←source-file-1, ... ,source-file-n

File specifications consist of


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 file  then  REL is
assumed.  If no file extension for the listing file is given  then at
Stanford A.I. Lab and at Tenex sites (including TOPS-20 sites) LST is
assumed; at other sites, CRF  is used.  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):
62                           Appendix A                          FAIL

        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

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.

The E 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
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):


The text  is typed  to FAIL  and terminated  with control-Z  (↑Z) (at
Stanford A.I. Lab displays, control-meta-line feed is used instead of
control-Z).   Using SNAIL  (known elsewhere  as COMPIL),  the command
sequence would be


The file name  F is needed to  satisfy the SNAIL syntax;   the device
name DSK: is needed to switch the default input device to DSK.
FAIL                         Appendix A                            63

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:.

To provide some compatibility with SNAIL-style commands, FAIL accepts
"=" for "←" in the command line.  Also, either "+" or ";" may be used
instead of "," to separate source-file names.
64                           Appendix B                          FAIL

                  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.
FAIL                         Appendix C                            65

                         Predefined Opcodes

The standard machine instruction mnemonics of the KL10 are defined in

When the  Stanford A.I. Lab  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  A.I.  Lab.  The  indication SAIL  is  used to
indicate  UUOs and  machine instructions  available only  at Stanford
A.I. Lab.  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.  KI and KL  signify instructions that are available  on the
KI10 and KL10 processors.  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 A.I. Lab  UUOs; consult the  appropriate reference
manual.  Also note that  some DEC mnemonics conflict with  those used
at Stanford A.I. Lab.
66                           Appendix C                          FAIL

$.        Predefined    page 18      AOJG      347000,,0
.         Predefined    page 18      AOJGE     345000,,0
.ASSIGN   Pseudo-op     page 46      AOJL      341000,,0
.COMMON   Pseudo-op     page 46      AOJLE     343000,,0
.CPU.     Predefined    page 19      AOJN      346000,,0
.DIRECT   Pseudo-op     page 45      AOS       350000,,0
.FATAL    Pseudo-op     page 45      AOSA      354000,,0
.FNAM1    Predefined    page 19      AOSE      352000,,0
.FNAM2    Predefined    page 19      AOSG      357000,,0
.GOPDEF   Pseudo-Op     page 33      AOSGE     355000,,0
.INSERT   Pseudo-Op     page 44      AOSL      351000,,0
.LIBRARY  Pseudo-Op     page 35      AOSLE     353000,,0
.LINK     Pseudo-Op     page 35      AOSN      356000,,0
.LNKEND   Pseudo-Op     page 35      APRENB    CALLI 16      UUO
.LOAD     Pseudo-Op     page 35      ARRAY     Pseudo-Op     page 42
.ORG      Pseudo-Op     page 28      ASCID     Pseudo-Op     page 40
.REQUEST  Pseudo-Op     page 35      ASCII     Pseudo-Op     page 40
.REQUIRE  Pseudo-Op     page 35      ASCIZ     Pseudo-Op     page 40
.TEXT     Pseudo-Op     page 46      ASH       240000,,0
                                     ASHC      244000,,0
ACCTIM    CALLI 400101  SAIL         ASSIGN    Pseudo-Op     page 46
ACTCHR    CALLI 400105  SAIL         ASUPPRESS Pseudo-Op     page 37
ADD       270000,,0                  ATTSEG    CALLI 400016  SAIL
ADDB      273000,,0
ADDI      271000,,0                  BEEP      CALLI 400111  SAIL
ADDM      272000,,0                  BEGIN     Pseudo-Op     page 33
ADJSP     105000,,0     KL           BEND      Pseudo-Op     page 33
ADSMAP    CALLI 400110  SAIL         BLKI      700000,,0     I/O
AND       404000,,0                  BLKO      700100,,0     I/O
ANDB      407000,,0                  BLOCK     Pseudo-Op     page 42
ANDCA     410000,,0                  BLT       251000,,0
ANDCAB    413000,,0                  BUFLEN    CALLI 400042  SAIL
ANDCAI    411000,,0                  BYTE      Pseudo-Op     page 39
ANDCAM    412000,,0
ANDCB     440000,,0                  CAI       300000,,0
ANDCBB    443000,,0                  CAIA      304000,,0
ANDCBI    441000,,0                  CAIE      302000,,0
ANDCBM    442000,,0                  CAIG      307000,,0
ANDCM     420000,,0                  CAIGE     305000,,0
ANDCMB    423000,,0                  CAIL      301000,,0
ANDCMI    421000,,0                  CAILE     303000,,0
ANDCMM    422000,,0                  CAIN      306000,,0
ANDI      405000,,0                  CALL      040000,,0     UUO
ANDM      406000,,0                  CALLI     047000,,0     UUO
AOBJN     253000,,0                  CALLIT    CALLI 400074  SAIL
AOBJP     252000,,0                  CAM       310000,,0
AOJ       340000,,0                  CAMA      314000,,0
AOJA      344000,,0                  CAME      312000,,0
AOJE      342000,,0                  CAMG      317000,,0
FAIL                         Appendix C                            67

CAMGE     315000,,0                  DIVI      235000,,0
CAML      311000,,0                  DIVM      236000,,0
CAMLE     313000,,0                  DMOVE     120000,,0     KI
CAMN      316000,,0                  DMOVEM    124000,,0     KI
CHNSTS    716000,,0     SAIL         DMOVN     121000,,0     KI
CLKINT    717000,,0     SAIL         DMOVNM    125000,,0     KI
CLOSE     070000,,0     UUO          DMUL      116000,,0     KL
CLRBFI    051440,,0     UUO          DPB       137000,,0
CLRBFO    051500,,0     UUO          DPYCLR    701000,,0     SAIL
COMMENT   Pseudo-Op     page 44      DPYOUT    703000,,0     SAIL
CONI      700240,,0     I/O          DPYPOS    702100,,0     SAIL
CONO      700200,,0     I/O          DPYSIZ    702140,,0     SAIL
CONS      257000,,0     SAIL         DSKPPN    CALLI 400071  SAIL
CONSO     700340,,0     I/O          DSKTIM    CALLI 400072  SAIL
CONSZ     700300,,0     I/O          DSUB      115000,,0     KL
CORE      CALLI 11      UUO
CORE2     CALLI 400015  SAIL         EIOTM     CALLI 400005  SAIL
CREF      Pseudo-Op     page 48      END       Pseudo-Op     page 43
CTLV      CALLI 400001  SAIL         ENTER     077000,,0     UUO
                                     ENTRY     Pseudo-Op     page 34
DADD      114000,,0     KL           EQV       444000,,0
DATAI     700040,,0     I/O          EQVB      447000,,0
DATAO     700140,,0     I/O          EQVI      445000,,0
DATE      CALLI 14      UUO          EQVM      446000,,0
DAYCNT    CALLI 400100  SAIL         EXCH      250000,,0
DDCHAN    CALLI 400067  SAIL         EXIT      CALLI 12      UUO
DDIV      117000,,0     KL           EXTEND    123000,,0     KL
DDTGT     CALLI 5       UUO          EXTERNAL  Pseudo-Op     page 34
DDTIN     CALLI 1       UUO
DDTOUT    CALLI 3       UUO          FAD       140000,,0
DDTRL     CALLI 7       UUO          FADB      143000,,0
DDUPG     715140,,0     SAIL         FADL      141000,,0
DEBREAK   CALLI 400035  SAIL         FADM      142000,,0
DEC       Pseudo-Op     page 39      FADR      144000,,0
DEFINE    Pseudo-Op     page 49      FADRB     147000,,0
DEPHASE   Pseudo-Op     page 30      FADRI     145000,,0
DETSEG    CALLI 400017  SAIL         FADRL     145000,,0
DEVCHR    CALLI 4       UUO          FADRM     146000,,0
DEVNUM    CALLI 400104  SAIL         FBREAD    706000,,0     SAIL
DEVUSE    CALLI 400051  SAIL         FBWAIT    CALLI 400057  SAIL
DFAD      110000,,0     KI           FBWRT     707000,,0     SAIL
DFDV      113000,,0     KI           FDV       170000,,0
DFMP      112000,,0     KI           FDVB      173000,,0
DFN       131000,,0                  FDVL      171000,,0
DFSB      111000,,0     KI           FDVM      172000,,0
DIAL      CALLI 400117  SAIL         FDVR      174000,,0
DISMISS   CALLI 400024  SAIL         FDVRB     177000,,0
DIV       234000,,0                  FDVRI     175000,,0
DIVB      237000,,0                  FDVRL     175000,,0
68                           Appendix C                          FAIL

FDVRM     176000,,0                  HLLOI     521000,,0
FIX       122000,,0     KI xSAIL     HLLOM     522000,,0
FIXR      126000,,0     KI           HLLOS     523000,,0
FLTR      127000,,0     KI           HLLS      503000,,0
FMP       160000,,0                  HLLZ      510000,,0
FMPB      163000,,0                  HLLZI     511000,,0
FMPL      161000,,0                  HLLZM     512000,,0
FMPM      162000,,0                  HLLZS     513000,,0
FMPR      164000,,0                  HLR       544000,,0
FMPRB     167000,,0                  HLRE      574000,,0
FMPRI     165000,,0                  HLREI     575000,,0
FMPRL     165000,,0                  HLREM     576000,,0
FMPRM     166000,,0                  HLRES     577000,,0
FOR       Pseudo-Op     page 55      HLRI      545000,,0
FSB       150000,,0                  HLRM      546000,,0
FSBB      153000,,0                  HLRO      564000,,0
FSBL      151000,,0                  HLROI     565000,,0
FSBM      152000,,0                  HLROM     566000,,0
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 49      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 34      HRLZI     515000,,0
                                     HRLZM     516000,,0
HALT      254200,,0                  HRLZS     517000,,0
HISEG     Pseudo-Op     page 30      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
FAIL                         Appendix C                            69

HRROM     562000,,0                  INTACM    CALLI 400027  SAIL
HRROS     563000,,0                  INTDEJ    723000,,0     SAIL
HRRS      543000,,0                  INTDMP    723140,,0     SAIL
HRRZ      550000,,0                  INTEGER   Pseudo-Op     page 42
HRRZI     551000,,0                  INTENB    CALLI 400025  SAIL
HRRZM     552000,,0                  INTENS    CALLI 400030  SAIL
HRRZS     553000,,0                  INTERNAL  Pseudo-Op     page 34
                                     INTGEN    CALLI 400033  SAIL
IBP       133000,,0                  INTIIP    CALLI 400031  SAIL
IDIV      230000,,0                  INTIPI    723200,,0     SAIL
IDIVB     233000,,0                  INTIRQ    CALLI 400032  SAIL
IDIVI     231000,,0                  INTJEN    723000,,0     SAIL
IDIVM     232000,,0                  INTMSK    720000,,0     SAIL
IDPB      136000,,0                  INTORM    CALLI 400026  SAIL
IENBW     CALLI 400045  SAIL         INTUUO    723000,,0     SAIL
IFAVL     Conditional   page 60      INWAIT    051600,,0     SAIL
IFDEF     Conditional   page 60      IOPDL     726000,,0     SAIL
IFDIF     Conditional   page 59      IOPOP     725000,,0     SAIL
IFE       Conditional   page 59      IOPUSH    724000,,0     SAIL
IFG       Conditional   page 59      IOR       434000,,0
IFGE      Conditional   page 59      IORB      437000,,0
IFIDN     Conditional   page 59      IORI      435000,,0
IFL       Conditional   page 59      IORM      436000,,0
IFLE      Conditional   page 59      IOWD      Pseudo-Op     page 40
IFMAC     Conditional   page 60      IWAIT     CALLI 400040  SAIL
IFN       Conditional   page 59      IWKMSK    723100,,0     SAIL
IFNAVL    Conditional   page 60
IFNDEF    Conditional   page 60      JBTSTS    CALLI 400013  SAIL
IFNMAC    Conditional   page 60      JCRY      255300,,0
IFNOP     Conditional   page 60      JCRY0     255200,,0
IFOP      Conditional   page 60      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          JSYS      104000,,0
INCHSL    051240,,0     UUO          JUMP      320000,,0
INCHWL    051200,,0     UUO          JUMPA     324000,,0
INIT      041000,,0     UUO          JUMPE     322000,,0
INPUT     066000,,0     UUO          JUMPG     327000,,0
INSKIP    051540,,0     SAIL         JUMPGE    325000,,0
70                           Appendix C                          FAIL

JUMPL     321000,,0                  NAMEIN    CALLI 400043  SAIL
JUMPLE    323000,,0                  NOLIT     Pseudo-Op     page 47
JUMPN     326000,,0                  NOSYM     Pseudo-Op     page 48

KAFIX     247000,,0     KA SAIL      OCT       Pseudo-Op     page 39
KIFIX     122000,,0     KI SAIL      OPDEF     Pseudo-Op     page 33
                                     OPEN      050000,,0     UUO
LALL      Pseudo-Op     page 47      OR        434000,,0
LDB       135000,,0                  ORB       437000,,0
LEYPOS    702300,,0     SAIL         ORCA      454000,,0
LINK      Pseudo-Op     page 35      ORCAB     457000,,0
LINKEND   Pseudo-Op     page 35      ORCAI     455000,,0
LINKUP    CALLI 400023  SAIL         ORCAM     456000,,0
LIOTM     CALLI 400006  SAIL         ORCB      470000,,0
LIST      Pseudo-Op     page 47      ORCBB     473000,,0
LIT       Pseudo-Op     page 32      ORCBI     471000,,0
LOC       Pseudo-Op     page 28      ORCBM     472000,,0
LOCK      CALLI 400076  SAIL         ORCM      464000,,0
LOGIN     CALLI 15      UUO          ORCMB     467000,,0
LOGOUT    CALLI 17      UUO          ORCMI     465000,,0
LOOKUP    076000,,0     UUO          ORCMM     466000,,0
LSH       242000,,0                  ORG       Pseudo-Op     page 28
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 48
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 30
MOVSI     205000,,0                  PJOB      CALLI 30      UUO
MOVSM     206000,,0                  PNAME     CALLI 400007  SAIL
MOVSS     207000,,0                  POINT     Pseudo-Op     page 39
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
FAIL                         Appendix C                            71

PPIOT     702000,,0     SAIL         SEND      710000,,0     SAIL
PPREL     702200,,0     SAIL         SET       Pseudo-Op     page 29
PPSEL     702000,,0     SAIL         SETA      424000,,0
PPSPY     CALLI 400107  SAIL         SETAB     427000,,0
PRGEND    Pseudo-Op     page 43      SETACT    051640,,0     SAIL
PRINTS    Pseudo-Op     page 48      SETAI     425000,,0
PRINTX    Pseudo-Op     page 48      SETAM     426000,,0
PTGETL    711540,,0     SAIL         SETCA     450000,,0
PTIFRE    711100,,0     SAIL         SETCAB    453000,,0
PTJOBX    711700,,0     SAIL         SETCAI    451000,,0
PTLOAD    711640,,0     SAIL         SETCAM    452000,,0
PTOCNT    711140,,0     SAIL         SETCM     460000,,0
PTRD1S    711200,,0     SAIL         SETCMB    463000,,0
PTRD1W    711240,,0     SAIL         SETCMI    461000,,0
PTRDS     711400,,0     SAIL         SETCMM    462000,,0
PTSETL    711600,,0     SAIL         SETCRD    CALLI 400073  SAIL
PTWR1S    711300,,0     SAIL         SETDDT    CALLI 2       UUO
PTWR1W    711340,,0     SAIL         SETLIN    051340,,0     SAIL
PTWRS7    711440,,0     SAIL         SETM      414000,,0
PTWRS9    711500,,0     SAIL         SETMB     417000,,0
PTYGET    711000,,0     SAIL         SETMI     415000,,0
PTYREL    711040,,0     SAIL         SETMM     416000,,0
PTYUUO    711000,,0     SAIL         SETNAM    CALLI 43      UUO
PURGE     Pseudo-Op     page 36      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 44      SETPOV    CALLI 32      UUO
RADIX50   Pseudo-Op     page 41      SETPR2    CALLI 400052  SAIL
REASSI    CALLI 21      UUO          SETPRO    CALLI 400020  SAIL
RELEAS    071000,,0     UUO          SETPRV    CALLI 400066  SAIL
RELOC     Pseudo-Op     page 28      SETSTS    060000,,0     UUO
REMAP     CALLI 37      UUO          SETUWP    CALLI 36      UUO
RENAME    055000,,0     UUO          SETZ      400000,,0
REPEAT    Pseudo-Op     page 58      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 40
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 38      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
72                           Appendix C                          FAIL

SKPSEN    710240,,0     SAIL         TDZA      634000,,0
SLEEP     CALLI 31      UUO          TDZE      632000,,0
SLEVEL    CALLI 400044  SAIL         TDZN      636000,,0
SNEAKS    CALLI 400064  SAIL         TIMER     CALLI 22      UUO
SNEAKW    CALLI 400063  SAIL         TITLE     Pseudo-Op     page 43
SOJ       360000,,0                  TLC       641000,,0
SOJA      364000,,0                  TLCA      645000,,0
SOJE      362000,,0                  TLCE      643000,,0
SOJG      367000,,0                  TLCN      647000,,0
SOJGE     365000,,0                  TLN       601000,,0
SOJL      361000,,0                  TLNA      605000,,0
SOJLE     363000,,0                  TLNE      603000,,0
SOJN      366000,,0                  TLNN      607000,,0
SOS       370000,,0                  TLO       661000,,0
SOSA      374000,,0                  TLOA      665000,,0
SOSE      372000,,0                  TLOE      663000,,0
SOSG      377000,,0                  TLON      667000,,0
SOSGE     375000,,0                  TLZ       621000,,0
SOSL      371000,,0                  TLZA      625000,,0
SOSLE     373000,,0                  TLZE      623000,,0
SOSN      376000,,0                  TLZN      627000,,0
SPCWAR    043000,,0     SAIL         TMPCOR    CALLI 44      UUO
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 47      TRO       660000,,0
SUPPRESS  Pseudo-Op     page 37      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
FAIL                         Appendix C                            73

TSOE      673000,,0                  XCT       256000,,0
TSON      677000,,0                  XGPUUO    CALLI 400075  SAIL
TSZ       631000,,0                  XLIST     Pseudo-Op     page 47
TSZA      635000,,0                  XLIST1    Pseudo-Op     page 47
TSZE      633000,,0                  XOR       430000,,0
TSZN      637000,,0                  XORB      433000,,0
TTCALL    051000,,0     UUO          XORI      431000,,0
TTREAD    051700,,0     SAIL         XORM      432000,,0
TTYIOS    CALLI 400014  SAIL         XPUNGE    Pseudo-Op     page 36
TTYJOB    CALLI 400113  SAIL         XWD       Pseudo-Op     page 40
TTYUUO    051000,,0     UUO
TWOSEG    Pseudo-Op     page 30

UFA       130000,,0
UGETF     073000,,0     UUO
UINBF     704000,,0     SAIL
UNIVERSAL Pseudo-Op     page 37
UOUTBF    705000,,0     SAIL
UPGIOT    703000,,0     SAIL
UPGMVE    713000,,0     SAIL
UPGMVM    714000,,0     SAIL
USE       Pseudo-Op     page 29
USETI     074000,,0     UUO
USETO     075000,,0     UUO
USKIP     CALLI 400041  SAIL
UWAIT     CALLI 400034  SAIL

VAR       Pseudo-Op     page 32

WAIT      CALLI 10      UUO
WHO       CALLI 400112  SAIL
WRCV      710040,,0     SAIL

XALL      Pseudo-Op     page 47
XCREF     Pseudo-Op     page 48
74                           Appendix D                          FAIL

                  Stanford A. I. Lab 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 }   RO

        NUL     Null
        TAB     Horizontal Tab
        LF      Line Feed
        VT      Vertical Tab
        FF      Form Feed
        CR      Carriage Return
        SP      Space
        ALT     Altmode
        RO      Rub Out (On A.I. Lab displays this key is labeled BS)

The differences between  ASCII and the  Stanford A. I.  Lab character
set may be summarized briefly as follows:

        1. ASCII codes 0 through 37 do not print anything

        2.  The Stanford  characters "←"  and "↑"  correspond  to the
        ASCII characters underbar "_" and carat "∧".
FAIL                         Appendix D                            75

        3. In ASCII codes 175 and 176 are "}" and "~".
76                           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
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
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
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                            77

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
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
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
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
101 A   upper case letters      used  for identifiers;   B and  E are
                                special in numbers;  E is  special in
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)
78                           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            absolute value operator
175 ALT altmode                 same as right brace (176)
176 }   right brace             see left brace (173)
177 BS  backspace               illegal in input
FAIL                                                               79


$. 18, 27, 30                         backslash 53
                                      backward reference 15
. 18, 27, 30                          BEGIN 33
.ASSIGN 46                            BEND 33
.COMMON 46                            binary universal file 37, 38
.CPU. 19                              blank 49
.DIRECT 45                            block 11
.FATAL 45                             block number 33
.FNAM1 19                             BLOCK pseudo-op 42
.FNAM2 19                             Block Structure 20
.GOPDEF 33                            braces 45, 49, 52, 56
.INSERT 44                            brackets 25, 42, 52
.ITABM 45, 53                         brokets 5, 25, 45, 49, 52
.LIBRARY 35                           BYTE 39
.LINK 35                              byte pointer 39
.LOAD 35                              carriage return 7, 43, 47, 50,
.NOBIN 45                                  52
.NOUNV 45                             Character FOR 56
.ORG 28                               character interpretations 76
.REQUEST 35                           close single quote 15, 29
.REQUIRE 35                           colon 4, 16, 19, 40, 44, 48
.TEXT 46                              comma 4, 6, 29, 34, 39, 40, 41,
.XTABM 45, 53                              42, 49, 52, 57, 61
                                      comma-comma 5
absolute 11, 18, 64                   Command Language 61
AC 4                                  comment 7
Accumulator Field 4                   COMMENT pseudo-op 44
Address Field 4                       COMPIL 62
apostrophe 15, 29                     Complex Atoms 25
Arguments in Macro Calls 52           concatenation character 50, 55
Arguments in Macro                    Conditional Assembly 59
     Definitions 50                   Constants 11
Arithmetic FOR 57                     constants optimization 26
ARRAY 42                              containment character 56
ASCID 40                              control-meta-line feed 62
ASCII character set 74                control-Z 62
Ascii Constants 14                    CREF 1, 48, 62
ASCII pseudo-op 40                    CREF pseudo-op 48
ASCIZ 40                              Cross-Reference Listing 48, 62
Assembler Control Statements 43
ASSIGN 46                             DDT 1, 19, 23, 33, 41, 43
assignment statement 17               DEC pseudo-op 39
ASUPPRESS 37                          Decimal Numbers 12
at-sign 4, 55                         decimal point 13
atomic statement 5, 7, 25             DEFINE pseudo-op 49
atoms 7, 10                           defined 11, 15, 16
available 11, 20, 22                  DEPHASE 30
80                              Index                            FAIL

Destination of Assembled              IFE 59
     Code 28                          IFG 59
device code 7                         IFGE 59
device number 7                       IFIDN 59
Device Selection Field 6              IFL 59
dollar sign 10                        IFLE 59
dollar-point 18, 27, 30               IFMAC 60
double quote 14                       IFN 59
double-arrow 7                        IFNAVL 60
down-arrow 6, 22, 24, 60              IFNDEF 60
                                      IFNMAC 60
END 43                                IFNOP 60
Entering Data 39                      IFOP 60
ENTRY 24, 34                          Index Field 5
entry blocks 24, 34                   indirect bit 4
entry point 24                        Indirect Field 4
epsilon 56                            Input-Output Instruction
equal sign 12, 17, 19, 44                  Statement 6
Expressions 7                         Instruction Statement 3
EXTERNAL 24, 34                       INTEGER 42
external symbols 24, 34               INTERNAL 24, 34
                                      internal symbols 34
fixup 16                              IOWD 40
Floating-Point Numbers 13             IRP 55
FOR 55                                IRPC 55
FOR-body 55
form feed 48                          KA10 45
formal arguments 56                   KI10 45
forward reference 15, 42
Full-Word Expression 5                Labels 16
FUN 38, 45, 62                        LALL 47
                                      left-arrow 4, 17, 19, 24, 40,
GDEFINE pseudo-op 49                       44, 48, 57
GLOBAL pseudo-op 34                   library 24
global symbols 23                     library search mode 24
                                      line feed 7, 44, 50
Half-Killed Symbols 19                LINK 35
Halfword Statement 5                  Linkage with Separately
hardware input-output                      Assembled Programs 23
     instruction 6                    LINKEND 35
hardware instruction 3, 65            LIST 47
high segment 30                       Listing Control Statements 47
HISEG 30                              LIT 32, 43
                                      literal-label 27, 36, 37
Identifiers 10                        literals 25, 26, 32, 43
IF-body 59                            loader 1, 8, 11, 16, 23, 24,
IFAVL 60                                   30, 34, 35, 36, 41, 42, 64
IFDEF 60                              Loader Control Statements 46
IFDIF 59                              LOC 28
FAIL                            Index                              81

local symbols 23                      RAID 1, 19, 23, 33, 41, 43
location counter 16, 18, 28, 29       range specifier 56
                                      reference 15
machine instruction 3, 65             RELOC 28
Macro Bodies 50                       relocatable 11, 17, 18, 64
Macro Calls 51                        relocation constant 64
Macros 49                             relocation factor 64
multiple definition 17                REPEAT 58
multiple location counters 29         reserved identifiers 10
                                      Reserving Space for Data 42
NOLIT 47                              right-arrow 53
null argument 52                      Scaled Numbers 12
null statement 2                      SEARCH 38
number sign 4, 18, 32, 40, 42,        segment 30
     44, 48                           semicolon 7, 43, 47, 52
Numbers 12                            SET 29
Numeric IFs 59                        Simple Numbers 12
                                      sixbit 14, 41
OCT 39                                Sixbit Constants 14
octal 12                              SIXBIT pseudo-op 40
Opcode Field 3                        slash 61
OPDEF 33                              SNAIL 62
opdefs 33                             special characters 76
open single quote 4                   Stanford Character Set 74
operator 7                            starting address 43
ORG 28                                Statement Termination 7
                                      Statements 2
PAGE pseudo-op 48                     String FOR 56
parameter 17                          SUBTTL 47
parentheses 5, 7, 39, 49, 50,         SUPPRESS 37
     52, 56, 61                       suppress bit 37
percent sign 10                       symbol 11
PHASE 30                              Symbol IFs 60
point 10, 18, 27, 30                  Symbol Modifiers 33
POINT pseudo-op 39                    Symbols 15
Polish fixup 8
Predefined Opcodes 65                 tab 49
PRGEND 43                             Text IFs 59
PRINTS 48                             text statements 40
PRINTX 48                             tilde 4, 21, 40, 44, 48
program 23                            TITLE 43
Pseudo-Ops 28                         Truncated Expression 6
PURGE 36                              two-segment program 30
                                      TWOSEG 30
question mark 22
                                      unavailable 11, 21
RADIX 44                              undefined 11, 64
RADIX50 41                            underbar 10
82                              Index                            FAIL

universal program 37
universal symbols 37
unrelocatable 11, 64
up-arrow 4, 20, 24, 35, 40, 44,
USE 29
user-defined opcode 33
UUO 1, 3, 6, 65

Values 10
VAR 32, 43
Variables 18, 32, 42, 43

XWD 40