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

⟦5159c3d1e⟧ TextFile

    Length: 108288 (0x1a700)
    Types: TextFile
    Names: »D173«

Derivation

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

TextFile

                                                   i 
           
          P_R_E_F_A_C_E_ 
           
          PASCAL80 is the common systems programming language for future RC
          products, including the RC700 and RC850 product families. 
           
          The present manual is aimed at systems programmers writing pro-
          grams in the PASCAL80 language intended to run on the PI-1
          machine 2 which constitutes the core of RC700 and RC850 pro-
          ducts.  
           
          The manual has been edited with the purpose of making it -
          together with the PASCAL80 Report 1 - sufficient as a collec-
          tion of general reference material for a programmer of the
          described category.  
           \f

                                                 ii 
           \f

                                               iii 
           
          T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ 
           
          1.  INTRODUCTION ..........................................   1 
           
          2.  A SHORT DESCRIPTION OF THE PI-1 MACHINE ...............   3 
              2.1  Segments .........................................   4 
              2.2  The Private Monitor ..............................   5 
                   2.2.1  Wait Functions ............................   6 
                   2.2.2  Scheduling ................................   7 
                   2.2.3  CHANNEL Statement .........................   9 
              2.3  Standard Processes ...............................   9 
           
          3.  PASCAL80 ON THE PI-1 MACHINE ..........................  11 
              3.1  Implementation Details and Language Modifications   11 
                   3.1.1  Parameterized Types .......................  11 
                   3.1.2  Reals .....................................  11 
                   3.1.3  Radix .....................................  12 
                   3.1.4  Bounds of Subrange Types ..................  12 
                   3.1.5  Message Header ............................  12 
                   3.1.6  LOCK and CHANNEL Statements ...............  12 
                   3.1.7  Pool Initialization .......................  13 
                   3.1.8  Process Parameters ........................  13 
                   3.1.9  Incarnation Termination ...................  13 
                   3.1.10 Routine Exit ..............................  13 
                   3.1.11 Exception Handling ........................  13 
                   3.1.12 Prefix ....................................  14 
                   3.1.13 Character String ..........................  14 
                   3.1.14 Program ...................................  14 
              3.2  Predefined Types .................................  14 
              3.3  Predefined Routines ..............................  15 
                   3.3.1  Shallow Routines ..........................  15 
                   3.3.2  Deep Routines .............................  16 
                   3.3.3  I/O and CPU Control Routines ..............  19 
           
                   4.  LINKING Z80 ASSEMBLY PROGRAMS INTO PASCAL80 PROGRAMS ..  21 
               \f

                                        iv 
           
                   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_ 
           
          5.  REPRESENTATION AND LAYOUT OF VARIABLES ................  25 
              5.1  Representation of Values .........................  25 
                   5.1.1  Enumeration Types .........................  25 
                   5.1.2  Shielded and Pointer Types ................  25 
                   5.1.3  Structured Types ..........................  26 
                   5.1.4  Type Size .................................  26 
              5.2  Memory Layout ....................................  27 
                   5.2.1  Addressing ................................  27 
                   5.2.2  Stack Frame ...............................  28 
                   5.2.3  Structured Types ..........................  30 
                          5.2.3.1  Arrays and Records, Not Packed ...  30 
                          5.2.3.2  Packed Arrays and Records ........  31 
                          5.2.3.3  Set Types ........................  32 
           
          A_P_P_E_N_D_I_C_E_S_: 
           
          A.  REFERENCES ............................................  35 
           
          B.  HOW TO USE THE PASCALZ80 COMPILER .....................  36 
              B.1  Call of the Compiler .............................  36 
              B.2  Contexts .........................................  38 
           
          C.  PASCALZ80 ERROR MESSAGES ..............................  39 
              C.1  Messages from Pass 1 .............................  39 
               C.2  Messages from Pass 3 .............................  42 
               C.3  Messages from Pass 4 .............................  48 
               C.4  Messages from Pass 5 .............................  49 
               C.5  Messages from Pass 6 .............................  50 
           
              D.  HOW TO BUILD A PI-1 LIBRARY ON THE RC8000..............  51 
              D.1  InsertZ80 ........................................  51 
              D.2  DeleteZ80 ........................................  53 
              D.3  ListZ80 ..........................................  53 
           \f

                                        v 
           
                   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_ 
           
          E.  HOW TO GENERATE A BOOTSTRAP IMAGE FOR THE PI-1 MACHINE 
              ON THE RC8000 .........................................  54 
              E.1  Error Messages ...................................  56 
           
          F.  HOW TO TRANSFER BINARY FILES BETWEEN THE RC8000 AND THE 
              TEKTRONIX 8002A DEVELOPMENT SYSTEM ....................  58 
                  F.1  Tektronix Utility Program >CT> ...................  58 
                       F.2  Tektronix Utility Program >CB> ...................  59 
              F.3  RC8000 Utility Program >tekmove> .................  59 
              F.4  Examples of How to Transfer Programs .............  60 
           \f

                                        vi 
           \f

F_       1_._ _ _ _ _ _ _ _ _I_N_T_R_O_D_U_C_T_I_O_N_                                                     1.
           
          The PI-1 implementation of PASCAL80 1 has two main components:
          the PI-1 machine based on the Z80 microprocessor and a cross-
          compiler which runs on the RC8000 and generates code in the PI-1
          machine object code format.  
           
          PASCAL80 as defined in 1 presupposes a number of primitive
          functions, which in the language are expressed mostly in terms of
          predefined routines, particularly in the area of process synchro-
          nization, inter-communication, and scheduling. These functions are
          provided by the PI-1 basic software, PIBS. The PI-1 machine con-
          sists of a Z80 CPU with some amount of memory, PIBS, and an inter-
          preter for the PI-1 instruction set which is designed to support
          the sequential part of the PASCAL80 language.  
           
          A thorough description of the PI-1 machine is given in 2. Chap-
          ter 2 of this manual contains a brief introduction which will be
          sufficient for most PASCAL80 programmers. Programmers who need to
          write Z80 assembly code to be integrated into a PASCAL80 program
          (see below) may need to refer to 2 as well as the assembly lan-
          guage and assembler manuals 4, 5. 
           
          Chapter 3 may be seen as a continuation of 1. The PI-1 version
          of a number of language details which have been left in the
          report as "implementation dependent" is described, and so are
          some modifications and limitations relative to the language
          definition given in 1. Chapter 3 contains a complete list of
          all predefined routines of PI-1 PASCAL80. The repertoire is
          somewhat richer than that described in 1, and all routines
          which represent additions or modifications compared to the report
          are explained.  
           
          In general, the execution by interpretation of compiled PASCAL80
          code will be slower than the execution of optimal machine (Z80)
          code with similar function by a considerable factor. Commonly,
          however, a very small part of a program, typically one containing\f

          often repeated loops, accounts for most of the execution time.
                   Indeed, in applications for which performance on the PI-1 machine
          can be foreseen as problematic, we expect to be able easily to
          identify the time-critical parts.  
           
          The general strategy supported by the PI-1 PASCAL80 compiler to
          improve performance for such applications is to locate the cri-
          tical part of the program and rewrite it as a Z80 assembler pro-
          gram. The available mechanisms for linking such assembler coded
          program parts into a PASCAL80 program are described in chapter 4.
           
          Memory allocation and representation of variables of the various
          PASCAL80 types are discussed in chapter 5.  
           
          Information about practical procedures for compilation, linking,
          and loading of PASCAL80 programs is given in appendices.  
           \f

F_       2_._ _ _ _ _ _ _ _ _A_ _S_H_O_R_T_ _D_E_S_C_R_I_P_T_I_O_N_ _O_F_ _T_H_E_ _P_I_-_1_ _M_A_C_H_I_N_E_                          2.
           
          The PI-1 machine executes P_A_S_C_A_L_8_0_ _s_y_s_t_e_m_s_. A PASCAL80 system is
          defined as the execution of a P_A_S_C_A_L_8_0_ _p_r_o_g_r_a_m_. A PASCAL80 pro-
          gram consists of a number of p_r_o_c_e_s_s_e_s_. A process, as defined in
          1, is a description of a data structure and some actions on
          the data structure. The execution of the actions of a process on
          the data structure is called a process i_n_c_a_r_n_a_t_i_o_n_. Each process
          incarnation has a private data structure. In general, several
          incarnations of a process may share one description of the ac-
          tions (reentrant code).  
           
          The definition of the PASCAL80 language given in 1 implicitly
          presumes the availability of a number of basic system functions
          which for the most part are expressed in terms of predefined rou-
          tines. In the PI-1 machine these functions are performed by the
          PI-1 basic software, PIBS. The most important part of PIBS is the
          so-called private monitor, PRIVMON, which is explained in section
          2.2 below.  
           
          The Z80 microprocessor and its memory, augmented with PIBS, con-
          stitutes the b_a_s_i_c_ _l_e_v_e_l_ of the PI-1 machine. The machine at this
          level supports the PASCAL80 concepts introduced above, but it
          sees process incarnations as executing Z80 machine instructions.
          Indeed it is fully possible to write a process at this level,
          i.e. in Z80 assembly code, and use the functions of PIBS. The
          standard processes in the PI-1 machine (see section 2.3) and a
          number of RC850 drivers have been constructed in this way.  
           
          Processes written in PASCAL80, however, will execute at the
          i_n_t_e_r_p_r_e_t_e_d_ _l_e_v_e_l_ of the PI-1 machine. When compiled, a PASCAL80
          program will be transformed into a sequence of PI-1 instructions
          which are executed by the second software component of the PI-1
          machine, the PI-1 interpreter. Seen from the basic level of the
          PI-1 machine the interpreter is merely a reentrant piece of code
          shared by many process incarnations.  
           \f

                   In the present manual the interpreter and its instruction set is
          not discussed in detail. Suffice it to say that the instruction
          set is very similar to, in fact derived from, that of the RC3502,
          and that it provides direct support for a number of PASCAL80 lan-
          guage constructs, such as e.g. FOR-, LOCK-, and CHANNEL-state-
          ments and set types.  
           
           
