There are two assemblers on the 1906A at ACL - PLAN and PLASYD. The earlier system is PLAN which is a conventional assembler and is defined in the ICL PLAN Reference Manual (TP No 4322). This contains complete specifications of all the instructions and facilities available in the various versions of PLAN. PLASYD is an implementation language and has been used internally by ICL to write the more recent compiler software. Whereas PLAN is a fixed format language with, in most cases, a 1-1 correspondence between PLAN instructions and 1900 orders generated, PLASYD is ALGOL-like and consequently is more readable if carefully laid out. In some cases, the quality of code produced by PLASYD may be slightly worse than PLAN but this is usually compensated for by the improvement in readability. The main deficiency of PLASYD is its lack of a macro feature.
A complete description of the PLASYD language and how it interfaces with FORTRAN and ALGOL is given in the PLASYD Manual produced by and available from ACL. Users are strongly advised to use PLASYD in preference to PLAN.
The examples given below show some simple programs coded in both PLASYD and PLAN. In each case, the PLASYD program is given first.
LOWER INTEGER A,B,C(10); LOWEND; INTEGER D,E(5); -------------------------- #LOWER A,B,C(10) #UPPER D,E(5)
X1:=A+B; C:=X1; -------------------------- LDX 1 A ADX 1 B STO 1 C
IF X2 <CH 3 THEN X1:=0; -------------------------- TXL 2 '3' BCC L2 L1 LDN 1 0 L2
FOR X1:=A STEP -1 UNTIL 3 DO C(X1):=0; -------------------------- LDX 1 A L1 STOZ LIA(1) SBN 1 3 BZE 1 L2 ADN 1 2 BRN L1 L2
PLASYD, standing for Programming LAnguage for SYstem Development, was designed in mid-1968 as a basic tool for the production of new optimising and conversational FORTRAN compilers for the ICL 1900 series of computers. Although previous scientific compilers for the 1900 series have used special purpose languages for syntax analysis and other specialised tasks, a large amount of the coding was done in PLAN. It was felt that for the new project a more systematic, easily intelligible and maintainable language would be preferable.
PLASYD needed to use all the machine facilities efficiently and also have an algorithmic structure to aid readability. These conditions pointed to an implementation language similar to PL360 but adapted for the 1900 series order code. PL360's block structure and all operations concerned with flow of control were adapted almost intact, being virtually machine independent. However, storage types and method of manipulating them had to be modified to fit in with the 1900 series architecture. In particular, a method of exploiting the directly and indirectly addressable areas of data storage on the 1900 was devised.
PLASYD is superficially ALGOL-like, having a block structure, type and procedure declarations, a similar form of identifiers and similar assignment and control statements. However, recursion is not provided automatically and consequently all storage assignments may be made at compile time. The compiler generates semicompiled output similar to other 1900 series compilers. Segmentation and common storage are provided in the language so that it is possible to compile PLASYD routines which can communicate with both FORTRAN and ALGOL programs. Consequently, it is quite feasible to recede the most frequently-used routines of a program in PLASYD for greater efficiency.
The most fundamental difference between PLASYD and high level programming languages is the splitting of variables into two classes, accumulators and cells. Accumulators correspond directly to the 1900 integer and floating point accumulators, whereas cells require storage and correspond closely to variables in high level languages. The ability to specify the accumulators to be used gives the programmer control over the form of instructions to be compiled. Unlike high level languages, assignment statements do not allow parentheses and all operators, including the assignment itself, are obeyed strictly from left to right. For example, the statement:
X1 := A-B AND 3 SRL 2;
produces code:
In general, each operator/operand pair in an assignment statement produces a single machine code instruction. However, in some cases than one instruction may be generated.
PLASYD is a free format language except that reserved words, such as BEGIN, must be delimited by spaces or newlines.
A special library of useful PLASYD routines exists at ACL. Further details can be obtained from the Program Advisory Office.
The main ICL publication is the PLAN Reference Manual (Publication No 4322). This contains a full specification of the instructions and facilities available in the various PLAN dialects (PLAN 4 is used at ACL). The TASK Manual describes how to run PLAN programs at ACL. Details of a PLAN preprocessor and information peculiar to the 1906A here are given in the 1900 PLAN Supplement produced by the Laboratory.
The aim of this chapter is to outline the main features of PLAN 4 in such a way that a simple understanding of PLAN is obtained. This Part should be read in conjunction with Part Y which outlines the 1900 order code and gives the mnemonics used for individual 1900 instructions.
A PLAN program consists of a sequence of statements of the following types:
PLAN statements can occur in any sequence except that every program or segment must start with a #PROGRAM directive and end with a SEND directive.
A PLAN segment or program may be preceded by a number of control parameters. If none is given, a default set is provided by the TASK system by inclusion of the PD parameter.
The store required by a PLAN program is divided into the following areas:
The Lower Data Store must be completely within the first 4096 location of the program while the other areas may fall beyond this range.
This area of store can be accessed directly without index modification, and is, therefore, used to hold the data accessed most frequently. Symbols appearing in the operand field of a non-branch instruction are allocated space here automatically. However, the #LOWER directive defines data storage explicitly and is recommended in preference to the implied declaration.
As source program instructions are read, machine orders are compiled consecutively in this area. Any symbol appearing in the label field of an instruction will be given a value equal to the address of the compiled instruction. Symbols appearing in the operand field of branch instructions will be assumed to be labels even if they have not yet been defined.
The Upper Data Store can be completely outside the first 4096 location and, consequently, data in this area may only be addressed indirectly by modification. It is normally used for large tables and arrays which are naturally addressed in this way. Areas of Upper Data Store are given symbolic names by the #UPPER directive.
This is defined immediately above Upper Data Store and can be as long as the remaining available store. It is used for data whose length is unknown until execution time. An area is specified as the stack by a #ELASTIC directive.
PLAN programs are submitted either on cards or at a MOP terminal. One statement is written per line in the following format:
Character Positions 1-5 Label field for operation statement 1-11 Label field for constant data statement 7-11 Operation field 13-14 Accumulator field 16-72 Operand field 73-80 Identification
Each field except the operand field must be left-justified. Blanks are ignored in the operand field unless they are part of a text string. Symbolic names consist of alphanumeric strings with the first character alphabetic. The contents of the various fields are:
A simpler layout for PLAN statements is available via the PLAN preprocessor described in ACL's 1900 PLAN Supplement.
Data statements are usually made under the control of a #LOWER or #UPPER directive. The last one that appears remains in control until another command appears. Variable data statements cause storage to be allocated in either the upper or lower variable data store while constant data statements cause storage to be allocated in the preset area.
The names of the storage areas are written in the operand field and can be up to 11 characters in length and separated by commas. If the allocated area is more than one word long, the length must be given in brackets following the name. For example:
#LOWER VEL,A1,A2,ARRY(20),C1,DEFN #UPPER UP1,UP2,UP3
If a location is to contain a specific value, the name is written in the label field and the value in the operand field. If the area is to contain several constants, these may be separated by commas. The constant values may be defined as:
For example:
DATANAME #717,23,-57,1.75E-03,-2.86E+12 DATATWO 8HABCDEFGH,8/DATATWO.0
A typical format for an operation statement is:
FFF X NNN(M)
where
FFF is the instruction mnenomic (Y.2.3) X is the accumulator 0-7 NNN is the operand M is 1, 2 or 3, the modifier
Typical examples are:
LDX 1 DATANAME(2) STO 1 VEL+2
The operand field defines the address of a word of storage or instruction and, in some cases, it can be an integer (a shift instruction, for example). Some possible operands are:
LDN 1 23+7 LDN 2 A2-A1 ADN 3 #73 SLC 3 2(1)
LDX 1 VEL+2 ADX 2 C1-7
LDX 1 '#273' LDX 2 '3HABC'
BRN *+3
All directives are preceded by the # symbol. A description of the more important ones is given below. If the symbol # is followed by a space then a comment may be placed in the operand field. A comment will be listed in the compiler printout. It will have no other effect.
The CUE directive has a single parameter in the operand field which is an alphanumeric name by which the next location can be referenced from another segment of the program. A replacer, which is a location containing the address of the CUEd location, is automatically generated in Extended Branch Mode and can be used by a replaced branch instruction.
The DEFINE directive has in its operand field a name followed by a = symbol and a value. The name may be used in place of the value in subsequent PLAN instructions. This directive allows the form of a program to change significantly just by changing the DEFINE directive. Examples are:
#DEFINE SIZE=27 #DEFINE SIZEP1=SIZE+1 #DEFINE MASK=#77
This directive defines the following variable data statements as allocating storage in the Stack area which is placed at the top of the program's storage area. The ELASTIC directive is of the form:
#ELASTIC COMMON/TOPNAME/
The area is given a name (TOPNAME in the example) which must be unique within the program. All segments using this area should have an ELASTIC directive. Only one such area may be defined and it cannot contain preset values.
This directive indicates the end of a program segment.
The ENTRY directive has a single digit parameter in the operand field. It defines an entry point for the program with the digit specifying which one. At least one entry point should be specified in a program.
The LOWER directive indicates that the following data statements require storage in the lower data store (N.3.2).
The MACRO command indicates the start of a macro definition. On the next line, the name of the macro directive must appear in the operation field with any parameters given in the operand field separated by commas. Each parameter must be a single letter of the alphabet. Following this line will a ppear the instructions making up the macro with parameters given in place of actual arguments. A call of the macro has the same form as the line defining the macro name but with actual arguments replacing the parameters. The macro definition is terminated by the next directive. An example macro is:
#MACRO ADDS A,B,C,D LDX D A ADX D B STO D C
An example call is:
ADDS ARG1,ARG2,RES,3
This would be equivalent to writing:
LDX 3 ARG1 ADX 3 ARG2 STO 3 RES
Data statements may appear in a macro but only one item may be defined on each line.
The MONITOR directive defines areas of store to be printed out during the execution of the program. The user may insert MONITOR requests at various points in his program. Whether or not printing actually takes place will depend on the current settings of switches corresponding to bits 0 to 9 of word 30 of each program.
The MONITOR directive is of the following form:
#MONITOR n/m c/a c/a ...
The parameters are as follows:
n = an integer in the range 0 to 511 that gives the number of c/a parameters following
m = a three digit number where the first digit defines the switch which will determine whether printing will take place and where the remaining two digits can be used to identify the point in the source program from which the output comes. It is usual to have the m values for different monitor points unique. If 1000 is added to the m value, the contents of the accumulators will not be printed.
c = number of words of store to be printed out. The count must be less than 512
a = address of first word of store to be printed. The format of the printout is as follows:
An example is:
MONITOR 1/501 47/STADR
The ORDER directive can only appear in the steering segment for an overlay program. It indicates that the segments will be presented in the sequence required for consolidation. The program must be presented in the order:
The OVERLAY directive can only appear in the steering segment. An overlay program consists of an area of permanent storage and a number of overlay areas. Each overlay area can hold only one of a number of overlay units. The OVERLAY directive is of the following form:
#OVERLAY (1/1)SEG1,(1/2)SEG2 (2/1)SEG3,(2/2)SEG4,(2/3)SEG5 (3/1)SEG5,(3/2)SEG7
Each line consists of a set of entries separated by commas which define the overlay structure. These entries have the form:
(A/U)SEG
where:
A is the area number in the range 1 to 255 U is the unit number in the range 1 to 1023 SEG is the segment name.
The example above has three areas. The second area has three units (SEG3,SEG4,SEG5), only one of which can be in the area at a time.
The PAGE directive will insert a page-throw before continuing the compilation listing.
The PERMANENT directive defines those segments of an overlayed program which are to reside permanently in store. A list of the segments separated by commas is given in the operand field. The directive should appear in the operand field.
This directive is similar to LOWER but defines the area as PURE.
The PMODE directive defines the address and branch modes to be used. The possibilities are 15AM,22AM,DBM,EBM. For example:
#PMODE 22AM,EBM
It is only effective in a steering segment.
This directive is similar to UPPER but defines the area as PURE.
The PROGRAM directive is used to name the program or segment, specify the address and branch modes and indicate if it is pure. In the operand field, the directive has the program name (if any) followed by a / symbol and the segment name for a segment. The complete program must be preceded by a PROGRAM directive which just defines the name of the program.. Following the names, the address and branch mode may be specified as a list separated by commas and within brackets. It is also possible to define impure code. For example:
//PROGRAM XXXX/ SEGMNTNM(15AM,22AM,EBM,IMPURE)
This example indicates a program that needs to work in both 15-bit and 22-bit address mode.
The SET directive is similar to DEFINE except that the same name may be redefined by another SET directive.
This directive introduces a steering line which controls the options available at compilation time. More than one option can be defined separated by commas. The possibilities are:
This directive indicates that the succeeding statements are data statements requiring storage space in the upper data area (N.3.4).
A PLAN segment or program to be compiled can be preceded by a number of control parameters. If none are given, a default set is provided by the TASK system. The control parameters are written one on each line. The most commonly used ones are given below. Control parameters start in the first column.
This parameter is optional and, if present, must be the first one. It has the form:
PROG (NAME)
The parameter NAME is any four-character name and this name is used as the object program name overriding any program name given in a PROGRAM directive. The default setting in TASK is:
PROG(PLAN)
This parameter causes all files still open to be closed and peripherals to be released. The whole program must end with an ENDPROG.
OUT(filename) OUT(filename,csn)
The first defines the specified filestore file as the output file and opens it. The second defines an exofile where csn is the cartridge serial number. The default setting used by TASK is:
OUT (A)
The filenames are, in fact, dummy names.
IN(x,filename,csn) for exofiles IN(x,filename,tsn) for magnetic tapes
The specified file is opened for reading input. The parameter x is a digit between 1 and 4 which can be used as a shorthand way of referring to the file. The parameter tsn defines the tape serial number.
REN(filename)
The output file specified in the immediately preceding parameter is renamed.
WSF(name)
A new subfile is opened on the output file (this must already be open). The subfile remains open until another WSF is encountered. The default setting by TASK is:
WSF(SUBROUTINES)
If no WSF parameter is present, no semicompiled will be produced.
STEER(opt,opt,...)
A STEER parameter will control the steering of all segments. The parameters opt may be from the set given in N.3.6.18. The default setting by TASK is:
STEER(LIST,OBJECT)
If OBJECT is not specified, no semicompiled output will be produced.
PLAN(CR) PLAN(TR)
This parameter defines whether the source for the next segment is on cards or paper tape. It is necessary to have, for example, a PLAN(CR) parameter between each segment of the program.
NEXT(DMY)
This causes the compiler to delete itself at the end of the compilation.
BIN BIN(filename)
This causes automatic consolidation to take place. If filename is omitted, the binary program produced is left in core ready to be run (this is TASK default); otherwise, it will be written to the specified direct access file.