DataMuseum.dk

Presents historical artifacts from the history of:

CP/M

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦936288054⟧ TextFile

    Length: 147584 (0x24080)
    Types: TextFile
    Names: »D169«

Derivation

└─⟦4b76feb82⟧ Bits:30008865 Diskette med tekster der formodes at være 31-D-163…174
    └─⟦this⟧ »D169« 

TextFile

           
           \f

                                                 i 
           
          T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ _
           
          1.  INTRODUCTION ..........................................   1 
           
          2.  BASIC DEFINITIONS .....................................   3 
              2.1  Vocabulary .......................................   3 
              2.2  Syntax Diagrams ..................................   3 
                   2.2.1  Comments ..................................   4 
                   2.2.2  Identifiers ...............................   5 
                   2.2.3  Numbers ...................................   5 
                   2.2.4  Separators ................................   6 
                   2.2.5  Strings of Characters .....................   6 
              2.3  Fundamental Concepts .............................   7 
           
          3.  THE PASCAL80 LANGUAGE .................................  10 
              3.1  The Process Structure ............................  10 
              3.2  The Process Heading ..............................  12 
              3.3  The Declaration Part .............................  13 
                   3.3.1  Label Declaration Part ....................  14 
                   3.3.2  Constants Definition Part .................  15 
                   3.3.3  Variable Declaration Part .................  17 
                   3.3.4  Type Definition Part ......................  18 
                          3.3.4.1  Types ............................  18 
                          3.3.4.2  Type Compatibility ...............  31 
                   3.3.5  Routine Declaration Part ..................  34 
                          3.3.5.1  Scope Rules ......................  37 
                          3.3.5.2  Routine Blocks ...................  38 
                          3.3.5.3  Functions ........................  38 
                   3.3.6  Export Part ...............................  39 
              3.4  The Statement Part ...............................  40 
                   3.4.1  Statements ................................  40 
                   3.4.2  Assignment Statement ......................  41 
                   3.4.3  Exchange Statement ........................  44 
                   3.4.4  Repetitive Statements .....................  44 
                   3.4.5  Conditional Statements ....................  46 
                   2.4.6  Procedure Call ............................  48 
                   3.4.7  With Statement ............................  50 
                   3.4.8  Lock Statement ............................  50 
                   3.4.9  Channel Statement .........................  51 \f

                                        ii 
           
          T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _(_c_o_n_t_i_n_u_e_d_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ _
           
                   3.4.10  Goto Statement ...........................  52 
                   3.4.11  Standard Routines abs, succ, pred, chr, 
                           ord ......................................  52 
           
          4.  PROCESS COMMUNICATION .................................  54 
              4.1  General Process Communication ....................  54 
              4.2  The Predefined Communication Routines ............  68 
           
          5.  PROCESS CONTROL .......................................  75 
              5.1  The Predefined Routines for Process Control ......  75 
           
          6.  UTILITY PROGRAMS ......................................  78 
              6.1  Indent ...........................................  78 
              6.2  Cross Reference Program ..........................  79 
           
           
          A_P_P_E_N_D_I_X_: 
           
          A.  REFERENCES ............................................  81 
           
           \f

F_       1_._ _ _ _ _ _ _ _ _I_N_T_R_O_D_U_C_T_I_O_N_ 1.
           
          This first edition of the PASCAL80 User>s Guide is mainly based
          on extracts from earlier PASCAL80 papers such as the Report 1,
          and some preliminary introductions, and information published in
          Danish under the common little "PASCAL80 NYT". 
           
          This manual is directed to those who have previously acquired
          some familiarity with computer programming, and now wish to get
          acquainted with the programming language PASCAL80. The style of
          the manual is that of a tutorial, i.e. a demonstration of the
          language features by means of examples. 
          For a concise ultimate of the language definition the PASCAL80
          REPORT 1 may be used and the actual implementations are des-
          cribed in xx-PASCAL80-REFERENCE manuals, by now xx is RC3502 and
          RC850. 
           
          Since PASCAL80 is based directly on Wirth>s Standard Pascal 2
          familiarity with that language means that the parts concerning
          sequential programs, i.e. most of the declarations and control
          statements, may be well known. PASCAL80 can be characterized as
          Standard Pascal without files but extended with communication
          primitives to be used to connect concurrent process incarnations.
           
          For programmers acquainted with ALGOL, or FORTRAN it may prove
          helpful to glance at PASCAL80 in terms of these other languages.
          For this purpose we list the following characteristics of
          PASCAL80. 
           
          1.  Declaration of variables is mandatory. 
          2.  Certain key words (e.g. PROCESS, BEGIN) are "reserved" and
              cannot be used as identifiers. In this manual they are writ-
              ten with capital letters. 
          3.  The semicolon (;) is considered as a statement separator, not
              a statement terminator. 
          4.  The standard data types are those of whole numbers, the logi-
              cal values, the characters, semaphores, shadows, references,
              and pools. The basic data structuring facilities include the
              array, the record (corresponding to COBOL>s "structure"),\f

                       the pool, and the set. These structures can be combined and
              nested. 
          5.  The facilities of the ALGOL switch and the computed go to of
              FORTRAN are represented by the case statement. 
          6.  The for statement corresponding to the DO loop of FORTRAN,
              may only have steps of 1 (TO) or -1 (DOWNTO) and is executed
              only as long as the value of the control variable lies within
              the limits. Consequently, the controlled statement may not be
              executed at all. 
          7.  There are no conditional expressions and no multiple assign-
              ments. 
          8.  Procedures and functions may be called recursively. 
          9.  There is no "own" attribute for variables (as in ALGOL).
              Parameters are called either by value or by reference; 
              there is no call by name. 
          10. The "block structure" differs from that of ALGOL insofar as
              there are no anonymous blocks, i.e. each block is given a
              name, and thereby is made into a routine. 
          11. PASCAL80 is equipped with semaphores as a synchronizing tool
              and message buffers as a communication tool. 
          12. Concurrent process incarnations are synchronized by means of
              signal-wait primitives. 
               
               \f

F_       2_._ _ _ _ _ _ _ _ _B_A_S_I_C_ _D_E_F_I_N_I_T_I_O_N_S_ 2.
           
2_._1_ _ _ _ _ _ _ _V_o_c_a_b_u_l_a_r_y_ 2.1
           
          The basic vocabulary consists of language symbols and user
          defined symbols. The language symbols are reserved words (key
          words) and punctuation marks: 
           
          AND            ELSE          LABEL          PROCESS 
          ARRAY          END           LOCK           RECORD 
          AS             EXPORT        MOD            REPEAT 
          BEGIN          EXTERNAL      NOT            SET 
          BEGINBODY      FOR           OF             THEN 
          CASE           FORWARD       OR             TO 
          CHANNEL        FUNCTION      OTHERWISE      TYPE 
          CONST          GOTO          PACKED         UNTIL 
          DIV            IF            POOL           VAR 
          DO             IN            PREFIX         WHILE 
          DOWNTO         INCLUDE       PROCEDURE      WITH 
           
          +        -         *       /       "       >       <       ' 
          <'       <=        '=      (       )       (.      .) 
          =        :=        :=:     .       ,       :       ;       .. 
          ***      (*        *)      !       ?       <*      *'      # 
           
          The user may not use the reserved words in a context other than
          that explicit stated in the definition of PASCAL80; in particu-
          lar, these words may not be used as identifiers. 
           
           
2_._2_ _ _ _ _ _ _ _S_y_n_t_a_x_ _D_i_a_g_r_a_m_s_ 2.2
           
          The syntax of PASCAL80 is defined graphically by syntax diagrams.
          A syntax diagram consists of arrows, language symbols, and names
          of syntax diagrams. A PASCAL80 program is syntactically correct
          if it can be obtained by traversing the syntax diagrams. A trav-
          ersal must follow the arrows. The name of a syntax diagram indi-
          cates a traversal of the corresponding diagram. The result of a
          traversal is the sequence of language symbols encountered in the
          traversal. \f

                   The following is an example of a syntax diagram. 
           
          while statement: 
           
                'WHILE       'expression     'DO      'statement     ' 
           
          The syntax diagram defines the name (while statement) and syntax
          of language construct. The name is used when the construct is
          referred to elsewhere in the text or in other syntax diagrams. 
          Language symbols are either names in capital letters (e.g. WHILE)
          or punctuation marks (e.g. :=). 
           
          Constructs defined by other syntax diagrams are given by their
          names in small letters (e.g. expression). To be able to distin-
          quish between several occurrences of a construct, its name my be
          subscripted. 
           
           
2_._2_._1_ _ _ _ _ _C_o_m_m_e_n_t_s_ 2.2.1
           
          Comment: 
           
                  '    '(* '                      ' '*)     '      ' 
                            < character< 
                            < non-printing symbol< 
                             
                     '<*    '                     ' '*'     ' 
                            < character< 
                            < non-printing symbol< 
           
          Comments may be inserted between any two identifiers, numbers or
          special symbols. A comment does not affect the execution of the
          program. 
           
           \f

         2_._2_._2_ _ _ _ _ _I_d_e_n_t_i_f_i_e_r_s_ 2.2.2
           
          Names denoting labels, constants, types, variables, processes,
          and routines are called identifiers. They must begin with a
          letter or an underscore which may be followed by any combination
          and number of letters, digits, and underscores. Contrary to
          Standard PASCAL all the characters of an identifier are recog-
          nized as significant. Small and big letters are handled as being
          the same in identifiers. 
           
          identifier: 
                     
                         'letter ' '           '       ' 
                            ' _   '  < letter< 
                                    < digit< 
                                    <    _< 
           
          letter is   A,B,...,Å,a,b,c,...,å 
          digit  is   0,1,2,...,9 
           
          Examples of legal identifiers: 
          step     use _count     Local _Message 
           _ _ _ _ _very _ _ _special _ _ _defined _ _ _identifier 
           
          Note: "Local _Message" is identical to "local message", 
          "LOCAL _MESSAGE", and any other combination of small and big
          letters. 
           
           
2_._2_._3_ _ _ _ _ _N_u_m_b_e_r_s_2.2.3
           
          At label can be either an identifier or a numeric value in
          PASCAL80, this is in contrast to Standard Pascal where label is
          demanded to be an unsigned integer. 
           \f

                   numeric value: 
           
                        '   'digit    '    '        ' 
                         < 
           
                      '#b ' 'binary digit ' ' 
                      '#o ' 'octal digit  ' ' 
                      '#h ' 'hexa digit   ' ' 
                      
                     binary digits are 0..1 
                     octal digits are  0..7 
                     hexa digits are   0..9 and a..f 
           
          Example of legal numbers: 
          7913    0033     #b101     #hff00     #o7654 
           
           
2_._2_._4_ _ _ _ _ _S_e_p_a_r_a_t_o_r_s_ 2.2.4
           
          Blanks, nl>s, ff>s and comments are considered as separators. 
          Separators can appear between any two consecutive language
          symbols. 
          No separator may occur within an identifier, number, numeric
          value, or language symbol. At least one separator must appear
          between any pair of consecutive identifiers, character strings,
          numbers, numeric values, or language symbols. 
           
           
2_._2_._5_ _ _ _ _ _S_t_r_i_n_g_s_ _o_f_ _C_h_a_r_a_c_t_e_r_s_ 2.2.5
           
          A character string is a sequence of characters enclosed by quote
          marks, both single and double guote marks are legal but the end
          mark must match the start mark. 
           \f

                   Character string: 
           
                           '  '" '-'string character ' '"   '  ' 
                                            < 
               
                              '> ' 'string character ' '>   ' 
                                            < 
           
          String characters are the printable subset of the alphabet, 
          excluding newline (nl) and form feed (ff),  i.e. > >, >!>, ...,> >
           
          Examples of legal strings: 
          "abcd", " > > is a strange character", >"> 
           
          Note: If a string surrounded by single quote marks is to contain
          a quote mark or a string surrounded by double quote marks is to
          contain the surrounding quote mark, then this quote mark is to be
          written twice, for example """" is equivalent to >">, and >>>> is
          equivalent to ">".  
           
           
2_._3_ _ _ _ _ _ _ _F_u_n_d_a_m_e_n_t_a_l_ _C_o_n_c_e_p_t_s_ 2.3
           
          This section gives a brief explanation of a few concepts and the
          context in which they are used. The complete description of all
          PASCAL80 concepts is given in the following sections. 
           
          A p_r_o_g_r_a_m_ consists of a number of processes. Each p_r_o_c_e_s_s_ is a
          description of some actions and a description of a data struc-
          ture. An i_n_c_a_r_n_a_t_i_o_n_ of a process is the execution of the actions
          on a private data structure. Many incarnations can be executed
          concurrently. 
           
          Actions are described by s_t_a_t_e_m_e_n_t_s_. The actions of one incarna-
          tion are executed one at a time in the order defined by the
          statements. The actions manipulate the data structure, which is
          described by a number of v_a_r_i_a_b_l_e_s_. A v_a_r_i_a_b_l_e_ has a name and a
          type. The t_y_p_e_ describes the set of values the variable can hold
          when the program is executed. There is a number of p_r_e_d_e_f_i_n_e_d_
          t_y_p_e_s_ (integer, char, boolean, reference, semaphore, and shadow).
           \f

                   New types are defined either by listing their values or by com-
          bining several types into a s_t_r_u_c_t_u_r_e_d_ _t_y_p_e_. 
           
          A number of statements and declarations can be combined into a
          r_o_u_t_i_n_e_ _d_e_c_l_a_r_a_t_i_o_n_. Activation of a routine is described by
          r_o_u_t_i_n_e_ _c_a_l_l_s_ (statement). 
           
          Process incarnations communicate by exchanging m_e_s_s_a_g_e_s_. A mes-
          sage can be accessed by one incarnation at a time. 
           
           
           
          place data             M          await access 
          in M      A                       to M         B 
           
                    T_i_m_e_ _T_: A has exclusive access to the message M. 
           
                                 M          read data 
                    A                       in M      B 
           
                    T_i_m_e_ _T_ _+_ _1_: B has exclusive access to M. 
           
          Variables of the two predefined types reference and semaphore are
          used for accessing and exchanging access to messages. 
           
          The value of a reference variable is either a reference to a mes-
          sage or nil (representing "no reference"). A message can be
          accessed through at most one reference variable at a time. Since
          process incarnations access messages through reference variables
          only, mutually exclusive access to messages is secured. 
           
          Incarnations exchange access to messages by means of q_u_e_u_e_ _s_e_m_a_p_-
          h_o_r_e_s_. An incarnation places a message in a semaphore from which
          another incarnation can get access to it. Variables of type se-
          maphore can be declared in any process. A semaphore variable may
          be accessible by many incarnations simultaneously. 
           \f

                   Processes can be nested and a process which is declared within
          another process is a sub-process (of the surrounding process). 
           
          An arbitrary number of incarnations of sub-processes (children)
          can be created, they are all controlled by the parent. 
          Incarnations are created and removed dynamically. 
           
          A process can have f_o_r_m_a_l_ _p_a_r_a_m_e_t_e_r_s_. When an incarnation of the
          process is created a number of a_c_t_u_a_l_ _p_a_r_a_m_e_t_e_r_s_ is given. Incar-
          nations communicate through common semaphore variables only. In
          this way a process determines the communication paths of sub-pro-
          cesses. Note, however, that the controlling process incarnation
          need not participate in the comminication. 
           
           \f

F_3_._ _ _ _ _ _ _ _ _T_H_E_ _P_A_S_C_A_L_8_0_ _L_A_N_G_U_A_G_E_ 3.
           
          This chapter consists of descriptions of the different compo-
                   nents of a PASCAL80 process. First an example which shows the
          structure of a complete process definition, and after the example
          is given a more precise description of the syntactical defini-
          tion, of the different parts of the process definition. 
           
           
3_._1_ _ _ _ _ _ _ _T_h_e_ _P_r_o_c_e_s_s_ _S_t_r_u_c_t_u_r_e_ 3.1
           
          A PASCAL80 process consists of d_e_c_l_a_r_a_t_i_o_n_s_ of constants, types,
          variables, routines, labels, and some s_t_a_t_e_m_e_n_t_s_ that operate on
          the declared objects. 
           
          This is an outline of a PASCAL80 process: 
           
          PROCESS catalog; 
            CONST 
               idlength = 10; 
               catalogsize = 256; 
            TYPE 
                        identifier = ARRAY (1 .. idlength) OF char; 
M_m_m_            . 
            . 
P_p_p_            . 
            VAR 
               name: identifier; 
               found: boolean; 
               index: integer; 
            FUNCTION hash (id: identifier): integer; 
               VAR 
                 key, next: integer; 
                 ch: char; \f

            BEGIN (* body of function hash *) 
               key:= 1; 
               next:= 0; 
                        REPEAT 
                  next:= next + 1; 
                  ch:= id (next); 
                  IF ch <' sp 
                     THEN key:= key * ord (ch) MOD catalogsize + 1; 
               UNTIL (ch = sp) OR (next '= idlength); 
               hash:= key; 
            END; (* of hash *) 
M_m_m_            . 
            . 
P_p_p_            . 
            BEGIN (* main program *) 
M_m_m_             . 
            . 
P_p_p_            . 
               index:= hash (name); 
               REPEAT 
M_m_m_               . 
               . 
P_p_p_               . 
                  found:= --- 
M_m_m_                  . 
                  . 
P_p_p_                  . 
               UNTIL found; 
M_m_m_               . 
               . 
P_p_p_               . 
            END. 
             
          The process contains a declaration of 
           
          - two contants: idlength with the value 10 and catalogsize with
            the value 256 
             
          - a type: identifier which is an array of characters 
             \f

          - three variables: name which can hold a value of type identi-
            fier, found which can hold a value of type boolean, and index
            which can hold an integer. 
           
          - a function hash which maps an identifier to an integer. 
             
          The function has a formal parameter id and three local variables
          key, next, and ch. The assignment statement: index:= hash (name)
          contains a call of the function; the result of the function is
          assigned to the variable index. 
           
          All declared objects have names: catalog, idlength, catalogsize,
          identifier, name, found, index, hash, id, key, next, and ch.
          These names are defined by declarations before they are used in
          statements. 
           
           
         3_._2_ _ _ _ _ _ _ _T_h_e_ _P_r_o_c_e_s_s_ _H_e_a_d_i_n_g_ 3.2
           
          The process heading consists of an identification of the process
          to be declared and a parameter description. The process in the
          example of section 3.1 has no parameter, the identification is
          "catalog". 
           
          process heading: 
           
               'PROCESS     'process name    'formal parameter   ' 
           
          (formal parameters are described in subsection 3.3.5). 
           
          Declarations common to more processes may be defined in a
          context, and it may be specified in the call of the compiler
          which context(s) to include. The syntax is: 
           
          context: 
           
              'context name   ';   'context declarations   '.   ' 
           \f

          context declarations: 
           
                         '              '                           ' 
                           <                                       
                                                               ;   
                              'constant declaration           ' 
                              'type declaration               ' 
                              'external routine declaration   ' 
           
           
          external routine declaration: 
           
                  '  'procedure heading   '    ';     external     ' 
                     'function heading 
           
           
3_._3_ _ _ _ _ _ _ _T_h_e_ _D_e_c_l_a_r_a_t_i_o_n_ _P_a_r_t_ 3.3
           
          The declarations of a program serves as a description of the data
          which are manipulated by the actions performed by the program. 
           
          declarations: 
           
               '               '                         '     '
               <               <                           
                    'contstant declaration        '  '; 
                    'type declaration             ' 
                    'variable declaration         ' 
                    'label declaration            ' 
                    'routine declaration          ' 
                    'prefixed process declaration ' 
                    'export export part           ' 
           
          The order of declarations is only restricted of the demand for
          definition before use. 
           
           \f

3_._3_._1_ _ _ _ _ _L_a_b_e_l_ _D_e_c_l_a_r_a_t_i_o_n_ _P_a_r_t_ 3.3.1
           
          A l_a_b_e_l_ is an identification of a statement, it can be either a
          number or an identifier. Every label must be declared. 
           
          label declaration: 
           
                  'LABEL      '     label     '                  ' 
                                   ,< 
           
          label: 
           
             '   'number        '                                ' 
                  'identifier 
           
          Example: 
           
          LABEL 7913, even _action; 
                    
          A label is denoted by the identifier or the integer value of the
          number. (GOTO statement 3.4.10) 
           
          A l_a_b_e_l_ _i_s_ _d_e_f_i_n_e_d_ by a labelled statement. 
           
          labelled statement: 
           
                  'label     ':     'statement               ' 
           
          Labels must be defined and used in the scope (not block) where
          they are declared. A label may only be defined once in a scope. 
          Scope is defined in subsection 3.3.5. 
           
          example: 
           
          error _action: exception (error _code); 
           
           \f

3_._3_._2_ _ _ _ _ _C_o_n_s_t_a_n_t_s_ _D_e_f_i_n_i_t_i_o_n_ _P_a_r_t_ 3.3.2
           
          If a value is used serveral times in a program, it is useful to
          declare a constant with this value. In the program the constant
          is used to denote the value. 
           
          constant declaration: 
           
                CONST  '  'constant name  '=  'constant expression  '   ' 
                                              ;< 
           
          The constant expression is an expression the value of which may
          be computed at compile time, i.e. each operand must be a constant
          or a symbolic value. A very convenient feature of PASCAL80 is the
          so-called structured value which may be used for defining
          constants and for initialization of structured variables. 
           
                   structured value: 
           
               '   'character string                        '      ' 
                   'set                                     ' 
                   'type name     '(     'value list    ')  ' 
           
          value list: 
           
               '   '   'unit                                '   '   ' 
                    'repetition     '***    'unit 
                                    ,< 
           
          Units of a value list are given one at a time (separated by ,) or
          by repeating a unit. The value of repetition specifies how many
          times the unit is repeated. 
           \f

          A structured value is built as follows: 
           
          - type name denotes a record type: 
            There must be a unit for each field and the first field gets
            the value of the first unit, the second field the value of the
            second unit etc. The repetition cannot be used. 
             
          - type name denotes an array type: 
            There must be a unit for each element and the first element
            gets the value of the first unit, the second element the value
            of the second unit etc. 
             
          repetition: 
           
                  'constant expression                              ' 
           
          unit: 
           
              '   'constant expression   '                          ' 
                           '? 
           
                   The unit "?" specifies n_o_ _v_a_l_u_e_, i.e. the component is skipped,
          its type is compatible with any type. This element is necessary
          to specify values of components which have no symbolic represen-
          tation, e.g. values of shielded types. The no value element can
          only be used in value lists. 
           
          Example: 
           
                    CONST 
                       catalogsize = 256; 
                       test = true; 
                       nul = 0; 
           
          If these values are changed, only the constant declaration needs
          to be changed. 
           
           \f

3_._3_._3_ _ _ _ _ _V_a_r_i_a_b_l_e_ _D_e_c_l_a_r_a_t_i_o_n_ _P_a_r_t_ 3.3.3
           
          A declaration of a variable must specify the name and type of the
          variable. 
           
          variable declaration: 
           
              'VAR ' 'variable name list ':  'type ' 'initialization '  '  '
                                                          ' 
                                          ;< 
           
          variable declaration 
           
               ' 'variable name   '                                       '
                       ,< 
           
          initialization: 
           
                        ':=     'constant expression                      '
           
                   The type of the expression must be compatible with the type of
          the variable. 
           
          The value specified by the constant expression becomes the ini-
          tial value of all variables in the variable name list. 
           
          Example: 
           
                    VAR 
                        found: boolean:= false; 
                        index: 1 .. catalogsize; 
                        name: identifier:= identifier (idlength***sp); 
           \f

          The type defines which values a variable can hold. The variable
          found can hold the boolean values false and true, the initial
          value is false. The variable index can hold an integer in the
          range 1 to 256 (catalogsize = 256) the value of index is unde-
          fined until first assignment. The value of a variable is changed
          by an assignment: 
           
                    found:= true; 
                    index:= index MOD catalogsize + 1; 
           
           
3_._3_._4_ _ _ _ _ _T_y_p_e_ _D_e_f_i_n_i_t_i_o_n_ _P_a_r_t_ 3.3.4
           
          All data which is manipulated by a PASCAL80 program has a type. 
          All operands (variables, constants, values etc.) have a fixed
          type and for each operator and statement there are strict rules
          defining which types of operands it accepts. 
           
           
3_._3_._4_._1_ _ _ _T_y_p_e_s_ 3.3.4.1
           
          A_ _t_y_p_e_ _i_s_ _a_ _s_e_t_ _o_f_ _v_a_l_u_e_s_ _a_n_d_ _a_ _m_e_t_h_o_d_ _o_f_ _a_c_c_e_s_s_i_n_g_ _t_h_e_s_e_ _v_a_l_u_e_s_.
          There is a number of predefined types: integer, char, boolean,
          semaphore, reference, and shadow. New types are named and defined
          by type declarations. 
                    
          type declaration: 
           
               'TYPE   '    'type name  '=type   '      ' 
                                   ;< 
           \f

          type: 
           
              '    'enumeration type      '                      ' 
                   'shielded type          ' 
                   'pointer type           ' 
                   'structured type        ' 
                   'named type             ' 
                   'frozen type 
           
          Type declarations may not be recursive, except in a type declara-
          tion: 
                   TYPE name = t; 
          where t may contain the pointer type   name as an element or
          field type; 
           
          E_n_u_m_e_r_a_t_i_o_n_ _T_y_p_e_s_ 
          An e_n_u_m_e_r_a_t_i_o_n_ _t_y_p_e_ consists of a finite, totally ordered set of
          values. Furthermore, there is a mapping from the set of values to
          the integers. 
           
          enumeration type: 
           
               '    'char             '                             ' 
                    'boolean          ' 
                    'integer          ' 
                    'scalar type      ' 
                    'subrange type    ' 
           
          The three predefined types char, boolean, and integer are
          described below. 
           
          S_c_a_l_a_r_ _T_y_p_e_s_ 
          A s_c_a_l_a_r_ _t_y_p_e_ is a sequence of values (scalar constants). A
          scalar type is declared by listing its values in increasing
          order. 
           
                   scalar type: 
           
              '(    '    'scalar constant   '    ')                   ' 
                                 ,< 
           \f

          scalar constant: 
           
                  'identifier                                         ' 
           
          A s_c_a_l_a_r_ _c_o_n_s_t_a_n_t_ is an identifier appearing in the declaration
          of a scalar type T. The type of the scalar constant is T. Con-
M_M_m_          sider the following scalar type (e , e , ... e , e   , ... e ), 
P_P_p_                                              0   1       n   n+1       N 
M_M_m_          then e    is the p_r_e_d_e_c_e_s_s_o_r_ of e  and e    is the s_u_c_c_e_s_s_o_r_ of e
P_P_p_                  n-1                        n      n+1                      n
M_M_m_          the o_r_d_i_n_a_l_ _v_a_l_u_e_ of e  is n. The predecessor of e  and the
P_P_p_                                  n                           0 
M_M_m_          successor of e  are undefined. 
P_P_p_                          N 
           
          Example: 
           
          TYPE 
               device = (drum, tape, disk); 
           
          The type device has the values drum, tape, and disk. 
           
                    
          T_h_e_ _T_y_p_e_ _C_h_a_r_ 
           
          The type c_h_a_r_ is a predefined enumeration type. Its values are
          the (Danish) ISO characters. 
           
           _ _ _ _ _ _0_ _ _ _ _1_ _ _ _ _2_ _ _ _ _3_ _ _ _ _4_ _ _ _ _5_ _ _ _ _6_ _ _ _ _7_ _ _ _ _8_ _ _ _ _9_ _ _ _ _ _ 
           0   nul  soh  stx  etx  eot  enq  ack  bel  bs   ht 
          10   nl   vt   ff   cr   so   si   dle  dc1  dc2  dc3 
          20   dc4  nak  syn  etb  can  em   sub  esc  fs   gs 
          30   rs   us   sp   !    "             %    &    > 
          40   (    )    *    +    ,    -    .    /    0    1 
          50   2    3    4    5    6    7    8    9    :    ; 
          60   <    =    '    ?    @    A    B    C    D    E 
          70   F    G    H    I    J    K    L    M    N    O 
          80   P    Q    R    S    T    U    V    W    X    Y 
          90   Z    Æ    Ø    Å          _         a    b    c 
         100   d    e    f    g    h    i    j    k    l    m 
         110   n    o    p    q    r    s    t    u    v    w 
         120   x    y    z    æ    ø    å         del 
          \f

          The characters are numbered and the ordinal number of a character
          is the sum of its row and column number in the above table. The
          ordinal values define the ordering of the characters. 
           
          > > (sp), >!> >">, ... > > are printing characters. 
           
          T_h_e_ _T_y_p_e_ _B_o_o_l_e_a_n_ 
           
          The type b_o_o_l_e_a_n_ is a predefined scalar type, defined as: 
           
          TYPE     boolean = (false, true); 
           
          S_u_b_r_a_n_g_e_ _T_y_p_e_s_ 
          A type can also be declared as a_ _s_u_b_r_a_n_g_e_ of an already defined
          type. 
           
          A subrange type is a sub-sequence of an enumeration type. 
           
                   subrange type: 
           
                     'min bound      '..      'max bound             ' 
           
          min bound, max bound: 
           
                     'expression                                     ' 
           
          The min and max bounds must be of the same enumeration type. 
           
          example: 
           
          TYPE 
               index = 1 .. catalogsize; 
               small _letters = "a" .. "å"; 
               byte = 0 .. 255; 
           
          These declarations restrict the set of values of the type to the
          specified range. 
           \f

          S_t_r_u_c_t_u_r_e_d_ _T_y_p_e_s_ 
           
          A structured type is a composition of other types. There are
          three kinds of structured types: array, record, and set. 
           
          structured type: 
           
               '              '  '   'array type    '                 ' 
                   'PACKED           'record type   ' 
                                     'set type      ' 
           
          A structured type has a number of c_o_m_p_o_n_e_n_t_ _t_y_p_e_s_. 
           
          A_r_r_a_y_ _T_y_p_e_s_ 
           
          An a_r_r_a_y_ consists of a number of elements of the same type. The
          number of elements is specified by an index type. 
           
                   array type: 
           
              'ARRAY    '(  '  'index type  '  ')    'OF  'element type   '
                                   ,< 
           
          index type, element type: 
           
              'type                                                       '
           
          The index type must be an enumeration type or the name of an
          enumeration type. 
           
          Example: 
           
          TYPE 
               identifier = ARRAY (1 .. idlength) OF char; 
               count = ARRAY (letters) OF integer; 
          VAR 
               id: identifier; 
           \f

          The elements of the array "id" have indices from 1 to 10 (idlength).
          The value of an element can be changed: 
           
               id (5):= "x"; 
           
          An array value (whole array) can also be constructed and
          manipulated: 
           
               CONST 
                 blank = "         "; 
               . 
               . 
               . 
               IF id <' blank 
                 THEN ... 
           
                   Then array type 
           
M_M_m_                    ARRAY (t ,t ) OF t 
P_P_p_                            1  2      3 
           
          is a shorthand for the type 
           
M_M_m_                    ARRAY (t ) OF ARRAY (t ) OF t . 
P_P_p_                            1             2      3 
           
          This is a m_u_l_t_i_-_d_i_m_e_n_s_i_o_n_a_l_ array. The number of index types is
          the d_i_m_e_n_s_i_o_n_ of the array. 
           
          The name of an array variable denotes the whole array. An element
          is accessed by the array variable followed by an index enclosed
          in parentheses. An index consists of a number of index expres-
          sions. The number of index expressions must be less than or equal
          to the dimension of the array. 
           
          If the element type itself is structured, the c_o_m_p_o_n_e_n_t_ _t_y_p_e_s_ _o_f_
          t_h_e_ _a_r_r_a_y_ _t_y_p_e_ are the component types of the element type. 
           \f

          array variable: 
           
                     'variable   '                   '                  ' 
                                    'indec selector 
           
          index selector: 
           
                '(    '    'index expression    '    ')                 ' 
                                  ,< 
           
          index expression: 
           
                'expression                                             ' 
           
          The type of each index expression must be compatible with the
          corresponding index type. 
           
                   R_e_c_o_r_d_ _T_y_p_e_s_ 
           
          A r_e_c_o_r_d_ consists of a number of fields. Each f_i_e_l_d_ has a name
          and a type. 
           
          record type: 
           
                  'RECORD       'field list        'END            ' 
           
          field list: 
           
               '  'field name list      ':    'field type ' ' '; '     ' 
                                        ;<                     ' 
           
          field name list: 
           
               '  'field name     '                                    ' 
                    ,< 
           \f

          Example: 
           
                    TYPE 
                       catalogentry = RECORD 
                                          id: identifier; 
                                          hashkey: integer; 
                                          medium: device; 
                                          addr: range; 
                                      END; 
                    VAR 
                       element: catalogentry; 
           
          The record of type catalogentry has four fields: id, hashkey,
          medium, and addr. These fields are of the type identifier,
          integer, device, and range respectively. The value of a field can
          be changed or read: 
           
                    element.medium:= drum; 
                    IF element.id (1) <_ "a" THEN ... 
                     
                   Values of record type are structured values (see subsection
          3.4.1): 
           
                    element:= catalogentry (blank, 0, drum, 16712); 
           
          S_e_t_ _T_y_p_e_s_ 
           
          The values of a s_e_t_ _t_y_p_e_ are the subset of some enumeration type.
           
          set type: 
           
                   'SET          'OF        'element type          ' 
           
          element type: 
           
                    'type                                          ' 
           
          The element type must be an enumeration type or the name of an
          enumeration type. 
           \f

          A s_e_t_ _e_l_e_m_e_n_t_ is a value of the element type. The component type
          of a set is the element type. 
           
          Values of set type are written as a list of set elements. 
           
          set: 
           
               '(.  '  '  'element list  '  '  '.)                   ' 
                                ,< 
                                ' 
           
          element list: 
           
               '   'element                              '            ' 
M_M_m_                   'element         '..     'element 
P_P_p_                           1                        2 
           
                   element: 
           
                  'expression                                         ' 
           
          All elements in a set must be of the same type and these must all
          be compatible with the element type. The empty set is denoted
          (..). The type of (..) is compatible with any set type. 
           
          A variable of type set can be given a value: 
           
                    digits:= (. "0" .. "9".); 
           
          The operators on set operands are + (union), * (intersection), 
          - (difference), and IN (membership). 
           \f

          Example: 
           
                    TYPE 
                        characters = SET OF char; 
                    VAR 
                        digits, letters: characters; 
                    FUNCTION nextid: identifier; 
                        VAR 
                            i: 1 .. idlength; 
                            ch: char; 
                    BEGIN (* body of nextid *) 
                      i:= 1; 
                      nextid:= blank; 
                      ch:= getchar; 
                      IF ch IN letters THEN 
                         WHILE (ch IN (letters + digits)) AND (i <= idlength) DO
                         BEGIN 
                           nextid (i):= ch; 
                           i:= i + 1; 
                           ch:= getchar; 
                         END; 
                    END; (* of nextid *) 
                     
                   (Note, getchar is not a PASCAL80 primitive). 
           
          As the above examples show, a type (predefined or programmer
          defined) can be used for constructing values of the type,
          defining constants, and declaring variables. 
           
          P_o_i_n_t_e_r_ _T_y_p_e_s_ 
           
          The values of pointer type are pointers to variables or nil (no
          pointer). 
           
          pointer type: 
           
                    '          'type                              ' 
           \f

          The value nil belongs to every pointer type; it does not point to
          any variable. 
           
          Assignments can be made to variables of pointer types. 
           
          The variable pointed to by a pointer (value) is denoted by a
          variable of pointer type followed by an arrow ( ). 
           
          For the use of pointer variables and pointer types see the
          example in section 4.2 (under "ref"). 
           
          F_r_o_z_e_n_ _T_y_p_e_s_ 
           
          In PASCAL80 the programmer has the possibility of declaring vari-
          ables and parameters as "read only" i.e. the variable/parameters
          cannot be changed inside the process/routine with the read-only
          declaration. 
           
          frozen type: 
           
                    '!      'base type                                    '
           
          base type: 
           
                   'type                                                  '
           
                   A variable of a frozen type must not be used as the lefthand side
          of an assignment, in an exchange statement, or as a variable
          parameter, unless the formal parameter is of the same frozen
          type! 
           
          A frozen type is compatible with its base type. The component
          types of a frozen type are the component types of the base type. 
           
          S_h_i_e_l_d_e_d_ _T_y_p_e_s_ 
           
          Variables of s_h_i_e_l_d_e_d_ _t_y_p_e_s_ enable a process incarnation to
          communicate with and control other incarnations. 
           \f

          shielded type: 
           
              '    'reference    '                                        '
                   'semaphore    ' 
                   'shadow       ' 
                   'pool type    ' 
           
          The values of shielded types cannot be accessed directly. They
          are protected against malicious or accidental misuse. Therefore,
          the assignment statement cannot be applied to variables of
          shielded types. The exhange statement is provided instead (see
          subsection 3.4.3). 
           
          T_h_e_ _T_y_p_e_ _R_e_f_e_r_e_n_c_e_ 
           
          The values of type r_e_f_e_r_e_n_c_e_ are references to messages or nil
          (no reference). A message is always accessible through exactly
          one reference variable. 
           
          The syntax used to denote the accessible fields of a message
          header is derived from considering the type reference as a
          predefined pointer type (see section 5.3): 
           
          TYPE reference =   message; 
           
                   The type of the message header is: 
           
          TYPE 
               message = RECORD (*message header*) 
                           size, messagekind: !integer; 
                           u1, u2, u3, u4: 0..255; 
                           (*owner, answer:  semaphore; 
                           data:  message data; 
                           other implementation dependent fields*) 
                         END; 
           \f

          The interpretation of s_i_z_e_ and m_e_s_s_a_g_e_k_i_n_d_ is i_m_p_l_e_m_e_n_t_a_t_i_o_n_
          d_e_p_e_n_d_e_n_t_. The owner, answer, and data fields cannot be used
          directly. 
           
          M_e_s_s_a_g_e_s_ 
           
          Process incarnations communicate by exchanging access to messages
          which hold data. When a process has access to a message it can
          place data in or read data from the message. A message can be
          accessed by one incarnation at a time (see section 2.3) 
           
          A message consists of a m_e_s_s_a_g_e_ _h_e_a_d_e_r_ and m_e_s_s_a_g_e_ _d_a_t_a_ (possibly
          empty). A h_e_a_d_e_r_ _m_e_s_s_a_g_e_ is a message with no message data. 
           
          T_h_e_ _T_y_p_e_ _S_e_m_a_p_h_o_r_e_ 
           
          A q_u_e_u_e_ _s_e_m_a_p_h_o_r_e_ consists of a sequence (fifo) of messages and a
          set of waiting process incarnations. One of these is always
          empty. The values of type semaphore are queue semaphores. 
           
          The semaphore is o_p_e_n_ when the set of waiting incarnations is
          empty and the sequence of messages in non-empty. When the
          sequence is empty and the set of waiting incarnations is none-
          empty, the semaphore is l_o_c_k_e_d_. If both are empty, the semaphore
          is p_a_s_s_i_v_e_. 
           
                   These concepts are described in details in the sections concern-
          ing process communication (chapter 4). 
           
          Variables of type semaphore (or variables with semaphore compo-
          nents) are restricted only to be declared in the declarations of
          a process and not in the declarations of a routine. 
           
          T_h_e_ _T_y_p_e_ _S_h_a_d_o_w_ 
           
          The values of type s_h_a_d_o_w_ are references to process incarnations
          or nil (no reference). Initially, a shadow variable is nil. 
           \f

          A shadow variable is given a value by creating a new incarnation.
          The incarnation is controlled through the shadow variable. 
          The predefined routines for controlling incarnations are des-
          cribed in the sections concerning process control (chapter 5). 
           
          P_o_o_l_ _T_y_p_e_s_ 
           
          A p_o_o_l_ consists of a number of messages. 
           
          pool type: 
           
                   'POOL         'cardinality  '  'OF     'type   '     '
                                                       ' 
           
          cardinality: 
           
                  'expression                                           ' 
           
          Initially a pool consists of a number of messages. The number is
          the value of cardinality (expression) which must be a positive
          integer. Each of the messages can hold a value from type. If no
          type is specified, the messages have headers only. 
           
          With each variable of type pool an anonymous semaphore is asso-
          ciated. This is the owner semaphore of all messages in the pool. 
          A message is allocated from the pool by the predefined procedure
          alloc (see chapter 4). 
           
           
3_._3_._4_._2_ _ _ _T_y_p_e_ _C_o_m_p_a_t_i_b_i_l_i_t_y_ 3.3.4.2
           
          In PASCAL80 any operand has a fixed type which can be determined
          statically. The type of constants, variables, and formal parame-
          ters is specified in their declaration. \f

             CONST 
                length = 16; 
             TYPE 
                word = ARRAY  (0 .. length - 1) OF boolean; 
             CONST 
                nul = word (length *** false); 
             VAR 
                status: word; 
           
          The constant length is of type integer. The construct 
          "word (length *** false)" is a value of type word where all
          elements are false. The constant nul and the variable status are
          both of type word. 
           
          The type of an expression is determined by the types of its
          operands and the way they are combined by operators. The addition
          of two integers, i.e. length + 1, gives a result of type integer,
          comparison of two integers, i.e. j <= length, gives a result of
          type boolean, conjunction of two booleans gives a boolean result,
          i.e. found AND (j <= length) etc. The operator AND can only be
          applied to boolean operands, the operator / can only be applied
          to integer operands etc. Similar restrictions are put on the
          operands used in all other constructs. In a while statement, for
          example, an expression of type boolean must be given: 
           
               WHILE found AND (j <= length) DO ... 
           
          A value of some type T can be assigned to a variable of the same
          type.  
               status:= nul; 
           
                   T_h_e_ _t_y_p_e_s_ _o_f_ _t_w_o_ _o_p_e_r_a_n_d_s_ _a_r_e_ _t_h_e_ _s_a_m_e_ _o_n_l_y_ _i_f_ _t_h_e_i_r_ _t_y_p_e_ _n_a_m_e_s_
          (_i_d_e_n_t_i_f_i_e_r_s_)_ _a_r_e_ _t_h_e_ _s_a_m_e_,_ _o_r_ _t_h_e_ _t_w_o_ _o_p_e_r_a_n_d_s_ _a_r_e_ _d_e_c_l_a_r_e_d_ _i_n_
          t_h_e_ _s_a_m_e_ _l_i_s_t_. 
           \f

          VAR 
               status: word; 
               mask  : word; 
               result: ARRAY (0 .. length - 1) OF boolean; 
               trap  : ARRAY (0 .. length - 1) OF boolean; 
               rec1, rec2: record ... end; 
           
          The types of status and mask are the same, but none of them are
          the same as the type of result. Consequently: 
           
               status:= mask; 
           
          is a valid assignment, but 
           
               status:= result; 
           
          is not a valid assignment. Furthermore, the type of trap is
          neither the same as the type of result nor the same as the type
          of status and mask. And the operands rec1 and rec2 are of the
          same type. 
           
M_M_m_          The type t  is c_o_m_p_a_t_i_b_l_e_ with the type t  if: 
P_P_p_                    1                              2 
           
M_M_m_                    - t  and t  are the same named type 
P_P_p_                       1      2 
M_M_m_                    - t  is a subrange or t  or t  is a subrange of t 
P_P_p_                       1                   2     2                   1 
M_M_m_                    - t  is SET OF b  and t  is SET OF b  and 
P_P_p_                       1            1      2            2 
M_M_m_                      b  is compatible with b 
P_P_p_                       1                     2 
M_M_m_                    - t  is ! t 
P_P_p_                       1       2 
M_M_m_                    - t  is  t and t  is  t where t is a type name 
P_P_p_                       1            2 
M_M_m_                    - t  and t  are of pool type 
P_P_p_                       1      2 
           
          Note, that the relation compatible is not symmetric. If the type
M_M_m_          t  is compatible with the type t , a value of type t  can be
P_P_p_           1                              2                   1 
M_M_m_          assigned to a variable of type t . 
P_P_p_                                          2 \f

3_._3_._5_ _ _ _ _ _R_o_u_t_i_n_e_ _D_e_c_l_a_r_a_t_i_o_n_ _P_a_r_t_ 3.3.5
           
          A number of statements and declarations can be combined into a
          routine. When the routine is called, the data structure defined
          by the declarations is allocated and the statements are executed.
          A routine is either a procedure or a function. 
           
          routine declaration: 
           
               '   'procedure heading '  ';    'block                     '
                   'function heading 
           
          procedure heading: 
           
                  'PROCEDURE     'procedure name    'formal parameters    '
           
          function heading: 
           
                   'FUNCTION  'function name  'formal parameters ':type   '
           
          The type of a function cannot be a shielded type. 
           
                   F_o_r_m_a_l_ _P_a_r_a_m_e_t_e_r_s_ 
           
          The f_o_r_m_a_l_ _p_a_r_a_m_e_t_e_r_s_ specify the interface between a block and
          the surrounding. For each formal parameter is given its kind,
          formal name, and type. 
           
          formal parameters: 
           
                   '                                             '        '
                       '(    '  'parameter description '    ') 
                                           ;< 
           
          parameter description: 
           
                '         '    'formal name list ':  'type           '    '
                   'VAR 
           \f

          formal name list: 
           
                '  'formal name  '                                        '
                         ,< 
           
          If VAR is specified the parameter is of kind variable: a v_a_r_
          p_a_r_a_m_e_t_e_r_; otherwise the parameter is of kind value: a v_a_l_u_e_
          p_a_r_a_m_e_t_e_r_. 
           
          A formal parameter is used as a declared variable of the speci-
          fied name and type. 
           
          Parameters with components of shielded type must be of kind vari-
          able. 
           
                   Example: 
           
          TYPE 
               parity = (even, odd); 
               frame = 0 .. 31; 
          FUNCTION frame _parity (arg: frame): parity; 
          CONST 
            table = (. 0,3,5,6,9,10,12,15, 
                      17,18,20,23,24,27,29,30 .); 
                       
                    (* The set table contains all values of type 
                       frame with even parity *) 
           
          BEGIN 
            IF arg IN table 
               THEN frame _parity:= even 
               ELSE frame _parity:= odd; 
          END; 
           
          A routine can have local declarations as in this case the con-
          stant table. A function returns a result, this result is the
          value assigned to the funcion name, e.g. frame _parity:= even. The
          function has a parameter with the name arg and the type frame.
          The type of the result is parity. 
           \f

          Routine declarations can be nested: 
           
          TYPE 
             parity = (even, odd); 
             byte = 0 .. 255; 
          FUNCTION byte _parity (arg: byte) : parity; 
             TYPE 
                 frame = 0 .. 31; 
             FUNCTION frame _parity (arg: frame) : parity; 
                 CONST 
                    table = (. 0,3,5,6,9,10,12,15, 
                              17,18,20,23,24,27,30 .); 
              
                      BEGIN (* frame parity *) 
                IF arg IN table 
                   THEN frame _parity:= even 
                   ELSE frame _parity:= odd; 
             END; 
          BEGIN (* byte parity *) 
             IF frame _parity (arg MOD 32) = frame _parity (arg DIV 32) 
                THEN byte _parity:= even 
                ELSE byte _parity:= odd; 
          END; 
           
          The declaration of a name in a routine is only valid inside the
          routine. Outside the routine it is invisible. The constant table
          can therefore only be applied in the function frame _parity where
          it is declared. But it cannot be applied in the function 
          byte _parity. Similarly, the type frame is not known outside
          byte _parity. It can, however, be applied in inner routines such
          as the function frame _parity. The exact rules about valid con-
          texts for a variable are called the scope rules (see the next
          subsection). 
           \f

          The scope rules require that a process or routine is declared
          before it is used. A declaration where the block is a forward
          block is an announcement of a routine or process declaration
          which is given textually later, this is a f_o_r_w_a_r_d_ _d_e_c_l_a_r_a_t_i_o_n_.
          The heading of the declaration must be the same as the heading
          given in the forward declaration. That is the name, type, and
          order of the formal parameters must be the same. 
           
           
3_._3_._5_._1_ _ _ _S_c_o_p_e_ _R_u_l_e_s_ 3.3.5.1
           
          A scope is one of the following: 
           
          -  a field list excluding inner scopes, 
          -  a process or routine heading excluding inner scopes, 
          -  a block excluding inner scopes, 
          -  a prefix excluding inner scopes, 
          -  a local declaration (in a lock statement) excluding inner scopes.
                    
          A name can be declared once in each scope only. All names must be
          declared before they are used. If a name is declared both in a
          scope and in an inner scope, it is always the inner declaration
          which is effective in the inner scope. 
           
          Generally the declaration of a name is effective in the rest of
          the block where it is declared. Further details for each kind of
          name is given below. 
           
          c_o_n_s_t_a_n_t_ _n_a_m_e_, t_y_p_e_ _n_a_m_e_, v_a_r_i_a_b_l_e_ _n_a_m_e_, and r_o_u_t_i_n_e_ _n_a_m_e_: The
          declaration of these names is effective in the rest of the block
          excluding inner process blocks. 
           
          f_i_e_l_d_ _n_a_m_e_: The declaration of a field name is effective in the
          rest of the block excluding inner process blocks. But the field
          name can be used in record variables and with-statements only. 
           \f

          s_c_a_l_a_r_ _c_o_n_s_t_a_n_t_: The declaration of a scalar constant name is
          effective in the rest of the block excluding inner process
          blocks. But used in a type definition of a fieldname the constant
          name can be used in with-statements only. 
           
          l_a_b_e_l_: The declaration of a label is effective in the scope where
          it is declared. 
           
          r_o_u_t_i_n_e_ _p_a_r_a_m_e_t_e_r_ _n_a_m_e_ (implicit and explicit): The declaration
          of a routine parameter name is effective in the routine block.
          Note that the declaration is not effective in the routine
          heading.
           
          p_r_o_c_e_s_s_ _n_a_m_e_: The declaration of a process name is effective in
          the rest of the block where it is declared excluding inner pro-
          cess blocks. 
           
           
         3_._3_._5_._2_ _ _ _R_o_u_t_i_n_e_ _B_l_o_c_k_s_ 3.3.5.2
           
          Within the block of a routine a recursive call of the routine can
          be made. 
           
          Processes, exception routines, and variables with semaphore or
          pool components cannot be declared in a routine block. 
           
           
3_._3_._5_._3_ _ _ _F_u_n_c_t_i_o_n_s_ 3.3.5.3
           
          A function name may appear as a variable on the left head side of
          an assignment. The type in the function heading is the f_u_n_c_t_i_o_n_
          t_y_p_e_, it specifies the range of the function. The value of a
          function is the dynamically last value assigned to the function
          variable. 
           \f

          function variable: 
           
                   'function name                                  ' 
           
           
3_._3_._6_ _ _ _ _ _E_x_p_o_r_t_ _P_a_r_t_ 3.3.6
           
          Export part is an implementation dependent feature which may open
          for special linkage editor facilities (see chapter 4). 
           
          export part: 
           
              'EXPORT ' 'export name   '=   'exp.kind   'simple variable' '
                                        ;< 
           
                   exp.kind: 
           
              '     'VALUE      '     ' 
                    'DISP       ' 
                    'SIZE       '                 N_o_t_e_: 
                    'ADDRESS    '                 The five words for exp.kind
                    'OFFSET     '                 are not reserved words! 
           
          VALUE      is for constants only 
           
          DISP       is for fields only and means displacement relative to
                     record start 
           
          SIZE       is for constants, entire variables, and fields. SIZE
                     means size (in bytes) of the type which is associated
                     to the "simple variable" 
           
          ADDRESS    indicates absolute address 
           
          OFFSET     indicates relative offset in current stack frame 
           \f

          simple variable: 
           
               'simple var name '                      '                  '
                                    field name<   .< 
           
          simple var name can be either a constant name or a variable name.
           
           
3_._4_ _ _ _ _ _ _ _T_h_e_ _S_t_a_t_e_m_e_n_t_ _P_a_r_t_ 3.4
           
          This section contains subsections describing the syntax and the
          use of the different statements which are included in the
          language. Most of the statements are also found in Standard
          PASCAL and may be well known language elements. 
           
           
         3_._4_._1_ _ _ _ _ _S_t_a_t_e_m_e_n_t_s_ 3.4.1
           
          The statements of a process describe the actions which are exe-
          cuted by a process incarnation. These statements are collected in
          a compound statement. 
           
          compound statement: 
           
                     'BEGIN     '  'statement  '   'END                   '
                                       ;< 
           
          The statements are executed one at a time in the specified order.
           
          Below, all statement forms are given together with references to
          their precise description: 
           \f

          statement:                                          section 
           
               '                                          '  ' 
                     'compound statement                  '   3.4.1 
                     'procedure call                      '   3.4.6 
                     'assignment statement                '   3.4.2 
                     'exchange statement                  '   3.4.3 
                     'case statement                      '   3.4.5 
                     'for statement                       '   3.4.4 
                     'if statement                        '   3.4.5 
                     'repeat statement                    '   3.4.4 
                     'while statement                     '   3.4.4 
                     'with statement                      '   3.4.7 
                     'goto statement                      '   3.4.10 
                     'labelled statement                  '   3.4.10 
                     'lock statement                      '   3.4.8 
                     'channel statement                   '   3.4.9 
           
           
         3_._4_._2_ _ _ _ _ _A_s_s_i_g_n_m_e_n_t_ _S_t_a_t_e_m_e_n_t_ 3.4.2
           
          assignment statement: 
           
                  'variable        ':=     'expression                    '
           
          The type of the variable must be compatible with the type of the
          expression. 
           
          Assignments can be made to a variable of: 
           
                    - a simple type, 
                    - a pointer type, 
                    - a structured type where all components are of a
                      simple type or a pointer type. 
           
          The assignment statement replaces the current value of the vari-
          able by the value of the expression. 
           \f

          E_x_p_r_e_s_s_i_o_n_s_ describe how values are computed. Expressions are
          evaluated from left to right using the following precedence
          rules: 
           
                    NOT has the highest precedence followed by 
                    *, /, DIV, MOD, AND            followed by 
                    + , - , OR                     followed by 
                    =, <', <, <=, ', '=, IN 
           
          expression: 
           
                'simple expression    '                              '    '
                                          '=---'--'simple expression 
                                          ' <'  ' 
                                          ' <   ' 
                                          ' <=  ' 
                                          ' '   ' 
                                          ' '=  ' 
                                          ' IN  ' 
           
                   simple expression 
           
               '         '    '  'term  '                           ' 
                   ' +   '     <   + < 
                   ' -   '     <   -  < 
                               <   OR < 

          term: 
           
                '   'factor    '                                    ' 
                 <     *< 
                 <      /< 
                 <     DIV< 
                 <     MOD< 
                 <     AND< 
           \f

          N_o_t_e_: All factors in an expression are evaluated. 
           
          Factor: 
           
            '     'operand         '         '                      ' 
               '(  'expression  )  ' 
               'NOT  'factor       ' 
           
          operand: 
           
             '     'variable   '                                    ' 
                   'value 
           
          V_a_r_i_a_b_l_e_s_ 
           
          The term variable includes declared variables, formal parameters,
          and function variables. All variables are denoted by their name
          and possibly a selector. 
           
                   variable: 
           
              '   'variable name        '                             ' 
                  'function variable    ' 
                  'formal name          ' 
                  'array variable       ' 
                  'record variable      ' 
                  'pointed variable     ' 
           
          array 
          record     variables are described in subsection 3.3.4 
          pointed 
           
          function   variables are described in subsection 3.3.5.3 
           \f

          Variables of shielded and pointer types are implicitly given the
          following initial values: 
           
          semaphore: passive 
          shadow:    nil 
          reference: nil 
          pool:      a number of messages, determined by the cardinality
                     expression; the contents of these messages are unde-
                     fined 
          pointer:   nil 
           
           
3_._4_._3_ _ _ _ _ _E_x_c_h_a_n_g_e_ _S_t_a_t_e_m_e_n_t_ 3.4.3
           
          exchange statement: 
           
                  'variable      ':=:     'variable                       '
           
          The two variables must either both be of type reference or both
          be of type shadow. 
           
          The exchange statement exchanges the values of the two variables.
           
           
         3_._4_._4_ _ _ _ _ _R_e_p_e_t_i_t_i_v_e_ _S_t_a_t_e_m_e_n_t_s_ 3.4.4
           
          R_e_p_e_a_t_ _S_t_a_t_e_m_e_n_t_ 
           
          repeat statement: 
           
               'REPEAT    '   'statement   '    'UNTIL    'expression    ' 
                                   ;< 
           
          The result of the expression must be of type boolean. 
           
          The statement sequence is executed one or more times. Every time
          the sequence has been executed, the expression is evaluated, when
          the result is true the repeat statement is completed. 
           \f

           W_h_i_l_e_ _S_t_a_t_e_m_e_n_t_ 
           
          while statement: 
           
                'WHILE        'expression      'DO      'statement    ' 
           
          The result of the expression must be of type boolean. 
           
          The statement is executed a number of times (possibly zero). The
          expression is evaluated before each execution, when the result is
          false, the while statement is completed. 
           
          F_o_r_ _S_t_a_t_e_m_e_n_t_ 
           
          for statement: 
           
              'FOR    'variable    ':=   'for list   'DO   'statement     '
           
          for list: 
           
                                 'TO     ' 
M_M_m_              'expression     '               'expression                ' 
P_P_p_                         1                               2 
U_U_u_                               --'DOWNTO-' 
                   The two expressions must be of the same enumeration type and the
          type of the variable must be compatible with this. 
           
          The selection of the variable cannot be changed in the statement.
          Hence, if the variable has array indices or pointers, changes to
          these (in the statement) will not affect the selection. 
           
          The statement is executed with consecutive values of the variable
          The ordinal value of the variable can either be incremented (in
M_M_m_          steps of 1 (succ)) from expression  TO expression , or descrem- 
P_P_p_                                            1              2 
M_M_m_          ted (in steps 1 (pred)) from expression  DOWNTO expression . The
P_P_p_                                                 1                  2 
          two expressions are evaluated once, before the repetition. If the
M_M_m_          value of expression  is greater than the value of expression  and
P_P_p_                             1                                        2 
          TO is specified, the statement is not executed. 
           \f

M_M_m_           Similarly, if the value of expression  is less than the value of
P_P_p_                                               1 
M_M_m_          expression   and DOWNTO is specified, the statement is not execu-
P_P_p_                    2 
          ted. 
           
          The value of the variable is dependent of the expressions after
          the for statement. 
           
           
3_._4_._5_ _ _ _ _ _C_o_n_d_i_t_i_o_n_a_l_ _S_t_a_t_e_m_e_n_t_s_ 3.4.5
           
          C_a_s_e_ _ _S_t_a_t_e_m_e_n_t_ 
           
          case statement: 
           
              'CASE    'switch    OF '   'case list element   'end part   '
                                                ;< 
                   end part: 
           
              '                                   ' 'END                  '
                  'OTHERWISE   '  'statement  ' 
                                       ;< 
           
          case list element: 
           
           ' ' ' 'constant expression                         ' ' ':   statement '  '
                 'constant expression '.. 'constant expression 
                                      ,< 
           
                                          ' 
           
          switch: 
           
                    'expression                                           '
           \f

          The values of the constant expressions in case list elements are
          called c_a_s_e_ _l_a_b_e_l_s_. All case labels and the switch must be of the
          same enumeration type and all case labels must be distinct. The
          switch is evaluated and the statement labelled by the value of
          the switch is executed. If no such label is present, the state-
          ment following OTHERWISE is executed; if OTHERWISE is not speci-
          fied, an exception occurs. 
           
          I_f_ _S_t_a_t_e_m_e_n_t_ 
           
          if statement: 
           
M_M_m_             'IF 'expression   'THEN  'statement   ' 'ELSE  'statement   '  '
P_P_p_                                                1                     2 
U_U_u_                                                            ' 
           
          The result of the expression must be of type boolean. 
           
M_M_m_             Statement  is executed if the value of the expression is true. If
P_P_p_                   1 
M_M_m_            it is false, statement  (if specified) is executed. 
P_P_p_                                2 
           
          The statement: 
           
M_M_m_                    IF e  THEN IF e  THEN s  ELSE s 
P_P_p_                        1          2       1       2 
           
                    is equivalent to: 
                     
M_M_m_                         IF e 
P_P_p_                             1 
                            THEN BEGIN 
M_M_m_                                   IF e 
P_P_p_                                       2 
M_M_m_                                      THEN s 
P_P_p_                                            1 
M_M_m_                                      ELSE s 
P_P_p_                                            2 
U_U_u_                                   END 
           \f

3_._4_._6_ _ _ _ _ _P_r_o_c_e_d_u_r_e_ _C_a_l_l_ 3.4.6
           
          routine call: 
           
                 'routine name      'actual parameters                    '
           
          A r_o_u_t_i_n_e_ _c_a_l_l_ binds actual parameters to formal parameters,
          allocates local variables, and executes the compound statement of
          the block. When the compound statement is completed, local vari-
          ables are deallocated and execution is resumed immediately after
          the routine call. All local reference and shadow variables must
          be nil when the compound statement is completed, otherwise an
          exception occurs. 
           
          The variables of a routine are associated with a specific call;
          they exist from the routine call until the compound statement (of
          the block) is completed. When a routine is called recursively,
          several versions of the variables exist simultaneously, one for
          each uncompleted call. 
          The difference between a procedure and a function is that a pro-
          cedure call is a statement and a function call a factor (function
          variable) in an expression. 
           
          A f_u_n_c_t_i_o_n_ _c_a_l_l_ is an operand in an expression. 
           
          function call: 
           
                 'function name      'actual parameters             ' 
           
          A_c_t_u_a_l_ _P_a_r_a_m_e_t_e_r_s_ 
           
          When a process incarnation is created or a routine is called
          a_c_t_u_a_l_ _p_a_r_a_m_e_t_e_r_s_ are bound to formal parameters. 
                    
          actual parameters: 
           
               '                                  '                 ' 
                   '( ' 'actual parameter '  ') 
                                ,< \f

          actual parameter: 
           
                    'expression                                     ' 
           
          There must be an actual parameter for each explicit formal para-
          meter. 
           
          The binding of an actual parameter to a formal parameter depends
          on the parameter kind: 
           
          value:    The type of the actual parameter must be compatible
                    with the type of the formal parameter. The value of the
                    actual parameter is evaluated and this value becomes
                    the initial value of the formal parameter. Assignments
                             to the formal parameter within the block does not
                    affect the actual parameter (call by value). 
                     
          variable: The type of the actual and formal parameter must be the
                    same. The actual parameter must be a variable, the
                    value of this variable becomes the initial value of the
                    formal parameter. Changes to the value of the formal
                    parameter within the block affects the actual parameter
                    directly. 
           
                    The actual parameter selects a variable, this selection
                    cannot be changed in the block. Hence, if the variable
                    has array indices or pointers, changes to these do not
                    affect the selection (c_a_l_l_ _b_y_ _r_e_f_e_r_e_n_c_e_). 
                     
                    An element or a field of a packed variable cannot be an
                    actual var parameter. The w_h_o_l_e_ packed variable can,
                    however, be an actual var parameter. 
           
           \f

3_._4_._7_ _ _ _ _ _W_i_t_h_ _S_t_a_t_e_m_e_n_t_ 3.4.7
           
          with statement: 
           
                  'WITH   '  'record variable  '    'DO   'statement     ' 
                                    ,< 
           
          Within the statement fields can be accessed by giving their field
          names only. 
           
          The with statement 
           
                    WITH v1, v2, ..., vn DO s; 
           
          is a shorthand for the nested with statement shown below. 
           
                             WITH v1 DO 
                      WITH v2 DO 
                      . 
                        . 
                          . 
                          WITH vn DO s; 
           
          The record variable selects a record, this selection cannot be
          changed in the statement. Hence, if the record variable has array
          indices or pointers, changes to these (in the statement) will not
          affect the selection. 
           
           
3_._4_._8_ _ _ _ _ _L_o_c_k_ _S_t_a_t_e_m_e_n_t_ 3.4.8
           
          lock statement: 
           
             'LOCK 'reference variable 'AS 'local declaration 'DO 'statement  '
           
          local declaration: 
           
                'local name       ':         'type                   ' 
           \f

          reference variable: 
           
                'variable                                            ' 
           
          local name: 
           
                'identifier                                          ' 
           
          The component types of the type must be simple. The reference
          variable must refer to a message (must not be nil), otherwise an
          exception occurs. If the message is too small to represent the
          specified type an exception occurs. 
           
                   In the statement local name is a declared variable with the
          specified type. In the statement the reference variable must not
          be used as part of an exchange statement or as a parameter to
          signal, return, release, pop, or push. 
           
          The data part of a message is manipulated as a declared variable
          with the local name. It is always the top in the message stack
          which is manipulated. 
           
           
3_._4_._9_ _ _ _ _ _C_h_a_n_n_e_l_ _S_t_a_t_e_m_e_n_t_ 3.4.9
           
          channel statement: 
           
              'CHANNEL       'reference variable    'DO    'statement     '
           
          The reference variable must refer to a message (must not be nil).
          Any implementation may place restrictions on this message. If the
          message is not of this restricted form an exception occurs. 
           
          In the statement the reference variable must not be used as part
          of an exchange statement or as a parameter to, signal, return,
          release, pop, or push. 
           \f

                   The channel statement controls the handling of peripherals in an
          implementation dependent way. 
           
           
3_._4_._1_0_ _ _ _ _G_o_t_o_ _S_t_a_t_e_m_e_n_t_ 3.4.10
           
          goto statement: 
           
                  'GOTO      'label                                   ' 
           
          The goto statement, the declaration of the label, and the
          definition of the label must be in the same scope. 
           
          Execution continues at the statement labelled by the label
          (labelled statement). 
           
          Jumps out of a channel or lock statement and jumps out of a
          routine are not allowed. 
           
          labelled statement: 
           
             'label  ':   'statement          ' 
           
           
3_._4_._1_1_ _ _ _ _S_t_a_n_d_a_r_d_ _R_o_u_t_i_n_e_s_ _a_b_s_,_ _s_u_c_c_,_ _p_r_e_d_,_ _c_h_r_,_ _o_r_d_ 3.4.11
           
          The absolute value of an integer variable is given as the result
          of: 
           
               FUNCTION abs (int: integer) : integer; 
           
          The successor and predecessor of a variable of scalar type is
          given as the result of: 
           
               FUNCTION succ (s: s _type): s _type 
           
               FUNCTION pred (s: s _type): s _type 
           
          s _type may be any scalar type. 
          succ taken on the last element and pred taken on the first ele-
          ment of a scalar type results in an exception. 
           \f

          The character with the ordinal value n is the result of a call
          chr(n) where chr is defined as: 
           
               FUNCTION chr (n: 0 .. 127): char; 
           
          The ordinal value of a scalar element is retrieved by the func-
          tion ord: 
           
               FUNCTION ord (s: s _type): integer; 
           
          where s _type may be any scalar type. 
           
           \f

F_       4_._ _ _ _ _ _ _ _ _P_R_O_C_E_S_S_ _C_O_M_M_U_N_I_C_A_T_I_O_N_ 4.
           
          This chapter contains a general description of communication
          between incarnations, i.e. a description of the language concepts
          and the tables available for the programmer. After that is a more
          detailed description of the predefined routines intended for syn-
          chronization of the communication between process incarnations. 
           4.1
           
4_._1_ _ _ _ _ _ _ _G_e_n_e_r_a_l_ _P_r_o_c_e_s_s_ _C_o_m_m_u_n_i_c_a_t_i_o_n_ 
           
          A process consists of a number of statements and declarations. An
          incarnation of a process is the execution of the actions on a
          private data structure. Many incarnations can be executed concur-
          rently. 
           
          Process incarnations communicate by exchanging m_e_s_s_a_g_e_s_. A mes-
          sage can be accessed by at most one incarnation at a time. 
           
M_m_m_               place data                         await access 
                                    M 
P_p_p_               in M                               to M 
                         A                                     B 
           
                      T_i_m_e_ _T_: A has exclusive access to the message M. 
           
           
                                                  read data 
                                      M 
                                                  in M 
                         A                                     B 
           
                      T_i_m_e_ _T_ _+_ _1_: B has exclusive access to M. 
           
          The two predefined types reference and semaphore are used for re-
          ferencing and exchanging access to messages. 
           \f

                   The value of a reference variable is either a reference to a
          message or nil (representing "no reference"). At most one
          variable references a message. Since process incarnations access
          messages through reference variables only, mutually exclusive
          access to messages is secured. 
           
          Q_u_e_u_e_ _s_e_m_a_p_h_o_r_e_s_ are used for exchanging access to messages. 
           
          A queue semaphore consists of a sequence (fifo) of messages and a
          set of waiting process incarnations. One of these is always
          empty. 
           
          A queue semaphore s can be in one of three states: 
           
          o_p_e_n_ 
                     1 
                     2               The sequence of messages is n_o_t_ _e_m_p_t_y_.
M_m_m_              s      .               The set of incarnations is e_m_p_t_y_. 
                     . 
P_p_p_                     . 
           
                     N 
                    sequence of 
                    messages 
           
          l_o_c_k_e_d_ 
           
                                     The sequence of messages is e_m_p_t_y_. 
                                     The set of incarnations is n_o_t_ _e_m_p_t_y_. 
               s 
                         waiting 
                         incarnations 
           
          p_a_s_s_i_v_e_ 
           
              s                      The sequence of messages is e_m_p_t_y_. 
                                     The set of incarnations is e_m_p_t_y_. 
           \f

                   Any process may contain declarations of variables of type sema-
          phore, and it may receive semaphore variables as parameters when
          it is created. All declared semephore variables are initially in
          the passive state. In constrast to variables of any other type a
          semaphore variable can be accessible by many process incarnations
          simultaneously. 
           
          example: 
           
               PROCESS converter (input, output: semaphore); 
                 VAR 
                    myown: ARRAY (1 .. 2) OF semaphore; 
           
          The process converter has access to four semaphores: input,
          output, myown(1), and myown(2). 
           
          The predefined routines signal and wait are used for exchanging
          access to messages. 
           
               PROCEDURE signal (VAR r: reference; VAR s: semaphore); 
           
          The reference r must reference a message. If the semaphore s is
          open or passive, the message referenced by r is entered in the
          sequence of messages belonging to s. 
           
          o_p_e_n_ _o_r_ _p_a_s_s_i_v_e_ 
           
          incarnation executing signal 
                                                            1 
                r                                     s     2 
M_m_m_                                                               . 
                            message                         . 
P_p_p_                                                             .
                                                             
                                                            N 
                                                         sequence of 
                                                         messages 
                               p_r_i_o_r_ _t_o_ _s_i_g_n_a_l_ _(_r_,_ _s_)_ 
           \f

                   incarnation executing signal 
           
                                                  s         1 
                r                                           2 
M_m_m_                  nil                                       . 
                                                            . 
P_p_p_                                                            . 
                                                             
                                                            N 
                                                            N + 1 
                                                         sequence of 
                                                         messages 
           
                                 a_f_t_e_r_ _s_i_g_n_a_l_ _(_r_,_ _s_)_ 
           
          If s is locked one incarnation is removed from the set of waiting
          incarnations and reactivated. That is, it will be allowed to com-
          plete the call of wait which caused it to wait. 
           
          l_o_c_k_e_d_ 
           
          incarnation executing signal 
                                                 incarnation executing wait
           
                                        s 
               r 
                                message 
           
           
                                               waiting incarnations 
           
                           p_r_i_o_r_ _t_o_ _s_i_g_n_a_l_ _(_r_,_ _s_)_ 
           
          incarnation executing signal 
                                                 incarnation executing wait
           
               r 
                 nil                  message 
                                       
                                      s 
           
                                                 waiting incarnations 
                           a_f_t_e_r_ _s_i_g_n_a_l_ _(_r_,_ _s_)_ 
           \f

                        PROCEDURE wait (VAR r: reference; VAR s: semaphore); 
           
          The reference r must be nil. If the semaphore is open the first
          message in the sequence is removed and r becomes a reference to
          this message. 
           
          o_p_e_n_ 
           
                      1                          incarnation executing wait
                      2           message                 r 
M_m_m_            s         .                                      nil 
                      . 
P_p_p_                      .
                       
                      N 
            sequence of messages 
                                  p_r_i_o_r_ _t_o_ _w_a_i_t_ _(_r_,_ _s_)_ 
           
                      2 
M_m_m_            s         .                  message incarnation executing wait
                      .                                  r 
P_p_p_                      . 
                       
                      N 
            sequence of messages 
                                  a_f_t_e_r_ _w_a_i_t_ _(_r_,_ _s_)_ 
           
           
          If the state is locked or passive the incarnation is temporarily
          stopped and entered in the set of waiting incarnations. 
           
          l_o_c_k_e_d_ _o_r_ _p_a_s_s_i_v_e_ 
           
                                                 incarnation executing wait
                                                       r 
                       s                                  nil 
           
                                  waiting incarnations 
                              p_r_i_o_r_ _t_o_ _w_a_i_t_ _(_r_,_ _s_)_ 
           \f

                                             incarnation executing wait 
                                                 r 
              s                                    nil 
           
           
                                                              waiting 
                                                              incarnations 
           
          Incarnation has been stopped during wait (r, s) 
           
          It is implementation dependent which one of several waiting in-
          carnations is selected for activation during execution of signal.
          However, the selection algorithm must be fair: no incarnation may
          remain waiting indefinitely on a semaphore, provided some other
          incarnations continue to signal messages to that semaphore. 
           
          Execution of wait and of signal is performed indivisibly: e.g.
          from the moment an incarnation starts execution of a signal on a
          given semaphore and until the execution is completed, any other
          incarnation trying to operate on that semaphore variable is
          delayed. 
           
          A process may only inspect or alter the contents of a message in
          a so-called lock statement. Let r be a reference variable which
          references a message: 
           
               LOCK r AS b: t DO s; 
           
          In the statement s the message referenced by r is manipulated as
          if it were a variable with the name b of type t. 
           
          In the following example there are two processes, one which pro-
          duces data (e.g. input data) and one which consumes data (e.g.
          uses the input data in a computation). 
           \f

                   PROCESS producer (full,           PROCESS consumer (full, 
                  void: semaphore);                 void: semaphore); 
            TYPE                              TYPE 
               buffertype = ...;                 buffertype = ...; 
            VAR                               VAR 
               r: reference;                     r: reference; 
          BEGIN                             BEGIN 
             REPEAT                            REPEAT 
               wait (r, void);                   wait (r, full); 
               LOCK r AS b: buffertype DO        LOCK r AS b: buffertype DO
               BEGIN                             BEGIN 
                  (*...produce data...*)            (*...consume data...*) 
               END;                              END; 
               signal (r, full);                 signal (r, void); 
             UNTIL...;                         UNTIL...; 
          END;                              END; 
           
           
          The allocation of messages is specified by declaring a variable
          of pool type. 
           
             VAR 
                m: POOL cardinality OF type; 
           
          Initially, the variable m contains cardinality messages. These
          messages can hold a value from type. The predefined procedure
          alloc removes a message from a pool variable: 
           
             alloc (r, m, s); 
           
          The reference r must be nil. If the pool of messages is not emp-
          ty, one of the messages is removed and r references this message.
          If the pool is empty the process incarnation waits until a mes-
          sage is released (by another incarnation calling the predefined
          procedure release). 
           \f

                   Each message contains information about its origin. The third
          parameter to alloc must be a semaphore and it becomes the a_n_s_w_e_r_
          s_e_m_a_p_h_o_r_e_ of the message. This is the equivalent of a return
          address on an envelope of a letter. The answer semaphore is used
          in the predefined procedure return: 
           
               PROCEDURE return (VAR r: reference); 
           
          A call of return is equivalent to a call of signal: 
           
               signal (r, "answer semaphore") 
           
          But the answer semaphore is only implicitly available through
          return. 
           
          The following is a revised version of the producer comsumer
          example given above. 
           
          PROCESS proceducer (stream:       PROCESS comsumer (stream: 
                         semaphore);                     semaphore); 
            TYPE                              TYPE 
               buffertype = ...;                 buffertype = ...; 
            VAR                               VAR 
               r: reference;                     r: reference; 
               m: POOL 1 OF buffertype; 
               a: semaphore; 
          BEGIN                             BEGIN 
            alloc (r, m, a);                  REPEAT 
            REPEAT                               wait (r, stream); 
               LOCK r AS b: buffertype DO        LOCK r AS b: buffertype DO
               BEGIN                             BEGIN 
                 (*...produce buffer...*)          (*...comsume buffer...*)
               END;                              END; 
               signal (r, stream);               return (r); 
               wait (r, a);                   UNTIL...; 
            UNTIL...;                       END; 
          END; 
           
           \f

                   The following communication flow is possible by means of
          SIGNAL/RETURN: 
           
           
           
           
           
           
           
           
           
           
           
          A reference variable may point to none or a stack of messages.
          This is a generalization of the concept of reference variables as
          described earlier. In general terms a reference variable points
          to a stack of messages. 
           
          When the value of the reference variable is nil, the stack is
          empty. 
           
          A well-defined reference variable points to a stack of reference
          variables. The message header of the stack elements contains a
          field, which chains the messages together. This field is called
          the s_t_a_c_k_ _c_h_a_i_n_. This pointer is nil in the last element of the
          chain. 
           
          Two procedures: 
           
                 PUSH(<reference variable',<reference variable') 
                 POP (<reference variable',<reference variable') 
           
          are used to manipulate reference variables when interpreted as
          stack reference variables. 
           \f

                   example: 
           
                 VAR element: REFERENCE; 
                     stack:   REFERENCE; 
M_m_m_                 . 
                 . 
P_p_p_                 . 
                   PUSH (element, stack); 
M_m_m_                 . 
                 . 
P_p_p_                 . 
                   POP  (element, stack); 
           
          P_U_S_H_ _(_r_e_f_1_,_ _r_e_f_2_)_ 
           
          B_e_f_o_r_e_ _c_a_l_l_ 
           
                 ref1 - well-defined reference to element. 
                        The stack chain field in the element m_u_s_t_ be NIL. 
                         
                 ref2 - well-defined stackop element or 
                        nil if stack is empty: 
           
          A_f_t_e_r_ _c_a_l_l_ 
           
                 ref1 - nil 
                 ref2 - ref2:= old ref1 
           
          If the old ref1 has no associated message data, the message data
          associated the old ref2, if any, are assigned the old ref1,
          together with the pushing. 
           
          If the old ref1 has associated message data the old ref1 is just
          pushed. 
           \f

                   E_x_a_m_p_l_e_ 
           
          1)       Before call                        After call 
           
          ref1            ref2               ref1            ref2 
           
           
           
           
           
           
           
          2) 
           
          ref1            ref2               ref1            ref2 
           
           
           
           
           
           
           
           
           
           
          P_O_P_ _(_r_e_f_1_,_ _r_e_f_2_)_ 
           
          B_e_f_o_r_e_ _c_a_l_l_ 
           
                 ref1 - nil 
                 ref2 - well-defined stacktop element 
           
           \f

                   A_f_t_e_r_ _c_a_l_l_ 
           
                 ref1 - ref1:= old ref2 
                  
                  
                 ref2 - new stacktopelement. 
                        Note: ref2:= nil if the stack 
                                     became empty during call. 
           
          If the old stackop element has associated message data, and the
          new stackop element points to the same message data, the message
          data pointer in the popped element is set to nil. 
           
          This is not done if the new stackop element points either to
          another message data or points to nil. 
           \f

                   E_x_a_m_p_l_e_s_ 
           
          1)        Before call                       After call 
           
          ref1    ref2                      ref1    ref2 
           
           
           
           
           
           
           
          2) 
           
          ref1    ref2                      ref1    ref2 
           
           
           
           
           
           
           
          3) 
           
          ref1    ref2                      ref1    ref2 
           
           
           
           
           
           
           
           
           \f

                   The PUSH and POP procedures are especially suited to the
          following situations: 
           
          - to associate a new messageheader to received message data by
            the PUSH procedure in order to avoid copying of data, and to
            signal the message on to the next incarnation in the flow. The
            general answer mechanism will be to reestablish the original
            message header by a call of POP and return the message to the
            sender by calling RETURN. 
             
                SIGNAL         SIGNAL        SIGNAL       SIGNAL 
           
M_M_m_          P              P                           P               P 
P_P_p_           1              2                           n-1             n 
           
                RETURN         RETURN        RETURN       RETURN 
           
          - to pile together a number of messages and pass the whole batch
            to an incarnation by one call of SIGNAL. 
           
          S_e_m_a_p_h_o_r_e_ _P_o_i_n_t_e_r_s_ 
           
          A semaphore pointer variable is a variable of type: 
           
                    semaphore 
           
          A semaphore pointer variable is a variable, whose value refer-
          ences a semaphore variable. 
           
          If the value is not a reference to a semaphore variable, the
          value is nil. 
           
          The only legal operations on semaphore pointer variables are: 
           
                    nil, and := (assignment) 
           
          If p is a semaphore pointer variable, p  denotes the semaphore
          pointed to by p. 
           \f

         4_._2_ _ _ _ _ _ _ _T_h_e_ _P_r_e_d_e_f_i_n_e_d_ _C_o_m_m_u_n_i_c_a_t_i_o_n_ _R_o_u_t_i_n_e_s_ 4.2
           
          s_i_g_n_a_l_,_ _w_a_i_t_,_ _r_e_t_u_r_n_,_ _a_n_d_ _r_e_l_e_a_s_e_. 
           
          There are four predefined communication routines, signal, return,
          wait, and release. 
           
          PROCEDURE signal (VAR r: reference; VAR s: semaphore); 
           
          The reference parameter must refer to a message (must not be
          nil), otherwise an exception occurs. The reference variable is
          nil after a call of signal. 
           
          If the semaphore is passive or open, the message referred to by r
          becomes the last element of the semaphore>s sequence of messages.
          If the semaphore is locked, one of the incarnations waiting on
          the semaphore completes its wait call. 
           
          When several process incarnations are waiting, it is implementa-
          tion dependent which one is resumed by a signal call. No process
          must, however, be waiting indefinitely if other incarnations con-
          tinue to signal messages to the semaphore. 
           
          PROCEDURE return (VAR r: reference); 
           
          The parameter must refer to a message (must not be nil), other-
          wise an exception occurs. 
           
          The call: 
           
                    return (r); 
           
          has the same effect as the call: 
           
                    signal (r, r .answer ); 
           
          The latter is, however, not a valid call because the answer
          semaphore is not explicitly available. 
           \f

                   PROCEDURE release (VAR r: reference); 
           
          The parameter must refer to a message (must not be nil), other-
          wise an exception occurs. 
           
          The call: 
           
                    release (r); 
           
          has the same effect as the call: 
           
                    signal (r, r .owner ); 
           
          The latter is, however, not a valid call because the owner sama-
          phore is not explicitly avaiable. 
           
          PROCEDURE wait (VAR r: reference; VAR s: semaphore); 
           
          The reference parameter must be nil, otherwise an exception
          occurs. After a call of wait it refers to a message. 
           
          If the semaphore is open, the first message is removed from the
          semaphore>s sequence of messages. If the semaphore is passive or
          locked, the incarnation waits and enters the set of incarnations
          waiting on the semaphore. It can be resumed by another
          incarnation calling signal or return. 
           
          O_p_e_n_,_ _L_o_c_k_e_d_,_ _P_a_s_s_i_v_e_,_ _a_n_d_ _S_e_n_s_e_s_e_m_ 
           
          There are three predefined boolean functions to detect the state
          of a semaphore variable: 
           
          FUNCTION   open    (s: semaphore): boolean 
          FUNCTION   locked  (s: semaphore): boolean 
          FUNCTION   passive (s: semaphore): boolean 
           \f

                   The three states may be depicted as: 
           
          o_p_e_n_ 
                    1 
                    2                The sequence of messages is n_o_t_ _e_m_p_t_y_.
M_m_m_                    .                The set of incarnations is e_m_p_t_y_. 
                    . 
P_p_p_                     . 
                     
                     
                    N 
                   sequence of 
                   messages 
           
          l_o_c_k_e_d_ 
           
                                     The sequence of messages is e_m_p_t_y_. 
                                     The set of incarnations is n_o_t_ _e_m_p_t_y_. 
              s 
           
           
                        waiting 
                        incarnations 
           
          p_a_s_s_i_v_e_ 
           
             s                       The sequence of messages is e_m_p_t_y_. 
                                     The set of incarnations is e_m_p_t_y_. 
           
           
          S_e_n_s_e_s_e_m_ 
           
          PROCEDURE sensesem (VAR r: reference; 
                              VAR s: semaphore); 
           
          The body of sensesem is equivalent to: 
           
          IF open (s) THEN wait (r, s); 
           
          i.e. take a message from s if there is any, otherwise r remains
          nil. \f

                   R_e_f_ 
           
          Semaphore pointers may be assigned to denote a semaphore by means
          of the predefined routine ref: 
           
               FUNCTION ref (s: semaphore):  semaphore; 
           
          Semaphore pointers are initially set to nil by the system, this
          may be used to define a nilpointer which may be useful if
          semaphore pointers are used. 
           
          example: 
           
               var nil _pointer:!  semaphore; (* nil _pointer cannot be
                                              changed since it is frozen*)
               sem _arr: array (low .. high) of  semaphore; 
                
                  . 
                  . 
                
               sem _arr (index):= ref (sem); 
                
                  . 
                  . 
                
               sem _arr (index):= nil _pointer; 
           
           
          P_u_s_h_,_ _p_o_p_,_ _a_n_d_ _e_m_p_t_y_ 
           
          A message may consist of a stack of headers and data areas. The
          stack of message headers is the m_e_s_s_a_g_e_ _h_e_a_d_e_r_ _s_t_a_c_k_, and the
          stack of the data areas, the m_e_s_s_a_g_e_ _d_a_t_a_ _s_t_a_c_k_. 
           \f

                   message: 
           
M_M_m_               header         header  ...    header    message header stack
P_P_p_                     1              2              n 
           
M_M_m_                       data    ...      data           message data stack 
P_P_p_                           1                m 
           
          A header may or may not point to a data area (m <_ n). The t_o_p_
M_M_m_          h_e_a_d_e_r_ of the message is header . The t_o_p_ _d_a_t_a_ of a message is
P_P_p_                                         1 
M_M_m_          data . 
P_P_p_              1 
           
          The message is organized as a stack which is manipulated by the
          two predefined procedures push and pop. 
           
               PROCEDURE push (VAR r1, r2: reference); 
           
          The parameter r1 must refer to a message (must not be nil), and
          this message must have exactly one header, otherwise an exception
          occurs. The message accessible through r2 (possibly nil) is
          called the stack. 
           
          The header referred to by r1 becomes the new top header of the
          stack. After the call, r2 refers to the new stack. 
           
          If the new top message is a header message, the top data of r2
          remains the same. After the call r1 is nil. 
           
               PROCEDRUE pop (VAR r1, r2: reference); 
           
          Reference variable r1 must be nil and r2 must refer to a message
          (must not be nil), otherwise an exception occurs. 
           
          The top header is removed from the message (accessed through r2)
          and after the call r2 refers to the remaining part, while r1
          refers to the removed message. 
           \f

                   It may be detected if a reference variable refers to a message
          with one header only by means of the predefined boolean function:
           
               FUNCTION empty (r: reference): boolean 
          The body of empty may be: 
                   pop (local ref, r), 
                   empty:= nil (r) 
          where nil is another standard function: 
           
          N_i_l_ 
           
               FUNCTION nil (p: pointer _type): boolean 
           
          pointer _type may be any pointed type, for example reference which
          is defined like 
           
               TYPE reference =   message; 
           
          A_l_l_o_c_ _a_n_d_ _O_p_e_n_p_o_o_l_ 
           
          With each variable of type pool an anonymous semaphore is asso-
          ciated. This is the owner semaphore of all messages in the pool.
          A message is allocated from the pool by the predefined procedure
          alloc. 
           
          PROCEDURE alloc (VAR r: reference, VAR p: pool 1; VAR s: semaphore);
           
          The pool variable can be of any pool type. 
           
          The reference variable must be nil, otherwise an exception
          occurs. After the call it refers to a message. If the pool of
          message is not empty, one of the messages is removed. If the pool
          is empty the incarnation waits until a message is released to the
          pool by another process incarnation calling release. The answer
          semaphore of the removed message becomes s. 
           
          Variables of type pool (or variables with pool components) can
          only be declared in the declaration of a process and not in the
          declarations of a routine. \f

                   It may be detected if a pool is open (i.e. not empty) by means of
           
               FUNCTION openpool (VAR p: pool 1): boolean; 
           
          the function result becomes true if the pool is not empty (cf.
          function open for semaphore). 
           
           \f

F_       5_._ _ _ _ _ _ _ _ _P_R_O_C_E_S_S_ _C_O_N_T_R_O_L_ 5.
           
          Processes can be nested and a process declared within another
          process is a s_u_b_-_p_r_o_c_e_s_s_ (of the surrounding process). 
           
          An arbitrary number of incarnations of sub-processes (children)
          can be created, they are all controlled by the parent. Incar-
          nations are created and removed dynamically. 
           
          A process can have f_o_r_m_a_l_ _p_a_r_a_m_e_t_e_r_s_. When an incarnation of the
          process is created a number of a_c_t_u_a_l_ _p_a_r_a_m_e_t_e_r_s_ is given. Incar-
          nations communicate through common semaphore variables only. In
          this way a parent determines the communication paths of children.
          Note, however, that the controlling process incarnation need not
          participate in the communication. 
           
          Variables of the predefined type shadow are used to discern dif-
          ferent incarnations of sub-processes. A shadow variable is the
          controlling process> link to an incarnation of a child. There is
          a number of predefined routines for exercising this control
          (start, stop, etc.). 
           
           
5_._1_ _ _ _ _ _ _ _T_h_e_ _P_r_e_d_e_f_i_n_e_d_ _R_o_u_t_i_n_e_s_ _f_o_r_ _P_r_o_c_e_s_s_ _C_o_n_t_r_o_l_ 5.1
           
          L_i_n_k_ 
           
               FUNCTION link (external _name: alfa; 
                              process name): integer; 
           
          There must not be a process linked to process name, process name
          must be the name of a process. The process identified by the
          external _name is linked to process name. The external identifica-
          tion of processes is implementation dependent. 
          Result 0 means success, other values are implementation dependent
          error codes. \f

                        FUNCTION create (incarnation _name: alfa; 
                        process name (actual parameters); 
                   VAR sh: shadow; storage: integer): integer; 
           
          The shadow variable must be nil and process name must be linked
          to a process. Result 0 means success, other values are implemen-
          tation dependent error codes. 
           
          A new i_n_c_a_r_n_a_t_i_o_n_ of the process linked to process name is crea-
          ted. The storage parameter specifies the amount of storage for
          holding the runtime stack. The store is initialized with the
          actual parameters and various administrative informations but the
          incarnation is stopped. The created incarnation is a c_h_i_l_d_ of the
          creating incarnation, the p_a_r_e_n_t_. After the call the shadow
          variable refers to the child. 
           
          R_e_m_o_v_e_ 
           
               PROCEDURE remove (VAR sh: shadow); 
           
          The shadow variable must refer to a process incarnation (child),
          otherwise an exception occurs. 
           
          Remove terminates execution of the child and deallocates all its
          resources. Execution of that incarnation cannot be resumed.
          Remove also removes all incarnations controlled by the child,
          their children ect. 
           
          After the call the shadow variable is nil. 
           
          S_t_a_r_t_,_ _S_t_o_p_,_ _a_n_d_ _B_r_e_a_k_ 
           
          The following predefined procedures are used for controlling
          children between calls of create and remove. 
           
               PROCEDURE start (VAR sh: shadow; priority: integer); 
           \f

                   Start initiates or resumes execution of a child which is stopped.
          The meaning of priority is implementation dependent. 
           
               PRODURE stop (VAR sh: shadow); 
           
          The shadow variable must refer to a process incarnation (child). 
          The child is stopped. 
           
               PROCEDURE break (VAR sh: shadow; exception _code: integer); 
           
          The shadow variable must refer to a process incarnation (child).
          The call forces an exception upon the child. The meaning of the
          exception _code is implementation dependent. 
                    
          U_n_l_i_n_k_ 
           
               FUNCTION unlink (process name): integer; 
           
          At process must be linked to process name and no incarnations of
          the process may exist. After the call the link is deleted. 
          Result 0 means success, other values are implementation dependent
          error codes. 
           
           \f

F_6_._ _ _ _ _ _ _ _ _U_T_I_L_I_T_Y_ _P_R_O_G_R_A_M_S_ 6.
           
6_._1_ _ _ _ _ _ _ _I_n_d_e_n_t_ 6.1
           
          T_e_x_t_ _f_o_r_m_a_t_t_i_n_g_ _p_r_o_g_r_a_m_ 
           
          The program performs indention of source programs depending on
          the options specified in the call and on the keyswords (reserved
          words) of PASCAL/PASCAL80. 
           
                c_a_l_l_: 
           
M_m_m_                           1 
            <outputfile'=     indent <input file'   <option' 
P_p_p_                              0                                  0 
           
          <option'::= lines      line numbers are added 
                      mark       the blockstructure is made clear by means
                                 of ! between matching begin-end>s 
                      list       the same as: lines mark 
                      noind      the output will be left justified 
                      myind      the output indention is the same as the
                                 input indention 
                      lc         lists keywords in capital letters and
                                 identifiers in small (lower case) letters 
                      uc         both key words and indentifiers are listed
                                 in upper case letters 
                      help       produces a list of legal options 
           
          Storage requirements: 
           
          The core store required for indent is 16000 hW (size 16000). 
           
          E_r_r_o_r_ _m_e_s_s_a_g_e_s_: 
           
          ???   illegal input-filename 
                input file must be specified 
                 \f

          call: "indent help", for help 
                an error is detected in the program call, a new call
                "indent help" will produce a list of the valid options. 
                 
          **    warning, end(s) missing 
                an error in the begin-end structure has been detected. 
                 
          **    premature end of file 
                comment or string not terminated. 
                 
                 
6_._2_ _ _ _ _ _ _ _C_r_o_s_s_ _R_e_f_e_r_e_n_c_e_ _P_r_o_g_r_a_m_  6.2 
           
          Produces a cross reference listing of the identifiers and numbers
          and a use count of the PASCAL/PASCAL80 key words used in the input
          text. 
           
          The cross reference list is made with no regard to the block
          structure of the program. The list is sorted according to the
          ISO-alphabet, i.e. numbers before letters, but with no difference
          between upper and lower case letters. 
           
          The occurrence list for an identifier consists of a sequence of
          PASCAL/PASCAL80 line numbers. The occurrence kind is specified by
          means of the character following the line number: 
           
          *      meaning the identifier or number is found in a declaration part.  
           
          =      meaning the identifier is assigned to in the line specified. 
           
          :      meaning the identifier or number occurred as a label. 
           
          blank  all other uses 
           
          <<<<<<<<<<<<<<in the list is a warning denoting that the name
                 consists of more than 12 characters, which is the number
                 of significant characters for PASCAL-identifiers. 
           \f

          C_a_l_l_: 
M_m_m_                                                         1 
                 <output file' = cross <input file'   <option'
P_p_p_                                                         0 
           
          <option'::= bossline. <yes or no' 
           
                   <yes or no'::=  yes     bossline>s are added to the listing. 
                                   (default). 
           
                          no       only PASCAL/PASCAL80 line numbers are
                                   generated. 
           
          S_t_o_r_a_g_e_ _r_e_q_u_i_r_e_m_e_n_t_s_: 
           
          The core store required for cross is at least 40000 hW (size
          40000), but the requirement depends on the size of the input
          text. 
           
          E_r_r_o_r_m_e_s_s_: 
           
          ???     illegal output-filename 
                  left hand side of the call must be a name. 
                   
          ???     illegal input-filename 
                  input file must be specified 
                   
          ???     yes or no expected 
                  option >bossline> must be >bossline.yes> or >bossline.no>
                   
          ???     error in bracket structure, detected at line: xx 
                  missing ")" (>s) 
                   
          ???     error in blockstructure, detected at line: xx 
                  unmatched end 
                   
          *****   warning: hash table overflow at line: xx 
                  the name table ran full at line xx, the cross referencing
                  continues for the names met until line xx, new names in
                  the following lines are ignored. 
                   
                   \f

F_       A_._ _ _ _ _ _ _ _ _R_E_F_E_R_E_N_C_E_S_A.
           
          1  Staunstrup, J.: 
               PASCAL80 Report 
               RCSL No 52-AA964 
               A/S Regnecentralen af 1979 
                
          2  Jensen, K. and Wirth, N.: 
               PASCAL User Manual and Report 
               Springer - Verlag 
               Berlin 1974 
                \f

           
           \f

                                                 i 
           
          T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ _
           
          1.  INTRODUCTION ..........................................   1 
           
          2.  FUNCTIONS SUPPORTED BY THE DRIVER .....................   3 
           
          3.  DRIVER INTERFACE ......................................   4 
              3.1  Read Character ROM ...............................   4 
              3.2  Read Character RAM ...............................   4 
              3.3  Write Character RAM ..............................   4 
              3.4  Write Shadow RAM .................................   5 
              3.5  Write Attribute RAM ..............................   5 
           
          4.  DRIVER DECLARATION ....................................   6 
           
          5.  BASIC DISPLAY ROUTINES ................................   7 
           
           
          A_P_P_E_N_D_I_X_: 
           
          A.  REFERENCES ............................................  11 
           \f

                                        ii 
           \f

         1_._ _ _ _ _ _ _ _ _I_N_T_R_O_D_U_C_T_I_O_N_ 1.
           
          The RC850 display driver is used to control the screen display
          function of an RC850 terminal. The driver runs on the PI-1
                   Machine 1 implemented on a Z80-microprocessor as part of the
          RC850. 
           
          The functions provided by the driver may be characterized as
          rudimentary. Most of the functions are transparent transfer
          functions between CPU-memory and the various memories of the
          display module. The display module is described in detail in
          chapter 2 of 2. Its components are summarized below: 
           
          R_e_f_r_e_s_h_ _R_A_M_ 
          The memory holds the picture shown on the display, 2000 char-
          acters. 16 bits per. display position: 9 bits character value and
          7 bits attributes. 
           
          C_h_a_r_a_c_t_e_r_ _R_O_M_ 
          The memory holds up to 128 standard character patterns, addressed
          by character values 0-127. 
           
          C_h_a_r_a_c_t_e_r_ _R_A_M_ 
          This memory can hold up to 256 extra character patterns,
          addressed by character values 256-511. 
           
          S_h_a_d_o_w_ _R_A_M_ 
          This memory can hold 4 shadow patterns which can be shown
          together with the addressed character. It is addressed by 2
          attribute bits.  
           
          A_t_t_r_i_b_u_t_e_ _R_A_M_ 
          This memory can perform a conversion of 5 of the attribute bits
          to a number of different light effects on the display. 
           
          C_R_T_ _c_o_n_t_r_o_l_l_e_r_ 
          Contains the physical display parameters. These parameters are
          initialized by the driver, and can only be changed in the driver
          code. \f

                   Under normal use only the refresh RAM is updated dynamically. In
          fact when the driver is not performing a specifically requested
          transfer function it will continously transfer the contents of a
          buffer in CPU RAM, the r_e_f_r_e_s_h_ _R_A_M_ _o_r_i_g_i_n_a_l_ to the display
          refresh RAM by means of DMA. 
           
          With this strategy process incarnations on the PI-1 machine may
          update the display picture simply be writing into the refresh RAM
          original. 
           
          Normally, an RC850 application will issue very few request to the
          display driver, because only those functions which require syn-
          chronization by means of interrupts have been implemented as
          parts of the actual driver. A number of more commonly used func-
          tions are provided by the basic display routines described in
          chapter 5. The implementation of these functions in the form of
          routines eliminates a significant amount of costly process inter-
          communication. 
           \f

         2_._ _ _ _ _ _ _ _ _F_U_N_C_T_I_O_N_S_ _S_U_P_P_O_R_T_E_D_ _B_Y_ _T_H_E_ _D_R_I_V_E_R_ 2.
           
          The CTR controller will be initialized to physical characteris-
          tics as described in 2. 
           
          The contents of all RAM memories will be undefined, and the dis-
          play will be blocked. Proper initialization from the application
          should include writing of all RAM memories and unblocking the
          display. 
           
          The following data transfer functions are executed by the driver
          on request: 
           
          -  read character ROM to CPU RAM, 
          -  read/write character RAM, 
          -  write shadow RAM, 
          -  write attribute RAM. 
           
          Note that all display memories are accessed in blocks of bytes
          from byte 0 onwards. 
           
          The following basic functions on the display module are not
          performed by the driver, but by a collection of basic display
          routines described in chapter 5: 
           
          -  set/read cursor position, 
          -  block/unblock the display, 
          -  set cursor mode. 
           
           \f

         3_._ _ _ _ _ _ _ _ _D_R_I_V_E_R_ _I_N_T_E_R_F_A_C_E_ 3.
           
          The following description is based on the driver interface
          conventions 3. Each request supported by the driver is
          described in one section. 
           
           
3_._1_ _ _ _ _ _ _ _R_e_a_d_ _C_h_a_r_a_c_t_e_r_ _R_O_M_ 3.1
           
          Transfers contents of the character ROM to the data buffer. 
           
          function code 5 (read + 1 * 4) 
           
          Possible results: 
          0 processed succesfully 
          4 illegal function. 
           
           
3_._2_ _ _ _ _ _ _ _R_e_a_d_ _C_h_a_r_a_c_t_e_r_ _R_A_M_ 3.2
           
          Transfers contents of the character RAM to the data buffer. 
           
          function code 9 (read + 2 * 4) 
           
          Possible results: 
          0 processed succesfully 
          4 illegal function. 
           
           
3_._3_ _ _ _ _ _ _ _W_r_i_t_e_ _C_h_a_r_a_c_t_e_r_ _R_A_M_ 3.3
           
          Transfers contents of the data buffer to the character RAM. 
           
          function code 10 (write + 2 * 4) 
           
          Possible results: 
          0 processed successfully 
          4 illegal function. 
           \f

         3_._4_ _ _ _ _ _ _ _W_r_i_t_e_ _S_h_a_d_o_w_ _R_A_M_ 3.4
           
          Transfers contents of data buffer to shadow RAM. 
           
          function code 14 (write + 3 * 4) 
           
          Possible results: 
          0 processed succesfully 
          4 illegal function. 
           
           
3_._5_ _ _ _ _ _ _ _W_r_i_t_e_ _A_t_t_r_i_b_u_t_e_ _R_A_M_ 3.5
           
          Transfers contents of data buffer to attribute RAM. 
           
          function code 18 (write + 4 * 4) 
           
          Possible results: 
          0 processed succesfully 
          4 illegal function. 
           
           \f

         4_._ _ _ _ _ _ _ _ _D_R_I_V_E_R_ _D_E_C_L_A_R_A_T_I_O_N_ 4.
           
          The display driver is always placed in an RC850 bootstrap image
          along with the PI-1 basic software. The parent of the display
          driver is the Eve process (see 1). The PASCAL80 process heading
          of the display driver is as follows: 
           
          PROCESS Display _driver (VAR display _sem: semaphore; 
                                      int _vector: channel _number); 
           
          where display _sem is the driver>s request semaphore, and
          int _vector is the interrupt vector programmed in channel 2 of the
          CTC (used for interrupt on termination of DMA transfer). 
           
          The basic system variables used for performing display functions
          which are defined in the next chapter are also declared in the
          Eve process. 
           
           \f

         5_._ _ _ _ _ _ _ _ _B_A_S_I_C_ _D_I_S_P_L_A_Y_ _R_O_U_T_I_N_E_S_ 
           
          The routines described in the following are included in the boot-
          strap image of any RC850 terminal along with the display driver and
          included in the RC850 context used when compiling PASCAL80 program
          for an RC850 terminal. The routines access three basic system
          variables: 
           
          - the refresh RAM orginal, cf. chapter 1, 
          - the current cursor position (row, column), 
          - the current attribute byte (this is stored together with each
            character written). 
           
          PROCEDURE WriteDisplay (a: integer; b: byte); 
          The byte is written in the refresh RAM original at address a. 
           
          FUNCTION ReadDisplay (a: integer): byte; 
          The function returns the value stored at address a in the refresh
          RAM original. 
           
          PROCEDURE SetCursorPosition (r,c: byte); 
          The cursor is placed at location (r,c) on the display, and the
          current cursor position variable is updated to this value. The
          caller is responsible for ensuring that 0 <_ r <_ 24 and 0 <_ c <_ 79.
           
          PROCEDURE ReadCursorPosition (VAR r,c: byte); 
          The value of the current cursor position variable is copied into r
          and c. 
           
          PROCEDURE BlockDisplay; 
          Display of the contents of the refresh RAM on the screen is
          inhibited, i.e. the screen goes black. 
           
          PROCEDURE UnblockDisplay; 
          Display of the contents of the refresh RAM is enabled. 
           
          PROCEDURE SetCursorMode (mode: cursor _mode); 
          The type cursor _mode is defined as 
           \f

          cursor _mode = PACKED RECORD 
            dummy1:      bit; 
            blink:       boolean; 
            blinkrate:   bit; 
            dummy2:      bit; 
            startc:      0..13; 
            dummy3:      0..15; 
            endc:        0..13 
          END; 
           
                   A call of SetCursorMode will set the blink rate, size, and
          position of the cursor as specified by the fields of mode. 
           
          blink:           If TRUE, the cursor will blink. 
          blinkrate:       If 0 the blink rate is 1/32 of the field rate
                                    (50 Hz), otherwise 1/16. 
          startc and endc: First and last scanline of the cursor block. 
           
          PROCEDURE WriteChar (b: char); 
          The character is written on the display at the current cursor
          position which is then updated. Updating the cursor position
          (r,c) yields (r,c+1), except if c = 79 in which case a newline is
          output (see WriteNL). The cursor is set at the updated position.
          The attribute byte of the character is set to current attribute. 
           
          PROCEDURE WriteNL; 
          The cursor and current cursor position are both moved to the begin-
          ning of the next line. If the cursor was already in the last line
          (24) before the call, the screen image is rolled one line before
          the new line function is performed. Spaces are written in all char-
          acter positions of the new bottom line, with zero attribyte bytes. 
           
          PROCEDURE SetAttribute (att: byte); 
          The current attribute byte is set to the value of att. Subsequent
          characters written using WriteChar will have this byte as attri-
          bute byte. 
           \f

          PROCEDURE ClearScreen; 
          The procedure will clear the screen (setting all positions to
          blank with zero attribute), set current cursor position to (0,0)
          and set current attribute to 0. 
           
           \f

           
           \f

         A_._ _ _ _ _ _ _ _ _R_E_F_E_R_E_N_C_E_S_ A.
           
          1  RCSL No 31-D615: 
               The P1-1 Machine, Reference Manual. 
           
          2  RCSL No 31-D594: 
               RC850 Controllers, Reference Manual. 
           
          3  RCSL No 31-D617: 
               PASCAL80 Driver Conventions. 
           
           \f

«eof»