2_._1_ _ _ _ _ _ _ _S_e_g_m_e_n_t_s_ 2.1
           
          Physically the memory of the PI-1 machine is the memory of the
          Z80 microprocessor on which the PI-1 machine is implemented. Logi-
          cally this memory is divided into a number of s_e_g_m_e_n_t_s_. A segment
          occupies a contiguous area of memory, i.e. locations with conse-
          cutive addresses. A segment may be of any size up to 32 K bytes,
          and may begin in any location. A PI-1 PASCAL80 system has four
          kinds of segments (in addition to special segments containing
          basic system information): 
           
          - program segment 
           
          A program segment contains the executable code of a process, or
          of a separately compiled routine. The contents of a program seg-
          ment do not change when a system runs. Thus memory for a program
          segment can be allocated in ROM. Normally, however, this is not
          the case for compiled program segments (see 3). A compiled
          program segment which is not bound to absolute addresses of
          variables at the process block level (cf. chapter 4 and the abs
          option described in appendix B) is reentrant. A separately com-
          piled routine is always reentrant. When a process is reentrant
          several incarnations may be created sharing the same process
          segment.  
           \f

          - incarnation data segment 
           
          Each process incarnation has an incarnation data segment which
          contains its data structure consisting of the incarnation stack
          plus information needed by PIBS. The latter is not visible to the
          incarnation itself, i.e. this information cannot be referred to
          in the program text. The stack contains all parameters and va-
          riables of the incarnation, dynamically organized in a number of
          stack frames corresponding to the nest of routine calls generated
          by the execution of the process. Messages are not placed in
          incarnation data segments, because they can be passed from one
          incarnation to another. The incarnation data segment is dynamic
          and is always located in RAM.  
           
          - message header segment and data buffer segment 
             
          A message header segment is allocated for each message header in
          a system, and a data buffer segment for each message data part.
          Message header and data buffer segments are always located in
          RAM. 
           
          Memory allocation for the program segments in a bootstrap image
          (see 2) is done by the cross-linker (cf. appendix E). Addi-
          tional program segments may be loaded by a running system. Allo-
          cation of memory for these program segments and for dynamic
          segments is performed dynamically as the segments are needed.
          However, the PI-1 machine contains no support for deallocation
          and re-use of memory within a system. The memory allocation
          strategy is therefore of the simplest possible kind: by in-
          creasing addresses. 
           
           
2_._2_ _ _ _ _ _ _ _T_h_e_ _P_r_i_v_a_t_e_ _M_o_n_i_t_o_r_ 2.2
           
          The private monitor, PRIVMON, is responsible for 
          - scheduling incarnations and switching contexts, 
          - handling interrupts, 
          - message exchange between incarnations via semaphores, 
          - the delay (time-out) function, 
          - administering entry to and exit from CHANNEL statements, 
          - starting incarnations. 
           \f

          PRIVMON may be invoked by a call to one of ten predefined routi-
          nes: seven wait routines, signal, start, and interrupt. A call of
          the latter routine is normally caused by a hardware interrupt. In
          addition PRIVMON is invoked when an incarnation enters or leaves
          a CHANNEL statement and when the real time clock ticks. 
           
          All PRIVMON code is executed with the Z80 interrupt system dis-
          abled; thus PRIVMON is indivisible. 
           
           
2_._2_._1_ _ _ _ _ _W_a_i_t_ _F_u_n_c_t_i_o_n_s_ 2.2.1
           
          PRIVMON provides possibilities for an incarnation to wait for
          three kinds of event: 
           
          - an interrupt, i.e. actually a call of the PRIVMON routine
            interrupt with a parameter specifying a channel from which the
            incarnation is expecting an interrupt (see subsection 2.2.3). 
           
          - the arrival of a message via a specified semaphore, cf. the
            predefined routines signal and wait of 1. 
             
          - the expiry of a delay, specified as a number of delay time
            units, implemented by means of the delay clock (timer driver).
            The delay time unit is 20 msec. 
           
          If an incarnation has been started, and if it is not waiting for
          any event, it is able to run on the processor and is said to be
          a_c_t_i_v_e_. All active incarnations are members of the active queue
          (see below). 
           
          An incarnation may wait for any combination of the three kinds of
          event, but not on more than one semaphore or on more than one
          interrupting device simultaneously. Seven PRIVMON wait routines
          are available as predefined routines, corresponding to the seven
          different combinations of at least one of the three kinds of
          event: waitI, waitS, waitD, waitIS, waitID, waitSD, and waitISD,
          where I stands for interrupt, S for semaphore, and D for delay. 
           \f

          If an interrupt, i.e. a call of the PRIVMON routine interrupt,
          arrives for an incarnation which is not waiting for the inter-
          rupt, it is stored as pending. This is analogous to the situation
          where a message is signalled to a semaphore before an incarnation
          has called a PRIVMON routine to wait for it. In general, if an
          incarnation calls a PRIVMON routine to wait for one or more
          events, at least one of which has already occurred the routine
          returns immediately to the calling incarnation and it continues
          to run. 
           
          On the other hand, when an incarnation calls a PRIVMON routine to
          wait for a combination of one or more events, none of which has
          yet occurred, the incarnation is descheduled, removed from the
          active queue and tied up with PRIVMON data structures enabling
          PRIVMON to reactivate it when one of the desired events event-
          ually occurs. Because of the indivisibility of PRIVMON two events
          cannot occur simultaneously. 
           
          A multiple wait routine always returns a result of type activa-
          tion (cf. section 3.2) specifying the kind of event causing reac-
          tivation. In case an incarnation calls a PRIVMON routine to wait
          for a combination including an interrupt and a message both of
          which have already arrived it will receive only the interrupt. 
           
           
2_._2_._2_ _ _ _ _ _S_c_h_e_d_u_l_i_n_g_ 2.2.2
           
          The incarnations of a PI-1 PASCAL80 system are at any point in
          time divided into two priority classes: 
           
          Class I:  incarnations executing a CHANNEL statement thus
                    enabling these incarnations to be activated by inter-
                    rupts. An incarnation of a process containing one or
                    more CHANNEL statements is called a d_r_i_v_e_r_. 
                     
          Class II: other incarnations. These behave as coroutines. 
           
          This division is not static. It changes as drivers enter and exit
          their CHANNEL statements. 
           \f

          A running incarnation may be descheduled for two kinds of
          reasons: 
           
          - the incarnation explicitly calls a PRIVMON routine which either
            deactivates it (a wait routine) or activates an incarnation
            with higher priority (signal, start, interrupt), or the incar-
            nation leaves a CHANNEL statement thereby lowering its priority
            so that another incarnation has higher priority. 
           
          - a hardware interrupt occurs, causing a class I incarnation to
            be activated and made running. 
           
          The scheduling of class I incarnations depends on the hardware
          priorities of the attached devices (daisy chain). Nested inter-
          rupts may occur so that one driver interrupts another. 
           
          Scheduling of class II incarnations is based on priorities.
          PRIVMON maintains the a_c_t_i_v_e_ _q_u_e_u_e_ which is at any point in time
          a list (not FIFO queue) of all active incarnations, ordered
          according to priority. 
           
          The running incarnation is always the first incarnation in the
          active queue. The presence of the dummy incarnation ensures that
          the active queue is never empty. 
           
          Class I incarnations all have a priority higher than that of any
          class II incarnation. The active class I incarnations, if any,
          will therefore always be at the head of the active queue. 
           
          When an incarnation is activated, except when activated by inter-
          rupt, it is inserted in the active queue after all incarnations
          with the same or higher priority and before incarnations with
          lower priority. When an incarnation is activated by interrupt it
          is inserted as the first incarnation in the active queue and
          immediately becomes running. 
           
          Class II incarnations must not disable the interrupt system
          (incarnations of compiled PASCAL80 processes cannot do this). A
          class II incarnation will never be running if a class I incarna-
          tion is active. 
           
           \f

2_._2_._3_ _ _ _ _ _C_H_A_N_N_E_L_ _S_t_a_t_e_m_e_n_t_ 2.2.3
           
          Executing a CHANNEL statement enables an incarnation (driver) to
          interact with a device by receiving the interrupts generated on a
          specific channel, i.e. with a particular value of the interrupt
          vector (Z80 interrupt model 2). 
            
          The reference variable of the CHANNEL statement 1 must refer-
          ence a channel message. This channel message (see reservech, sec-
          tion 3.3) contains the value of the channel in question. The PI-1
          machine has precisely one channel message for each existing
          channel. 
           
          When an interrupt on the channel occurs, a hardware generated
          call of PRIVMON>s interrupt routine causes the incarnation to be
          activated, assuming it is waiting for an interrupt. 
           
          It is also possible for an incarnation to call interrupt, thereby
          generating a software interrupt to a driver. 
           
          When a driver enters a CHANNEL statement its priority is adjusted
          so that it executes the CHANNEL statement with a high priority.
          When it leaves the CHANNEL statement the priority is adjusted
          again to the value with which the driver was started. This may
          cause it to be descheduled. 
           
           
2_._3_ _ _ _ _ _ _ _S_t_a_n_d_a_r_d_ _P_r_o_c_e_s_s_e_s_ 2.3
           
          PIBS includes three standard process incarnations which are part
          of all PI-1 PASCAL80 systems: 
           
          - the initial incarnation (Adam) survives after initializing a
            system as a dummy incarnation with lower priority than any
            other incarnation. 
           
          - the timer driver is activated by regular hardware timer inter-
            rupts and causes the d_e_l_a_y_ _c_l_o_c_k_ to tick every delay time unit
            (see subsection 2.2.1).  
           \f

          The timer driver is a child of Adam. In addition every system
          must include an incarnation of an assembly coded process Eve,
          whose program segment is located in the bootstrap image (see
          2). Eve is started by Adam as the final action during system
          initialization. Eve is the root of the remaining part of the
          system. 
           
           \f

F_       3_._ _ _ _ _ _ _ _ _P_A_S_C_A_L_8_0_ _O_N_ _T_H_E_ _P_I_-_1_ _M_A_C_H_I_N_E_                                     3.
           
          This chapter together with the PASCAL80 report 1 contains the
          precise definition of the programming language PASCAL80 as im-
          plemented on the PI-1 machine.  
           
           
3_._1_ _ _ _ _ _ _ _I_m_p_l_e_m_e_n_t_a_t_i_o_n_ _D_e_t_a_i_l_s_ _a_n_d_ _L_a_n_g_u_a_g_e_ _M_o_d_i_f_i_c_a_t_i_o_n_s_ 3.1
           
          The PASCAL80 report leaves open a number of small parts of the
          language. A description of how these parts have been implemented
          is given in this section. Included is also information about a
          number of aspects of PI-1 PASCAL80 where the implementation de-
          viates from what the report prescribes. No indication is given
          of which parts of the description are supplementary to the report
          and which are alternative. As a rule information which is given
          in connection with a predefined routine (section 3.3) is not
          found in this section.  
           
          The page numbers given in each of the headings below refer to
          1. 
           
           
3_._1_._1_ _ _ _ _ _P_a_r_a_m_e_t_e_r_i_z_e_d_ _T_y_p_e_s_  (p. 9, 10, 36, 41, 42, 50, 51, 52) 3.1.1
           
          Parameterized types are not implemented. In particular the type
          string(n) is not defined.  
           
           
3_._1_._2_ _ _ _ _ _R_e_a_l_s_  (p. 10, 19, 63) 3.1.2
           
          The type real is not implemented. Numeric values can only be
          integral, i.e. no decimals or exponents are allowed.  
           
           \f

         3_._1_._3_ _ _ _ _ _R_a_d_i_x_  (p. 18)                                                   3.1.3
           
          Binary, octal, and hexadecimal numbers are indicated by the pre-
          fixes #b, #o, and #h. In hexadecimal numbers the digits a..f may
          be used.  
           
           
3_._1_._4_ _ _ _ _ _B_o_u_n_d_s_ _o_f_ _S_u_b_r_a_n_g_e_ _T_y_p_e_s_  (p. 19) 3.1.4
           
          The bounds min bound and max bound of a subrange type definition
          must be given by constant expressions.  
           
           
3_._1_._5_ _ _ _ _ _M_e_s_s_a_g_e_ _H_e_a_d_e_r_  (p. 21) 3.1.5
           
          The following fields of a message header are accessible:  
          size: !integer; (* size in bytes of message data *) 
          kind: !message _kind; (* see section 3.2 *) 
          u1, u2, u3, u4: byte; (* not present in channel message *) 
           
           
3_._1_._6_ _ _ _ _ _L_O_C_K_ _a_n_d_ _C_H_A_N_N_E_L_ _S_t_a_t_e_m_e_n_t_s_  (pp. 26-27) 3.1.6
           
          The report specifies certain restrictions on the use of the ref-
          erence variable of a LOCK or CHANNEL statement. These restric-
          tions are not enforced by PI-1 PASCAL80. However, the reference
          variable of a LOCK statement is treated as follows: 
           
          - before the statement (after DO) is executed the reference vari-
            able is exchanged with an anonymous reference variable and
            thereby becomes NIL, 
             
          - after the statement the reference variable is again exchanged
            with the anonymous variable. If the anonymous reference does
            not hereby become NIL an exception occurs.  
             
          The substance of the implementation of the CHANNEL statement is
          explained in subsection 2.2.3. 
           
           \f

         3_._1_._7_ _ _ _ _ _P_o_o_l_ _I_n_i_t_i_a_l_i_z_a_t_i_o_n_  (p. 45)                                     3.1.7
           
          The allocation of memory for messages for a pool variable is per-
          formed during the initialization of an incarnation a_f_t_e_r_ it has
          been started and scheduled to run. One effect of this is that an
          incarnation may in unfortunate cases be successfully created and
          yet unable to run due to lack of memory.  
           
           
3_._1_._8_ _ _ _ _ _P_r_o_c_e_s_s_ _P_a_r_a_m_e_t_e_r_s_  (p. 51) 3.1.8
           
          Process parameters of reference, pool, or shadow types are not
          allowed, neither as variables, values, or components of struc-
          tured parameters. Pointers may be passed only as values or frozen
          variables. Semaphores may be passed as variables, but not as
          values. Otherwise, the restrictions mentioned in 1 are not
          enforced. 
           
           
3_._1_._9_ _ _ _ _ _I_n_c_a_r_n_a_t_i_o_n_ _T_e_r_m_i_n_a_t_i_o_n_  (p. 56) 3.1.9
           
          When an incarnation is terminated (by completing its compound
          statement) it is permanently descheduled and will not become
          running again. However, no garbage collection is performed. 
           
           
3_._1_._1_0_ _ _ _ _R_o_u_t_i_n_e_ _E_x_i_t_  (p. 57) 3.1.10
           
          The rule stated in 1, that all local reference and shadow vari-
          ables must be NIL at exit from a routine block, is not enforced.
           
           
3_._1_._1_1_ _ _ _ _E_x_c_e_p_t_i_o_n_ _H_a_n_d_l_i_n_g_ 3.1.11
           
          When an exception occurs the exception routine of the PI-1 ma-
          chine is called. It is described in section 3.3. The exception
          routine may also be called explicitly.  
           
                   If a routine with name exception is declared in a program, the
          usual scope rules will apply, but the handling of exceptions is
          not affected.  
           
           \f

3_._1_._1_2_ _ _ _ _P_r_e_f_i_x_  (p. 60) 3.1.12
           
          Prefixes as described in 1 have not been implemented. See the
          description of contexts in appendix B for a somewhat similar
          mechanism.  
           
          A routine may be compiled separately by using the syntax 
           
          -'PREFIX -'prefix name -'; -'routine declaration -' 
           
           
3_._1_._1_3_ _ _ _ _C_h_a_r_a_c_t_e_r_ _S_t_r_i_n_g_  (p. 64) 3.1.13
           
          The type of a one-dimensional array of char is called a string
          type. A character string is a value whose type is compatible with
          any string type. Thus character strings may be assigned to and
          compared with variables of string types, and used as actual para-
          meters for formal parameters of string types. Whenever appropri-
          ate a character string is truncated to the required number of
          characters or extended with spaces.  
           
          The predefined type alfa which is used to specify external names
          of processes is an example of a string type whose values may be
          written as character strings.  
           
           
3_._1_._1_4_ _ _ _ _P_r_o_g_r_a_m_ (p. 60) 3.1.14
           
          Each compilation of a PASCAL80 program, i.e. a process or a pre-
          fix yields an object module 2. The object module name is the
          process or prefix name. 
           
           
         3_._2_ _ _ _ _ _ _ _P_r_e_d_e_f_i_n_e_d_ _T_y_p_e_s_                                                 3.2
           
          The following types are predefined in PI-1 PASCAL80 in addition
          to those described in 1. 
           
          bit  = 0..1; 
          byte = 0..255; 
           \f

          activation = (a _interrupt, a _semaphore, a _delay); 
           
          The type activation is used for results from multiple wait func-
          tions to indicate the reason why an incarnation is activated (or
          continues to run).  
           
          message _kind = (datamsg, channelmsg); 
           
          The type message _kind is used in the kind field of a message
          header to indicate whether a message is a data message or a
          channel message.  
           
          alfa = ARRAY(1..12) OF char; 
           
          The type alfa is used to specify external process names (see link
          in the next section).  
           
           
         3_._3_ _ _ _ _ _ _ _P_r_e_d_e_f_i_n_e_d_ _R_o_u_t_i_n_e_s_                                              3.3
           
          The predefined routines supported by PI-1 PASCAL80 are divided
          into three groups: 
           
          - the s_h_a_l_l_o_w_ routines which are executed without involving PIBS;
            these routines are all functions and they may be considered as
            operators on their parameter types.  
             
          - the d_e_e_p_ routines which involve calls to PIBS, most often to
            PRIVMON.  
             
          - the i_/_o_ _a_n_d_ _C_P_U_ _c_o_n_t_r_o_l_ routines. 
             
             
3_._3_._1_ _ _ _ _ _S_h_a_l_l_o_w_ _R_o_u_t_i_n_e_s_ 3.3.1
           
          The following shallow routines are implemented in accordance with
          their definition in 1: abs, chr, empty, locked, nil, open, ord,
          passive, pred, ref, and succ.  
           \f

          Two shallow routines have been added: 
           
          FUNCTION openpool(VAR p: POOL 1): boolean; 
          A call of openpool returns the value TRUE if the pool is not
          empty, FALSE otherwise.  
           
             FUNCTION ownertest (VAR p: POOL 1; VAR r: reference): boolean; 
          A call of ownertest returns the value TRUE if the message
          accessed by r has been allocated from p, FALSE otherwise. If r is
          NIL an exception occurs. 
           
           
3_._3_._2_ _ _ _ _ _D_e_e_p_ _R_o_u_t_i_n_e_s_ 3.3.2
           
          All deep routines available in PI-1 PASCAL80 are listed below.
          Only those which differ from the definition in 1 are described
          in detail.  
           
                   PROCEDURE alloc(VAR r: reference; VAR p: POOL 1; VAR s: semaphore);
          See 1. 
           
          PROCEDURE break(VAR sh: shadow; excode: integer); 
          A call of break causes an exception to occur in the child
          (shadow), i.e. the exception routine is called f_r_o_m_ the child.  
           
          FUNCTION create(process name (actual parameters); 
                          VAR sh: shadow; size: integer): integer; 
          See 1. When create is called the shadow variable must be NIL,
          and the process name must either be internal, or an external name
          must have been linked to it (by link, see below), otherwise an
          exception occurs. The size parameter specifies the size in bytes
          of the incarnation stack in the data segment allocated for the
          incarnation which is created. If a process has not been linked to
          the process name it is searched for among the processes which
          have been loaded into the memory of the PI-1 machine, and if
          found, it is linked to the process name. If not found, the linker
          is invoked to search for the process in the object program cata-\f

          log (cf. 2). If the process is found in the catalog it is
          loaded and linked to the process name, otherwise create fails.
                   When a program is searched for, both the external name and the
                   parameter description must match. 
           
          The result of create is: 
          0 - if an incarnation is successfully created, 
          1 - if the process has not been found, 
          2 - if sufficient memory cannot be allocated. 
           
                  PROCEDURE exception (excode: integer); 
          A call of the exception procedure, which may be caused by the
                  occurrence of an exception, causes diagnostic information to be
          output on a suitable device, if one is present. A stack trace of
          the calling incarnation is included. Subsequently the PI-1
          machine stops executing the PASCAL80 system. 
           
          PROCEDURE interrupt(channel: integer); 
          A call of interrupt generates a software interrupt to the incar-
          nation which is executing a CHANNEL statement with a channel
          message containing a channel value equal to the parameter, cf.
          subsection 2.2.3. If no such incarnation exists the call has no
          effect. 
           
          PROCEDURE link(external _name: alfa; process name); 
          See 1. Note that only the external name, not the actual process
          is linked to the process.  
           
          PROCEDURE pop(VAR r1, r2: reference); 
          See 1. 
           
          PROCEDURE push(VAR r1, r2: reference); 
          See 1.  
           
          PROCEDURE release(VAR r: reference); 
          If the parameter is NIL a call of release causes an exception,
          otherwise the effect is dependent on the kind of message referred
          to by r. If the message is of kind datamsg it is released to its
          owner pool, i.e. made available for allocation by a call of\f

          alloc. If the message is of kind channelmsg the channel ident-
          ified by the message is released, i.e. it becomes free for reser-
          vation by a call to reservech. In both cases r is NIL on return
          from release.  
           
          FUNCTION remdelay : byte; 
          This function may be called after returning from a multiple wait
          function which includes waiting for a delay. The result returned
          is the number of time units which remained of the delay when the
          incarnation was activated. 
           
          PROCEDURE remove(VAR sh : shadow); 
          The procedure remove is not available in PI-1 PASCAL80. 
           
          PROCEDURE reservech(VAR r: reference; channel: integer); 
          When reservech is called r must be NIL, otherwise an exception
          occurs. If the specified channel is free before the call, it is
          reserved, and on return r will refer to its channel message. If
          the channel is not free the call has no effect, i.e. r is NIL on
          return.  
           
          PROCEDURE return(VAR r: reference); 
          See 1. 
           
                   PROCEDURE sensesem(VAR r: reference; VAR s: semaphore); 
          If the semaphore s is open, the call sensesem(r,s) is equivalent
          to waits(r,s), otherwise the call has no effect. 
           
          PROCEDURE signal(VAR r: reference; VAR s: semaphore);  
          See 1. 
           
          PROCEDURE start(VAR sh: shadow; priority: 1..254); 
          See 1. Notice that the parameter priority is not of type in-
          teger as in 1. The priority of the created incarnation with
          respect to scheduling is higher, the smaller the value of the
          priority parameter. 
           
          PROCEDURE stop(VAR sh: shadow); 
          The procedure stop is not available in PI-1 PASCAL80.  
           \f

          PROCEDURE wait(VAR r: reference; VAR s: semaphore); 
          Equivalent to waits; see subsection 2.2.1. 
           
          PROCEDURE waitd(delay: byte);  
          See subsection 2.2.1. 
           
          PROCEDURE waiti;  
          See subsection 2.2.1. 
           
          FUNCTION waitid(delay: byte): activation;  
          See subsection 2.2.1. 
           
          FUNCTION waitis(VAR r: reference; VAR s: semaphore): activation; 
          See subsection 2.2.1. 
           
          FUNCTION waitisd(VAR r: reference; VAR s: semaphore; 
                           delay: byte); activation; 
          See subsection 2.2.1. 
           
          PROCEDURE waits(VAR r: reference; VAR s: semaphore);  
          See subsection 2.2.1. 
           
          FUNCTION waitsd(VAR r: reference; VAR s: semaphore;  
                          delay: byte): activation;  
          See subsection 2.2.1. 
           
          PROCEDURE unlink(process name); 
          The procedure unlink is not available in PI-1 PASCAL80. 
           
           
         3_._3_._3_ _ _ _ _ _I_/_O_ _a_n_d_ _C_P_U_ _C_o_n_t_r_o_l_ _R_o_u_t_i_n_e_s_ 3.3.3
           
          The routines described below are available to perform i/o and CPU
          control control instructions of the Z80 microprocessor on which
          the PI-1 machine is based.  
           
          FUNCTION inbyte(inport: byte): byte; 
          A call of inbyte yields as result a byte read from the input port
          specified by the parameter (one Z80 IN instruction).  
           \f

          PROCEDURE inbyteblock(VAR r: reference; first, last: byte;  
                                inport: byte); 
          This procedure is equivalent to the following: 
          LOCK r AS buf: ARRAY(0..max) OF byte DO 
          FOR i:=first TO last DO buf(i):=inbyte(inport); 
          where max is sufficiently large and i is a byte. The procedure is
          executed by means of the Z80 INIR (block input) instruction.  
           
          PROCEDURE outbyte(outport, data: byte); 
          A call of outbyte causes the byte data to be output on the output
          port specified by outport (one Z80 OUT instruction).  
           
          PROCEDURE outbyteblock(VAR r: reference; first, last: byte;  
                                 outport: byte); 
          This procedure is equivalent to the following: 
          LOCK r AS buf: ARRAY(0..max) OF byte DO 
             FOR i:=first TO last DO outbyte(outport,buf(i));  
          where max is sufficiently large and i is a byte. The procedure is
           executed by means of the Z80 OTIR (block output) instruction.  
           
          PROCEDURE zenable; 
          A call of zenable causes the Z80 EI instruction to be executed,
          i.e. the interrupt system of the CPU is enabled.  
           
          PROCEDURE zreti; 
          A call of zreti causes the Z80 RETI instruction to be executed,
          notifying a peripheral device on the daisy chain that interrupt
          service is completed.  
            
           \f

4_._ _ _ _ _ _ _ _ _L_I_N_K_I_N_G_ _Z_8_0_ _A_S_S_E_M_B_L_Y_ _P_R_O_G_R_A_M_S_ _I_N_T_O_ _P_A_S_C_A_L_8_0_ _P_R_O_G_R_A_M_S_ 4.
           
          Inclusion of Z80 assembly code into a compiled PASCAL80 program
          may be necessary for one of two reasons: 
           
          - the need to optimize a time-critical part of the program, or 
          - the need to use special facilities at the basic level of the
            PI-1 machine which are not available at the interpreted
            PASCAL80 level, particularly in connection with treatment of
            interrupts in drivers. 
           
          The procedure for inclusion of an assembly language program in a
          compiled PASCAL80 program is as follows: 
           
          The program is written in the Z80 assembly language described in
          4 and assembled on the Tektronix 8002 microprocessor develop-
          ment system 5. Information about how the assembly language pro-
          gram interfaces to PIBS and the PI-1 interpreter, and about the
          facilities available at the basic level of the PI-1 machine is
          found in 2. 
           
          The object program produced by the Tektronix assembler is then
          transferred to a P_I_-_1_ _l_i_b_r_a_r_y_ on the RC8000 where the compiler
          runs. In the PI-1 library the assembler object program is stored
          together with a PASCAL80 procedure description, i.e. a name and a
          parameter description. The transfer of the assembler object pro-
          gram and the specification of the procedure description is done
          by means of utility programs which are described in appendices D
          and F. 
           
          The PI-1 compiler will include an assembler object program from
          a PI-1 library specified using the lib option (see appendix B)
          into a compiled program if an external procedure declaration
          compatible with the procedure description in the library and at
          least one call of the declared procedure occurs in the program. 
           \f

          For each call occurring in the PASCAL80 program of a procedure
          which has been included from the PI-1 library as described above
          the compiler generates code to evaluate the parameters and push
          them on the stack of the incarnation executing the call and sub-
          sequently transfer control to the entry point of the assembly
          language program. Information about the representation of par-
          ameters on an incarnation stack is found in chapter 5. 
           
          When a program is written in assembly language to replace a
          time-critical part of a PASCAL80 program it is necessary, or at
          least useful, to be able to access not only the parameters
          specified in the external procedure declaration, but also the
          variables of the process incarnation in which the assembly
          program is executed. For this reason the compiler supports
          linking of values exported from a PASCAL80 program to symbols
          declared as unbound globals in the assembly language program. 
           
          The values to be exported from a PASCAL80 program are defined in
          export parts occurring in the declarations of one or more blocks
          within the program. The syntax and semantics of an export part
          are described below: 
           
              export part: 
           
          -'  EXPORT-'-'export name -' = -'export kind -' simple variable -'
                                       ; 
           
          Each repetition of the loop yields one e_x_p_o_r_t_ _v_a_l_u_e_ which is
          associated with the export name, i.e. the same name must appear
          as an unbound global symbol in the assembly language program.
          Only the first eight characters of an export name are signifi-
          cant.  
           
          export kind: 
           
                         VALUE 
                         DISP 
                         SIZE 
                         ADDRESS 
                         OFFSET 
           \f

                   simple variable: 
                
               -'  simple var name -'                      -'   -'   
                                         field name <-.<-    
                
          Simple var name can be either a constant name or a variable name.
          If it is a constant name, or if the variable is of a packed
          record type, field name indexing is not allowed. It follows that
          simple variable is either a constant, a variable, or a field of a
          record variable which is not packed.  
           
          The export value must always be representable in a word (16 bits)
          or a byte (8 bits), cf. chapter 5. The export kind determines how
          the export value is calculated: 
           
          VALUE     The simple variable must be a constant. The export
                    value is the value of the constant. 
                     
          DISP      The simple variable must be a field of a record. The
                    export value is the displacement of the field relative
                    to the start of the record. 
                     
          SIZE      The export value is the size in bytes of the type of
                    the simple variable. 
                     
          ADDRESS   The simple variable must be a variable or a field of a
                    variable record declared at the process block level of
                    a separately compiled process. The export value is the
                    address of the simple variable, and when the object
                    program resulting from the compilation is loaded and
                    linked on the PI-1 machine it is relocated as the
                    absolute Z80 address of the simple variable. Thus the
                    corresponding global symbol in the assembly language
                    program may be used directly as a variable address. 
                     
                    Notice that a program which contains exported values of
                    kind ADDRESS will not be reentrant (see also the abs
                    option in appendix B). 
                     \f

          OFFSET    The simple variable must be a variable or field of a
                    record variable. The export value is the offset of the
                    simple variable within its local stack frame. 
           
           \f

F_       5_._ _ _ _ _ _ _ _ _R_E_P_R_E_S_E_N_T_A_T_I_O_N_ _A_N_D_ _L_A_Y_O_U_T_ _O_F_ _V_A_R_I_A_B_L_E_S_                              5.
           
          In this chapter it is explained how values of the various types
          of PASCAL80 are represented in the PI-1 implementation and how
          memory is allocated and laid out to hold the values of the vari-
          ables of a process incarnation. 
           
           
5_._1_ _ _ _ _ _ _ _R_e_p_r_e_s_e_n_t_a_t_i_o_n_ _o_f_ _V_a_l_u_e_s_ 5.1
           
5_._1_._1_ _ _ _ _ _E_n_u_m_e_r_a_t_i_o_n_ _T_y_p_e_s_ 5.1.1
           
          An enumeration type is defined as consisting of a finite, totally
          ordered set of values, corresponding to a set of ordinal values
          which is a subset of the integral numbers. The representation of
          a value of an enumeration type is the two>s complement represen-
          tation of the corresponding ordinal value. If a type includes
          negative ordinal values the representation of values of the type
          is always in 16 bits (a word). If the type includes only non-
          negative ordinal values, and n is the largest of these then the
M_m_m_          representation is in log (n+1) bits (at most 16). Examples:
                                  2 
P_p_p_             - integer values (-32768..32767) are represented in 16 bits,
          - boolean values (false, true) are represented in 1 bit, 
          - char values (see 1) are represented in 7 bits, 
          - values of the subrange type -3..7 are represented in 16 bits,
          - values of the scalar type (red, green, blue, orange, pink) are
            represented in 3 bits. 
           
           
         5_._1_._2_ _ _ _ _ _S_h_i_e_l_d_e_d_ _a_n_d_ _P_o_i_n_t_e_r_ _T_y_p_e_s_ 5.1.2
           
          The representation of values of shielded and pointer types is not
          revealed. 
           
           \f

         5_._1_._3_ _ _ _ _ _S_t_r_u_c_t_u_r_e_d_ _T_y_p_e_s_                                                    5.1.3
           
          Values of array or record types are vectors of values of enumer-
          ation, shielded, pointer, and set types. The component values are
          represented as described for the component types. 
           
          The representation of values of a set type uses a bit vector
          whose length depends on the base type. The base type must be an
          enumeration type which does not include negative ordinal values.
           
          If the ordinal value set of the enumeration type T is the range
          m..n (m '_ 0) then values of the type set of T are represented in
          a bit vector with indices from 0 to n. The first m (possibly
          zero) of these bits are not significant. If the element of T
          whose ordinal value is i (m <_ i <_ n) is a member of a particular
          value of type set of T then bit i in the representation of that
          value is 1, otherwise it is 0. Example: 
           
          TYPE 
               a=set of 3..5; 
          VAR 
               b: a:=(.3,5.); 
           
          The value of b is represented as shown: 
           
          bit   0 1 2 3 4 5 
                      1 0 1   The shaded bits are not significant. 
           
           
5_._1_._4_ _ _ _ _ _T_y_p_e_ _S_i_z_e_        5.1.4
           
          The size of a type T, denoted S(T), is the number of bits used to
          represent values of type T. The concept of size is only relevant
          for types which are affected by packing when used for components
          of structured types, and is therefore not defined for all types.
          For enumeration types S(T) is computed as described above.
          Examples: S(char)=7, S(integer)=16. 
           
           \f

         5_._2_ _ _ _ _ _ _ _M_e_m_o_r_y_ _L_a_y_o_u_t_                                                       5.2
           
          The memory requirement of a type T, denoted M(T), is defined as
          the number of bytes which are allocated for a variable of type T.
           
          For an enumeration type T, M(T) depends on S(T), as follows: 
           
               1 <_ S(T) <_ 8:  M(T)=1 
               9 <_ S(T) <_ 16: M(T)=2 
           
          For shielded and pointer types, M(T) is the following: 
           
               M(reference)= 2 
               M(semaphore)= 3 
               M(shadow)   = 2 
               M(pointer)  = 2 
               M(pool)     = 3 
                
          Memory requirement for structured types is described in connec-
          tion with memory layout for these types in subsections 5.2.3 and
          5.2.4. 
           
           
5_._2_._1_ _ _ _ _ _A_d_r_e_s_s_i_n_g_      5.2.1
           
          The memory of the PI-1 machine consists of a sequence of eight
          bit bytes. Each byte has an address. Two consecutive bytes may be
          used as a sixteen bit word.  
           
          In Intel fashion a word consists of high byte (most significant
          halfword) and low byte (least significant halfword). The low byte
          is always the byte with the l_o_w_e_s_t_ address.  
           
          An integral number of bytes is allocated for each variable. The
          address of a variable is the smallest of the addresses of the
          bytes allocated for the variable.  
                    
           \f

         5_._2_._2_ _ _ _ _ _S_t_a_c_k_ _F_r_a_m_e_                                                         5.2.2
           
          Memory for variables declared in process or routine blocks is
          allocated in s_t_a_c_k_ _f_r_a_m_e_s_ in the data segment of the incarnation
          to which the variables belong. The general layout of an incarna-
          tion stack is shown in fig. 1.  
           
          In the portion of a stack frame used for declared variables
          memory is allocated from high to low addresses in the order of
          declaration of the variables in the program text. 
           
          The two bytes allocated for a variable of an enumeration type T
          with M(T)=2 are treated as a word, i.e. the most significant
          halfword has the highest byte address. A variable of an enumer-
          ation type is always right justified, i.e. placed in the least
          significant bits of the allocated byte or word.  
           
          Example: Corresponding to the declarations: 
           
          VAR 
               a: reference; 
               b: char; 
               c,d: 0..7; 
               e: integer; 
           
          memory is allocated within a stack frame as illustrated in fig.
          2. 
           
          address  MSB         LSB 
                            7 6 5 4 3 2 1 0 
M_m_m_                s-6 
                                   e 
P_p_p_             s-5 
                      s-4               d            the shaded areas are unused 
                      s-3               c 
             s-2          b 
M_m_m_                s-1 
                          a 
P_p_p_                s 
           
                   Figure 2: Memory layout for simple declared variables in stack
                             frame. 
                
           \f

F_                  
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
          Figure 1: Incarnation stack layout (snapshot). 
           \f

F_                 The layout of actual parameters is similar to that of declared
          variables, with a minor modification: since the smallest unit of
          memory pushed on the evaluation stack is a word, each actual
          parameter of a process or routine stack frame occupies an
          integral number of words. Similarly to the case of declared
          variables, an actual parameter of an enumeration type of size
          less than 16 (bits) is placed in the least significant bits of
          the allocated word. 
           
           
         5_._2_._3_ _ _ _ _ _S_t_r_u_c_t_u_r_e_d_ _T_y_p_e_s_     5.2.3
           
          The memory requirement of a structured type is determined by the
          memory requirements of the component type(s). However, the memory
          requirement of a packed record or array is always at least two
          (bytes). 
           
          The memory allocated for a variable of a structured type is sub-
          allocated for the components of the variable in a fashion which
          depends on whether the type is declared as packed or not. 
           
          For an array, memory is allocated from low to high addresses for
          the elements in index order, and for a record, memory is allo-
          cated from low to high addresses for the fields in the order they
          are declared in the record type definition. 
           
           
5_._2_._3_._1_ _ _ _A_r_r_a_y_s_ _a_n_d_ _R_e_c_o_r_d_s_,_ _N_o_t_ _P_a_c_k_e_d_ 5.2.3.1
           
          For an array or record type which is not packed, memory allocation
          for the components takes place in a fashion similar to the allo-
          cation of memory for declared variables in a stack frame, except
          that increasing address order is used, i.e: 
           
               - from low to high addresses, 
               - an integral number of bytes per component, 
               - right justification of each enumeration type component
                 within the allocated byte or word. 
           \f

          Example: With the record type definition below. Fig. 3 shows the
          layout of a variable of type r. 
           
          TYPE 
               r=RECORD 
                   a: reference; 
                   b: char; 
                   c,d: 0..7; 
                   e: integer 
               END; 
           
           
                   address  7 6 5 4 3 2 1 0 
M_m_m_                  s 
                                   a 
P_p_p_             s+1 
                      s+2          b 
                      s+3               c 
                      s+4               d 
M_m_m_                s+5 
                                   e 
P_p_p_             s+6 
 
                   Figure 3: Memory layout for record type (not packed). 
           
                   By summation (or multiplication) the memory requirement of an
          array or record type may be determined from the above rules for
          sub-allocation of memory for components. For the record type in
          the example M(r)=7. 
           
           
5_._2_._3_._2_ _ _ _P_a_c_k_e_d_ _A_r_r_a_y_s_ _a_n_d_ _R_e_c_o_r_d_s_      5.2.3.2
           
          When memory is laid out for a packed array or record type compo-
          nents of types with size less than 16 (bits) (for arrays: 6 bits)
          are packed, if possible. Packing always takes place in a word,
          from most to least significant bit, and each component is allo-
          cated as many bits as indicated by its size. By this rule unused
          space may be left in the least significant bits of a word in
          which one or more components are packed. 
           \f

                   Notice that in the current implementation only components of
          enumeration types are candidates for packing. 
           
          Example: The layout of variables of the following packed record
          type is shown in fig. 8. 
           
          TYPE 
               q=PACKED RECORD 
                   a: reference; 
                   b: char; 
                   c,d: 0..7; 
                   e: integer 
               END; 
           
                   MSB                               LSB 
                            15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 
                         s                    a 
                       s+2            b           c     d 
                       s+4                    e 
           
                   Figure 4: Memory layout for record. M(q)=6. 
           
           
    5_._2_._3_._3_ _ _ _S_e_t_ _T_y_p_e_s_      5.2.3.3
           
          The memory requirement of a set type is always an even number (of
          bytes), i.e. an integral number of words is allocated for each
          variable of a set type. The number of words used is the smallest
          number which will accomodate the bit vector used to represent
          values of the set type, cf. subsection 5.1.3. The bit vector is
          laid out with index 0 in the most significant bit of the first
          word. The last word may contain an unused portion in its least
          significant bit positions. Example: see fig. 5. 
           \f

          address  15  14  13  12  11  10  9  8  7  6  5  4  3  2  1  0 
          s 
          s+2 
          s+4 
          s+6 
                    
          Figure 5: Layout of a variable of the type set of 0..50;
                    13 bits are unused. The memory requirement of the type
                    is 8. 
           
           \f

F_\f

F_       A_._ _ _ _ _ _ _ _ _R_E_F_E_R_E_N_C_E_S_    A.
           
          1  RCSL No 52-AA964: 
               PASCAL80 Report 
           
          2  RCSL No 31-D615: 
               The PI-1 Machine, Reference Manual 
           
          3  System User>s Package for 
               Tektronix 8002A microprocessor development system 
           
          4  Z80-Assembly Language Programming Manual, 
               Zilog, inc.  
           
          5  Z80 Assembler and Emulator User>s Manual for  
               Tektronix 8002A microprocessor development system  
           
           \f

F_       B_._ _ _ _ _ _ _ _ _H_O_W_ _T_O_ _U_S_E_ _T_H_E_ _P_A_S_C_A_L_Z_8_0_ _C_O_M_P_I_L_E_R_    B.
           
B_._1_ _ _ _ _ _ _ _C_a_l_l_ _o_f_ _t_h_e_ _C_o_m_p_i_l_e_r_ B.1
           
M_m_m_                          1             <s'<options'                  1 
            <bin file'=     pascalz80                    <s'<source' 
                                0             <s'<context'                  0 
P_p_p_                                                          0 
           
                                 list.  <yes or no' 
                               stop.  <pass no' 
                   <options'::=    lib.   <lib file' 
                             abs.   <yes or no' 
                          index. <yes or no' 
           
M_m_m_                          yes 
          <yes or no'::= 
P_p_p_                          no 
           
          <pass no'::=    1   3   4   5   6 
           
          <bin file'      is a file descriptor describing the backing
                          storage area where the object module ends. If
                          omitted, "pass6code" is assumed. 
                           
          <context'       is a text file containing declarations of types,
                          constants, and external routines. The syntax is
                          described in appendix B.2. 
                           
          <source'        is a text file defining a process or a prefix. If
                          no source is specified, the compiler reads the
                          source from current input. 
                           
          list            list.yes turns on listing of input on current
                          output. List.no turns listing off. 
                           \f

          stop            stop.<pass no' terminates the translation after
                          the specified pass. The passes perform 
                               1: syntax analysis 
                          3: machine independent semantic analysis 
                          4: storage allocation and machine dependent
                             semantic analysis 
                          5: code selection 
                          6: code assembly 
                           
          lib.<lib file'  specifies a user defined PI-1 library containing
                          Z80 assembler routines (see chapter 4 and
                          appendices D and F). 
                          <lib.file' must be a file descriptor describing
                          the library. 
                          If the same routine is in the user library and in
                          the system library, the routine from the user
                          library is included. 
                           
                   index           if index.yes is specified test on values assigned
                          to subrange variables and test on index in arrays
                          is included in the object program. If index.no is
                          specified no test is included. 
                           
          abs             if abs.yes is specified variables declared at the
                          outermost process block level are addressed by
                          absolute Z80 addresses; i.e. the program will n_o_t_
                          be reentrant. Variables declared at inner block
                          levels and in internal processes are always
                          addressed specified relative to local stack
                          frame. If abs.no is all variables are addressed
                          relative to a stack frame, and the program will
                          be reentrant. 
                           
          d_e_f_a_u_l_t_ _v_a_l_u_e_s_ 
          the call:       pascalz80 inputfile 
          is equivalent to: 
          poss6code = pascalz80 list.no stop.6 abs.no index.yes inputfile 
           
           \f

         B_._2_ _ _ _ _ _ _ _C_o_n_t_e_x_t_s_        B.2
           
          The context facility allows several input files to be specified
          for one compilation. This may be used for inclusion of (common)
          contexts (environments), i.e. constant and type definitions and
          declaration of external routines. The syntax is: 
           
          context: 
           
               context name      ;      context declarations      . 
           
           
          context declarations: 
           
           
           
P_                                 constant declaration 
                                 type declaration 
M_                                 external declaration 
           
           
          external routine declaration: 
           
P_                        procedure heading        ;        external 
M_                               function heading 
           
           \f

F_       C_._ _ _ _ _ _ _ _ _P_A_S_C_A_L_Z_8_0_ _E_R_R_O_R_ _M_E_S_S_A_G_E_S_    C.
           
C_._1_ _ _ _ _ _ _ _M_e_s_s_a_g_e_s_ _f_r_o_m_ _P_a_s_s_ _1_ C.1
           
           0  Illegal character or fatal error 
           1  Context expected 
           2  Idenfier expected 
           3  >;> expected 
           4  Identifier expected 
           5  >,> or >:> expected 
           6  Error in declaration 
           7  Set element or >.)> expected 
           8  Constant, variable, or >(<expression')> expected 
           9  Expression expected 
          10  Actual parameter expected 
          11  Expression expected 
          12  >of> expected 
          13  >(> expected 
          14  Identifier or >?> expected 
          15  >)> expected 
          16  Only >array>, >record>, and >set> can be packed structure 
          17  >..> expected 
          18  >)> or >,> expected 
          19  >)> or >,> expected in array declaration 
          20  >end> or >;> expected 
          21  >,> or >.)> expected 
          22  >;> or >)> expected 
          23  >:> expected 
          24  Unsigned integer expected 
          25  >:> expected 
          26  >begin> expected 
          27  Error in for-variable specification 
          28  >to> or >downto> expected 
          29  >of> expected 
          30  Error in channel-variable specification 
          31  >do> or >,> expected 
          32  >do> expected 
          33  >then> expected 
          34  Label expected (name or integer) \f

                    35  >,> or >:> expected 
           36  >else> expected 
           37  >;>, >end> or >otherwise> expected 
           38  >until> expected 
           39  Label definition expected (integer or name) 
           40  Error in label list (>,> or >;> expected) 
           41  >=> expected 
           42  Environment specification expected 
           43  >process> or >include> expected 
           44  >.> expected 
           45  >process> or >prefix> expected 
           46  Only procedure or function declaration allowed in a prefix 
           47  End of process expected 
          100  Error in real constant: digit expected 
          101  String did not terminate within line 
          102  Line too long, more than 150 characters 
           
          The following messages indicating fatal errors may appear from
          pass1 of the PASCAL80 compiler. The message will be preceded by
          the line just being parsed with an indication of error number 0
          discovered. 
           
          E.g. 
          917   21   if prod = 1305   then 
                                     0 
          ***   const >chbufmax> too small 
           
          In case no other errors are discovered a fatal error may indicate
          that one or more of the compiler tables are insufficient in size.
          But most often this kind of fatal errors appear in consequence of
          syntactical errors, and after correction of the marked errors the
          fatal error may disappear. 
           \f

          The messages are: 
           
          ***parse stack overflow.const >stackmax> too small 
             Parsing of a too small syntactical construction. 
              
                   ***end of file encountered 
             Input exhausted before the process/prefix has been satisfied. 
              
          ***recovery abandoned 
             The error recovery was unsuccessful. 
              
          ***reduction buffer overflow.const >redumax> too small 
             Parsing of a too complicated syntactical construction. 
              
          ***const >stringmax> too small 
             Literal text string too long. 
              
          ***const >chbufmax> too small 
             Parsing of a too complicated syntactical construction. 
              
          ***const >maxnamenodeindex> too small 
             Too many very long names. 
              
          ***const >maxnameheads> too small 
             Too many different names. 
              
          ***const >typebuffersize> too small 
             Too complicated type definition. 
              
           
           \f

C_._2_ _ _ _ _ _ _ _M_e_s_s_a_g_e_s_ _f_r_o_m_ _P_a_s_s_ _3_     C.2
           
          Error messages from pass 3 have the format: 
           
          ***pass 3 line <lineno', <operand no' <text' 
           
          where: 
           
          <lineno' is the line number where the error is detected 
           
          <operand no' gives a hint of where in the line the error was. 
           
                        Operands are: identifiers and numbers (Note: the empty set
               does not count). 
                
               First operand in a line has number 1. (Note: if <operand no'
               is 0, the error occurred before the first operand in the
               line, maybe even in the last part of the previous line). 
           
          undeclared, 
          (*identifier not declared*) 
           
          inconsistent _use, 
          (*identifier used before declaration*) 
           
          double _declaration, 
          (*identifier already declared at this level*) 
           
          label _not _declared, 
          (*label-identification not declared at all*) 
           
          not _label _name, 
          (*other identifier used as label-name*) 
           
          multiple _defined _label, 
          (*label defined several times at this level*) 
           
          label _not _locally _declared, 
          (*label-identifier declared at surrounding level*) 
                    \f

          erroneous _label, 
          (*use of a multiple defined label*) 
           
          label _used _from _inner, 
          (*a label-ident has been used in inner routine*) 
           
          label _used _outside _scope, 
          (*goto leading into control-structure*) 
           
          label _defined _outside _lock _or _channel, 
          (*goto out of lock- or channel statements*) 
           
                   not _typename, 
          (*identifier is not a type-identifier*) 
           
          recursive _use _of _type, 
          (*error in record or array etc.*) 
           
          recursive _constant _use, 
          (*constant is used in its own definition-expression*) 
           
          illegal _pool _type, 
          (*pool ... of <illegal type'*) 
           
          pool _cardinality _must _be _integer, 
          (*illegal size>ing of pool type*) 
           
          subrange _elems _must _be _enumeration, 
          (*illegal limit-types in subrange def*) 
           
          type _may _only _be _used _at _process _level, 
          (*nb: semaphore, pool*) 
           
          process _only _allowed _at _processlevel, 
          (*processes inside functions/procedures forbidden*) 
           
          external _only _at _processlevel, 
          (*restriction on >external>*) 
           \f

          illegal _formal _type, 
          (*formal type may not be used in this context*) 
           
          illegal _function _type, 
          (*functiontype may not contain: semaphore etc.*) 
           
          paramlist _changed _since _forwarddecl, 
          (*>new> paramlist may be empty or exact the same*) 
           
          forward _not _solved, 
          (*forward-declared routine not followed with the real body*) 
           
                   funcval _not _used, 
          (*function-value has not been defined at all*) 
           
          type _has _pointers, 
          (*locktype contains pointer-types*) 
           
          type _has _systemtypes, 
          (*locktype contains semaphore, reference, shadow, pool*) 
           
          operands _incompatible, 
          (*operands not of same typename*) 
           
          for _incompatible, 
          (*for-variable/startvalue/endvalue not of compatible types*) 
           
          case _incompatible, 
          (*case-expression/caselabels not of compatible types*) 
           
          if _type, 
          (*if-expression must be boolean type*) 
           
          repeat _type, 
          (*until-expression must be boolean type*) 
           
          while _type, 
          (*while-expression must be boolean type*) 
           \f

          with _type, 
          (*with-variable must be a record*) 
           
          lock _type, 
          (*lock-variable must be reference type*) 
           
          channel _type, 
          (*channel-variable must be reference type*) 
           
          not _index _type, 
          (*type of operand must be enumeration-type*) 
           
                   not _variable, 
          (*operand cannot be used as variable*) 
           
          field _must _follow _recordtype, 
          (*<variable' in front of <.' is not a record*) 
           
          name _not _fieldname, 
          (*<name' after <.' is not a fieldname of <variable'*) 
           
          must _be _pointertype _before _uparrow, 
          (*<variable' in front of <uparrow' is not a pointer*) 
           
          mixed _type _in _setlist, 
          (*elements in set-value may not be mixed*) 
           
          relation _error, 
          (*illegal mixture of types in relation*) 
           
          arithmetic _error, 
          (*illegal mixture of types in term of factor*) 
           
          monadic _error, 
          (*illegal type for monadic operator*) 
           
          real _not _implemented, 
          (*real occuring in expression*) 
           \f

          real _expression _not _implemented, 
          (*real-division of integers not impl*) 
           
          illegal _in _expr, 
          (*illegal operand kind in expression*) 
           
          too _few _parameters, 
          (*too few actual parameters to routinecall (or strucrecord*) 
           
          too _many _actual _params, 
          (*errors in routinecall*) 
           
                   too _many _values _in _record _structure, 
          (*error in structured-record constant*) 
           
          type _must _be _record _or _array, 
          (*typename in front of arglist must be ...*) 
           
          double _param _only _in _struc _const, 
          (*the >***> operator must only occur in structured-array constant*) 
           
          subscript _after _nonarray, 
          (*name in front of arglist is not of array-type*) 
           
          incompatible _index, 
          (*index-expression does not match array-declaration*) 
           
          assign _incompatible, 
          (*incompatible types in assignment*) 
           
          exchange _incompatible, 
          (*incompatible types in exchange*) 
           
          not _procedure _call, 
          (*the statement is not a procedure-call*) 
           
          variable _may _not _be _packed, 
          (*for-variable or actual var-param is packed*) 
           \f

          not _assignable, 
          (*operand may not be assigned: sem, pool, ref, shadow, frozen*) 
           
          not _exchangeable, 
          (*operand may not be exchanged: sem, pool, frozen*) 
           
          exchange _type, 
          (*type must be: reference or shadow*) 
           
          Illegal _var _param _substitution, 
          (*formal and actual type must match exactly*) 
           
                   illegal _value _param _substitution, 
          (*actual and formal types are not compatible*) 
           
          actual _may _not _be _frozen, 
          (*formal is not frozen, therefore ...*) 
           
          skipparam _only _in _struc _const, 
          (*the >?> may only occur in structured constants*) 
           
          struc _arr _impossible, 
          (*incomp. types in structured array-constant*) 
           
          struc _rec _incompatible, 
          (*incomp. types in structured record-constant*) 
           
          var _init _incompatible, 
          (*incomp. types in var-initialization*) 
           
          repetition _type, 
          (*repetition must be integer*) 
           
           \f

         C_._3_ _ _ _ _ _ _ _M_e_s_s_a_g_e_s_ _f_r_o_m_ _P_a_s_s_ _4_         C.3
           
          All error messages from pass 4 have the format: 
           
          xxx pass 4 line <no', <text' 
           
          where <no' is the line number where the error is detected. 
           
          <text' is one among the following: 
           
          subrange def.           Error in the definition of subrange type
                                  - lower bound ' upper bound. 
           
          set def.                Error in the definition of set type -
                                  lower bound of the basis subrange type is
                                  negative. 
           
                   pool def.               Error in the definition of pool type -
                                  number of elements is zero or negative. 
                
          record size             Record type ' 65536 bytes. 
           
          array size              Array type ' 65536 bytes. 
           
          constant value          Value of constant outside interval
                                  bounds. 
                
          case label range        In a case label interval first ' last. 
           
          constant                Syntax error in number. 
           
          set constant            Error in set constant, - negative
                                  constant, or an interval with first value
                                  < last value, or constant ' 1023. 
           
          times                   Wrong number of values in constant of
                                  array type. 
                \f

          not constant            Variable, or set constant used in
                                  expression, outside the statement part of
                                       a procedure or process.  
           
          stack                   Variable in a block occupies more than
                                  65536 bytes. 
           
          overflow                Value of constant or constant expression
                                  outside the interval - 32768, 32767. 
           
                   export value error      Value export of other than constant. 
           
          packed field export     Export of fields not allowed. 
           
          export offset error     Address export of variable not declared
                                  at process block level, or declared at
                                  process level of an internal process. 
                                   
                   compiler error          error in pass 4. 
                                   
          compilation terminated by <error' 
               where <error' is 
               operand overflow    
                  too complicated arithmetic expressions. 
               constant area overflow 
                  too many or too big structured constants. 
                
          Other error messages may occur, caused by fatal error in pass 4. 
           
           
C_._4_ _ _ _ _ _ _ _M_e_s_s_a_g_e_s_ _f_r_o_m_ _P_a_s_s_ _5_ 
           
          Error messages from poss 5 have the format:  
             *** pass 5 line <no', <text' 
          where <no' is the line number where the error is detected. 
           
          <text' is among the following: 
          +decl. caselabel        ambiguous caselabel 
           \f

          too many pool buffers   max. 127 buffers in pool 
           
          too many formal parameters 
                                  max. 10 formal parameters in externally
                                  defined routine 
                
          routine not implemented 
                                  call of routine which is not implemented 
           
          export name +decl.      ambiguous export name 
           
          export name <name' unknown in <routine' 
                                  Use of not defined export name. 
           
          byte overflow <name' = <value' in <routine' 
                                  value of export name ' 255. 
           
          library <name' not found 
                                    The library lib.<name' in the call, does
                                  not exist. 
             
          Other error messages may occur, caused by fatal error in pass 5. 
           
           
    C_._5_ _ _ _ _ _ _ _M_e_s_s_a_g_e_s_ _f_r_o_m_ _P_a_s_s_ _6_    C.5
           
          Only messages caused by fatal error in pass 6. 
           
           \f

F_       D_._ _ _ _ _ _ _ _ _H_O_W_ _T_O_ _B_U_I_L_D_ _A_ _P_I_-_1_ _L_I_B_R_A_R_Y_ _O_N_ _T_H_E_ _R_C_8_0_0_0_ D.
           
          With the programs >insertz80>, >listz80>, and >deletez80> it is
          possible to maintain PI-1 libraries on the RC8000. A PI-1 library
          consists of a number of named entries. The names must be RC8000
          names (FP names). There are four kinds of entries: 
           
          - Z80 routines in assembler object format 
            These routines may be included in compiled PASCAL80 programs as
            described in chapter 4. 
             
          - PASCAL80 object modules 
            The output from a pascalz80 compilation is a PASCAL80 object
            module. In fact the output file is formatted as a PI-1 library
            with one entry. 
             
          - basic routine 
             
          - reserved name 
            The latter two entry types are used in the basic compiler
            library to implement the predefined PASCAL80 routines. 
           
          The programs require at least 25000 Hw memory. 
           
           
D_._1_ _ _ _ _ _ _ _I_n_s_e_r_t_Z_8_0_ D.1
           
          The program inserts an entry in a PI-1 library. 
           
          C_a_l_l_: 
M_m_m_                                         1                             10 
          insertz80   lib.<pascal80 lib'   <entry spec'   <param spec' 
P_p_p_                                         0                              0 
           
          <pascal80 lib' is a file descriptor describing the backing
          storage area of the library. 
           
          If lib.<pascal80 lib' is omitted the name >pascal80lib> (the
          basic compiler library) is assumed. Basic routines and reserved
          names can only be inserted in this way. 
           \f

          <entry spec'::= <Z80 spec'  <obj spec'  <basic spec'  <reserve spec' 
                   The <entry spec' specifies the kind and the name of the entry to
          be inserted, and if necessary also the file from which to read
          the routine or module. It is not checked whether an entry with
          the same name is already in the library. 
           
M_m_m_                                                  1 
          <Z80 spec'::= <Z80 name'  entry.<name' 
P_p_p_                                                  0 
          The Z80 routine from the file <Z80 name' is inserted as an entry
          with name <name' in the library. If the entry parameter is not
          present the entry is given the name specified by a NAME assembler
          directive which must in this case must have been present during
          assembly. 
           
M_m_m_                                                              1 
          <obj spec'::= module.<bin file'   entry.<name' 
P_p_p_                                                           0 
             The PASCAL80 object module from the file <bin file' (same as left
          hand side of compiler call, cf. appendix B) is inserted as an
          entry with name <name'. If the entry parameter is omitted the
          entry is given the object module name; see subsection 3.1.14. 
           
          <basic spec'::= basic.<no'.<name' 
          The basic routine number <no' is inserted as an entry with name
          <name'. 
           
          <reserve spec'::= reserved.<no'.<name' 
          The entry <name' is inserted as a reserved name. 
           
          <param spec'::= <kind'. <type' 
          The parameters of the inserted routine or process must be
          described in the order of declaration. 
           
          <kind'::= val  var 
           
          <type'::= pointer  semaphore  reference 
                    shadow   pool 
                    sysr.<mem req' sysa.<mem req' <mem req' 
           \f

          Shielded and pointer types are called system types. Depending on
          the type of each parameter, specify 
          - for a system type: the type name 
          - for a record type with system component type(s): sysr 
          - for an array type with system component type(s): sysa 
          - for all other types: only <mem req'. 
          <mem req', when specified, is the memory requirement (in bytes)
          of the type (cf. chapter 5). 
           
           
         D_._2_ _ _ _ _ _ _ _D_e_l_e_t_e_Z_8_0_ D.2
           
          The program deletes entries in a PI-1 library. 
           
          C_a_l_l_: 
           
M_m_m_                                         1 
          deletez80  lib.<pascal80 lib'     <name' 
P_p_p_                                         0 
           
          The entry with name <name' is deleted in the library <pascal80 lib'. 
           
          If lib.<pascal80 lib' is omitted the name >pascal80lib> is
          assumed. 
           
           
D_._3_ _ _ _ _ _ _ _L_i_s_t_Z_8_0_ D.3
           
          The program produces a list of entries in the library on current
          output including the names and the parameters of the routines. 
           
          C_a_l_l_: 
           
M_m_m_                                      1                1  1 
          listz80  lib.<pascal80 lib'   <name'  .code  
P_p_p_                                      0                0  0 
           
          <name'   name of entry, if omitted all entries are listed. 
           
          code     if present the binary code is listed. 
           
          If lib.<pascal80 lib' is omitted the name >pascal80lib> is
          assumed. 
           
           \f

F_       E_._ _ _ _ _ _ _ _ _H_O_W_ _T_O_ _G_E_N_E_R_A_T_E_ _A_ _B_O_O_T_S_T_R_A_P_ _I_M_A_G_E_ _F_O_R_ _T_H_E_ _P_I_-_1_ _M_A_C_H_I_N_E_ _O_N_ _T_H_E_E.
          R_C_8_0_0_0_ 
           
          With the program >pilink> it is possible to generate a file
          containing the specified object modules and the necessary library
          routines. The file will be a bootstrap image, i.e. all references
          between modules are resolved, except for linking of external
          process names, and the image must be located starting from
          address 0. 
           
          Basic software for the PI-1 machine must always be included in a
          bootstrap image. The basic software exists in a number of
          versions. A bootstrap image may be a ROM image which is suitable
          for blasting in ROM or it may be a RAM image which can be loaded
          by a PI-1 machine bootstrap loader. For further details, see 2.
           
          C_a_l_l_ _o_f_ _p_i_l_i_n_k_: 
           
M_m_m_           
                                     <objfile'  .<process name'.<size' 
                         1                                              0 
            <outfile' =     pilink   lib.<libfile' 
                         0 
                                     <params' 
P_p_p_                                                                            0
           
M_m_m_                                   yes 
                           print. 
                                    no 
           
                                   yes 
                           map. 
                                    no 
          <params'::= 
                                   yes 
                           rom. 
                                    no 
           
P_p_p_                           basic.<basic system' 
              
                   <size'::= integer 
           
          <outfile' 
          <objfile' 
          <process name'       ::= <name' 
          <libfile' 
          <basic system' 
           \f

                   <outfile' 
          A file descriptor describing the document where the bootstrap
          image is output. If no outfile is specified the bootstrap image
          is output to an anonymous work file. 
           
          <objfile' 
          A file descriptor describing a document containing one or more
          modules which are all included in the coreimage. The objfile may
          be the output from a pascalz80 compilation or a PI-1 library file
          created by >insertz80> (see appendix D). 
           
          <process name'.<size' 
          If any of the modules in an objfile are not reentrant processes,
          the <objfile' specification must be followed by the names of
          these processes, and their stack sizes. 
           
          lib. <libfile' 
          <libfile' is a file descriptor describing a document containing a
          PI-1 library (i.e. separately compiled routine). A module boot-
          strap from a libfile is included in the image, if it is referen-
          ced from an included module. 
           
          basis.<basic system' 
          <basic system must be a file descriptor describing a document
          containing PI-1 basic software. There must be precisely one
          occurence of this parameter in a call of pilink. 
           
          rom.yes 
          The bootstrap is created as a ROM image. 
           
          rom.no 
          The bootstrap is created as a RAM image. The rom parameter may
          occur at most once. Default rom.no. 
           
          map.yes 
          For each module included in the bootstrap, a line is listed, on
          current output, containing module name and the addresses of
          linker table entry, start, entry, and the date the module is
          compiled. For a non-reentrant process the first address of the
              stack is also listed. 
           \f

          The map parameter may occur at most once. Default map.no. 
           
          print.yes 
          print.no 
          Controls printing of the bootstrap image on current output. The
          print parameter affects only printing of modules included from
          files specified after the print parameter. 
          The initial setting is print.no. 
           
           
E_._1_ _ _ _ _ _ _ _E_r_r_o_r_ _M_e_s_s_a_g_e_s_     E.1
                    
          ***pilink param <illegal parameter' 
             Illegal parameter syntax. The parameter is ignored. 
              
          ***pilink too many parameters 
             Too many parameters in the call. 
              
          ***pilink <name' unknown 
             Document with <name' unknown. 
              
          ***pilink stack size for <name' missing 
             Stack size for non-reentrant process module missing. 
              
          ***pilink <name' + declaration 
             Two modules with same name not allowed. 
              
          ***pilink byte overflow in <name' 
             Error in user Z80 assembler routine included in module with
             <name'. 
              
          ***pilink <name' too big 
             Max module size (20000 bytes) exceeded. 
              
          ***pilink program too big 
             Max bootstrap image size (64 K bytes) exceeded. 
              
          ***pilink stack too big 
             Stack top for module exceeds 64 K bytes. 
              \f

                   ***pilink too many modules 
             Max number of modules in image exceeded (max = 75). 
              
          ***pilink too many sections in <name' 
             Too many user Z80 assembler routines in module <name'  
             (max = 30). 
              
          ***pilink too many externals in <name' 
             Max number of externals in module <name' exceeded (max = 50). 
              
          ***pilink fatal error 
             Program error. 
              
          Other error messages may occur, caused by fatal error in pilink. 
           
           \f

F_       F_._ _ _ _ _ _ _ _ _H_O_W_ _T_O_ _T_R_A_N_S_F_E_R_ _B_I_N_A_R_Y_ _F_I_L_E_S_ _B_E_T_W_E_E_N_ _T_H_E_ _R_C_8_0_0_0_ _A_N_D_ _T_H_E_ _T_E_K_T_R_O_N_I_X_F.
          8_0_0_2_A_ _D_E_V_E_L_O_P_M_E_N_T_ _S_Y_S_T_E_M_ 
           
          The object code is transferred between the two computers in the
          Tekhex textformat 3. This format represents binary code as
          ASCII-encoded hexadecimal digits (two digits per byte of code).
          Each block is identified with a header character, a slash charac-
          ter, and includes two checksums. 
           
          Transferring data between RC8000 and Tektronix is done with
          Tektronix in the COMM operation mode 3. 
           
          To convert object code between Tektex and binary two utility
          programs are available on the Tektronix development system called
          >CB> (convert to binary) and >CT> (convert to Tektex). 
           
          On the RC8000 the program >tekmove> takes care of receiving
          Tektex blocks from Tektronix and converting them to binary, as
          well as converting binary to Tektex blocks and transmitting them
          to Tektronix. 
           
           
   F_._1_ _ _ _ _ _ _ _T_e_k_t_r_o_n_i_x_ _U_t_i_l_i_t_y_ _P_r_o_g_r_a_m_ _>_C_T_>_ F.1
           
          The program converts a binary file on the Tektronix development
          system to a file in the Tekhex format. 
           
          C_a_l_l_: 
           
          XEQ   CT  <binfile'  <tektexfile' 
           
          <binfile'::=    name of the binary file (input) 
          <tektexfile'::= name of the Tekhex file (output) 
           
           \f

F_._2_ _ _ _ _ _ _ _T_e_k_t_r_o_n_i_x_ _U_t_i_l_i_t_y_ _P_r_o_g_r_a_m_ _>_C_B_>_ F.2
           
          The program converts a file in the Tekhex textformat, (transfer-
          red from RC8000) to a binary file. 
           
                   C_a_l_l_: 
           
          XEQ  CB  <tektexfile' <binfile' 
           
          <tektexfile'::= name of the Tekhex file (input) 
          <binfile'   ::= name of the binary file (output) 
           
           
         F_._3_ _ _ _ _ _ _ _R_C_8_0_0_0_ _U_t_i_l_i_t_y_ _P_r_o_g_r_a_m_ _>_t_e_k_m_o_v_e_>_ F.3
           
          The program performs conversion and transfer of files between
          RC8000 and Tektronix. 
           
          C_a_l_l_: 
           
M_m_m_                   to                             1 
          tekmove         <file'    block.<size'
P_p_p_                   from                           0 
           
          to     The program reads Tekhex blocks from the file with
                 descriptor >v>, (terminal input, i.e. the Tektronix system
                 in the COMM mode) and converts them into the bs area with
                 the name <file'. 
                  
          from   The program reads from the bs area <file', converts the
                 contents to Tekhex blocks and writes these into the file
                 with descriptor >v> (terminal output, i.e. the Tektronix
                 system). 
                  
          block  The blocks transferred from RC8000 to Tektronix contain
                 <size' hexadecimal bytes of data. Default block length is
                 58 hexadecimal bytes. 
                  
          The program can run under the operating systems >s> and >sos>. 
           
           \f

F_._4_ _ _ _ _ _ _ _E_x_a_m_p_l_e_s_ _o_f_ _H_o_w_ _t_o_ _T_r_a_n_s_f_e_r_ _P_r_o_g_r_a_m_s_ F.4
           
          The RC8000 is supposed to be connected to the 8002A via the
          remote input/output (jack J101), and commands are entered on the
          8002A system terminal (jack J100). 
           
          a_)_ _T_r_a_n_s_f_e_r_r_i_n_g_ _p_r_o_g_r_a_m_s_ _f_r_o_m_ _8_0_0_2_A_ _t_o_ _R_C_8_0_0_0_ 
           
          In the example a program >TEST> on the 8002A is transferred to a
          file >test> on RC8000. 
          The program is converted to Tekhex format by typing: 
           
               XEQ   CT  TEST  TESTH <CR' 
           
                   Now the file TESTH contains the file TEST in Tekhex format. 
           
          The COMM terminal level is entered by typing: 
           
               COMM  M=0  T=1  P=7 <CR' 
           
          After enrolling by the operating system on RC8000 (>sos> or >s>)
          the program >tekmove> is called: 
           
               tekmove to test CNTRL@<TESTH <CR' 
           
          The command makes the 8002A enter the transfer level and >TESTH>
          is transferred to the file >test> on RC8000. 
           
          After a successful transfer the 8002A automatically re-enters the
          terminal level. 
           
          By typing CNTRL@ ESC you exit from COMM and get back in normal
          mode. 
           \f

          b_)_ _T_r_a_n_s_f_e_r_r_i_n_g_ _p_r_o_g_r_a_m_s_ _f_r_o_m_ _R_C_8_0_0_0_ _t_o_ _8_0_0_2_A_ 
           
          COMM is entered as described in a). After enrolling by the
          operating system the transfer is performed by typing: 
           
               tekmove from test CNTRL@'TESTH<CR' 
           
          The file >test> on RC8000 is transferred to the file >TESTH>
          (Tekhex format) on 8002A. After exit from COMM the Tektex file is
          converted to binary by typing: 
           
               XEQ  CB  TESTH  TEST 
           
               \f

                    
           \f

«eof»